from inspect import getcomments
from pickle import FALSE, TRUE
import ee
import geemap
import datetime
import pandas as pd
import shapely.wkt
import multiprocessing
ee.Initialize()

visParamsTrue = {'bands': ['B4', 'B3', 'B2'], min: 0, max: 2000}
CLOUD_FILTER = 50
CLD_PRB_THRESH = 50
NIR_DRK_THRESH = 0.15
CLD_PRJ_DIST = 1
BUFFER = 5

def transformPolygon(polygon):
    Polygon = shapely.wkt.loads(polygon)
    input_polygon = shapely.wkt.dumps(Polygon)[10:-2]
    split_polygon = input_polygon.split(",")
    return_arr = []
    for sub_arr in split_polygon:
        split_subarr = sub_arr.split(" ")
        clean_split_subbarr = list(filter(None, split_subarr))
        return_arr.append(clean_split_subbarr)
    return_str = [[float(c) for c in row] for row in return_arr]
    return return_str

def get_s2_sr_cld_col(geom, start_date, end_date):
    s2_sr_col = (ee.ImageCollection('COPERNICUS/S2_SR')
                 .filterBounds(geom)
                 .filterDate(start_date, end_date)
                 .sort('CLOUD_COVERAGE_ASSESSMENT'))
                # .filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', CLOUD_FILTER)))
    s2_cloudless_col = (ee.ImageCollection('COPERNICUS/S2_CLOUD_PROBABILITY')
                        .filterBounds(geom)
                        .filterDate(start_date, end_date))
    return ee.ImageCollection(ee.Join.saveFirst('s2cloudless').apply(
        primary=s2_sr_col,
        secondary=s2_cloudless_col,
        condition=ee.Filter.equals(
            leftField='system:index',
            rightField='system:index'
        )
    ))

def add_cloud_bands(img):
    cld_prb = ee.Image(img.get('s2cloudless')).select('probability')
    is_cloud = cld_prb.gt(CLD_PRB_THRESH).rename('clouds')
    return img.addBands(ee.Image([cld_prb, is_cloud]))

def add_shadow_bands(img):
    not_water = img.select('SCL').neq(6)
    SR_BAND_SCALE = 1e4
    dark_pixels = img.select('B8').lt(
        NIR_DRK_THRESH*SR_BAND_SCALE).multiply(not_water).rename('dark_pixels')
    shadow_azimuth = ee.Number(90).subtract(
        ee.Number(img.get('MEAN_SOLAR_AZIMUTH_ANGLE')))
    cld_proj = (img.select('clouds').directionalDistanceTransform(shadow_azimuth, CLD_PRJ_DIST*10)
                # .reproject({'crs': img.select(0).projection(), 'scale': 100})
                .select('distance')
                .mask()
                .rename('cloud_transform'))
    shadows = cld_proj.multiply(dark_pixels).rename('shadows')
    return img.addBands(ee.Image([dark_pixels, cld_proj, shadows]))

def add_cld_shdw_mask(img):
    img_cloud = add_cloud_bands(img)
    img_cloud_shadow = add_shadow_bands(img_cloud)
    is_cld_shdw = img_cloud_shadow.select('clouds').add(
        img_cloud_shadow.select('shadows')).gt(0)
    is_cld_shdw2 = (is_cld_shdw.focal_min(2).focal_max(BUFFER*2/20)
                    # .reproject({'crs': img.select([0]).projection(), 'scale': 20})
                    .rename('cloudmask'))
    return img_cloud_shadow.addBands(is_cld_shdw2)

def apply_cld_shdw_mask(img):
    not_cld_shdw = img.select('cloudmask').Not()
    return img.select('B.*').updateMask(not_cld_shdw)

def calculate_ndvi_ndwi(image_masked, geom):
    ndwi = image_masked.normalizedDifference(['B3', 'B8']).rename('NDWI')
    ndvi = image_masked.normalizedDifference(['B8', 'B4']).rename('NDVI')
    # print('NDWI')
    avg_ndwi_mosaic = ndwi.reduceRegion(
        ee.Reducer.mean(), geom, 10).get('NDWI').getInfo()
    # max = ndwi.reduceRegion(ee.Reducer.max(), geom, 10).get('NDWI').getInfo()
    # min = ndwi.reduceRegion(ee.Reducer.min(), geom, 10).get('NDWI').getInfo()
    # print('avg', avg_ndwi_mosaic, 'min', min, 'max', max)
    ndwiParams = {min: -1, max: 1, 'palette': ['8E3200', '#A64B2A', 'D7A86E',
                                               '#FFEBC1', '#E3CAA5', '#d7efa9', '#9ecae1', '#4292c6', '#2171b5', '#08519c']}
    # if (avg_ndwi_mosaic >= -1 and avg_ndwi_mosaic <= -0.3):
    #     print("NDWI result: Drought")
    # elif(avg_ndwi_mosaic >= -0.3 and avg_ndwi_mosaic <= 0.0):
    #     print("NDWI result: Moderately Drought")
    # elif(avg_ndwi_mosaic >= 0.0 and avg_ndwi_mosaic <= 0.2):
    #     print("NDWI result: Flood")
    # else:
    #     print("NDWI result: Water surface")
    flood_threshold_ndwi = 0
    flood_ndwi = ndwi.gte(flood_threshold_ndwi).selfMask()
    flood_pixel_area_ndwi = flood_ndwi.multiply(ee.Image.pixelArea())
    flood_area_ndwi = flood_pixel_area_ndwi.reduceRegion(**{
        'reducer': ee.Reducer.sum(),
        'geometry': geom,
        'scale': 10
    })
    # print(flood_area_ndwi.getInfo(), 'flood area ndwi')
    drought_threshold1_ndwi = 0
    drought_ndwi = ndwi.lt(drought_threshold1_ndwi).selfMask()
    drought_pixel_area_ndwi = drought_ndwi.multiply(ee.Image.pixelArea())
    drought_area_ndwi = drought_pixel_area_ndwi.reduceRegion(**{
        'reducer': ee.Reducer.sum(),
        'geometry': geom,
        'scale': 10
    })
    # print(drought_area_ndwi.getInfo(), 'drought area ndwi')
    # print('NDVI')
    avg_ndvi_mosaic = ndvi.reduceRegion(
        ee.Reducer.mean(), geom, 10).get('NDVI').getInfo()
    # max = ndvi.reduceRegion(ee.Reducer.max(), geom, 10).get('NDVI').getInfo()
    # min = ndvi.reduceRegion(ee.Reducer.min(), geom, 10).get('NDVI').getInfo()
    # print('avg', avg_ndvi_mosaic, 'min', min, 'max', max)
    ndviParams = {min: -1, max: 1, 'palette': ['#08306b', '#0850d1', '#2171b5',
                                               '#4292c6', '#9ecae1', '#b8d4e1', '#d7a86e', '#e9efc0', '#83bd75', '#4e944f']}
    # if (avg_ndvi_mosaic >= 0.1 and avg_ndvi_mosaic <= 0.4):
    #     print("NDVI result: Drought")
    # elif(avg_ndvi_mosaic > 0.4 and avg_ndvi_mosaic <= 1):
    #     print("NDVI result: Vegetation")
    # elif(avg_ndvi_mosaic >= -1 and avg_ndvi_mosaic < 0.1):
    #     print("NDVI result: Flood")

    flood_threshold_ndvi = 0.17
    flood_ndvi = ndvi.lt(flood_threshold_ndvi).selfMask()
    flood_pixel_area_ndvi = flood_ndvi.multiply(ee.Image.pixelArea())
    flood_area_ndvi = flood_pixel_area_ndvi.reduceRegion(**{
        'reducer': ee.Reducer.sum(),
        'geometry': geom,
        'scale': 10
    })
    # print(flood_area_ndvi.getInfo(), 'flood area ndvi')
    drought_threshold1_ndvi = 0.17
    drought_threshold2_ndvi = 0.45
    drought_ndvi = ndvi.gte(drought_threshold1_ndvi).And(
        ndvi.lte(drought_threshold2_ndvi)).selfMask()
    drought_pixel_area_ndvi = drought_ndvi.multiply(ee.Image.pixelArea())
    drought_area_ndvi = drought_pixel_area_ndvi.reduceRegion(**{
        'reducer': ee.Reducer.sum(),
        'geometry': geom,
        'scale': 10
    })
    # print(drought_area_ndvi.getInfo(), 'drought area ndvi')
    vegetation_threshold1_ndvi = 0.45
    vegetation_ndvi = ndvi.gt(vegetation_threshold1_ndvi).selfMask()
    vegetation_pixel_area_ndvi = vegetation_ndvi.multiply(ee.Image.pixelArea())
    vegetation_area_ndvi = vegetation_pixel_area_ndvi.reduceRegion(**{
        'reducer': ee.Reducer.sum(),
        'geometry': geom,
        'scale': 10
    })
    # print(vegetation_area_ndvi.getInfo(), 'vegetation area ndvi')
    return {'flood_area_ndwi': flood_area_ndwi.getInfo()['NDWI'], 'drought_area_ndwi': drought_area_ndwi.getInfo()['NDWI'], 'avg_ndwi_mosaic':avg_ndwi_mosaic, 'flood_area_ndvi': flood_area_ndvi.getInfo()['NDVI'], 'drought_area_ndvi': drought_area_ndvi.getInfo()['NDVI'], 'vegetation_area_ndvi': vegetation_area_ndvi.getInfo()['NDVI'],'avg_ndvi_mosaic':avg_ndvi_mosaic}

def compute_NDVI_NDWI(geom, input_date):
    try:
        rawPolygon = ee.Geometry.Polygon(transformPolygon(geom))
        START_DATE = datetime.datetime.strptime(input_date, "%Y-%m-%d")
        START_DATE = ee.Date(START_DATE)
        END_DATE = START_DATE.advance(5, 'days')
        s2_sr_cld_col_eval = get_s2_sr_cld_col(
            rawPolygon, START_DATE, END_DATE)
        img = s2_sr_cld_col_eval
        try:
            epochtime = img.aggregate_array('system:time_start').getInfo()[-1]
        except:
            epochtime = 0
        img = s2_sr_cld_col_eval.map(add_cld_shdw_mask)
        img = img.first()
        image_masked = apply_cld_shdw_mask(img)

        area_after_masking = image_masked.reduceRegion(
            ee.Reducer.sum(), rawPolygon, 10).get('B1').getInfo()
        # print(area_after_masking, 'Area after masking within 5 days')

        area_before_masking = img.reduceRegion(
            ee.Reducer.sum(), rawPolygon, 10).get('B1').getInfo()
        # print(area_before_masking, 'Area before masking within 5 days')
        if(area_after_masking == area_before_masking):
            calc_ndvi_ndwi = calculate_ndvi_ndwi(image_masked, rawPolygon)
            return calc_ndvi_ndwi, epochtime
        else:
            return 0, 0
    except:
        return 'error', 0

def compute(dataframe):
    for index, row in dataframe.iterrows():
        print("Working On index: ", index)
        result, epochtime = compute_NDVI_NDWI(
            row['geom'], row['warranty_dmgdate'])
        if(result != 0 and result != 'error'):
            dataframe.at[index, 'flood_area_ndwi'] = str(
                result['flood_area_ndwi'])
            dataframe.at[index, 'drought_area_ndwi'] = str(
                result['drought_area_ndwi'])
            dataframe.at[index, 'avg_ndwi_mosaic'] = str(
                result['avg_ndwi_mosaic'])
            dataframe.at[index, 'flood_area_ndvi'] = str(
                result['flood_area_ndvi'])
            dataframe.at[index, 'drought_area_ndvi'] = str(
                result['drought_area_ndvi'])
            dataframe.at[index, 'vegetation_area_ndvi'] = str(
                result['vegetation_area_ndvi'])
            dataframe.at[index, 'avg_ndvi_mosaic'] = str(
                result['avg_ndvi_mosaic'])
        else:
            dataframe.at[index, 'flood_area_ndwi'] = "-"
            dataframe.at[index, 'drought_area_ndwi'] = "-"
            dataframe.at[index, 'avg_ndwi_mosaic'] = "-"
            dataframe.at[index, 'flood_area_ndvi'] = "-"
            dataframe.at[index, 'drought_area_ndvi'] = "-"
            dataframe.at[index, 'vegetation_area_ndvi'] = "-"
            dataframe.at[index, 'avg_ndvi_mosaic'] = "-"
        if(epochtime != 0 and result != 'error'):
            normalTime = datetime.datetime.fromtimestamp(
                epochtime/1000).strftime("%Y-%m-%d")
            dataframe.at[index, 'sat_time'] = normalTime
        elif(result == 'error'):
            dataframe.at[index, 'sat_time'] = "Calculation Error"
        else:
            dataframe.at[index, 'sat_time'] = "Cloudy"
    return dataframe

# geom = ee.Geometry.Polygon([[102.5633930333, 15.3911126506452], [102.5633412905, 15.3911006621863], [102.5632589747, 15.3910814856279], [102.5630058721, 15.3910283104296], [
#     102.5628613992, 15.3909717388604], [102.5629181022, 15.3884164751931], [102.5631823462, 15.3885207260593], [102.5635976384, 15.3886884700794], [102.5633930333, 15.3911126506452]])
# START_DATE = ee.Date('2021-5-5')

if __name__ == "__main__":
    df = pd.read_csv('./raw_data_800.csv', header=0)
    num_processes = multiprocessing.cpu_count()
    chunk_size = df.shape[0] if(
        int(df.shape[0]/num_processes) == 0) else int(df.shape[0]/num_processes)
    chunks = [df.iloc[df.index[i:i + chunk_size]]
              for i in range(0, df.shape[0], chunk_size)]
    pool = multiprocessing.Pool(processes=num_processes)
    result = pool.map(compute, chunks)
    df2 = pd.DataFrame()
    for i in range(len(result)):
        df2 = pd.concat([df2, result[i]], axis=0)
    df2.to_csv(r'C:\Users\geoma\Downloads\ee\ee\testndvindwi.csv',
               index=False, header=True)

NDVI and NDWI on Sentinel-2A images/NDVINDWI.py


import socket
import numpy as np
from gym import spaces
import pickle
#import paramiko
import copy
import os

class DCS_env:
    def __init__(self, host_ip='192.168.3.37', host_port=30000, size=1024):
        # 参数调整
        self.state_dim = 12
        self.action_dim = 7
        self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(self.state_dim,), dtype=np.float32)
        self.action_space = spaces.Box(low=-1, high=1, shape=(self.action_dim,), dtype=np.float32)
        self.HOST = host_ip
        self.PORT = host_port
        self.BufferSize = size
        # socket.AF_INET (IPV4)
        # socket.SOCK_STREAM (TCP)
        #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 绑定客户端IP和端口号
        #s.bind((self.HOST, self.PORT))
        # 最大允许连接数量
        #s.listen(3)
        # 阻塞，当出现客户端的请求完成连接，并获取数据和客户端的信息
        #self.conn, self.addr = s.accept()
        #client = paramiko.SSHClient
        self.recvfile_path = '/home/tete/work/RLP2021/server/transfile/observation.txt'
        self.sendfile_path = '/home/tete/work/RLP2021/server/transfile/action.txt'
        self.timestamp = None

    def read_trans(self):
        while True:
            timeinfo = os.stat(self.recvfile_path).st_mtime

            if timeinfo != self.timestamp and os.path.getsize(self.recvfile_path) > 0:
                #print('size',os.path.getsize(self.recvfile_path))
                self.timestamp = timeinfo
                #print('timeinfo', timeinfo)
                trans_file = open(self.recvfile_path,'r+')
                valid_trans = trans_file.read()
                trans_file.close()
                #print('valid_trans', valid_trans)
                break
        return valid_trans

    def send_trans(self, data):
        file = open(self.sendfile_path, 'wb+')
        file.write(data.encode())
        file.close()

    def reset(self):
        #self.conn.sendall('Ready'.encode('gb2312'))
        self.send_trans('Ready')
        while True:
            trans = self.read_trans()
            _, ourplane, _, _, _ = self.obs_parser(trans)
            #print('ourplane', ourplane)
            if ourplane[2] > 50: break
        next_obserstr = self.read_trans()
        initial_obs, _, _, _, _  = self.obs_parser(next_obserstr)
        print('successfully send reset command to client')
        return initial_obs

    def step(self, a):
        #a = [1,2,3,4,5,6,7]
        action = '1' + '@' + str(a[0]) + ',' + str(a[1]) + ',' + str(a[2]) + ',' + str(a[3]) + ',' + str(a[4]) + ',' + str(a[5]) + ',' + str(a[6])
        #print(action)
        self.send_trans(action)
        #print('successfully send action to client')
        next_obserstr = self.read_trans()
        #print('next_obserstr', next_obserstr)
        full_next_obs, next_ourplane, _, _, _ = self.obs_parser(next_obserstr)
        rwd = self.reward(next_obserstr)
        done = 1 if next_ourplane[2] < 20 else 0
        # 关闭客户端连接
        # conn.colse()
        return full_next_obs, rwd, done, 0

    def reward(self, obsstr):
        _, ourplane, allyplane, enemyplane1, enemyplane2 = self.obs_parser(obsstr)
        #print('duudwdwd', np.linalg.norm(ourplane - enemyplane1))
        #print('debug', min(np.linalg.norm(ourplane - enemyplane1, 2), np.linalg.norm(ourplane - enemyplane2, 2)))
        rwd = -min(np.linalg.norm(np.array(ourplane) - np.array(enemyplane1), 2), np.linalg.norm(np.array(ourplane) - np.array(enemyplane2), 2))
        return rwd

    def obs_parser(self, obsstr):
        #obsstr_sib = copy.deepcopy(obsstr)
        #obsstr = obsstr.decode('gb2312')
        #print("obsstr", obsstr)
        ourplane = [float(str(obsstr).split('@', 4)[0].split(':', 3)[0]), float(str(obsstr).split('@', 4)[0].split(':', 3)[1]), float(str(obsstr).split('@', 4)[0].split(':', 3)[2])]
        allyplane = [float(str(obsstr).split('@', 4)[1].split(':', 3)[0]), float(str(obsstr).split('@', 4)[1].split(':', 3)[1]), float(str(obsstr).split('@', 4)[1].split(':', 3)[2])]
        enemyplane1 = [float(str(obsstr).split('@', 4)[1].split(':', 3)[0]), float(str(obsstr).split('@', 4)[1].split(':', 3)[1]), float(str(obsstr).split('@', 4)[1].split(':', 3)[2])]
        enemyplane2 = [float(str(obsstr).split('@', 4)[2].split(':', 3)[0]), float(str(obsstr).split('@', 4)[2].split(':', 3)[1]), float(str(obsstr).split('@', 4)[2].split(':', 3)[2])]
        observation = ourplane.copy()
        observation.extend(allyplane)
        observation.extend(enemyplane1)
        observation.extend(enemyplane2)
        #print('observation', observation)
        return observation, ourplane, allyplane, enemyplane1, enemyplane2


import os
import argparse

import joblib
import pandas as pd
from sklearn import metrics
from sklearn import tree

import config
import model_dispatcher

def run(fold, model):
    #read the training data with folds
    df = pd.read_csv(config.TRAINING_FILE)

    #to replace by feature engineering
    df = df.drop(['Name', 'Sex','Embarked','Ticket', 'Fare', 'Cabin'], axis=1)
    df.dropna(inplace=True)

    #training data
    df_train = df[df.kfold != fold].reset_index(drop=True)

    #validation data
    df_valid = df[df.kfold == fold].reset_index(drop=True)

    #drop label column from df and convert to array
    x_train= df_train.drop('Survived', axis=1).values
    x_valid= df_valid.drop('Survived', axis=1).values

    #target is label column
    y_train = df_train.Survived.values
    y_valid = df_valid.Survived.values

    #simple Decision Tree model
    clf = model_dispatcher.models[model]

    #fit the model using
    clf.fit(x_train, y_train)

    #create predictions
    preds = clf.predict(x_valid)

    #calculate and print accuracy
    accuracy = metrics.accuracy_score(y_valid, preds)
    print(f'Fold={fold}, Accuracy={accuracy}')

    #save the model
    joblib.dump(
        clf,
        os.path.join(config.MODEL_OUTPUT, f'df_{fold}.bin')
    )

if __name__ == '__main__':
    #initialize ArgumentParser class
    parser = argparse.ArgumentParser()

    #add the arguments needed
    parser.add_argument(
        '--fold',
        type=int)
    parser.add_argument(
        '--model',
        type=str)

    #read the arguments from the comand Lines
    args = parser.parse_args()

    #run the fold specified by command line arguments
    run(
        fold=args.fold,
        model=args.model
    )


import librosa, librosa.display
import os
import pandas as pd
import numpy as np

def normalize_volume(file_path):
    y, sr = librosa.load(file_path)
    y_norm = librosa.util.normalize(y, axis=0)
    return y_norm, sr

def extract_features(y_norm, sr):

    features = []

    # Tempo and beats
    tempo, beats = librosa.beat.beat_track(y=y_norm, sr=sr)
    beats_mean = beats.mean()
    beats_var = beats.var()
    features.extend((tempo, beats_mean, beats_var))

    # Zero crossings
    zero_crossings = librosa.zero_crossings(y=y_norm, pad=False)
    zero_crossings_mean = zero_crossings.mean()
    zero_crossings_var = zero_crossings.var()
    features.extend((zero_crossings_mean, zero_crossings_var))

    # Spectral centroid
    spectral_centroids = librosa.feature.spectral_centroid(y=y_norm, sr=sr)[0]
    spectral_centroids_mean = spectral_centroids.mean()
    spectral_centroids_var = spectral_centroids.var()
    features.extend((spectral_centroids_mean,spectral_centroids_var))

    # Specral Rolloff
    spectral_rolloff = librosa.feature.spectral_rolloff(y=y_norm, sr=sr)[0]
    spectral_rolloff_mean = spectral_rolloff.mean()
    spectral_rolloff_var = spectral_rolloff.var()
    features.extend((spectral_rolloff_mean, spectral_rolloff_var))

    # MFCCs
    mfccs = librosa.feature.mfcc(y=y_norm, sr=sr, n_mfcc=40)
    for mfcc in mfccs:
        features.append(mfcc.mean())
        features.append(mfcc.var())

    return features


from __future__ import annotations
from typing import Any, List, Literal, Optional, TYPE_CHECKING, Tuple, Type, TypeVar, Callable, Union, Dict, overload
from contextvars import ContextVar
import inspect
import os

from .item import Item, ItemCallbackType
from ..enums import ChannelType, ComponentType
from ..partial_emoji import PartialEmoji
from ..emoji import Emoji
from ..utils import MISSING
from ..components import (
    SelectOption,
    SelectMenu,
)
from ..app_commands.namespace import Namespace

__all__ = (
    'Select',
    'UserSelect',
    'RoleSelect',
    'MentionableSelect',
    'ChannelSelect',
    'select',
)

if TYPE_CHECKING:
    from typing_extensions import TypeAlias, Self

    from .view import View
    from ..types.components import SelectMenu as SelectMenuPayload
    from ..types.interactions import SelectMessageComponentInteractionData
    from ..app_commands import AppCommandChannel, AppCommandThread
    from ..member import Member
    from ..role import Role
    from ..user import User
    from ..interactions import Interaction

    ValidSelectType: TypeAlias = Literal[
        ComponentType.string_select,
        ComponentType.user_select,
        ComponentType.role_select,
        ComponentType.channel_select,
        ComponentType.mentionable_select,
    ]
    PossibleValue: TypeAlias = Union[
        str, User, Member, Role, AppCommandChannel, AppCommandThread, Union[Role, Member], Union[Role, User]
    ]

V = TypeVar('V', bound='View', covariant=True)
BaseSelectT = TypeVar('BaseSelectT', bound='BaseSelect[Any]')
SelectT = TypeVar('SelectT', bound='Select[Any]')
UserSelectT = TypeVar('UserSelectT', bound='UserSelect[Any]')
RoleSelectT = TypeVar('RoleSelectT', bound='RoleSelect[Any]')
ChannelSelectT = TypeVar('ChannelSelectT', bound='ChannelSelect[Any]')
MentionableSelectT = TypeVar('MentionableSelectT', bound='MentionableSelect[Any]')
SelectCallbackDecorator: TypeAlias = Callable[[ItemCallbackType[V, BaseSelectT]], BaseSelectT]

selected_values: ContextVar[Dict[str, List[PossibleValue]]] = ContextVar('selected_values')

class BaseSelect(Item[V]):
    """The base Select model that all other Select models inherit from.

    This class inherits from :class:`Item` and implements the common attributes.

    The following implement this class:

    - :class:`~discord.ui.Select`
    - :class:`~discord.ui.ChannelSelect`
    - :class:`~discord.ui.RoleSelect`
    - :class:`~discord.ui.MentionableSelect`
    - :class:`~discord.ui.UserSelect`

    .. versionadded:: 2.1

    Attributes
    ------------
    row: Optional[:class:`int`]
        The relative row this select menu belongs to. A Discord component can only have 5
        rows. By default, items are arranged automatically into those 5 rows. If you'd
        like to control the relative positioning of the row then passing an index is advised.
        For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic
        ordering. The row number must be between 0 and 4 (i.e. zero indexed).
    """

    __slots__ = ('_provided_custom_id', '_underlying', 'row', '_values')

    __item_repr_attributes__: Tuple[str, ...] = (
        'placeholder',
        'min_values',
        'max_values',
        'disabled',
    )

    def __init__(
        self,
        type: ValidSelectType,
        *,
        custom_id: str = MISSING,
        row: Optional[int] = None,
        placeholder: Optional[str] = None,
        min_values: Optional[int] = None,
        max_values: Optional[int] = None,
        disabled: bool = False,
        options: List[SelectOption] = MISSING,
        channel_types: List[ChannelType] = MISSING,
    ) -> None:
        super().__init__()
        self._provided_custom_id = custom_id is not MISSING
        custom_id = os.urandom(16).hex() if custom_id is MISSING else custom_id
        if not isinstance(custom_id, str):
            raise TypeError(f'expected custom_id to be str not {custom_id.__class__.__name__}')

        self._underlying = SelectMenu._raw_construct(
            type=type,
            custom_id=custom_id,
            placeholder=placeholder,
            min_values=min_values,
            max_values=max_values,
            disabled=disabled,
            channel_types=[] if channel_types is MISSING else channel_types,
            options=[] if options is MISSING else options,
        )

        self.row = row
        self._values: List[PossibleValue] = []

    @property
    def values(self) -> List[PossibleValue]:
        values = selected_values.get({})
        return values.get(self.custom_id, self._values)

    @property
    def custom_id(self) -> str:
        """:class:`str`: The ID of the select menu that gets received during an interaction."""
        return self._underlying.custom_id

    @custom_id.setter
    def custom_id(self, value: str) -> None:
        if not isinstance(value, str):
            raise TypeError('custom_id must be a str')

        self._underlying.custom_id = value
        self._provided_custom_id = True

    @property
    def placeholder(self) -> Optional[str]:
        """Optional[:class:`str`]: The placeholder text that is shown if nothing is selected, if any."""
        return self._underlying.placeholder

    @placeholder.setter
    def placeholder(self, value: Optional[str]) -> None:
        if value is not None and not isinstance(value, str):
            raise TypeError('placeholder must be None or str')

        self._underlying.placeholder = value

    @property
    def min_values(self) -> int:
        """:class:`int`: The minimum number of items that must be chosen for this select menu."""
        return self._underlying.min_values

    @min_values.setter
    def min_values(self, value: int) -> None:
        self._underlying.min_values = int(value)

    @property
    def max_values(self) -> int:
        """:class:`int`: The maximum number of items that can be chosen for this select menu."""
        return self._underlying.max_values

    @max_values.setter
    def max_values(self, value: int) -> None:
        self._underlying.max_values = int(value)

    @property
    def disabled(self) -> bool:
        """:class:`bool`: Whether the select is disabled or not."""
        return self._underlying.disabled

    @disabled.setter
    def disabled(self, value: bool) -> None:
        self._underlying.disabled = bool(value)

    @property
    def width(self) -> int:
        return 5

    def to_component_dict(self) -> SelectMenuPayload:
        return self._underlying.to_dict()

    def _refresh_component(self, component: SelectMenu) -> None:
        self._underlying = component

    def _refresh_state(self, interaction: Interaction, data: SelectMessageComponentInteractionData) -> None:
        values = selected_values.get({})
        payload: List[PossibleValue]
        try:
            resolved = Namespace._get_resolved_items(interaction, data['resolved'])
            payload = list(resolved.values())
        except KeyError:
            payload = data.get("values", [])  # type: ignore

        self._values = values[self.custom_id] = payload
        selected_values.set(values)

    def is_dispatchable(self) -> bool:
        return True

    @classmethod
    def from_component(cls, component: SelectMenu) -> Self:
        return cls(
            **{k: getattr(component, k) for k in cls.__item_repr_attributes__},
            row=None,
        )

class Select(BaseSelect[V]):
    """Represents a UI select menu with a list of custom options. This is represented
    to the user as a dropdown menu.

    .. versionadded:: 2.0

    Parameters
    ------------
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        If not given then one is generated for you.
    placeholder: Optional[:class:`str`]
        The placeholder text that is shown if nothing is selected, if any.
    min_values: :class:`int`
        The minimum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 0 and 25.
    max_values: :class:`int`
        The maximum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 1 and 25.
    options: List[:class:`discord.SelectOption`]
        A list of options that can be selected in this menu.
    disabled: :class:`bool`
        Whether the select is disabled or not.
    row: Optional[:class:`int`]
        The relative row this select menu belongs to. A Discord component can only have 5
        rows. By default, items are arranged automatically into those 5 rows. If you'd
        like to control the relative positioning of the row then passing an index is advised.
        For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic
        ordering. The row number must be between 0 and 4 (i.e. zero indexed).
    """

    __item_repr_attributes__ = BaseSelect.__item_repr_attributes__ + ('options',)

    def __init__(
        self,
        *,
        custom_id: str = MISSING,
        placeholder: Optional[str] = None,
        min_values: int = 1,
        max_values: int = 1,
        options: List[SelectOption] = MISSING,
        disabled: bool = False,
        row: Optional[int] = None,
    ) -> None:
        super().__init__(
            self.type,
            custom_id=custom_id,
            placeholder=placeholder,
            min_values=min_values,
            max_values=max_values,
            disabled=disabled,
            options=options,
            row=row,
        )

    @property
    def values(self) -> List[str]:
        """List[:class:`str`]: A list of values that have been selected by the user."""
        return super().values  # type: ignore

    @property
    def type(self) -> Literal[ComponentType.string_select]:
        """:class:`.ComponentType`: The type of this component."""
        return ComponentType.string_select

    @property
    def options(self) -> List[SelectOption]:
        """List[:class:`discord.SelectOption`]: A list of options that can be selected in this menu."""
        return self._underlying.options

    @options.setter
    def options(self, value: List[SelectOption]) -> None:
        if not isinstance(value, list):
            raise TypeError('options must be a list of SelectOption')
        if not all(isinstance(obj, SelectOption) for obj in value):
            raise TypeError('all list items must subclass SelectOption')

        self._underlying.options = value

    def add_option(
        self,
        *,
        label: str,
        value: str = MISSING,
        description: Optional[str] = None,
        emoji: Optional[Union[str, Emoji, PartialEmoji]] = None,
        default: bool = False,
    ) -> None:
        """Adds an option to the select menu.

        To append a pre-existing :class:`discord.SelectOption` use the
        :meth:`append_option` method instead.

        Parameters
        -----------
        label: :class:`str`
            The label of the option. This is displayed to users.
            Can only be up to 100 characters.
        value: :class:`str`
            The value of the option. This is not displayed to users.
            If not given, defaults to the label. Can only be up to 100 characters.
        description: Optional[:class:`str`]
            An additional description of the option, if any.
            Can only be up to 100 characters.
        emoji: Optional[Union[:class:`str`, :class:`.Emoji`, :class:`.PartialEmoji`]]
            The emoji of the option, if available. This can either be a string representing
            the custom or unicode emoji or an instance of :class:`.PartialEmoji` or :class:`.Emoji`.
        default: :class:`bool`
            Whether this option is selected by default.

        Raises
        -------
        ValueError
            The number of options exceeds 25.
        """

        option = SelectOption(
            label=label,
            value=value,
            description=description,
            emoji=emoji,
            default=default,
        )

        self.append_option(option)

    def append_option(self, option: SelectOption) -> None:
        """Appends an option to the select menu.

        Parameters
        -----------
        option: :class:`discord.SelectOption`
            The option to append to the select menu.

        Raises
        -------
        ValueError
            The number of options exceeds 25.
        """

        if len(self._underlying.options) > 25:
            raise ValueError('maximum number of options already provided')

        self._underlying.options.append(option)

class UserSelect(BaseSelect[V]):
    """Represents a UI select menu with a list of predefined options with the current members of the guild.

    If this is sent a private message, it will only allow the user to select the client
    or themselves. Every selected option in a private message will resolve to
    a :class:`discord.User`.

    .. versionadded:: 2.1

    Parameters
    ------------
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        If not given then one is generated for you.
    placeholder: Optional[:class:`str`]
        The placeholder text that is shown if nothing is selected, if any.
    min_values: :class:`int`
        The minimum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 0 and 25.
    max_values: :class:`int`
        The maximum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 1 and 25.
    disabled: :class:`bool`
        Whether the select is disabled or not.
    row: Optional[:class:`int`]
        The relative row this select menu belongs to. A Discord component can only have 5
        rows. By default, items are arranged automatically into those 5 rows. If you'd
        like to control the relative positioning of the row then passing an index is advised.
        For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic
        ordering. The row number must be between 0 and 4 (i.e. zero indexed).
    """

    def __init__(
        self,
        *,
        custom_id: str = MISSING,
        placeholder: Optional[str] = None,
        min_values: int = 1,
        max_values: int = 1,
        disabled: bool = False,
        row: Optional[int] = None,
    ) -> None:
        super().__init__(
            self.type,
            custom_id=custom_id,
            placeholder=placeholder,
            min_values=min_values,
            max_values=max_values,
            disabled=disabled,
            row=row,
        )

    @property
    def type(self) -> Literal[ComponentType.user_select]:
        """:class:`.ComponentType`: The type of this component."""
        return ComponentType.user_select

    @property
    def values(self) -> List[Union[Member, User]]:
        """List[Union[:class:`discord.Member`, :class:`discord.User`]]: A list of members
        and users that have been selected by the user.

        If this is sent a private message, it will only allow
        the user to select the client or themselves. Every selected option in a private
        message will resolve to a :class:`discord.User`.

        If invoked in a guild, the values will always resolve to :class:`discord.Member`.
        """
        return super().values  # type: ignore

class RoleSelect(BaseSelect[V]):
    """Represents a UI select menu with a list of predefined options with the current roles of the guild.

    Please note that if you use this in a private message with a user, no roles will be displayed to the user.

    .. versionadded:: 2.1

    Parameters
    ------------
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        If not given then one is generated for you.
    placeholder: Optional[:class:`str`]
        The placeholder text that is shown if nothing is selected, if any.
    min_values: :class:`int`
        The minimum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 0 and 25.
    max_values: :class:`int`
        The maximum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 1 and 25.
    disabled: :class:`bool`
        Whether the select is disabled or not.
    row: Optional[:class:`int`]
        The relative row this select menu belongs to. A Discord component can only have 5
        rows. By default, items are arranged automatically into those 5 rows. If you'd
        like to control the relative positioning of the row then passing an index is advised.
        For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic
        ordering. The row number must be between 0 and 4 (i.e. zero indexed).
    """

    def __init__(
        self,
        *,
        custom_id: str = MISSING,
        placeholder: Optional[str] = None,
        min_values: int = 1,
        max_values: int = 1,
        disabled: bool = False,
        row: Optional[int] = None,
    ) -> None:
        super().__init__(
            self.type,
            custom_id=custom_id,
            placeholder=placeholder,
            min_values=min_values,
            max_values=max_values,
            disabled=disabled,
            row=row,
        )

    @property
    def type(self) -> Literal[ComponentType.role_select]:
        """:class:`.ComponentType`: The type of this component."""
        return ComponentType.role_select

    @property
    def values(self) -> List[Role]:
        """List[:class:`discord.Role`]: A list of roles that have been selected by the user."""
        return super().values  # type: ignore

class MentionableSelect(BaseSelect[V]):
    """Represents a UI select menu with a list of predefined options with the current members and roles in the guild.

    If this is sent in a private message, it will only allow the user to select
    the client or themselves. Every selected option in a private message
    will resolve to a :class:`discord.User`. It will not give the user any roles
    to select.

    .. versionadded:: 2.1

    Parameters
    ------------
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        If not given then one is generated for you.
    placeholder: Optional[:class:`str`]
        The placeholder text that is shown if nothing is selected, if any.
    min_values: :class:`int`
        The minimum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 0 and 25.
    max_values: :class:`int`
        The maximum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 1 and 25.
    disabled: :class:`bool`
        Whether the select is disabled or not.
    row: Optional[:class:`int`]
        The relative row this select menu belongs to. A Discord component can only have 5
        rows. By default, items are arranged automatically into those 5 rows. If you'd
        like to control the relative positioning of the row then passing an index is advised.
        For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic
        ordering. The row number must be between 0 and 4 (i.e. zero indexed).
    """

    def __init__(
        self,
        *,
        custom_id: str = MISSING,
        placeholder: Optional[str] = None,
        min_values: int = 1,
        max_values: int = 1,
        disabled: bool = False,
        row: Optional[int] = None,
    ) -> None:
        super().__init__(
            self.type,
            custom_id=custom_id,
            placeholder=placeholder,
            min_values=min_values,
            max_values=max_values,
            disabled=disabled,
            row=row,
        )

    @property
    def type(self) -> Literal[ComponentType.mentionable_select]:
        """:class:`.ComponentType`: The type of this component."""
        return ComponentType.mentionable_select

    @property
    def values(self) -> List[Union[Member, User, Role]]:
        """List[Union[:class:`discord.Role`, :class:`discord.Member`, :class:`discord.User`]]: A list of roles, members,
        and users that have been selected by the user.

        If this is sent a private message, it will only allow
        the user to select the client or themselves. Every selected option in a private
        message will resolve to a :class:`discord.User`.

        If invoked in a guild, the values will always resolve to :class:`discord.Member`.
        """
        return super().values  # type: ignore

class ChannelSelect(BaseSelect[V]):
    """Represents a UI select menu with a list of predefined options with the current channels in the guild.

    Please note that if you use this in a private message with a user, no channels will be displayed to the user.

    .. versionadded:: 2.1

    Parameters
    ------------
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        If not given then one is generated for you.
    channel_types: List[:class:`~discord.ChannelType`]
        The types of channels to show in the select menu. Defaults to all channels.
    placeholder: Optional[:class:`str`]
        The placeholder text that is shown if nothing is selected, if any.
    min_values: :class:`int`
        The minimum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 0 and 25.
    max_values: :class:`int`
        The maximum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 1 and 25.
    disabled: :class:`bool`
        Whether the select is disabled or not.
    row: Optional[:class:`int`]
        The relative row this select menu belongs to. A Discord component can only have 5
        rows. By default, items are arranged automatically into those 5 rows. If you'd
        like to control the relative positioning of the row then passing an index is advised.
        For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic
        ordering. The row number must be between 0 and 4 (i.e. zero indexed).
    """

    __item_repr_attributes__ = BaseSelect.__item_repr_attributes__ + ('channel_types',)

    def __init__(
        self,
        *,
        custom_id: str = MISSING,
        channel_types: List[ChannelType] = MISSING,
        placeholder: Optional[str] = None,
        min_values: int = 1,
        max_values: int = 1,
        disabled: bool = False,
        row: Optional[int] = None,
    ) -> None:
        super().__init__(
            self.type,
            custom_id=custom_id,
            placeholder=placeholder,
            min_values=min_values,
            max_values=max_values,
            disabled=disabled,
            row=row,
            channel_types=channel_types,
        )

    @property
    def type(self) -> Literal[ComponentType.channel_select]:
        """:class:`.ComponentType`: The type of this component."""
        return ComponentType.channel_select

    @property
    def channel_types(self) -> List[ChannelType]:
        """List[:class:`~discord.ChannelType`]: A list of channel types that can be selected."""
        return self._underlying.channel_types

    @channel_types.setter
    def channel_types(self, value: List[ChannelType]) -> None:
        if not isinstance(value, list):
            raise TypeError('channel_types must be a list of ChannelType')
        if not all(isinstance(obj, ChannelType) for obj in value):
            raise TypeError('all list items must be a ChannelType')

        self._underlying.channel_types = value

    @property
    def values(self) -> List[Union[AppCommandChannel, AppCommandThread]]:
        """List[Union[:class:`~discord.app_commands.AppCommandChannel`, :class:`~discord.app_commands.AppCommandThread`]]: A list of channels selected by the user."""
        return super().values  # type: ignore

@overload
def select(
    *,
    cls: Type[SelectT] = Select[V],
    options: List[SelectOption] = MISSING,
    channel_types: List[ChannelType] = ...,
    placeholder: Optional[str] = ...,
    custom_id: str = ...,
    min_values: int = ...,
    max_values: int = ...,
    disabled: bool = ...,
    row: Optional[int] = ...,
) -> SelectCallbackDecorator[V, SelectT]:
    ...

@overload
def select(
    *,
    cls: Type[UserSelectT] = UserSelect[V],
    options: List[SelectOption] = MISSING,
    channel_types: List[ChannelType] = ...,
    placeholder: Optional[str] = ...,
    custom_id: str = ...,
    min_values: int = ...,
    max_values: int = ...,
    disabled: bool = ...,
    row: Optional[int] = ...,
) -> SelectCallbackDecorator[V, UserSelectT]:
    ...

@overload
def select(
    *,
    cls: Type[RoleSelectT] = RoleSelect[V],
    options: List[SelectOption] = MISSING,
    channel_types: List[ChannelType] = ...,
    placeholder: Optional[str] = ...,
    custom_id: str = ...,
    min_values: int = ...,
    max_values: int = ...,
    disabled: bool = ...,
    row: Optional[int] = ...,
) -> SelectCallbackDecorator[V, RoleSelectT]:
    ...

@overload
def select(
    *,
    cls: Type[ChannelSelectT] = ChannelSelect[V],
    options: List[SelectOption] = MISSING,
    channel_types: List[ChannelType] = ...,
    placeholder: Optional[str] = ...,
    custom_id: str = ...,
    min_values: int = ...,
    max_values: int = ...,
    disabled: bool = ...,
    row: Optional[int] = ...,
) -> SelectCallbackDecorator[V, ChannelSelectT]:
    ...

@overload
def select(
    *,
    cls: Type[MentionableSelectT] = MentionableSelect[V],
    options: List[SelectOption] = MISSING,
    channel_types: List[ChannelType] = MISSING,
    placeholder: Optional[str] = ...,
    custom_id: str = ...,
    min_values: int = ...,
    max_values: int = ...,
    disabled: bool = ...,
    row: Optional[int] = ...,
) -> SelectCallbackDecorator[V, MentionableSelectT]:
    ...

def select(
    *,
    cls: Type[BaseSelectT] = Select[V],
    options: List[SelectOption] = MISSING,
    channel_types: List[ChannelType] = MISSING,
    placeholder: Optional[str] = None,
    custom_id: str = MISSING,
    min_values: int = 1,
    max_values: int = 1,
    disabled: bool = False,
    row: Optional[int] = None,
) -> SelectCallbackDecorator[V, BaseSelectT]:
    """A decorator that attaches a select menu to a component.

    The function being decorated should have three parameters, ``self`` representing
    the :class:`discord.ui.View`, the :class:`discord.Interaction` you receive and
    the chosen select class.

    To obtain the selected values inside the callback, you can use the ``values`` attribute of the chosen class in the callback. The list of values
    will depend on the type of select menu used. View the table below for more information.

    +----------------------------------------+-----------------------------------------------------------------------------------------------------------------+
    | Select Type                            | Resolved Values                                                                                |
    +========================================+=================================================================================================================+
    | :class:`discord.ui.Select`             | List[:class:`str`]                                                                                |
    +----------------------------------------+-----------------------------------------------------------------------------------------------------------------+
    | :class:`discord.ui.UserSelect`         | List[Union[:class:`discord.Member`, :class:`discord.User`]]                                                     |
    +----------------------------------------+-----------------------------------------------------------------------------------------------------------------+
    | :class:`discord.ui.RoleSelect`         | List[:class:`discord.Role`]                                                                                |
    +----------------------------------------+-----------------------------------------------------------------------------------------------------------------+
    | :class:`discord.ui.MentionableSelect`  | List[Union[:class:`discord.Role`, :class:`discord.Member`, :class:`discord.User`]]                              |
    +----------------------------------------+-----------------------------------------------------------------------------------------------------------------+
    | :class:`discord.ui.ChannelSelect`      | List[Union[:class:`~discord.app_commands.AppCommandChannel`, :class:`~discord.app_commands.AppCommandThread`]]  |
    +----------------------------------------+-----------------------------------------------------------------------------------------------------------------+

    .. versionchanged:: 2.1
        Added the following keyword-arguments: ``cls``, ``channel_types``

    Example
    ---------
    .. code-block:: python3

        class View(discord.ui.View):

            @discord.ui.select(cls=ChannelSelect, channel_types=[discord.ChannelType.text])
            async def select_channels(self, interaction: discord.Interaction, select: ChannelSelect):
                return await interaction.response.send_message(f'You selected {select.values[0].mention}')

    Parameters
    ------------
    cls: Union[Type[:class:`discord.ui.Select`], Type[:class:`discord.ui.UserSelect`], Type[:class:`discord.ui.RoleSelect`], \
        Type[:class:`discord.ui.MentionableSelect`], Type[:class:`discord.ui.ChannelSelect`]]
        The class to use for the select menu. Defaults to :class:`discord.ui.Select`. You can use other
        select types to display different select menus to the user. See the table above for the different
        values you can get from each select type. Subclasses work as well, however the callback in the subclass will
        get overridden.
    placeholder: Optional[:class:`str`]
        The placeholder text that is shown if nothing is selected, if any.
    custom_id: :class:`str`
        The ID of the select menu that gets received during an interaction.
        It is recommended not to set this parameter to prevent conflicts.
    row: Optional[:class:`int`]
        The relative row this select menu belongs to. A Discord component can only have 5
        rows. By default, items are arranged automatically into those 5 rows. If you'd
        like to control the relative positioning of the row then passing an index is advised.
        For example, row=1 will show up before row=2. Defaults to ``None``, which is automatic
        ordering. The row number must be between 0 and 4 (i.e. zero indexed).
    min_values: :class:`int`
        The minimum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 0 and 25.
    max_values: :class:`int`
        The maximum number of items that must be chosen for this select menu.
        Defaults to 1 and must be between 1 and 25.
    options: List[:class:`discord.SelectOption`]
        A list of options that can be selected in this menu. This can only be used with
        :class:`Select` instances.
    channel_types: List[:class:`~discord.ChannelType`]
        The types of channels to show in the select menu. Defaults to all channels. This can only be used
        with :class:`ChannelSelect` instances.
    disabled: :class:`bool`
        Whether the select is disabled or not. Defaults to ``False``.
    """

    def decorator(func: ItemCallbackType[V, BaseSelectT]) -> ItemCallbackType[V, BaseSelectT]:
        if not inspect.iscoroutinefunction(func):
            raise TypeError('select function must be a coroutine function')
        callback_cls = getattr(cls, '__origin__', cls)
        if not issubclass(callback_cls, BaseSelect):
            supported_classes = ", ".join(["ChannelSelect", "MentionableSelect", "RoleSelect", "Select", "UserSelect"])
            raise TypeError(f'cls must be one of {supported_classes} or a subclass of one of them, not {cls!r}.')

        func.__discord_ui_model_type__ = callback_cls
        func.__discord_ui_model_kwargs__ = {
            'placeholder': placeholder,
            'custom_id': custom_id,
            'row': row,
            'min_values': min_values,
            'max_values': max_values,
            'disabled': disabled,
        }
        if issubclass(callback_cls, Select):
            func.__discord_ui_model_kwargs__['options'] = options
        if issubclass(callback_cls, ChannelSelect):
            func.__discord_ui_model_kwargs__['channel_types'] = channel_types

        return func

    return decorator  # type: ignore


from IAF.flows.iaf import IAF_mod
from torch import nn
import torch
class IAF_flow(nn.Module):
    def __init__(self, dim, n_flows,tanh_flag,C=100):
        super().__init__()
        self.flow = nn.ModuleList([
            IAF_mod(dim,dim,dim) for _ in range(n_flows)
        ])
        self.C = C
        self.tanh_flag = tanh_flag

    def forward(self, z0,h=None):
        log_det = 0
        zk = z0
        for f in self.flow:
            zk,ld = f(zk,h)
            log_det= log_det+ld
        if self.tanh_flag:
            return self.C*torch.tanh(zk/self.C),log_det
        else:
            return zk,log_det


import argparse
import matplotlib.pyplot as plt
import numpy as np
import h5py
import gusto_dataset

global_vars = dict(num_files=0, file_index=0)

def plot_faces(filename, args):
    dset = gusto_dataset.GustoDataset(filename)
    segments = dset.get_face_segments()
    for seg in segments:
        plt.plot(seg[:,0], seg[:,2], '-o', c='k')
    plt.axis('equal')
    plt.margins(0.1)

def plot_1d(filename, args):
    dset = gusto_dataset.GustoDataset(filename)
    x = dset.get_cell_variable('x3', row=args.row)
    y = dset.get_cell_variable(args.data, row=args.row)
    c = float(global_vars['file_index']) / global_vars['num_files']
    plt.plot(x, y, '-o', c=[c]*3)
    plt.xlabel('z')
    plt.ylabel(args.data)

def triangle_variable_plot(filename, args):
    dset = gusto_dataset.GustoDataset(filename)
    x = dset.get_cell_variable('x1')
    z = dset.get_cell_variable('x3')
    f = dset.get_cell_variable('dg')
    plt.tripcolor(x, z, f)
    plt.axis('equal')
    plt.colorbar()

def triangle_mesh_plot(filename, args):
    dset = gusto_dataset.GustoDataset(filename)
    x = dset.get_cell_variable('x1')
    z = dset.get_cell_variable('x3')
    plt.triplot(x, z)
    plt.axis('equal')

def triangle_vert_plot(filename, args):
    dset = gusto_dataset.GustoDataset(filename)
    x = dset.get_vert_variable('x1')
    z = dset.get_vert_variable('x3')
    f = dset.get_vert_variable(args.data)
    plt.tripcolor(x, z, f)
    plt.axis('equal')

def mesh_plot(filename, args):
    from matplotlib.collections import PolyCollection
    dset = gusto_dataset.GustoDataset(filename)
    vert = dset.get_cell_polygons()
    data = dset.get_cell_variable(args.data, log=args.log)

    # u0 = dset.get_cell_variable('u0')
    # b0 = dset.get_cell_variable('b0')
    # b1 = dset.get_cell_variable('b1')
    # b2 = dset.get_cell_variable('b2')
    # b3 = dset.get_cell_variable('b3')
    # dg = dset.get_cell_variable('dg')
    # bb = b1*b1 + b2*b2 + b3*b3 - b0*b0
    # data = np.log10(bb / (dg * u0))

    # u1 = dset.get_cell_variable('u1')
    # u3 = dset.get_cell_variable('u3')
    # up = (u1**2 + u3**2)**0.5
    # data = up
    # data = np.log10(data)

    cells = PolyCollection(vert, array=data, cmap=args.cmap,
                           linewidths=0.0, antialiased=True)
    fig = plt.figure()
    ax0 = fig.add_subplot(1, 1, 1)
    ax0.add_collection(cells)
    ax0.autoscale_view()
    ax0.set_aspect('equal')
    fig.colorbar(cells)
    plt.show()

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument('command')
    parser.add_argument('filenames', nargs='+')
    parser.add_argument('-d', '--data', default='dg')
    parser.add_argument('--cmap', default='jet')
    parser.add_argument('--row', default=0, type=int)
    parser.add_argument('--log', action='store_true', default=False)

    args = parser.parse_args()

    plots = {'1d': plot_1d,
             'vert': triangle_vert_plot,
             'trimesh': triangle_mesh_plot,
             'triplot': triangle_variable_plot,
             'mesh': mesh_plot,
             'faces': plot_faces}

    global_vars['num_files'] = len(args.filenames)
    for n, f in enumerate(args.filenames):
        global_vars['file_index'] = n
        plots[args.command](f, args)
    plt.show()


from gensim.models.doc2vec import TaggedDocument
from utils import ExecutionTime

def tagging(cleaned_text: list):
    print('Tagging started...')
    t = ExecutionTime()
    t.start()
    idx = [str(i) for i in range(len(cleaned_text))]
    tagged_text = []
    for i in range(len(cleaned_text)):
        tagged_text.append(TaggedDocument(cleaned_text[i], [idx[i]]))
    t.end()
    print(f'Tagging completed in {t.get_exec_time():.2f} sec')
    return tagged_text


# De Django
from django.urls import path
# Propios
from . import views

urlpatterns = [
    path('',views.home,name='home'),
    path('manual',views.manual,name='manual'),
    path('login',views.login_page,name='login-page'),
    path('register',views.register,name='register'),
    path('logout',views.logout_staff,name='logout'),
    path('personal',views.staff_page,name='staff'),
    path('clientes',views.clients,name='clients'),
    path('inventario',views.invetory,name='inventory'),
    path('settings',views.settings,name='settings')
]


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

import re
from flask import redirect, url_for

id_check = re.compile('([0-9a-f]+)')
genre_check = re.compile('([0-9a-z_]+)')
zip_check = re.compile('([0-9a-zA-Z_.-]+.zip)')
fb2_check = re.compile('([ 0-9a-zA-ZА-Яа-я_,.:!-]+.fb2)')

def unurl(s: str):
    tr = {
        '%22': '"',
        '%27': "'",
        '%2E': ".",
        '%2F': '/'
    }
    ret = s
    if ret is not None:
        for r, v in tr.items():
            ret = ret.replace(r, v)
    return ret

def redir_invalid(redir_name):
    location = url_for(redir_name)
    code = 302  # for readers
    return redirect(location, code, Response=None)

def validate_id(s: str):
    ret = s
    if id_check.match(s):
        return ret
    return None

# simple prefix validation in .../sequenceindes and .../authorsindex
def validate_prefix(s: str):
    ret = s.replace('"', '`').replace("'", '`')  # no "' quotes in database
    if len(ret) > 10:
        return None
    return ret

def validate_genre(s: str):
    ret = s
    if genre_check.match(s):
        return ret
    return None

def validate_genre_meta(s: str):
    ret = s
    if genre_check.match(s):
        return ret
    return None

# search pattern some normalization
def validate_search(s: str):
    if s is None:
        return ""
    ret = unurl(s).replace('"', '`').replace("'", '`').replace(';', '')
    if len(ret) > 128:
        ret = ret[:128]
    return ret

def validate_zip(s: str):
    ret = s
    if zip_check.match(s):
        return ret
    return None

def validate_fb2(s: str):
    ret = unurl(s)
    if fb2_check.match(s):
        return ret
    return None


import maze
from PIL import Image, ImageDraw
import time
from sys import argv

def print_maze(side, mymaze):
    print("|-" * side + "|")
    for i, slot in enumerate(mymaze):
        print(slot, end=' ') if slot is not None else print('X', end=' ')
        if (i + 1) % (side) == 0:
            print("")
    print("|-" * side + "|")

def draw_polygon(size, draw, ind, block_size, color):
        draw.polygon([(ind % size) * block_size,
                      (ind // size) * block_size,
                      (ind % size) * block_size + block_size,
                      (ind // size) * block_size,
                      (ind % size) * block_size + block_size,
                      (ind // size) * block_size + block_size,
                      (ind % size) * block_size,
                      (ind // size) * block_size + block_size],
                     fill=color)

def paint_solution_manhattan(array, size, block_size, path):
        start_time = time.time()
        img = Image.new(
            'L',
            (size * block_size,
             size * block_size),
            color=255)
        draw = ImageDraw.Draw(img)
        for i,v in enumerate(array):
            draw_polygon(size, draw, i, block_size, 255-v)
            print("Painting solution... {}%".format((i*100)//(len(array)+1)),end='\r')

        print("Painting solution... 100%")
        img.save("{}.bmp".format(path), quality=100, subsampling=0)
        elapsed_time = time.time() - start_time
        print("Elapsed time painting solution : {}".format(elapsed_time))

def main(side):
	maze_ = maze.Maze(side)
	mazeSum = [0]*(side*side)

	for i in range(255):
		maze_.generate_new_maze()
		maze_.solve_maze()
		mazeSum = [mazeSum[i] + (1 if v==2 else 0) for i,v in enumerate(maze_.pathing)]
		print("Working... {}%".format((i*100)//255),end='\r')
	print()

	#print_maze(SIDE, mazeSum)
	paint_solution_manhattan(mazeSum, side, 15, "grey_scale")

if __name__ == "__main__":
	try:
		main(int(argv[1]))
	except (ValueError, IndexError):
		print("Usage is: python3 {} line_size".format(argv[0]))


from pytube import YouTube
def checkVideoResolution(tmp):
    videoResolution = ["2160p","1440p","1080p","720p","480p","360p","240p", "144p"]
    array = []
    url = YouTube(tmp)
    for i in range(len(videoResolution)):
        if(len(url.streams.filter(adaptive=True, file_extension='mp4', res=videoResolution[i]))>0):
            array.append(videoResolution[i])
    return array

def checkAudioResolution(tmp):
    audioResolution = ["128kbps","48kbps"]
    array = []
    url = YouTube(tmp)
    for i in range(len(audioResolution)):
        if(len(url.streams.filter(file_extension='mp4',type="audio", abr=audioResolution[i]))>0):
            array.append(audioResolution[i])
    return array


import sys
import getopt
import numpy as np
import scipy
from scipy import ndimage
from os import listdir
import matplotlib.pyplot as plt

def Read_CSV(fname):
    f = open(fname, "r")
    Y = np.empty((1, 0))
    X = np.empty((64*64*3,0))
    i=0
    for line in f:
        data = line.split(',')
        with urllib.request.urlopen(data[0]) as url:
            f = io.BytesIO(url.read())
        a = ndimage.imread(f, flatten=False)
        b = scipy.misc.imresize(a, size=(128, 128))
        b = b/255
        c = b.reshape(128*128*3, 1)
        X = np.hstack((X, c))
        Y[0].append(int(data[1]))
        i = i+1
    print(Y)
    return X, Y

def Read_File(fname):
    a = ndimage.imread(fname, flatten=False)
    b = scipy.misc.imresize(a, size=(128, 128))
    #Normalize data. 255 beecause max pixel value is 255
    b = b/255
    c = b.reshape(128*128*3, 1)
    return c

def collect_data(dirname):
    files = listdir(dirname)
    Y = np.empty((1, len(files)))
    X = np.empty((128*128*3,0))

    i = 0
    for f in files:
        a = Read_File(dirname + "/" + f)
        if f.find("cat") == -1:
            Y[0][i] = 0
        else:
            Y[0][i] = 1
        X = np.hstack((X, a))
        i = i+1
    return X, Y

def initialize_hyperparams():
    hyperparams = {}
    hyperparams["learning_rate"] = 0.01 # Learning rate of gradient descent
    hyperparams["num_iterations"] = 4000 # Number of iterations of propagation
    hyperparams["dims"] = [4, 4, 3, 1] # Number of nodes in each layer of NN
    hyperparams["lamba"] = 0.01 # Regularization param lambda
    hyperparams["beta1"] = 0.9 # Exponential Weighted average param
    hyperparams["beta2"] = 0.999 # RMSProp param
    hyperparams["epsilon"] = 10 ** -8 # Adams optimization zero correction
    hyperparams["minibatch"] = 100 # size of the minibatch, 0 indicates no minibatching
    return hyperparams

# Initialize the parameters
# lists_dims["n_x=l0", "l1", "l2" ....]
def initialize_parameters(lists_dims):
    parameters = []
    for i in range(1, len(lists_dims)):
        # 'He' initialization for random weights
        W = np.random.randn(lists_dims[i], lists_dims[i-1]) * np.sqrt(np.divide(2, lists_dims[i-1]))
        Vw = np.zeros(W.shape)
        Sw = np.zeros(W.shape)
        b = np.zeros((lists_dims[i], 1))
        Vb = np.zeros(b.shape)
        Sb = np.zeros(b.shape)
        parameters.append((W, b, Vw, Vb, Sw, Sb))
    return parameters

#Activation Functions
def sigmoid(Z, derivative):
    s = (1/(1+np.exp(-Z)))
    if derivative == True:
        return s*(1-s)
    return s

def relu(Z, derivative):
    for i in range(len(Z)):
        for j in range(len(Z[i])):
            if Z[i][j] > 0:
                if derivative == True:
                    Z[i][j] = 1
                else:
                    pass
            else:
                Z[i][j] = 0
    #print("RELU: ", Z)
    return Z

def forward_activation(Z, func):
    if func == "sigmoid":
        return sigmoid(Z, False)
    elif func == "relu":
        return relu(Z, False)
    else:
        assert(0)
    return None

# Calculate the Z and A parameters of forward propagation for each layer
def forward_propagate(X, parameters, N):
    forward_cache = []
    A = X
    AL = A
    for i in range(N):
        A = AL
        W, b, Vw, Vb, Sw, Sb = parameters[i]
        Z = np.dot(W, A) + b
        if i == N-1 :
            activation_func = "sigmoid"
        else:
            activation_func = "sigmoid"
        AL = forward_activation(Z, activation_func)
        forward_cache.append((A, Z, W, b))
    #print (AL)
    return AL, forward_cache

def regularize_cost(cost, m, lamba, parameters):
    if lamba == 0:
        return cost
    W, b, Vw, Vb, Sw, Sb = parameters[len(parameters)-1]
    n = np.linalg.norm(W)
    normalize = np.divide(lamba, 2*m)*n
    cost = cost + normalize
    return cost

def compute_cost(AL, Y):
    m = Y.shape[1]
    cost = -(np.sum(np.multiply(Y, np.log(AL)) + np.multiply((1-Y), np.log(1-AL))))/Y.shape[1]
    cost = np.squeeze(cost)
    return cost

def back_propagate_linear(dZ, forward_cache):
    A, Z, W, b = forward_cache
    m = A.shape[1]
    dW = (np.dot(dZ, A.T))/m
    assert(W.shape == dW.shape)
    db = (np.sum(dZ, axis=1, keepdims=True))/m
    assert(b.shape == db.shape)
    dA_prev = np.dot(W.T, dZ)
    assert(dA_prev.shape == A.shape)
    return dA_prev, dW, db

def back_propagate_activation(dA, forward_cache, activation_func):
    A, Z, W, b = forward_cache

    if activation_func == "relu":
        dZ = dA*relu(Z, True)
    elif activation_func == "sigmoid":
        dZ = dA*sigmoid(Z, True)
    else:
        assert(0)

    return back_propagate_linear(dZ, forward_cache)

def back_propagate(AL, Y, forward_cache):
    grads = []
    dA = - (np.divide(Y, AL) - np.divide((1-Y), (1-AL)))
    activation_func = "sigmoid"
    for cache in reversed(forward_cache):
        dA_prev, dW, db = back_propagate_activation(dA, cache, activation_func)
        grads.append((dW, db))
        dA = dA_prev
        activation_func = "sigmoid"
    return grads

def regularize_weights(W, m, learning_rate, lamba):
    if lamba == 0:
        return W
    W = W - np.multiply(np.divide(np.multiply(learning_rate, lamba), m), W)
    return W

# A combination of Exponential Weighted Average and RMSProp with bias correction
# To be used with mini-batches

def momentum(dW, db, Vw, Vb, hyperparams, layer):
    beta1 = hyperparams["beta1"]
    Vw = np.multiply(beta1, Vw) + np.multiply((1-beta1), dW)
    Vw_corrected = np.divide(Vw, (1-np.power(beta1, layer)))
    Vb = np.multiply(beta1, Vb) + np.multiply((1-beta1), db)
    Vb_corrected = np.divide(Vb, (1-np.power(beta1, layer)))
    return Vw_corrected, Vb_corrected, Vw, Vb

def rms_prop(dW, db, Sw, Sb, hyperparams, layer):
    beta2 = hyperparams["beta2"]
    epsilon = hyperparams["epsilon"]
    Sw = np.multiply(beta2, Sw) + np.multiply((1-beta2), np.power(dW,2))
    Sw_corrected = np.divide(Sw, (1-np.power(beta2, layer)))
    Sb = np.multiply(beta2, Sb) + np.multiply((1-beta2), np.power(db, 2))
    Sb_corrected = np.divide(Sb, (1-np.power(beta2, layer)))
    dW_optimized = np.divide(dW, (np.sqrt(Sw_corrected + epsilon)))
    db_optimized = np.divide(db, (np.sqrt(Sb_corrected + epsilon)))
    return dW_optimized, db_optimized, Sw, Sb

def adams_optimization(dW, db, Vw, Vb, Sw, Sb, hyperparams, layer):
    beta1 = hyperparams["beta1"]
    beta2 = hyperparams["beta2"]
    epsilon = hyperparams["epsilon"]
    Vw = np.multiply(beta1, Vw) + np.multiply((1-beta1), dW)
    Vw_corrected = np.divide(Vw, (1-np.power(beta1, layer)))
    Sw = np.multiply(beta2, Sw) + np.multiply((1-beta2), np.power(dW, 2))
    Sw_corrected = np.divide(Sw, (1-np.power(beta2, layer)))
    Vb = np.multiply(beta1, Vb) + np.multiply((1-beta1), db)
    Vb_corrected = np.divide(Vb, (1-np.power(beta1, layer)))
    Sb = np.multiply(beta2, Sb) + np.multiply((1-beta2), np.power(db, 2))
    Sb_corrected = np.divide(Sb, (1-np.power(beta2, layer)))
    dW_optimized = np.divide(Vw_corrected, (np.sqrt(Sw_corrected) + epsilon))
    db_optimized = np.divide(Vb_corrected, (np.sqrt(Sb_corrected) + epsilon))
    return dW_optimized, db_optimized, Vw, Vb, Sw, Sb

def update_parameters(m, parameters, grads, hyperparams):
    new_params = []
    learning_rate = hyperparams["learning_rate"]
    j=len(parameters)-1
    for i in range(len(parameters)):
        W, b, Vw, Vb, Sw, Sb = parameters[i]
        dW, db = grads[j]
        #dW, db, Vw, Vb, Sw, Sb = adams_optimization(dW, db, Vw, Vb, Sw, Sb, hyperparams, j+1)
        dW, db, Vw, Vb = momentum(dW, db, Vw, Vb, hyperparams, j+1)
        #dW, db, Sw, Sb = rms_prop(dW, db, Sw, Sb, hyperparams, j+1)
        j = j-1
        W = W - (learning_rate * dW)
        W = regularize_weights(W, m, learning_rate, hyperparams["lamba"])
        b = b - (learning_rate * db)
        new_params.append((W, b, Vw, Vb, Sw, Sb))
    return new_params

def calculate_success(Y, AL):
    p = np.around(AL)
    #print("Activation: ", AL)
    for i in range(len(p[0])):
        if(p[0][i] != Y[0][i]):
            p[0][i] = 0
        else:
            p[0][i] = 1
    print("Success Cal: ", p)
    #print("Expectation: ", Y)
    #print(p.shape)
    #print(np.sum(p))
    #print(len(p[0]))
    return np.squeeze(np.sum(p, axis=1, keepdims=1)/len(p[0]))

def create_mini_batches(X, Y, batch_size, seed):
    np.random.seed(seed)
    mini_batches = []
    if batch_size == 0:
        mini_batches.append((X,Y))
        return mini_batches
    m = X.shape[1]
    permutate = np.random.permutation(m)
    X_shuffle = X[:, permutate]
    Y_shuffle = Y[:, permutate]

    num_batches = int(np.floor(m/batch_size))
    for k in range(num_batches):
        mini_batches.append((X[:, batch_size*k:batch_size*(k+1)], Y[:, batch_size*k:batch_size*(k+1)]))

    if m%batch_size>0 :
        mini_batches.append((X[:, batch_size*num_batches:], Y[:, batch_size*num_batches:]))
    return mini_batches

def run_one_epoch(seed, X, Y, parameters, hyperparams, costs, m):
    N = len(parameters)
    batches = create_mini_batches(X, Y, hyperparams["minibatch"], seed)
    for batch in batches:
        X,Y = batch
        AL, forward_cache = forward_propagate(X, parameters, N)
        c = compute_cost(AL, Y)
        c = regularize_cost(c, m, hyperparams["lamba"], parameters)
        costs.append(c)
        grads = back_propagate(AL, Y, forward_cache)
        parameters = update_parameters(m, parameters, grads, hyperparams)
    return parameters, costs, AL

def train_model(X, Y, parameters, hyperparams):
    num_iterations = hyperparams["num_iterations"]
    N = len(parameters)
    m = X.shape[1]
    costs = []
    for i in range(num_iterations):
        parameters, costs, AL = run_one_epoch(i, X, Y, parameters, hyperparams, costs, m)
        if i%100 == 0:
            print ("Cost after ", i, " iterations:", costs[-1])
    AL, forward_cache = forward_propagate(X, parameters, N)
    print ("Trained model success rate: " +  str(calculate_success(Y, AL) *100) + "%")
    return parameters, costs

def test_model(X, Y, parameters):
    m = X.shape[1]
    N = len(parameters)
    AL, forward_cache = forward_propagate(X, parameters, N)
    return calculate_success(Y, AL)

def print_help():
    print ("classifier.py -l <learn_dir> -t <test_dir> -r <learn_rate> -i <num iterations> -n \"<comma separated num nodes in each layer>\"")

def plot_cost_gradient(cost):
    plt.plot(cost)
    plt.ylabel("Cost")
    plt.xlabel("Per 100 iterations")
    plt.title("Cost gradient")
    plt.show()

def main(argv):
    np.random.seed(1)
    learn_dir = "./images"
    test_dir = "./test"
    hyperparams = initialize_hyperparams()

    dims = hyperparams["dims"]

    try:
        opts, args = getopt.getopt(argv, "hl:t:r:i:n:",["help", "learndir=", "testdir=", "learnrate=", "iters=", "net="])
    except getopt.GetoptError:
        print_help()
        sys.exit(2)
    for opt, arg in opts:
        if opt == "-h":
            print_help()
            sys.exit(2)
        elif opt == "-l":
            learn_dir = arg
        elif opt == "-t":
            test_dir == arg
        elif opt == "-r":
            learning_rate = float(arg)
        elif opt == "-i":
            num_iterations = int(arg)
        elif opt == "-n":
            dims_str = arg.split(",")
            dims = []
            for num in dims_str:
                dims.append(int(num))
        else:
            print_help()
            sys.exit(2)
    XL, YL = collect_data(learn_dir)
    XT, YT = collect_data(test_dir)
    #Starting Hyperparameters
    lists_dims = [XL.shape[0]]
    for num in dims:
        lists_dims.append(num)
    print("NN Dimensions: ", lists_dims)
    #Train the model
    parameters = initialize_parameters(lists_dims)
    parameters, cost = train_model(XL, YL, parameters, hyperparams)
    # check out the success rate with a test run
    success_rate = test_model(XT, YT, parameters)
    print ("Test Success rate: " + str(success_rate*100) + "%")
    plot_cost_gradient(cost)

if __name__ == "__main__" :
    main(sys.argv[1:])


#!/usr/bin/env python2.7
import numpy as np
import cv2
import glob
import json
from copy import copy
import os

class Configure():
    def __init__(self):
        self.objpoints = []
        self.imgpoints = []
        self.height = 480
        self.width = 640

    def getCalibrationParameters(self):
        dim = (8,5)
        objp = np.zeros((dim[0]*dim[1], 3), np.float32)
        objp[:,:2] = np.mgrid[0:dim[0], 0:dim[1]].T.reshape(-1,2)
        images = glob.glob('../samples/pitch1/*.png')

        for fname in images:
            img = cv2.imread(fname)
            gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

            # Find the chess board corners
            ret, corners = cv2.findChessboardCorners(gray, dim, None)

            # If found, add object points, image points (after refining them)
            if ret == True:
                self.objpoints.append(objp)
                corners2 = copy(corners)
                criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
                _ = cv2.cornerSubPix(gray,corners2,(11,11),(-1,-1),criteria)
                self.imgpoints.append(corners2)

                # Draw and display the corners
                # Comment this out to skip showing sample images!
                _ = cv2.drawChessboardCorners(img, dim, corners2, ret)
                cv2.imshow('img',img)
            cv2.waitKey(1000)

        ret, camera_matrix, dist, _, _ = cv2.calibrateCamera(self.objpoints, self.imgpoints, gray.shape[::-1],None,None)
        new_camera_matrix, roi=cv2.getOptimalNewCameraMatrix(camera_matrix, dist,(self.width,self.height),0,(self.width,self.height))

        pitch1 = {'new_camera_matrix' : new_camera_matrix.tolist(),
            'camera_matrix' : camera_matrix.tolist(),
            'dist' : dist.tolist()}

        pitch0 = {'new_camera_matrix' : new_camera_matrix.tolist(),
            'camera_matrix' : camera_matrix.tolist(),
            'dist' : dist.tolist()}

        data = {0 : pitch0, 1: pitch1}

        return data

if __name__ == "__main__":
    path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "../config/", "undistort_pitch1.json")
    C = Configure()
    data = C.getCalibrationParameters()
    with open(path, 'w') as f:
        f.write(json.dumps(data))


from bs4 import BeautifulSoup
import requests
import json
import time
import random

headers = {
     'User-Agent': 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Mobile Safari/537.36'
 }
# GetAllLinksAndNamesFromPolitics
res = requests.get(f'https://www.bundestag.de/ajax/filterlist/de/abgeordnete/biografien/862712-862712?limit=20&noFilterSet=true&offset=0',headers=headers)
with open('AllData.html','a',encoding='utf-8') as f:
    f.write(res.text)
i = 12
while(i <= 732):
   res2 = requests.get(f'https://www.bundestag.de/ajax/filterlist/de/abgeordnete/biografien/862712-862712?limit=20&noFilterSet=true&offset={i}', headers=headers)
   with open('AllData.html','a',encoding='utf-8') as f:
        f.write(res2.text)
   del res2
   print(i)
   time.sleep(5)
   i+=20

# FormJsonFromHTML
with open('AllData.html','r',encoding='utf-8') as f:
    fileRaw = f.read()
soup = BeautifulSoup(fileRaw,'html.parser')
names = soup.find_all('div',class_ = 'bt-bild-info-text')
politicNameForHref = []
politicHref = []

for name in names:
    politicNameForHref.append(name.find('p').text.strip())
PoliticLinkJson = {}
namesHref = soup.find_all('a',href=True)
for href in namesHref:
    politicHref.append(href['href'])
a = 0
while(a < len(namesHref)):
    PoliticLinkJson[politicNameForHref[a]] =  'https://www.bundestag.de' + politicHref[a]
    a+=1

with open('PoliticLinkJson.json','w',encoding='utf-8') as f:
    json.dump(PoliticLinkJson,f,indent=4,ensure_ascii=False)

# PoliticsData

socialNetworks ={}
Person ={}
Persons = []
Name = []
Occupation = []
count = 0

while(count<len(politicHref)):
        res3 = requests.get('https://www.bundestag.de'+politicHref[count] , headers=headers)
        soup2 = BeautifulSoup(res3.text,'html.parser')
        Facebook = soup2.find('a', {'title' : 'Facebook'})

        socialNetworks['Facebook'] = '' if Facebook is None else Facebook['href']

        Homepage = soup2.find('a', {'title' : 'Homepage'})

        socialNetworks['Homepage'] = '' if Homepage is None else Homepage['href']

        Youtube = soup2.find('a', {'title' : 'Youtube'})

        socialNetworks['Youtube'] = '' if Youtube is None else Youtube['href']

        Twitter= soup2.find('a', {'title' : 'Twitter'})

        socialNetworks['Twitter'] = '' if Twitter is None else Twitter['href']

        Instagram = soup2.find('a', {'title' : 'Instagram'})

        socialNetworks['Instagram'] = '' if Instagram is None else Instagram['href']

        LinkedIn= soup2.find('a', {'title' : 'Instagram'})

        socialNetworks['LinkedIn'] =  '' if LinkedIn is None else LinkedIn['href']

        Name = soup2.find('div' , 'bt-biografie-name').find('h3')

        Occupation = soup2.find('div',class_= 'bt-biografie-beruf')

        Person['name'] = '' if Name is None else Name.text.strip()
        Person['socialNetworks'] = socialNetworks.copy()
        Person['Occupation'] = '' if Occupation is None else Occupation.text.strip()
        Persons.append(Person.copy())
        time.sleep(1)
        print(count)
        count+=1

with open('PoliticData.json','w',encoding='utf-8') as f:
    json.dump(Persons,f,indent=4,ensure_ascii=False)


import streamlit as st
import numpy as np
import pandas as pd
import plotly.express as px
from wordcloud import WordCloud, STOPWORDS
import matplotlib.pyplot as plt
from datetime import datetime
import db

st.title("Product Review Analysis")
st.sidebar.title("Select Your Choices")
st.set_option('deprecation.showPyplotGlobalUse', False)

data_path = ("Yelp.csv")

def load_data():
    data = pd.read_csv(data_path)
    data['date'] = pd.to_datetime(data['date'])
    return data

data = load_data()

st.markdown("")
see_data = st.expander('Click here to see the dataset')
with see_data:
        st.dataframe(data.reset_index(drop=True))
st.text('')

st.sidebar.subheader("Random Reviews")
random_tweet = st.sidebar.radio('Select the Sentiment',('positive','negative','neutral'))
if st.sidebar.checkbox("Show", False, key="1"):
    st.subheader("Here are some of random reviews according to your choice!")
    for i in range(len(data['date'])):
        if i ==5:
            break
        else:
            st.markdown(str(i+1) +"." + data.query("sentiments == @random_tweet")[['text']].sample(n=1).iat[0,0])

st.sidebar.markdown("### Visualization of Reviews")
select = st.sidebar.selectbox('Select type of visualization',['Histogram','PieChart'])

sentiment_count = data['sentiments'].value_counts()
sentiment_count = pd.DataFrame({'Sentiments':sentiment_count.index,'Reviews':sentiment_count.values})

if st.sidebar.checkbox('Show',False,key='0'):
    st.markdown("### No. of reviews by sentiments ")
    if select=='Histogram':
        fig = px.bar(sentiment_count,x='Sentiments',y='Reviews',color='Reviews',height=500)
        st.plotly_chart(fig)
    else:
        fig = px.pie(sentiment_count,values='Reviews',names='Sentiments')
        st.plotly_chart(fig)

st.sidebar.subheader("Breakdown Sentiments by city")
choice = st.sidebar.multiselect("Pick City", tuple(pd.unique(data["city"])))
if st.sidebar.checkbox("Show", False, key="5"):
    if len(choice) > 0:
        chosen_data = data[data["city"].isin(choice)]
        fig = px.histogram(chosen_data, x="city", y="sentiments",
                                histfunc="count", color="sentiments",
                                facet_col="sentiments", labels={"sentiments": "sentiment"})
        st.plotly_chart(fig)

# Word cloud
st.sidebar.subheader("Word Cloud")
word_sentiment = st.sidebar.radio("Which Sentiment to Display?", tuple(pd.unique(data["sentiments"])))
if st.sidebar.checkbox("Show", False, key="6"):
    st.subheader(f"Word Cloud for {word_sentiment.capitalize()} Sentiment")
    df = data[data["sentiments"]==word_sentiment]
    words = " ".join(df["text"])
    #processed_words = " ".join([word for word in words.split() if "http" not in word and not word.startswith() and word != "RT"])
    processed_words = " ".join([word for word in words.split()])
    wordcloud = WordCloud(stopwords=STOPWORDS, background_color="white", width=600, height=500).generate(processed_words)
    plt.imshow(wordcloud)
    plt.xticks([])
    plt.yticks([])
    st.pyplot()


import datetime
import json

import requests

from django.conf import settings
from django.db import models

class Bill(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)
    comment = models.CharField(max_length=45, default='')
    amount = models.FloatField(default=1.00)
    status = models.CharField(max_length=15, null=True, blank=True)
    site = models.CharField(max_length=45)

    def get_url(self):
        try:
            headers = {
                'Authorization': f'Bearer {settings.QIWI_SECRET_KEY}',
                'Content-Type': 'application/json',
                'Accept': 'application/json',
            }

            expirationDateTime = self.created_at + datetime.timedelta(days=2)
            expirationDateTime = expirationDateTime.strftime('%Y-%m-%dT%H:%M:%S+03:00')

            request_data = {
                'amount': {
                    'currency': 'RUB',
                    'value': str(round(self.amount, 2))
                },
                'comment': str(self.comment),
                'expirationDateTime': str(expirationDateTime),
            }
            request_data = json.dumps(request_data)
            response = requests.put(f'https://api.qiwi.com/partner/bill/v1/bills/{settings.QIWI_DB_VERSION}_{self.id}/', headers=headers, data=request_data)
            data = response.json()

            self.status = data['status']['value']
            return data['payUrl']
        except:
            return None

    def reject(self):
        try:
            headers = {
                'Authorization': f'Bearer {settings.QIWI_SECRET_KEY}',
                'Content-Type': 'application/json',
                'Accept': 'application/json',
            }
            response = requests.post(f'https://api.qiwi.com/partner/bill/v1/bills/{settings.QIWI_DB_VERSION}_{self.id}/reject/', headers=headers)
            data = response.json()

            self.status = data['status']['value']
        except:
            return

    def success(self):
        import hmac
        import hashlib

        try:
            secret_key = bytes(settings.OPLATA_KEY)
            message = bytes(f'{self.id}|{self.status}|RUB|{self.amount}')
            signature = hmac.new(secret_key, message, hashlib.sha256).hexdigest()

            headers = {
                'Content-Type': 'application/json',
                'X-Api-Signature-SHA256': signature,
            }

            request_data = {
                'id': self.id,
                'status': self.status,
                'amount': {
                    'currency': 'RUB',
                    'value': str(self.amount)
                },
                'comment': self.comment,
            }

            request_data = json.dumps(request_data)

            response = requests.post(self.site, data=request_data, headers=headers)
            return response
        except:
            return None


from sqlalchemy import and_
from sqlalchemy import delete
from sqlalchemy import desc
from sqlalchemy import select
from sqlalchemy.orm import Session

from danswer.db.models import ConnectorCredentialPair
from danswer.db.models import DeletionAttempt
from danswer.db.models import DeletionStatus
from danswer.db.models import IndexingStatus

def check_deletion_attempt_is_allowed(
    connector_credential_pair: ConnectorCredentialPair,
) -> bool:
    """
    To be deletable:
        (1) connector should be disabled
        (2) there should be no in-progress/planned index attempts
    """
    return bool(
        connector_credential_pair.connector.disabled
        and (
            connector_credential_pair.last_attempt_status != IndexingStatus.IN_PROGRESS
            and connector_credential_pair.last_attempt_status
            != IndexingStatus.NOT_STARTED
        )
    )

def create_deletion_attempt(
    connector_id: int,
    credential_id: int,
    db_session: Session,
) -> int:
    new_attempt = DeletionAttempt(
        connector_id=connector_id,
        credential_id=credential_id,
        status=DeletionStatus.NOT_STARTED,
    )
    db_session.add(new_attempt)
    db_session.commit()

    return new_attempt.id

def get_not_started_index_attempts(db_session: Session) -> list[DeletionAttempt]:
    stmt = select(DeletionAttempt).where(
        DeletionAttempt.status == DeletionStatus.NOT_STARTED
    )
    not_started_deletion_attempts = db_session.scalars(stmt)
    return list(not_started_deletion_attempts.all())

def get_deletion_attempts(
    db_session: Session,
    connector_ids: list[int] | None = None,
    statuses: list[DeletionStatus] | None = None,
    ordered_by_time_updated: bool = False,
    limit: int | None = None,
) -> list[DeletionAttempt]:
    stmt = select(DeletionAttempt)
    if connector_ids:
        stmt = stmt.where(DeletionAttempt.connector_id.in_(connector_ids))
    if statuses:
        stmt = stmt.where(DeletionAttempt.status.in_(statuses))
    if ordered_by_time_updated:
        stmt = stmt.order_by(desc(DeletionAttempt.time_updated))
    if limit:
        stmt = stmt.limit(limit)

    deletion_attempts = db_session.scalars(stmt)
    return list(deletion_attempts.all())

def delete_deletion_attempts(
    db_session: Session, connector_id: int, credential_id: int
) -> None:
    stmt = delete(DeletionAttempt).where(
        and_(
            DeletionAttempt.connector_id == connector_id,
            DeletionAttempt.credential_id == credential_id,
        )
    )
    db_session.execute(stmt)


from os import path

from django.conf import settings
from django.core.mail import EmailMultiAlternatives
from django.test import TestCase, override_settings
from django.test.client import RequestFactory
from django.urls import reverse

from ..errors import (
    AttachmentTooLargeError,
    AuthenticationError,
)
from ..signals import email_received, email_received_unacceptable
from ..views import receive_inbound_email, _log_request

from .test_files.sendgrid_post import test_inbound_payload as sendgrid_payload
from .test_files.mailgun_post import test_inbound_payload as mailgun_payload
from .test_files.mandrill_post import post_data as mandrill_payload
from .test_files.mandrill_post import (
    post_data_with_attachments as mandrill_payload_with_attachments
)

# don't read it out of the settings - fix it here so we know what we're using
DEFAULT_TEST_PARSER = "inbound_email.backends.sendgrid.SendGridRequestParser"
MANDRILL_REQUEST_PARSER = "inbound_email.backends.mandrill.MandrillRequestParser"
SENDGRID_REQUEST_PARSER = "inbound_email.backends.sendgrid.SendGridRequestParser"
MAILGUN_REQUEST_PARSER = "inbound_email.backends.mailgun.MailgunRequestParser"

class ViewFunctionTests(TestCase):
    """Tests for the inbound view function receive_inbound_email.

    The view function is responsible for loading the correct backend, and
    firing the signal once the email is parsed. This test suite contains no
    parsing tests - these are covered in the relevant backend tests - just tests
    for the signals.

    """
    def setUp(self):
        # Every test needs access to the request factory.
        self.factory = RequestFactory()
        self.url = reverse('receive_inbound_email')
        self.test_upload_txt = path.join(path.dirname(__file__), 'test_files/test_upload_file.txt')

    def _get_payloads_and_parsers(self, with_attachments=False):
        mpwa = mandrill_payload_with_attachments
        mp = mandrill_payload
        return [
            (MANDRILL_REQUEST_PARSER, mpwa if with_attachments else mp),
            (SENDGRID_REQUEST_PARSER, sendgrid_payload),
            (MAILGUN_REQUEST_PARSER, mailgun_payload),
        ]

    def test_log_inbound_requests(self):
        """Test the internal log function."""
        # just to exercise the function - it doesn't 'do' anything other than
        # log to the console, but is good to know that it doesn't break.

        for klass, payload in self._get_payloads_and_parsers():
            settings.INBOUND_EMAIL_PARSER = klass
            request = self.factory.post(self.url, data=payload)
            _log_request(request)

    def test_inbound_request_HEAD_200(self):
        """Return 200 OK to a HEAD request."""
        request = self.factory.head(self.url)
        response = receive_inbound_email(request)
        self.assertEqual(response.status_code, 200)

    def test_valid_request(self):
        """Test the RequestParseErrors are handled correctly, and return HTTP 200."""
        for klass, payload in self._get_payloads_and_parsers():
            settings.INBOUND_EMAIL_PARSER = klass
            request = self.factory.post(self.url, data=payload)
            response = receive_inbound_email(request)
            self.assertContains(response, "Successfully parsed", status_code=200)

    def test_parse_error_response_200(self):
        """Test the RequestParseErrors are handled correctly, and return HTTP 200."""
        settings.INBOUND_EMAIL_RESPONSE_200 = True
        for klass, payload in self._get_payloads_and_parsers():
            settings.INBOUND_EMAIL_PARSER = klass
            request = self.factory.post(self.url, data={})
            response = receive_inbound_email(request)
            self.assertContains(response, "Unable to parse", status_code=200)

    def test_parse_error_response_400(self):
        """Test the RequestParseErrors are handled correctly, and return HTTP 400."""
        settings.INBOUND_EMAIL_RESPONSE_200 = False
        request = self.factory.post(self.url, data={})
        response = receive_inbound_email(request)
        self.assertContains(response, "Unable to parse", status_code=400)

    def test_email_received_signal(self):
        """Test that a valid POST fires the email_received signal."""
        # define handler
        for klass, payload in self._get_payloads_and_parsers():

            def on_email_received(sender, **kwargs):
                self.on_email_received_fired = True
                self.assertEqual(sender.__name__, klass.split('.')[-1])
                request = kwargs.pop('request', None)
                email = kwargs.pop('email', None)
                self.assertIsNotNone(email)
                self.assertIsInstance(email, EmailMultiAlternatives)
                self.assertIsNotNone(request)
            email_received.connect(on_email_received)

            settings.INBOUND_EMAIL_PARSER = klass
            request = self.factory.post(self.url, data=payload)

            # connect handler
            self.on_email_received_fired = False

            # fire a request in to force the signal to fire
            receive_inbound_email(request)
            self.assertTrue(self.on_email_received_fired)

            email_received.disconnect(on_email_received)

    def test_email_received_unacceptable_signal_fired_for_too_large_attachment(self):
        # set a zero allowed max attachment size
        settings.INBOUND_EMAIL_ATTACHMENT_SIZE_MAX = 0

        for klass, payload in self._get_payloads_and_parsers(with_attachments=True):
            settings.INBOUND_EMAIL_PARSER = klass
            _payload = payload.copy()

            if klass == SENDGRID_REQUEST_PARSER:
                _payload['attachment'] = open(self.test_upload_txt, 'r')
            if klass == MAILGUN_REQUEST_PARSER:
                _payload['attachment-1'] = open(self.test_upload_txt, 'r')

            # define handler
            def on_email_received(sender, **kwargs):
                self.on_email_received_fired = True
                request = kwargs.pop('request', None)
                email = kwargs.pop('email', None)
                exception = kwargs.pop('exception', None)
                self.assertEqual(sender.__name__, klass.split('.')[-1])
                self.assertIsNotNone(request)
                self.assertIsInstance(email, EmailMultiAlternatives)
                self.assertIsInstance(exception, AttachmentTooLargeError)
            email_received_unacceptable.connect(on_email_received)

            self.on_email_received_fired = False

            request = self.factory.post(self.url, data=_payload)
            receive_inbound_email(request)
            self.assertTrue(self.on_email_received_fired, klass)
            email_received_unacceptable.disconnect(on_email_received)

    @override_settings(INBOUND_MANDRILL_AUTHENTICATION_KEY='mandrill_key')
    def test_email_received_unacceptable_signal_fired_for_mandrill_mistmatch_signature(self):
        parser = MANDRILL_REQUEST_PARSER
        payload = mandrill_payload
        settings.INBOUND_EMAIL_PARSER = parser
        _payload = payload.copy()

        # define handler
        def on_email_received(sender, **kwargs):
            self.on_email_received_fired = True
            request = kwargs.pop('request', None)
            email = kwargs.pop('email', None)
            exception = kwargs.pop('exception', None)
            self.assertEqual(sender.__name__, parser.split('.')[-1])
            self.assertIsNotNone(request)
            self.assertIsNone(email,)
            self.assertIsInstance(exception, AuthenticationError)
        email_received_unacceptable.connect(on_email_received)

        self.on_email_received_fired = False

        request = self.factory.post(
            self.url,
            data=_payload,
            HTTP_X_MANDRILL_SIGNATURE='invalid_signature',
        )
        receive_inbound_email(request)
        self.assertTrue(self.on_email_received_fired, parser)
        email_received_unacceptable.disconnect(on_email_received)