# -*- coding: utf-8 -*-
"""Run full pipeline using cell2location model."""

import gc
import os
import pickle
# +
import time
from os import mkdir

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import theano

import cell2location.plt as c2lpl
from cell2location.cluster_averages import get_cluster_averages
from cell2location.cluster_averages import select_features

def save_plot(path, filename, extension='png'):
    r""" Save current plot to `path` as `filename` with `extension`
    """

    plt.savefig(path + filename + '.' + extension)
    # fig.clear()
    plt.close()

def run_regression(sc_data, model_name='RegressionNBV4Torch',
                   verbose=True, return_all=True,
                   train_args={
                       'covariate_col_names': None, 'sample_name_col': "sample", 'tech_name_col': None,
                       'n_iter': 15000, 'learning_rate': 0.005,
                       'sample_prior': False, 'readable_var_name_col': "SYMBOL"
                   },
                   model_kwargs={},
                   posterior_args={'n_samples': 1000},
                   export_args={'path': "./results", 'save_model': True,
                                'run_name_suffix': '', 'scanpy_coords_name': 'coords'}):
    r""" Run cell2location model: train, sample prior and posterior, save, export results and save diagnostic plots
    Spatial expression of cell types (proxy for density) is exported as columns of adata.obs,
       named `'mean_nUMI_factors' + 'cluster name'` for posterior mean or
             `'q05_nUMI_factors' + 'cluster name'` for 5% quantile of the posterior
    and as np.ndarray in `adata.uns['mod']['post_sample_means']['nUMI_factors']` (also post_sample_q05, post_sample_q95, post_sample_sd)
    Anndata object with exported results, W weights representing cell state densities, and the trained model object are saved to `export_args['path']`
    :param sc_data: anndata object with single cell / nucleus data
    :param model: model name as a string
    :param train_args: arguments for training methods. See help(c2l.LocationModel) for more details
                'covariate_col_names' - a list of columns in sp_data.obs that contains covariates of interest
                'sample_name_col' - column in sp_data.obs that contains sample / slide ID (e.g. Visium section)
                                    - for plotting W cell locations
                'mode' - "normal" or "tracking" parameters?
                'use_raw' - extract data from RAW slot of anndata? Applies only to spatial, not single cell reference.
                'sample_prior' - use sampling from the prior to evaluate how reasonable priors are for your data.
                                 This is not essential for Visium data but can be very useful for troubleshooting.
                                 It is essential for choose priors appropriate for any other spatial technology.
                                 Caution: takes a lot of RAM (10th-100s of GB).
                'n_prior_samples' - Number of prior sample. The more the better but also takes a lot of RAM.
                'n_restarts' - number of training restarts to evaluate stability
                'n_type' - type of restart training: 'restart' 'cv' 'bootstrap'(see help(c2l.LocationModel.fit_advi_iterative) for details)
                'method' - which method to use to find posterior. Use default 'advi' unless you know what you are doing.
                'readable_var_name_col' - column in sp_data.var that contains readable gene ID (e.g. HGNC symbol)

                'fact_names' - optional list of factor names, by default taken from sc_data.
    :param posterior_args: arguments for sampling posterior,
                We get 1000 samples from the posterior distribution of each parameter
                to compute means, SD, 5% and 95% quantiles - stored in `mod.samples` and exported in `adata.uns['mod']`.
                'n_samples' - number of samples to get from posterior approximation to compute average and SD of that distribution
    :param export_args: arguments for exporting results
                'path' - path where to save results
                'plot_extension' - file extention of saved plots
                'save_model' - boolean, save trained model? Could be useful but also takes up GBs of disk.
                'export_q05' - boolean, save plots of 5% quantile of parameters.
    :param return_all: return the model and annotated `sp_data` or just save both?
    :return: results as a dictionary {'mod','sp_data','sc_obs','model_name',
                                      'summ_sc_data_args', 'train_args','posterior_args', 'export_args',
                                      'run_name', 'run_time'}
    """

    # set default parameters

    d_train_args = {'mode': "normal", 'use_raw': True, 'data_type': "float32",
                    'n_iter': 100000, 'learning_rate': 0.001, 'total_grad_norm_constraint': 200,
                    'method': 'advi',
                    'sample_prior': True, 'n_prior_samples': 10,
                    'n_restarts': 2, 'n_type': "restart",
                    'tracking_every': 1000, 'tracking_n_samples': 50, 'readable_var_name_col': None,
                    'sample_name_col': None, 'fact_names': None}

    d_posterior_args = {'n_samples': 1000, 'evaluate_stability_align': False, 'mean_field_slot': "init_1"}

    d_export_args = {'path': "./results", 'plot_extension': "png",
                     'save_model': True, 'run_name_suffix': '', 'export_q05': True,
                     'scanpy_coords_name': 'spatial'}

    # replace defaults with parameters supplied
    for k in summ_sc_data_args.keys():
        d_summ_sc_data_args[k] = summ_sc_data_args[k]
    summ_sc_data_args = d_summ_sc_data_args
    for k in train_args.keys():
        d_train_args[k] = train_args[k]
    train_args = d_train_args
    for k in posterior_args.keys():
        d_posterior_args[k] = posterior_args[k]
    posterior_args = d_posterior_args
    for k in export_args.keys():
        d_export_args[k] = export_args[k]
    export_args = d_export_args

    theano.config.allow_gc = True

    # start timing
    start = time.time()

    sp_data = sp_data.copy()

    # move spatial coordinates to obs for compatibility with our plotter
    sp_data.obs['imagecol'] = sp_data.obsm[export_args['scanpy_coords_name']][:, 0]
    sp_data.obs['imagerow'] = sp_data.obsm[export_args['scanpy_coords_name']][:, 1]

    # import the specied version of the model
    if type(model_name) is str:
        import cell2location.models as models
        Model = getattr(models, model_name)
    else:
        Model = model_name

    ####### Summarising single cell clusters #######
    if verbose:
        print('### Summarising single cell clusters ###')

    if not isinstance(sc_data, pd.DataFrame):
        # if scanpy compute cluster averages
        cell_state_df = get_cluster_averages(sc_data, cluster_col=summ_sc_data_args['cluster_col'])
        obs = sc_data.obs
    else:
        # if dataframe assume signature with matching .index to sp_data.var_names
        cell_state_df = sc_data.copy()
        obs = cell_state_df

    # select features if requested
    if summ_sc_data_args['selection'] == 'high_cv':

        cv = cell_state_df.var(1) / cell_state_df.mean(1)
        cv = cv.sort_values(ascending=False)
        cell_state_df = cell_state_df.loc[cv[np.arange(summ_sc_data_args['select_n'])].index, :]

    elif summ_sc_data_args['selection'] == 'cluster_markers':
        if isinstance(sc_data, pd.DataFrame):
            raise ValueError(
                'summ_sc_data_args["selection"] = "cluster_markers" can only be used with type(sc_data) Anndata')

        sel_feat = select_features(sc_data, summ_sc_data_args['cluster_col'],
                                   n_features=summ_sc_data_args['select_n'], use_raw=train_args['use_raw'])
        cell_state_df = cell_state_df.loc[cell_state_df.index.isin(sel_feat), :]

    elif summ_sc_data_args['selection'] == 'AutoGeneS':

        cv = cell_state_df.var(1) / cell_state_df.mean(1)
        cv = cv.sort_values(ascending=False)
        cell_state_df = cell_state_df.loc[cv[np.arange(summ_sc_data_args['select_n'])].index, :]

        from autogenes import AutoGenes
        ag = AutoGenes(cell_state_df.T)
        ag.run(ngen=5000, seed=0, nfeatures=summ_sc_data_args['select_n_AutoGeneS'], mode='fixed')
        pareto = ag.pareto
        print(ag.plot(size='large', weights=(1, -1)))
        # We then pick one solution and filter its corresponding marker genes:
        cell_state_df = cell_state_df[pareto[len(pareto) - 1]]  # select the solution with min correlation

    elif summ_sc_data_args['selection'] is not None:
        raise ValueError("summ_sc_data_args['selection'] can be only None, high_cv, cluster_markers or AutoGeneS")

    # extract data as a dense matrix
    if train_args['use_raw']:
        X_data = sp_data.raw.X.toarray()
    else:
        X_data = sp_data.X.toarray()

    # Filter cell states and X_data to common genes
    sp_ind = sp_data.var_names.isin(cell_state_df.index)
    if np.sum(sp_ind) == 0:
        raise ValueError('No overlapping genes found, check that `sc_data` and `sp_data` use the same variable names')
    X_data = X_data[:, sp_ind]
    cell_state_df = cell_state_df.loc[sp_data.var_names[sp_ind], :]

    # prepare cell state matrix
    cell_state_mat = cell_state_df.values

    # if factor names not provided use cluster names
    if train_args['fact_names'] is None:
        fact_names = cell_state_df.columns
    else:  # useful for unobserved factor models
        fact_names = train_args['fact_names']

    if train_args['sample_name_col'] is None:
        sp_data.obs['sample'] = 'sample'
        train_args['sample_name_col'] = 'sample'

    if train_args['readable_var_name_col'] is not None:
        readable_var_name_col = sp_data.var[train_args['readable_var_name_col']][sp_ind]
    else:
        readable_var_name_col = None

    ####### Creating model #######
    if verbose:
        print('### Creating model ### - time ' + str(np.around((time.time() - start) / 60, 2)) + ' min')
    mod = Model(cell_state_mat, X_data,
                data_type=train_args['data_type'], n_iter=train_args['n_iter'],
                learning_rate=train_args['learning_rate'],
                total_grad_norm_constraint=train_args['total_grad_norm_constraint'],
                verbose=verbose,
                var_names=sp_data.var_names[sp_ind],
                var_names_read=readable_var_name_col,
                obs_names=sp_data.obs_names,
                fact_names=fact_names,
                sample_id=sp_data.obs[train_args['sample_name_col']],
                **model_kwargs)

    ####### Print run name #######
    run_name = str(mod.__class__.__name__) + '_' + str(mod.n_fact) + 'clusters_' \
               + str(mod.n_cells) + 'locations_' + str(mod.n_genes) + 'genes' \
               + export_args['run_name_suffix']

    print('### Analysis name: ' + run_name)  # analysis name is always printed

    # create the export directory
    path = export_args['path'] + run_name + '/'
    if not os.path.exists(path):
        mkdir(path)

    fig_path = path + 'plots/'
    if not os.path.exists(fig_path):
        mkdir(fig_path)

    ####### Sampling prior #######
    if train_args['sample_prior']:
        if verbose:
            print('### Sampling prior ###')

        mod.sample_prior(samples=train_args['n_prior_samples'])

        # plot & save plot
        mod.plot_prior_vs_data()
        save_plot(fig_path, filename='evaluating_prior', extension=export_args['plot_extension'])
        plt.close()

    ####### Training model #######
    if verbose:
        print('### Training model ###')
    if train_args['mode'] == 'normal':
        mod.fit_advi_iterative(n=train_args['n_restarts'], method=train_args['method'],
                               n_type=train_args['n_type'], progressbar=verbose)

    elif train_args['mode'] == 'tracking':
        mod.verbose = False
        mod.track_parameters(n=train_args['n_restarts'],
                             every=train_args['tracking_every'], n_samples=train_args['tracking_n_samples'],
                             n_type=train_args['n_type'],
                             df_node_name1='nUMI_factors', df_node_df_name1='spot_factors_df',
                             df_prior_node_name1='spot_fact_mu_hyp', df_prior_node_name2='spot_fact_sd_hyp',
                             mu_node_name='mu', data_node='X_data',
                             extra_df_parameters=['spot_add'],
                             sample_type='post_sample_means')

    else:
        raise ValueError("train_args['mode'] can be only 'normal' or 'tracking'")

    theano.config.compute_test_value = 'ignore'
    ####### Evaluate stability of training #######
    if train_args['n_restarts'] > 1:
        mod.evaluate_stability(n_samples=posterior_args['n_samples'],
                               align=posterior_args['evaluate_stability_align'])
        save_plot(fig_path, filename='evaluate_stability', extension=export_args['plot_extension'])
        plt.close()

    ####### Sampling posterior #######
    if verbose:
        print('### Sampling posterior ### - time ' + str(np.around((time.time() - start) / 60, 2)) + ' min')
    mod.sample_posterior(node='all', n_samples=posterior_args['n_samples'],
                         save_samples=False, mean_field_slot=posterior_args['mean_field_slot']);

    # evaluate predictive accuracy
    mod.compute_expected()

    ####### Export summarised posterior & Saving results #######
    if verbose:
        print('### Saving results ###')

    # save W cell locations (cell density)
    # convert cell location parameters (cell density) to a dataframe
    mod.sample2df(node_name='spot_factors')
    # add cell location parameters to `sp_data.obs`
    sp_data = mod.annotate_spot_adata(sp_data)
    # save
    mod.spot_factors_df.to_csv(path + 'W_cell_density.csv')
    if export_args['export_q05']:
        mod.spot_factors_q05.to_csv(path + 'W_cell_density_q05.csv')

    # convert cell location parameters (mRNA count) to a dataframe, see help(mod.sample2df) for details
    mod.sample2df(node_name='nUMI_factors')

    # add cell location parameters to `sp_data.obs`
    sp_data = mod.annotate_spot_adata(sp_data)

    # save W cell locations (mRNA count)
    mod.spot_factors_df.to_csv(path + 'W_mRNA_count.csv')
    if export_args['export_q05']:
        mod.spot_factors_q05.to_csv(path + 'W_mRNA_count_q05.csv')

    # add posterior of all parameters to `sp_data.uns['mod']`
    mod.fact_filt = None
    sp_data = mod.export2adata(adata=sp_data, slot_name='mod')
    sp_data.uns['mod']['fact_names'] = list(sp_data.uns['mod']['fact_names'])
    sp_data.uns['mod']['var_names'] = list(sp_data.uns['mod']['var_names'])
    sp_data.uns['mod']['obs_names'] = list(sp_data.uns['mod']['obs_names'])

    # save spatial anndata with exported posterior
    sp_data.write(filename=path + 'sp.h5ad', compression='gzip')

    # save model object and related annotations
    if export_args['save_model']:
        # save the model and other objects
        res_dict = {'mod': mod, 'sp_data': sp_data, 'sc_obs': obs,
                    'model_name': model_name, 'summ_sc_data_args': summ_sc_data_args,
                    'train_args': train_args, 'posterior_args': posterior_args,
                    'export_args': export_args, 'run_name': run_name,
                    'run_time': str(np.around((time.time() - start) / 60, 2)) + ' min'}
        pickle.dump(res_dict, file=open(path + 'model_.p', "wb"))

    else:
        # just save the settings
        res_dict = {'sc_obs': obs, 'model_name': model_name,
                    'summ_sc_data_args': summ_sc_data_args,
                    'train_args': train_args, 'posterior_args': posterior_args,
                    'export_args': export_args, 'run_name': run_name,
                    'run_time': str(np.around((time.time() - start) / 60, 2)) + ' min'}
        pickle.dump(res_dict, file=open(path + 'model_.p', "wb"))

    ####### Plotting #######
    if verbose:
        print('### Ploting results ###')

    # Show training history #
    if verbose:
        print(mod.plot_history(0))
    else:
        mod.plot_history(0)
    save_plot(fig_path, filename='training_history_all', extension=export_args['plot_extension'])
    plt.close()

    if verbose:
        print(mod.plot_history(int(np.ceil(train_args['n_iter'] * 0.2))))
    else:
        mod.plot_history(int(np.ceil(train_args['n_iter'] * 0.2)))
    save_plot(fig_path, filename='training_history_without_first_20perc',
              extension=export_args['plot_extension'])
    plt.close()

    # Predictive accuracy
    try:
        mod.plot_posterior_mu_vs_data()
        save_plot(fig_path, filename='data_vs_posterior_mean_Poisson_rate',
                  extension=export_args['plot_extension'])
        plt.close()
    except Exception as e:
        print('Some error in plotting `mod.plot_posterior_mu_vs_data()`\n ' + str(e))

    ####### Ploting posterior of W / cell locations #######
    if verbose:
        print('### Ploting posterior of W / cell locations ###')

    data_samples = sp_data.obs[train_args['sample_name_col']].unique()
    cluster_plot_names = mod.spot_factors_df.columns
    cluster_plot_names = pd.Series([i[17:] for i in mod.spot_factors_df.columns])

    try:
        for i in data_samples:
            p = c2lpl.plot_factor_spatial(adata=sp_data,
                                          fact_ind=np.arange(mod.spot_factors_df.shape[1]),
                                          fact=mod.spot_factors_df,
                                          cluster_names=cluster_plot_names,
                                          n_columns=6, trans='log',
                                          sample_name=i, samples_col=train_args['sample_name_col'],
                                          obs_x='imagecol', obs_y='imagerow')
            p.save(filename=fig_path + 'cell_locations_W_mRNA_count_' + str(i) + '.' + export_args['plot_extension'])

            if export_args['export_q05']:
                p = c2lpl.plot_factor_spatial(adata=sp_data,
                                              fact_ind=np.arange(mod.spot_factors_q05.shape[1]),
                                              fact=mod.spot_factors_q05,
                                              cluster_names=cluster_plot_names,
                                              n_columns=6, trans='log',
                                              sample_name=i, samples_col=train_args['sample_name_col'],
                                              obs_x='imagecol', obs_y='imagerow')
                p.save(filename=fig_path + 'cell_locations_W_mRNA_count_q05_' + str(i) + '.' \
                                + export_args['plot_extension'])

            if verbose:
                print(p)
    except Exception as e:
        print('Some error in plotting `mod.plot_factor_spatial()`\n ' + str(e))

    if verbose:
        print('### Done ### - time ' + res_dict['run_time'])

    if return_all:
        return res_dict
    else:
        del res_dict
        del mod
        gc.collect()
        return str((time.time() - start) / 60) + ' min'


"""Views module."""

from flask import request, render_template
from dependency_injector.wiring import inject, Provide

from services import SearchService
from containers import Container

@inject
def index(search_service: SearchService = Provide[Container.search_service]):
    query = request.args.get('query', 'Dependency Injector')
    limit = request.args.get('limit', 10, int)

    repositories = search_service.search_repositories(query, limit)

    return render_template(
        'index.html',
        query=query,
        limit=limit,
        repositories=repositories,
    )


import scipy.io as io
import tensorflow as tf
from tensorflow import keras
import numpy as np

rawdata = io.loadmat('ioraw.mat')
locals().update(rawdata)

train_stop = int(X.shape[0]*0.7)

train_in = np.expand_dims(X[:train_stop,:],axis=4)
train_out = Y[:train_stop,:]
test_in = np.expand_dims(X[train_stop:,:],axis=4)
test_out = Y[train_stop:,:]

model = keras.models.Sequential()

model.add(keras.layers.Conv3D(8,(8,8,2),input_shape=(*X.shape[1:],1),activation='relu'))
model.add(keras.layers.MaxPooling3D((4,4,1)))
model.add(keras.layers.Flatten())
model.add(keras.layers.Dense(1,activation='sigmoid'))

model.compile(optimizer='adam',loss='mean_squared_error',metrics=['accuracy'])

model.fit(train_in,train_out,epochs=1000,verbose=1)

scores = model.evaluate(test_in,test_out)
print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))


import pygame
import os

def load_image(name, color_key=None):
    fullname = os.path.join('images', name)
    try:
        image = pygame.image.load(fullname)
    except pygame.error as message:
        print('Cannot load image:', name)
        raise SystemExit(message)

    if color_key is not None:
        if color_key == -1:
            color_key = image.get_at((0, 0))
        image.set_colorkey(color_key)
    else:
        image = image.convert_alpha()
    return image

tile_width = 70
tile_height = 60
tile_images = {'volcano': load_image('volcano.png', -1), 'empty': load_image('earth.jpg')}

class Earth(pygame.sprite.Sprite):
    def __init__(self, tile_type, pos_x, pos_y, *args):
        super().__init__(args)
        self.image = tile_images[tile_type]
        self.rect = self.image.get_rect().move(tile_width * pos_x, tile_height * pos_y)


"""Описание базового менеджера хранилищ."""

import typing

from pony import orm

from jacob.database import models

class BaseStorageManager(object):
    """Базовый менеджер хранилищ."""

    def __init__(self, owner: typing.Union[models.Admin, int]):
        """Создаёт объект менеджера хранилищ.

        Args:
            owner: объект администратора
        """
        self.model = None
        self.owner = owner

    @orm.db_session
    def get_or_create(
        self,
    ) -> typing.Union[
        models.AdminConfig,
        models.ChatRegistrarConfig,
        models.FinancialConfig,
        models.Issue,
        models.MentionStorage,
        models.StateStorage,
    ]:
        """Получает существующий или создаёт новый объект хранилища.

        Returns:
            orm.Database().Entity: Объект хранилища
        """
        if isinstance(self.owner, int):
            owner = models.Student[self.owner]
        else:
            owner = self.owner

        storage = self.model.get(
            owner=owner,
        )

        if storage is None:
            storage = self.model(owner=owner)

        return storage

    @orm.db_session
    def update(
        self,
        **kwargs,
    ) -> typing.Union[
        models.AdminConfig,
        models.ChatRegistrarConfig,
        models.FinancialConfig,
        models.Issue,
        models.MentionStorage,
        models.StateStorage,
    ]:
        """Обновляет поля хранилища.

        Args:
            **kwargs: Поля для обновления

        Returns:
            orm.Database().Entity: Объект хранилища
        """
        storage = self.get_or_create()
        storage.set(**kwargs)

        return storage


from functools import wraps
import json

from libs.auth import Authenticate
from helpers.misc_hepler import get_bool_value

def check_if_authenticated(**details):
    def login_required(handler):
        @wraps(handler)
        def decorated_function(self, *args, **kwargs):
            auth_class = Authenticate()
            if self.auth_enabled:
                self.request.store_id = None
                if 'state' and 'permission' in details:
                    state = details['state']
                    permission = details['permission']
                else:
                    self.set_status(403)
                    self.write({'message': "unauthorized","success": False})
                    return

                # Retrieve session id from cookie.
                session_id = self.get_cookie('session')
                if session_id is None:
                    session_id = self.get_cookie(auth_class.session_id)

                if session_id is None:
                    self.set_status(403)
                    self.write({'message': "unauthorized","success": False})
                    return
                key = auth_class.session_prefix + session_id
                session_store = self.backend.get_alohomora_redis().hgetall(key)

                if not session_store:
                    self.set_status(403)
                    self.write({'message': "unauthorized","success": False})
                    return

                if 'is_superuser' not in session_store or not get_bool_value(session_store['is_superuser']):
                    if 'permission' in session_store:
                        allowed_permissions = json.loads(session_store['permission'])

                    if state not in allowed_permissions or permission not in allowed_permissions[state]:
                        self.set_status(403)
                        self.write({'message': "unauthorized","success": False})
                        return

                if auth_class.store_auth_required_key in details and details[auth_class.store_auth_required_key]:
                    self.request.store_id = None
                    if 'store_id' in session_store:
                        if not self.request.headers.get('store_id'):
                            self.request.store_id = session_store['store_id']

                self.request.user_id = None
                if 'user_id' in session_store:
                    if not self.request.headers.get('user_id'):
                        self.request.user_id = session_store['user_id']
                if 'username' in session_store:
                    if not self.request.headers.get('username'):
                        self.request.username = session_store['username']

                return handler(self, *args, **kwargs)
            else:
                return handler(self, *args, **kwargs)
        return decorated_function
    return login_required


import pytest
from django.test import Client

def test_api_route(client: Client):
    response = client.get("/api/route")

    assert response.status_code == 200
    assert response.content == b"ROUTE:GET"

    response = client.post("/api/route")

    assert response.status_code == 200
    assert response.content == b"ROUTE:POST"

@pytest.mark.parametrize(
    "method,content",
    [
        ("GET", b"GET"),
        ("HEAD", b""),
        ("POST", b"POST"),
        ("PUT", b"PUT"),
        ("PATCH", b"PATCH"),
        ("DELETE", b"DELETE"),
        ("OPTIONS", b"OPTIONS"),
        ("TRACE", b"TRACE"),
    ],
)
def test_api_method(client: Client, method: str, content: bytes):
    response = client.generic(method, "/api/")

    assert response.status_code == 200
    assert response.content == content


# -*- coding: utf-8 -*-
from locale import strcoll
from django.db.models import get_model

def unicode_sorter(key_input):
    """ This function implements sort keys for the german language according to
    DIN 5007."""

    # key1: compare words lowercase and replace umlauts according to DIN 5007
    key1 = key_input.lower()
    key1 = key1.replace(u"ä", u"a")
    key1 = key1.replace(u"ö", u"o")
    key1 = key1.replace(u"ü", u"u")
    key1 = key1.replace(u"ß", u"ss")

    # key2: sort the lowercase word before the uppercase word and sort
    # the word with umlaut after the word without umlaut
    #key2=input.swapcase()

    # in case two words are the same according to key1, sort the words
    # according to key2.
    return key1

def get_filterchain_kwargs(field, value):
    if value == '0':
        return {str("%s__isnull" % field): True}
    return {str(field): str(value)}

def get_filterchain_queryset(app, model, manager=None):
    model_class = get_model(app, model)
    if manager is not None and hasattr(model_class, manager):
        return getattr(model_class, manager)
    return model_class._default_manager

def render_filterchain_choices(item_queryset):
    if not item_queryset.ordered:
        item_list = list(item_queryset)
        item_list.sort(cmp=strcoll, key=lambda x: unicode_sorter(unicode(x)))
    else:
        item_list = item_queryset.iterator()
    return [{'value': item.pk, 'display': unicode(item)} for item in item_list]


from IPython.display import clear_output, Image, display, HTML
from functools import partial, update_wrapper
import tensorflow as tf
import numpy as np

def strip_consts(graph_def, max_const_size=32):
    """Strip large constant values from graph_def."""
    strip_def = tf.GraphDef()
    for n0 in graph_def.node:
        n = strip_def.node.add()
        n.MergeFrom(n0)
        if n.op == 'Const':
            tensor = n.attr['value'].tensor
            size = len(tensor.tensor_content)
            if size > max_const_size:
                tensor.tensor_content = "<stripped %d bytes>"%size
    return strip_def

def show_graph(graph_def, max_const_size=32):
    """Visualize TensorFlow graph."""
    if hasattr(graph_def, 'as_graph_def'):
        graph_def = graph_def.as_graph_def()
    strip_def = strip_consts(graph_def, max_const_size=max_const_size)
    code = """

        <link rel="import" href="https://tensorboard.appspot.com/tf-graph-basic.build.html" onload=load()>

          <tf-graph-basic id="{id}"></tf-graph-basic>

    """.format(data=repr(str(strip_def)), id='graph'+str(np.random.rand()))

    iframe = """

    """.format(code.replace('"', '"'))
    display(HTML(iframe))

def show_current_graph():
    show_graph(tf.get_default_graph().as_graph_def())

def wrapped_partial(func, *args, **kwargs):
    partial_func = partial(func, *args, **kwargs)
    update_wrapper(partial_func, func)
    return partial_func

def print_confusion_matrix(confusion_matrix, class_names, figsize = (10,7), fontsize=14):
    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    """Prints a confusion matrix, as returned by sklearn.metrics.confusion_matrix, as a heatmap.

    Arguments
    ---------
    confusion_matrix: numpy.ndarray
        The numpy.ndarray object returned from a call to sklearn.metrics.confusion_matrix.
        Similarly constructed ndarrays can also be used.
    class_names: list
        An ordered list of class names, in the order they index the given confusion matrix.
    figsize: tuple
        A 2-long tuple, the first value determining the horizontal size of the ouputted figure,
        the second determining the vertical size. Defaults to (10,7).
    fontsize: int
        Font size for axes labels. Defaults to 14.

    Returns
    -------
    matplotlib.figure.Figure
        The resulting confusion matrix figure
    """
    df_cm = pd.DataFrame(
        confusion_matrix, index=class_names, columns=class_names,
    )
    fig = plt.figure(figsize=figsize)
    try:
        heatmap = sns.heatmap(df_cm, annot=True, fmt="d")
    except ValueError:
        raise ValueError("Confusion matrix values must be integers.")
    heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right', fontsize=fontsize)
    heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=45, ha='right', fontsize=fontsize)
    plt.ylabel('True label')
    plt.xlabel('Predicted label')
    return fig


# https://www.tensorflow.org/tutorials/keras/classification
# MIT License
# Copyright (c) 2017 François Chollet

# tensorflow & tf.keras
import tensorflow as tf
from tensorflow import keras

# helper library
import numpy as np
import matplotlib.pyplot as plt

# fashion mnist data
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat', 'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

# Data preprocessing [0, 1]
train_images = train_images / 255.0
test_images = test_images / 255.0

train_images = train_images.reshape(-1, 28, 28, 1)
test_images = test_images.reshape(-1, 28, 28, 1)

# layers
model = keras.Sequential([
    keras.layers.Conv2D(filters=64, input_shape=(28, 28, 1), kernel_initializer='he_normal', kernel_size=(3, 3), padding='same', activation='relu'),
    keras.layers.BatchNormalization(),
    keras.layers.MaxPooling2D(pool_size=(2, 2)),
    keras.layers.Dropout(0.1),

    keras.layers.Conv2D(filters=64, kernel_size=(3, 3), padding='same', activation='relu'),
    keras.layers.MaxPooling2D(pool_size=(2, 2)),
    keras.layers.Dropout(0.1),

    keras.layers.Conv2D(filters=32, kernel_size=(3, 3)),

    keras.layers.Flatten(),
    keras.layers.Dense(units=512, activation='relu'),
    keras.layers.Dense(10, activation='softmax')  # densely-connected, softmax
])

# model compile
# loss function: minimize error
# optimizer: update the model based on loss function
# metrics: to monitor training and test
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# train the model
model.fit(train_images, train_labels, epochs=10)

# test accuracy
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\nTest Accuracy: ', test_acc)

predictions = model.predict(test_images)
print(predictions[0])
print('Prediction: ', np.argmax(predictions[0]))
print('Label: ', test_labels[0])

def plot_image(i, predictions_array, true_label, img):
    predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])

    plt.imshow(img, cmap=plt.cm.binary)

    predicted_label = np.argmax(predictions_array)
    if predicted_label == true_label:
        color = 'blue'  # correct
    else:
        color = 'red'   # wrong

    plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                         100 * np.max(predictions_array),
                                         class_names[true_label]), color=color)

def plot_value_array(i, predictions_array, true_label):
    predictions_array, true_label = predictions_array[i], true_label[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    thisplot = plt.bar(range(10), predictions_array, color="#777777")
    plt.ylim([0, 1])
    predicted_label = np.argmax(predictions_array)

    thisplot[predicted_label].set_color('red')
    thisplot[true_label].set_color('blue')

train_images = train_images.reshape(-1, 28, 28)
test_images = test_images.reshape(-1, 28, 28)

num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions, test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions, test_labels)
plt.show()


class DataAnalyzer:
    def __init__(self,nl_list):
        self.nl_list = nl_list
        self.length = 0

    def get_characters(self):
        chars = set()
        for nl in self.nl_list:
            for char in list(nl):
                chars.add(char)
        return sorted(chars)

    def get_nl_length(self):
        if self.length!=0: return self.length
        length = 0
        for nl in self.nl_list:
            length += len(nl)
        self.length = length
        return length

    def get_avg_length(self):
        return self.get_nl_length() *1.0 / len(self.nl_list)

    def get_words(self,alphabetic_words_only=True):
        import nltk
        words = set()
        for nl in self.nl_list:
            sentences = nltk.sent_tokenize(nl)
            for sentence in sentences:
                for word in nltk.word_tokenize(sentence):
                    if alphabetic_words_only==True:
                        if word.isalpha():
                            words.add(word)
                    else:
                        words.add(word)
        return sorted(words)

    def get_words_occurence(self,alphabetic_words_only=True,lower_case=True):
        import nltk
        import operator
        words = {}
        for nl in self.nl_list:
            sentences = nltk.sent_tokenize(nl)
            for sentence in sentences:
                for word in nltk.word_tokenize(sentence):
                    if lower_case==True: word = word.lower()
                    if (alphabetic_words_only==True and word.isalpha()) or alphabetic_words_only==False:
                        if word in words: words[word] += 1
                        else: words[word] = 1
        return list(reversed(sorted(words.items(), key=operator.itemgetter(1))))


# -*- coding: utf-8 -*-
import os, uuid
from flask import Flask, session, request, Response, render_template, redirect, url_for, flash, send_from_directory

from flask.ext.login import (LoginManager, current_user, login_required,
                            login_user, logout_user, UserMixin, AnonymousUser,
                            confirm_login, fresh_login_required)

from datetime import date
from PIL import Image

try:
    from json import dumps
except ImportError:
    from simplejson import dumps

def jsonify(f):
    def inner(*args, **kwargs):
        return Response(dumps(f(*args, **kwargs)), mimetype='application/json')
    return inner

thumb_size = 250, 200

class User(UserMixin):
    def __init__(self, name, id, active=True):
        self.name = name
        self.id = id
        self.active = active

    def is_active(self):
        return self.active

class Anonymous(AnonymousUser):
    name = u"Anonymous"

USERS = {
    1: User(u"daniel", 1),
}

USER_NAMES = dict((u.name, u) for u in USERS.itervalues())

app = Flask(__name__)

DEBUG = True

app.config.from_object(__name__)

app.config['SECRET_KEY'] = 'zuSAyu3XRqGRvAg0HxsKX12Nrvf6Hk3AgZCWg1S1j9Y='
app.config['UPLOAD_FOLDER'] = os.path.join(os.path.dirname(__file__), 'static', 'upload')
app.config['MAX_CONTENT_LENGTH'] = 2 * 1024 * 1024

login_manager = LoginManager()

login_manager.anonymous_user = Anonymous
login_manager.login_view = "login"
login_manager.login_message = u"Please log in to access this page."
login_manager.refresh_view = "reauth"

ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg'])

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS

def path2url(path):
    return '/%s/' % ('/'.join(path.split('\\')))

@app.route('/uploads/<filename>')
def uploaded_file(filename):
    return send_from_directory(app.config['UPLOAD_FOLDER'], filename)

@app.route('/rd/upload', methods=['GET', 'POST'])
@jsonify
def upload():
    if request.method == 'POST':
        file = request.files['file']
        if file and allowed_file(file.filename):
            folder_name = date.today().strftime('%Y-%m-%d')
            dir = os.path.join(app.config['UPLOAD_FOLDER'], folder_name)
            thumb_dir = os.path.join(app.config['UPLOAD_FOLDER'], folder_name, 'thumb')
            if not os.path.exists(dir):
                os.makedirs(dir)
            if not os.path.exists(thumb_dir):
                os.makedirs(thumb_dir)

            extension = os.path.splitext(file.filename)[1]
            filename = str(uuid.uuid4()) + extension
            file.save(os.path.join(dir, filename))
            #thumb
            im = Image.open(os.path.join(dir, filename))
            im.thumbnail(thumb_size)
            im.save(os.path.join(thumb_dir, filename), "JPEG")

            return {'filelink':'/static/upload/%s/%s' % (folder_name, filename)}
    else:
        file_list = []
        for root, dirs, files in os.walk(app.config['UPLOAD_FOLDER']):
            if dirs:
                url_prefix = path2url(root)
                for f in files:
                    file_list.append({
                        'thumb': url_prefix + 'thumb/' + f,
                        'image': url_prefix + f,
                        'folder': url_prefix,
                    })

        return file_list

@login_manager.user_loader
def load_user(id):
    return USERS.get(int(id))

login_manager.setup_app(app)

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

@app.route("/secret")
@fresh_login_required
def secret():
    return render_template("secret.html")

@app.route("/login", methods=["GET", "POST"])
def login():
    if request.method == "POST" and "username" in request.form:
        username = request.form["username"]
        if username in USER_NAMES:
            remember = request.form.get("remember", "no") == "yes"
            if login_user(USER_NAMES[username], remember=remember):
                flash("Logged in!")
                return redirect(request.args.get("next") or url_for("index"))
            else:
                flash("Sorry, but you could not log in.")
        else:
            flash(u"Invalid username.")
    return render_template("login.html")

@app.route("/reauth", methods=["GET", "POST"])
@login_required
def reauth():
    if request.method == "POST":
        confirm_login()
        flash(u"Reauthenticated.")
        return redirect(request.args.get("next") or url_for("index"))
    return render_template("reauth.html")

@app.route("/logout")
@login_required
def logout():
    logout_user()
    flash("Logged out.")
    return redirect(url_for("index"))

if __name__ == "__main__":
    app.run()


import os

from flask import Flask
from flask import render_template
from flask import url_for
from flask import request
from flask.ext.socketio import SocketIO

from twilio import twiml
from twilio.util import TwilioCapability

# Declare and configure application
app = Flask(__name__, static_url_path='/static')
app.config.from_pyfile('local_settings.py')
socketio = SocketIO(app)

# Build the demo query container
demo_queries = {'DEMENTIA AGGRESSION':
'''
Stay calm and speak in soothing voice, do not argue back. Remove
objects that are sharp or potentially dangerous. Leave the room
and call for help if harm is imminent.''',
                'DEMENTIA DELUSION':
'''Do not challenge their beliefs. Reasoning may not work and could
result in conflict. Agree with their feelings.''',
                'DEMENTIA WANDERING':
'''Ask where they are going and follow up with why they are going there.
Support what they want to do and make sure they are not at risk of
falling or tripping.''',
                'DEMENTIA SLEEP PROBLEMS':
'''Try to keep the person going to bed at the same time every night. Calm
activities at the end of the day and before bedtime may also help them sleep well.'''}

# Voice Request URL
@app.route('/voice', methods=['GET', 'POST'])
def voice():
    response = twiml.Response()
    response.say("Please send a text message with your question.")
    return str(response)

# SMS Request URL
@app.route('/sms', methods=['GET', 'POST'])
def sms():
    response = twiml.Response()
    body = request.form['Body']

    # Send the message to the web client
    socketio.emit('msg', {'body': body}, namespace='/dd')

    # Pick a message to send back to user
    msg = '''I am unable to understand your question. Can you phrase it differently?'''
    big_naked_body = body.upper().strip()
    if big_naked_body in demo_queries:
        msg = demo_queries[big_naked_body]

    # Send message back to user
    response.sms(msg)
    return str(response)

# Installation success page
@app.route('/')
def index():
    return render_template('index.html')

# If PORT not specified by environment, assume development config.
if __name__ == '__main__':
    port = int(os.environ.get("PORT", 5000))
    if port == 5000:
        app.debug = True
    #app.run(host='0.0.0.0', port=port)
    socketio.run(app, host='0.0.0.0', port=port)


import matplotlib.pyplot as plt
from skimage import io
from skimage import filters
from skimage import exposure
from skimage.color import rgb2gray
from skimage.measure import label, regionprops
from skimage.morphology import closing, square, opening
from skimage.segmentation import clear_border
import matplotlib.patches as mpatches
from skimage.color import label2rgb
from skimage.morphology import disk
from skimage.filters.rank import mean
from skimage.filters.rank import median
import numpy as np
from skimage.transform import resize
import cv2

#def increase_y ()
def slide(image):

    #print("Img", image.shape)
    # read the image and define the stepSize and window size
    # (width,height)
    #image = cv2.imread("cell.png") # your image path
    tmp = image # for drawing a rectangle
    stepSize = 99
    (w_width, w_height) = (99, 99) # window size
    for x in range(0, image.shape[1] - w_width , stepSize):
        for y in range(0, image.shape[0] - w_height, stepSize):
            window = image[x:x + w_width, y:y + w_height, :]

            # classify content of the window with your classifier and
            # determine if the window includes an object (cell) or not
            # draw window on image
            cv2.rectangle(tmp, (x, y), (x + w_width, y + w_height), (255, 0, 0), 2) # draw rectangle on image
            plt.imshow(tmp)
            # show all windows
    plt.show()

camera1 = io.imread("1.jpg", as_gray=True)
camera1 = resize(camera1, (300, 600))

camera1 = exposure.equalize_adapthist(camera1)
camera1 = exposure.rescale_intensity(camera1)
camera1 = exposure.adjust_sigmoid(camera1)

camera =  rgb2gray(camera1)
camera = mean(camera, disk(1))
camera = median(camera, disk(1))
from scipy.misc import imsave
#print(camera)
val = filters.threshold_otsu(camera)
camera = closing(camera > val, square(2))
camera = opening(camera, square(2))
camera = clear_border(camera)
#camera = label(camera)

from scipy import ndimage as ndi
cam = ndi.binary_fill_holes(camera)
#camera_opn = opening(cam, square(5))

label_objects, nb_labels = ndi.label(cam)
sizes = np.bincount(label_objects.ravel())
mask_sizes = sizes > 40
mask_sizes[0] = 0
cam_clear = mask_sizes[label_objects]
plt.imshow(cam_clear , cmap='gray', interpolation='nearest')
#camera2 = label(camera)
camera2 = label(cam_clear)
#print("DSDDD", camera2.shape)

'''
edges = canny(camera2, 2, 1, 25)
lines = probabilistic_hough_line(edges, threshold=10, line_length=5,
                                 line_gap=3)

# Generating figure 2
fig, axes = plt.subplots(1, 3, figsize=(15, 5), sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(camera, cmap=cm.gray)
ax[0].set_title('Input image')

ax[1].imshow(edges, cmap=cm.gray)
ax[1].set_title('Canny edges')
ax[2].imshow(edges * 0)
for line in lines:
    p0, p1 = line
    ax[2].plot((p0[0], p1[0]), (p0[1], p1[1]))
ax[2].set_xlim((0, camera2.shape[1]))
ax[2].set_ylim((camera2.shape[0], 0))
ax[2].set_title('Probabilistic Hough')
'''
camera = label2rgb(camera2, image=camera1)
fig, ax = plt.subplots(figsize=(10, 6))
ax.imshow(camera , cmap='gray', interpolation='nearest')
#ax.imshow(camera , cmap='gray', interpolation='nearest')
count = 0
regions = regionprops(camera2)
for region in regions:
    # take regions with large enough areas
    if region.area >= 650:
        # draw rectangle around segmented coins
        minr, minc, maxr, maxc = region.bbox
        slice_hei = int((maxr - minr)* 0.1)
        #print(minr, minc, maxr, maxc)
        croped = camera1[minr-slice_hei:maxr+slice_hei, minc:maxc]
        binary_crop = cam_clear[minr-slice_hei:maxr+slice_hei, minc:maxc]
        #print("Here",camera.shape)
        wid = int(((maxc - minc)/((maxr - minr)*(1.05)))*100)
        #print(wid)
        #croped1 = resize(croped, (wid, 100), anti_aliasing=True)
        #print(minr, minc, maxr, maxc)
        croped1 = resize(croped, (100, wid))
        binary_croped1 = resize(binary_crop, (100, wid)).astype(int)
        #plt.imshow(croped1)
        #print(binary_croped1)
        histogram = binary_croped1.sum(axis=1)
        maxi = np.amax(histogram)
        for i in range(50):
            if maxi-40 < histogram[i] < maxi+40:
                binary_croped1[i,:] = 0
        #plt.plot(binary_croped1)

        binary_croped_label = label(binary_croped1)
        char_regions = regionprops(binary_croped_label)
        #cv2.imshow('image',binary_croped_label)
        #cv2.imshow('image',img)
        #cv2.waitKey(0)
        #cv2.destroyWindow()
        #print(croped)
        #print(char_regions)
        #plt.ion()
        for char_reg in char_regions:
            #print(char_reg.area)
            if char_reg.area >= 650:
                 import random
                 change = random.random()%255
                 #print(change)
                 cminr, cminc, cmaxr, cmaxc = char_reg.bbox
                 char_slice_hei = int((cmaxr - cminr)* 0.1)
                 #print(minr, minc, maxr, maxc)
                 #plt.plot(croped1)
                 binary_crop = binary_croped1[cminr-char_slice_hei:cmaxr+char_slice_hei, cminc:cmaxc]
                 char_croped_si= croped1[0:100, cminc:cmaxc]
                 #print("Here",camera.shape)
                 cwid = int(((cmaxc - cminc)/((cmaxr - cminr)*(1.05)))*100)

                 char_croped1 = resize(char_croped_si, (100, cwid))
                 char_binary_croped1 = resize(binary_crop, (100, wid)).astype(int)
                 plt.imshow(char_croped1)
                 io.imsave('charimage'+str(change)+'.png', char_croped1)
        plt.show()
                 #rect = mpatches.Rectangle((cminc, cminr), cmaxc - cminc, (cmaxr - cminr)*(1.05),
                                  #fill=False, edgecolor=(change,0,0), linewidth=2)

        #print(histogram)

        #Show

        #his= np.histogram(croped1)
        #print(his)
        #slide(croped1)
        #io.all_warnings()
        #io.imsave('image'+str(count)+'.png', croped1)
        count+=1
        #plt.imshow(croped , cmap='gray', interpolation='nearest')
        rect = mpatches.Rectangle((minc, minr), maxc - minc, (maxr - minr)*(1.05),
                                fill=False, edgecolor='red', linewidth=2)
        ax.add_patch(rect)
ax.set_axis_off()
plt.tight_layout()
plt.show()


from __future__ import division

import gwpv.scene_configuration.transfer_functions as tf
import gwpv.scene_configuration.color as config_color
import h5py
import logging
import numpy as np
import os
import paraview.servermanager as pvserver
import paraview.simple as pv
import time
import tqdm
from gwpv.progress import TqdmLoggingHandler
from gwpv.scene_configuration import animate, camera_motion, parse_as

logger = logging.getLogger(__name__)

pv._DisableFirstRenderCameraReset()

# Load plugins
# - We need to load the plugins outside the `render` function to make
# them work with `multiprocessing`.
# - This has problems with `pvbatch`. We could use `PV_PLUGIN_PATH` env variable
# to load plugins, but then we have to get the client proxy somehow. Here's an
# attempt using ParaView-internal functions:
# WaveformDataReader = pv._create_func("WaveformDataReader", pvserver.sources)
# WaveformToVolume = pv._create_func("WaveformToVolume", pvserver.filters)
logger.info("Loading ParaView plugins...")
plugins_dir = os.path.join(
    os.path.dirname(os.path.dirname(os.path.dirname(__file__))),
    'paraview_plugins')
pv.LoadPlugin(os.path.join(plugins_dir, 'WaveformDataReader.py'),
              remote=False,
              ns=globals())
pv.LoadPlugin(os.path.join(plugins_dir, 'WaveformToVolume.py'),
              remote=False,
              ns=globals())
pv.LoadPlugin(os.path.join(plugins_dir, 'TrajectoryDataReader.py'),
              remote=False,
              ns=globals())
pv.LoadPlugin(os.path.join(plugins_dir, 'FollowTrajectory.py'),
              remote=False,
              ns=globals())
pv.LoadPlugin(os.path.join(plugins_dir, 'TrajectoryTail.py'),
              remote=False,
              ns=globals())
logger.info("ParaView plugins loaded.")

def render_frames(scene,
                  frames_dir=None,
                  frame_window=None,
                  render_missing_frames=False,
                  save_state_to_file=None,
                  no_render=False,
                  show_preview=False,
                  show_progress=False,
                  job_id=None):
    # Validate scene
    if scene['View']['ViewSize'][0] % 16 != 0:
        logger.warning("The view width should be a multiple of 16 to be compatible with QuickTime.")
    if scene['View']['ViewSize'][1] % 2 != 0:
        logger.warning("The view height should be even to be compatible with QuickTime.")

    render_start_time = time.time()

    # Setup layout
    layout = pv.CreateLayout('Layout')

    # Setup view
    if 'BackgroundTexture' in scene['View']:
        background_texture_config = scene['View']['BackgroundTexture']
        del scene['View']['BackgroundTexture']
    else:
        background_texture_config = None
    view = pv.CreateRenderView(**scene['View'])
    pv.AssignViewToLayout(view=view, layout=layout, hint=0)

    # Set spherical background texture
    if background_texture_config is not None:
        background_radius = background_texture_config['Radius']
        del background_texture_config['Radius']
        skybox_datasource = background_texture_config['Datasource']
        del background_texture_config['Datasource']
        background_texture = pvserver.rendering.ImageTexture(
            FileName=parse_as.path(scene['Datasources'][skybox_datasource]),
            **background_texture_config)
        background_sphere = pv.Sphere(Radius=background_radius,
                                      ThetaResolution=100,
                                      PhiResolution=100)
        background_texture_map = pv.TextureMaptoSphere(Input=background_sphere)
        pv.Show(background_texture_map,
                view,
                Texture=background_texture,
                BackfaceRepresentation='Cull Frontface',
                Ambient=1.0)

    # Load the waveform data file
    waveform_h5file, waveform_subfile = parse_as.file_and_subfile(
        scene['Datasources']['Waveform'])
    waveform_data = WaveformDataReader(FileName=waveform_h5file,
                                       Subfile=waveform_subfile)
    pv.UpdatePipeline()

    # Generate volume data from the waveform. Also sets the available time range.
    # TODO: Pull KeepEveryNthTimestep out of datasource
    waveform_to_volume_configs = scene['WaveformToVolume']
    if isinstance(waveform_to_volume_configs, dict):
        waveform_to_volume_configs = [{
            'Object': waveform_to_volume_configs,
        }]
        if 'VolumeRepresentation' in scene:
            waveform_to_volume_configs[0]['VolumeRepresentation'] = scene['VolumeRepresentation']
    waveform_to_volume_objects = []
    for waveform_to_volume_config in waveform_to_volume_configs:
        volume_data = WaveformToVolume(
            WaveformData=waveform_data,
            SwshCacheDirectory=parse_as.path(scene['Datasources']['SwshCache']),
            **waveform_to_volume_config['Object'])
        if 'Modes' in waveform_to_volume_config['Object']:
            volume_data.Modes = waveform_to_volume_config['Object']['Modes']
        if 'Polarizations' in waveform_to_volume_config['Object']:
            volume_data.Polarizations = waveform_to_volume_config['Object']['Polarizations']
        waveform_to_volume_objects.append(volume_data)

    # Compute timing and frames information
    time_range_in_M = volume_data.TimestepValues[
        0], volume_data.TimestepValues[-1]
    logger.debug(
        "Full available data time range: {} (in M)".format(time_range_in_M))
    if 'FreezeTime' in scene['Animation']:
        frozen_time = scene['Animation']['FreezeTime']
        logger.info("Freezing time at {}.".format(frozen_time))
        view.ViewTime = frozen_time
        animation = None
    else:
        if 'Crop' in scene['Animation']:
            time_range_in_M = scene['Animation']['Crop']
            logger.debug("Cropping time range to {} (in M).".format(time_range_in_M))
        animation_speed = scene['Animation']['Speed']
        frame_rate = scene['Animation']['FrameRate']
        num_frames = animate.num_frames(
            max_animation_length=time_range_in_M[1] - time_range_in_M[0],
            animation_speed=animation_speed,
            frame_rate=frame_rate)
        animation_length_in_seconds = num_frames / frame_rate
        animation_length_in_M = animation_length_in_seconds * animation_speed
        time_per_frame_in_M = animation_length_in_M / num_frames
        logger.info(
            "Rendering {:.2f}s movie with {} frames ({} FPS or {:.2e} M/s or {:.2e} M/frame)...".
            format(
                animation_length_in_seconds,
                num_frames,
                frame_rate,
                animation_speed,
                time_per_frame_in_M
            ))
        if frame_window is not None:
            animation_window_num_frames = frame_window[1] - frame_window[0]
            animation_window_time_range = (
                time_range_in_M[0] + frame_window[0] * time_per_frame_in_M,
                time_range_in_M[0] + (frame_window[1] - 1) * time_per_frame_in_M)
            logger.info(
                "Restricting rendering to {} frames (numbers {} to {}).".format(
                    animation_window_num_frames, frame_window[0],
                    frame_window[1] - 1))
        else:
            animation_window_num_frames = num_frames
            animation_window_time_range = time_range_in_M
            frame_window = (0, num_frames)

        # Setup animation so that sources can retrieve the `UPDATE_TIME_STEP`
        animation = pv.GetAnimationScene()
        # animation.UpdateAnimationUsingDataTimeSteps()
        # Since the data can be evaluated at arbitrary times we define the time steps
        # here by setting the number of frames within the full range
        animation.PlayMode = 'Sequence'
        animation.StartTime = animation_window_time_range[0]
        animation.EndTime = animation_window_time_range[1]
        animation.NumberOfFrames = animation_window_num_frames
        logger.debug("Animating from scene time {} to {} in {} frames.".format(
            animation.StartTime, animation.EndTime, animation.NumberOfFrames))

        def scene_time_from_real(real_time):
            return real_time / animation_length_in_seconds * animation_length_in_M

        # For some reason the keyframe time for animations is expected to be within
        # (0, 1) so we need to transform back and forth from this "normalized" time
        def scene_time_from_normalized(normalized_time):
            return animation.StartTime + normalized_time * (
                animation.EndTime - animation.StartTime)

        def normalized_time_from_scene(scene_time):
            return (scene_time - animation.StartTime) / (animation.EndTime -
                                                         animation.StartTime)

        # Setup progress measuring already here so volume data computing for
        # initial frame is measured
        if show_progress and not no_render:
            logging.getLogger().handlers = [TqdmLoggingHandler()]
            animation_window_frame_range = tqdm.trange(
                animation_window_num_frames,
                desc="Rendering",
                unit="frame",
                miniters=1,
                position=job_id)
        else:
            animation_window_frame_range = range(animation_window_num_frames)

        # Set the initial time step
        animation.GoToFirst()

    # Display the volume data. This will trigger computing the volume data at the
    # current time step.
    for volume_data, waveform_to_volume_config in zip(waveform_to_volume_objects, waveform_to_volume_configs):
        vol_repr = waveform_to_volume_config['VolumeRepresentation'] if 'VolumeRepresentation' in waveform_to_volume_config else {}
        volume_color_by = config_color.extract_color_by(vol_repr)
        if (vol_repr['VolumeRenderingMode'] == 'GPU Based'
                and len(volume_color_by) > 2):
            logger.warning(
                "The 'GPU Based' volume renderer doesn't support multiple components.")
        volume = pv.Show(volume_data, view, **vol_repr)
        pv.ColorBy(volume, value=volume_color_by)

    if 'Slices' in scene:
        for slice_config in scene['Slices']:
            slice_obj_config = slice_config.get('Object', {})
            slice = pv.Slice(Input=volume_data)
            slice.SliceType = 'Plane'
            slice.SliceOffsetValues = [0.]
            slice.SliceType.Origin = slice_obj_config.get(
                'Origin', [0., 0., -0.3])
            slice.SliceType.Normal = slice_obj_config.get(
                'Normal', [0., 0., 1.])
            slice_rep = pv.Show(slice, view,
                                **slice_config.get('Representation', {}))
            pv.ColorBy(slice_rep, value=volume_color_by)

    # Display the time
    if 'TimeAnnotation' in scene:
        time_annotation = pv.AnnotateTimeFilter(volume_data,
                                                **scene['TimeAnnotation'])
        pv.Show(
            time_annotation, view, **scene['TimeAnnotationRepresentation'])

    # Add spheres
    if 'Spheres' in scene:
        for sphere_config in scene['Spheres']:
            sphere = pv.Sphere(**sphere_config['Object'])
            pv.Show(sphere, view, **sphere_config['Representation'])

    # Add trajectories and objects that follow them
    if 'Trajectories' in scene:
        for trajectory_config in scene['Trajectories']:
            trajectory_name = trajectory_config['Name']
            radial_scale = trajectory_config['RadialScale'] if 'RadialScale' in trajectory_config else 1.
            # Load the trajectory data
            traj_data_reader = TrajectoryDataReader(
                RadialScale=radial_scale,
                **scene['Datasources']['Trajectories'][trajectory_name])
            # Make sure the data is loaded so we can retrieve timesteps.
            # TODO: This should be fixed in `TrajectoryDataReader` by
            # communicating time range info down the pipeline, but we had issues
            # with that (see also `WaveformDataReader`).
            traj_data_reader.UpdatePipeline()
            if 'Objects' in trajectory_config:
                with animate.restore_animation_state(animation):
                    follow_traj = FollowTrajectory(TrajectoryData=traj_data_reader)
                for traj_obj_config in trajectory_config['Objects']:
                    for traj_obj_key in traj_obj_config:
                        if traj_obj_key in [
                                'Representation', 'Visibility', 'TimeShift',
                                'Glyph'
                        ]:
                            continue
                        traj_obj_type = getattr(pv, traj_obj_key)
                        traj_obj_glyph = traj_obj_type(
                            **traj_obj_config[traj_obj_key])
                    follow_traj.UpdatePipeline()
                    traj_obj = pv.Glyph(Input=follow_traj,
                                        GlyphType=traj_obj_glyph)
                    # Can't set this in the constructor for some reason
                    traj_obj.ScaleFactor = 1.
                    for glyph_property in (traj_obj_config['Glyph'] if
                                           'Glyph' in traj_obj_config else []):
                        setattr(traj_obj, glyph_property,
                                traj_obj_config['Glyph'][glyph_property])
                    traj_obj.UpdatePipeline()
                    if 'TimeShift' in traj_obj_config:
                        traj_obj = animate.apply_time_shift(
                            traj_obj, traj_obj_config['TimeShift'])
                    pv.Show(traj_obj, view, **traj_obj_config['Representation'])
                    if 'Visibility' in traj_obj_config:
                        animate.apply_visibility(traj_obj,
                                                 traj_obj_config['Visibility'],
                                                 normalized_time_from_scene,
                                                 scene_time_from_real)
            if 'Tail' in trajectory_config:
                with animate.restore_animation_state(animation):
                    traj_tail = TrajectoryTail(TrajectoryData=traj_data_reader)
                if 'TimeShift' in trajectory_config:
                    traj_tail = animate.apply_time_shift(
                        traj_tail, trajectory_config['TimeShift'])
                tail_config = trajectory_config['Tail']
                traj_color_by = config_color.extract_color_by(tail_config)
                if 'Visibility' in tail_config:
                    tail_visibility_config = tail_config['Visibility']
                    del tail_config['Visibility']
                else:
                    tail_visibility_config = None
                tail_rep = pv.Show(traj_tail, view, **tail_config)
                pv.ColorBy(tail_rep, value=traj_color_by)
                if tail_visibility_config is not None:
                    animate.apply_visibility(
                        traj_tail,
                        tail_visibility_config,
                        normalized_time_from_scene=normalized_time_from_scene,
                        scene_time_from_real=scene_time_from_real)
            if 'Move' in trajectory_config:
                move_config = trajectory_config['Move']
                logger.debug(
                    "Animating '{}' along trajectory.".format(move_config['guiName']))
                with h5py.File(trajectory_file, 'r') as traj_data_file:
                    trajectory_data = np.array(traj_data_file[trajectory_subfile])
                if radial_scale != 1.:
                    trajectory_data[:, 1:] *= radial_scale
                logger.debug("Trajectory data shape: {}".format(
                    trajectory_data.shape))
                animate.follow_path(
                    gui_name=move_config['guiName'],
                    trajectory_data=trajectory_data,
                    num_keyframes=move_config['NumKeyframes'],
                    scene_time_range=time_range_in_M,
                    normalized_time_from_scene=normalized_time_from_scene)

    # Add non-spherical horizon shapes (instead of spherical objects following
    # trajectories)
    if 'Horizons' in scene:
        for horizon_config in scene['Horizons']:
            with animate.restore_animation_state(animation):
                horizon = pv.PVDReader(FileName=scene['Datasources']
                                       ['Horizons'][horizon_config['Name']])
                if horizon_config.get('InterpolateTime', False):
                    horizon = pv.TemporalInterpolator(
                        Input=horizon, DiscreteTimeStepInterval=0)
            if 'TimeShift' in horizon_config:
                horizon = animate.apply_time_shift(horizon,
                                                   horizon_config['TimeShift'],
                                                   animation)
            # Try to make horizon surfaces smooth. At low angular resoluton
            # they still show artifacts, so perhaps more can be done.
            horizon = pv.ExtractSurface(Input=horizon)
            horizon = pv.GenerateSurfaceNormals(Input=horizon)
            horizon_rep_config = horizon_config.get('Representation', {})
            if 'Representation' not in horizon_rep_config:
                horizon_rep_config['Representation'] = 'Surface'
            if 'AmbientColor' not in horizon_rep_config:
                horizon_rep_config['AmbientColor'] = [0., 0., 0.]
            if 'DiffuseColor' not in horizon_rep_config:
                horizon_rep_config['DiffuseColor'] = [0., 0., 0.]
            if 'Specular' not in horizon_rep_config:
                horizon_rep_config['Specular'] = 0.2
            if 'SpecularPower' not in horizon_rep_config:
                horizon_rep_config['SpecularPower'] = 10
            if 'SpecularColor' not in horizon_rep_config:
                horizon_rep_config['SpecularColor'] = [1., 1., 1.]
            if 'ColorBy' in horizon_rep_config:
                horizon_color_by = config_color.extract_color_by(
                    horizon_rep_config)
            else:
                horizon_color_by = None
            horizon_rep = pv.Show(horizon, view, **horizon_rep_config)
            if horizon_color_by is not None:
                pv.ColorBy(horizon_rep, value=horizon_color_by)
            # Animate visibility
            if 'Visibility' in horizon_config:
                animate.apply_visibility(
                    horizon,
                    horizon_config['Visibility'],
                    normalized_time_from_scene=normalized_time_from_scene,
                    scene_time_from_real=scene_time_from_real)
            if 'Contours' in horizon_config:
                for contour_config in horizon_config['Contours']:
                    contour = pv.Contour(Input=horizon,
                                         **contour_config['Object'])
                    contour_rep = pv.Show(contour, view,
                                          **contour_config['Representation'])
                    pv.ColorBy(contour_rep, None)
                    if 'Visibility' in horizon_config:
                        animate.apply_visibility(
                            contour,
                            horizon_config['Visibility'],
                            normalized_time_from_scene=normalized_time_from_scene,
                            scene_time_from_real=scene_time_from_real)

    # Configure transfer functions
    if 'TransferFunctions' in scene:
        for tf_config in scene['TransferFunctions']:
            colored_field = tf_config['Field']
            transfer_fctn = pv.GetColorTransferFunction(colored_field)
            opacity_fctn = pv.GetOpacityTransferFunction(colored_field)
            tf.configure_transfer_function(transfer_fctn, opacity_fctn,
                                           tf_config['TransferFunction'])

    # Save state file before configuring camera keyframes.
    # TODO: Make camera keyframes work with statefile
    if save_state_to_file is not None:
        pv.SaveState(save_state_to_file + '.pvsm')

    # Camera shots
    # TODO: Make this work with freezing time while the camera is swinging
    if animation is None:
        for i, shot in enumerate(scene['CameraShots']):
            if i == len(scene['CameraShots']) - 1 or (shot['Time'] if 'Time' in shot else 0.) >= view.ViewTime:
                camera_motion.apply(shot)
                break
    else:
        camera_motion.apply_swings(
            scene['CameraShots'],
            scene_time_range=time_range_in_M,
            scene_time_from_real=scene_time_from_real,
            normalized_time_from_scene=normalized_time_from_scene)

    # Report time
    if animation is not None:
        report_time_cue = pv.PythonAnimationCue()
        report_time_cue.Script = """
def start_cue(self): pass

def tick(self):
    import paraview.simple as pv
    logger = logging.getLogger('Animation')
    scene_time = pv.GetActiveView().ViewTime
    logger.info("Scene time: {}".format(scene_time))

def end_cue(self): pass
"""
        animation.Cues.append(report_time_cue)

    if show_preview and animation is not None:
        animation.PlayMode = 'Real Time'
        animation.Duration = 10
        animation.Play()
        animation.PlayMode = 'Sequence'

    if no_render:
        logger.info("No rendering requested. Total time: {:.2f}s".format(
            time.time() - render_start_time))
        return

    if frames_dir is None:
        raise RuntimeError("Trying to render but `frames_dir` is not set.")
    if os.path.exists(frames_dir):
        logger.warning("Output directory '{}' exists, files may be overwritten.".format(frames_dir))
    else:
        os.makedirs(frames_dir)

    if animation is None:
        pv.Render()
        pv.SaveScreenshot(os.path.join(frames_dir, 'frame.png'))
    else:
        # Iterate over frames manually to support filling in missing frames.
        # If `pv.SaveAnimation` would support that, here's how it could be
        # invoked:
        # pv.SaveAnimation(
        #     os.path.join(frames_dir, 'frame.png'),
        #     view,
        #     animation,
        #     FrameWindow=frame_window,
        #     SuffixFormat='.%06d')
        # Note that `FrameWindow` appears to be buggy, so we set up the
        # `animation` according to the `frame_window` above so the frame files
        # are numberd correctly.
        for animation_window_frame_i in animation_window_frame_range:
            frame_i = frame_window[0] + animation_window_frame_i
            frame_file = os.path.join(frames_dir,
                                      'frame.{:06d}.png'.format(frame_i))
            if render_missing_frames and os.path.exists(frame_file):
                continue
            logger.debug("Rendering frame {}...".format(frame_i))
            animation.AnimationTime = (
                animation.StartTime +
                time_per_frame_in_M * animation_window_frame_i)
            pv.Render()
            pv.SaveScreenshot(frame_file)
            logger.info("Rendered frame {}.".format(frame_i))

    logger.info(
        "Rendering done. Total time: {:.2f}s".format(time.time() -
                                                     render_start_time))


#
# Copyright (c) 2017, Prometheus Research, LLC
#

from rex.core import Extension

from ..util import record_to_dict
from ..validators import AssessmentDefinitionVal

__all__ = (
    'Definer',
)

class Definer(Extension):
    """
    An extension that allows developers to write code that in turn allows
    configuration authors to inject configurations segments into their
    definition that are determined at Mart creation time.
    """

    # The identifier of this Definer that configurations will use to invoke it.
    name = None

    @classmethod
    def enabled(cls):
        return cls.name is not None

    @classmethod
    def signature(cls):
        return cls.name

    @classmethod
    def get_assessments(cls, definer, definition, **options):
        """
        Retrieves Assessment definitions for the specified Mart Definition
        using the specified Definer. All definitions are validated and
        normalized.

        :param definer: the Definer to user
        :type definer: str
        :param definition:
            the Mart Definition to retrieve Assessment definitions for
        :type str: dict
        :rtype: list of dicts
        """

        assessments = cls.mapped()[definer]().assessments(
            definition,
            **options
        )

        validate = AssessmentDefinitionVal()
        return [
            record_to_dict(validate(assessment))
            for assessment in assessments
        ]

    def assessments(self, definition, **options):
        """
        Retrieves the Assessment definitions to use with the specified Mart
        Definition.

        This can/should be implemented by extensions.

        :param definition:
            the Mart Definition to retrieve Assessment definitions for
        :type str: dict
        :rtype: list of dicts
        """

        # pylint: disable=unused-argument,no-self-use

        return []  # pragma: no cover


import numpy as np
import cv2
import tkinter as tk
from tkinter import *
from tkinter import ttk

window=tk.Tk()
window.title("Tabs")
window.geometry('300x300')
frame = Frame(window)
frame.pack()
cap = cv2.VideoCapture(0)

ment = StringVar()

def func1():

    Input_name = str(E1.get())
    import cv2, sys, numpy, os
    haar_file = 'haarcascade_frontalface_default.xml'

# All the faces data will be
# present this folder
    datasets = 'datasets'

# These are sub data sets of folder,
# for my faces I've used my name you can
# change the label here
    sub_data = Input_name

    path = os.path.join(datasets, sub_data)
    if not os.path.isdir(path):
            os.mkdir(path)

# defining the size of images
    (width, height) = (130, 100)

#'0' is used for my webcam,
# if you've any other camera
# attached use '1' like this
    face_cascade = cv2.CascadeClassifier(haar_file)
    webcam = cv2.VideoCapture(0)

# The program loops until it has 30 images of the face.
    count = 1
    while count < 30:
            (_, im) = webcam.read()
            gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale(gray, 1.3, 4)
            for (x, y, w, h) in faces:
                    cv2.rectangle(im, (x, y), (x + w, y + h), (255, 0, 0), 2)
                    face = gray[y:y + h, x:x + w]
                    face_resize = cv2.resize(face, (width, height))
                    cv2.imwrite('% s/% s.png' % (path, count), face_resize)
            count += 1

            cv2.imshow('OpenCV', im)
            key = cv2.waitKey(10)
            if key == 27:
                    break

def func():
    import sys
    import numpy
    import os
    import cv2
    import pyttsx3
    from gtts import gTTS
    def SayName(a):
            engine.say("Hello "+str(a))
            engine.runAndWait()

    size = 4
    haar_file = 'haarcascade_frontalface_default.xml'
    datasets = 'datasets'
    engine = pyttsx3.init()
# Part 1: Create fisherRecognizer
    print('Recognizing Face Please Be in sufficient Lights...')

# Create a list of images and a list of corresponding names
    (images, lables, names, id) = ([], [], {}, 0)
    for (subdirs, dirs, files) in os.walk(datasets):
            for subdir in dirs:
                    names[id] = subdir
                    subjectpath = os.path.join(datasets, subdir)
                    for filename in os.listdir(subjectpath):
                            path = subjectpath + '/' + filename
                            lable = id
                            images.append(cv2.imread(path, 0))
                            lables.append(int(lable))
                    id += 1
    (width, height) = (130, 100)

# Create a Numpy array from the two lists above
    (images, lables) = [numpy.array(lis) for lis in [images, lables]]

# OpenCV trains a model from the images
# NOTE FOR OpenCV2: remove '.face'
    model = cv2.face.LBPHFaceRecognizer_create()
    model.train(images, lables)
#engine.say(names)
#engine.runAndWait()
# Part 2: Use fisherRecognizer on camera stream
    face_cascade = cv2.CascadeClassifier(haar_file)
    webcam = cv2.VideoCapture(0)
    count=0
    while True:
            (_, im) = webcam.read()
            gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
            faces = face_cascade.detectMultiScale(gray, 1.3, 5)
            for (x, y, w, h) in faces:
                    cv2.rectangle(im, (x, y), (x + w, y + h), (255, 0, 0), 2)
                    face = gray[y:y + h, x:x + w]
                    face_resize = cv2.resize(face, (width, height))
		# Try to recognize the face
                    prediction = model.predict(face_resize)
                    cv2.rectangle(im, (x, y), (x + w, y + h), (0, 255, 0), 3)
                    if prediction[1]<500:
                            cv2.putText(im, '% s - %.0f' % (names[prediction[0]], prediction[1]), (x-10, y-10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0))
                            Person_name=names[prediction[0]]
                            SayName(Person_name)
                    else:
                            cv2.putText(im, 'not recognized',(x-10, y-10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 255, 0))

            cv2.imshow('OpenCV', im)

            key = cv2.waitKey(10)
            if key == 27:
                    break

TAB_CONTROL=ttk.Notebook(window)

TAB1  = ttk.Frame(TAB_CONTROL)
TAB_CONTROL.add(TAB1, text = 'TAB1')

TAB_CONTROL.pack(expand=1, fill="both")

v = tk.IntVar()

tk.Label(TAB1,text="""Choose from following:""",justify = tk.LEFT,padx = 20)

b1 = Button(TAB1,text = "CAPTURE FACE",command = func1,activeforeground = "red",activebackground = "pink",pady=10).pack()

b2 = Button(TAB1,text = "FACE DETECT",command = func,activeforeground = "red",activebackground = "pink",pady=10).pack()

L1 = Label(TAB1, text=" Name")
L1.pack( side = LEFT)
E1 = Entry(TAB1, bd =5)
E1.pack(side = LEFT)

L1 = Label(TAB1, text=" Phone Number")
L1.pack( side = LEFT)
E2 = Entry(TAB1,textvariable=ment, bd =5)
E2.pack(side = LEFT)

window.mainloop()


"""Contains the `SlepianNoiseSouthAmerica` class."""
import numpy as np
import numpy.typing as npt
import pydantic

import sleplet._string_methods
import sleplet._validation
import sleplet.functions.slepian_south_america
import sleplet.noise
import sleplet.slepian.region
from sleplet.functions.fp import Fp

@pydantic.dataclasses.dataclass(config=sleplet._validation.Validation, kw_only=True)
class SlepianNoiseSouthAmerica(Fp):
    """
    Creates a noised Slepian region on the topographic map of the Earth of the
    South America region.
    """

    SNR: float = -10
    """A parameter which controls the level of signal-to-noise in the noised
    data."""

    def __post_init_post_parse__(self) -> None:
        super().__post_init_post_parse__()
        if (
            isinstance(self.region, sleplet.slepian.region.Region)
            and self.region.name_ending != "south_america"
        ):
            raise RuntimeError("Slepian region selected must be 'south_america'")

    def _create_coefficients(self) -> npt.NDArray[np.complex_ | np.float_]:
        sa = sleplet.functions.slepian_south_america.SlepianSouthAmerica(
            self.L,
            region=self.region,
            smoothing=self.smoothing,
        )
        noise = sleplet.noise._create_slepian_noise(
            self.L,
            sa.coefficients,
            self.slepian,
            self.SNR,
        )
        sleplet.noise.compute_snr(sa.coefficients, noise, "Slepian")
        return noise

    def _create_name(self) -> str:
        return (
            f"{sleplet._string_methods._convert_camel_case_to_snake_case(self.__class__.__name__)}"
            f"{sleplet._string_methods.filename_args(self.SNR, 'snr')}"
        )

    def _set_reality(self) -> bool:
        return False

    def _set_spin(self) -> int:
        return 0

    def _setup_args(self) -> None:
        if isinstance(self.extra_args, list):
            num_args = 1
            if len(self.extra_args) != num_args:
                raise ValueError(f"The number of extra arguments should be {num_args}")
            self.SNR = self.extra_args[0]


# -*- coding: utf-8 -*-
import sqlite3

# Enregistrement Materiel
class Materiel:

    def __init__(self):
        self.marque = ""
        self.modele = ""
        self.numero_serie = ""
        self.numero_tag = ""
        self.materiel = []

    def enregistrement_materiel(self):
        print("Materiel")
        self.marque = input("Entrée la marque: ")
        self.modele = input("Entrée le modèle: ")
        self.numero_serie = input("Entrée le numéro de sèrie: ")
        self.numero_tag = input("Entrée le numéro de Tag: ")
        self.materiel =[self.marque, self.modele, self.numero_serie, self.numero_tag]

    def modification_materiel(self):

        self.marque = input("Entrée la marque a modifier:")
        self.modele = input("Entrée le modèle a modifier:")
        self.numero_serie = input("Entrée le numéro de sèrie à modifier: ")
        self.numero_tag = input("Entrée le numéro de Tag à modifier: ")
        self.materiel = [self.marque,self.modele,self.numero_serie,self.numero_tag]

    def effacement_materiel(self):
        self.nLigneEff = int(input("Entrée la ligne à efffacer: "))
        self.nLigneEff = str(self.nLigneEff)  # transforme le nLigneEff en string

# Suivi du materiel
class Suivi(Materiel):

    def __init__(self):
        self.date_envoi = ""
        self.date_reception = ""
        self.status_envoi = "En-cours de réparation"

    def envoi_materiel(self):
        self.enregistrement_materiel()
        self.date_envoi = input("Entrée la date d'envoi:")
        self.materiel.append(self.date_envoi)
        self.date_reception = ""
        self.materiel.append(self.date_reception)
        self.status_envoi = "En-cours de réparation"
        self.materiel.append(self.status_envoi)
    def recu_materiel(self):
        self.date_reception = input("Entrée la date de récéption: ")

# Stockage de materiel dans la base donnée sqlite3
class Base_Donnee_Materiel(Suivi):

    def __init__(self):
        self.db_materiel = "DbTest3.db"
        self.connection_db = sqlite3.connect(self.db_materiel)
        self.curso_db_materiel = self.connection_db.cursor()

    def creation_db_materiel(self):

        # Création de table Materiel
        try:
            self.curso_db_materiel.execute('''CREATE TABLE STOCK_MATERIEL
                                       (
                                       Marque VARCHAR(50),
                                       Modele VARCHAR(50),
                                       Numero_Serie VARCHAR(50),
                                       Numero_Tag VARCHAR(50),
                                       Date_Envoi DATE,
                                       Date_Reception DATE,
                                       Status VARCHAR(100)
                                       )''')
            self.connection_db.commit()
        except sqlite3.OperationalError:
            print("Table exite déja !!!")
    @property
    def affichage_db_materiel(self):
        nligne = 1
        for db in self.curso_db_materiel.execute("SELECT * FROM STOCK_MATERIEL"):
            print("{}  | {} ".format(nligne, db))
            nligne = nligne + 1

    # Enregistrement d'un materriel dans la base donnée
    def enregistrement_materiel_db(self):
        self.envoi_materiel()
        self.curso_db_materiel.execute('''INSERT INTO STOCK_MATERIEL (
        Marque,
        Modele,
        Numero_Serie,
        Numero_Tag,
        Date_Envoi,
        Date_Reception,
        Status
        ) VALUES(?,?,?,?,?,?,?)''',(
            self.materiel[0],
            self.materiel[1],
            self.materiel[2],
            self.materiel[3],
            self.materiel[4],
            self.materiel[5],
            self.materiel[6]))
        self.connection_db.commit()

    # Modification d'un materriel dans la base donnée
    def modification_materiel_db(self):
        self.affichage_db_materiel
        self.ligneModifier = int(input("Entrée la ligne à modifier: "))
        self.modification_materiel()
        self.date_envoi =  input("Entrée nouvelle date d'envoi: ")
        self.date_reception = ""
        self.materiel.append(self.date_envoi)
        self.materiel.append(self.date_reception)
        self.status_envoi = "En-cours de réparation"
        self.materiel.append(self.status_envoi)
        self.materiel.append(self.ligneModifier)

        print(self.materiel)
        self.curso_db_materiel.execute('''UPDATE STOCK_MATERIEl SET
        Marque = ?,
        Modele = ?,
        Numero_Serie = ?,
        Numero_Tag = ?,
        Date_Envoi = ?,
        Date_Reception = ?,
        Status = ? WHERE rowid = ?
        ''',(self.materiel[0],
            self.materiel[1],
            self.materiel[2],
            self.materiel[3],
            self.materiel[4],
            self.materiel[5],
            self.materiel[6],
            self.materiel[7]))
        self.connection_db.commit()
        self.affichage_db_materiel
    # Effacement d'un materriel dans la base donnée
    def effacement_materiel_db(self):
        self.effacement_materiel()
        for lgDel in self.curso_db_materiel.execute('''SELECT * FROM STOCK_MATERIEL WHERE rowid = ?''',(self.nLigneEff)):
            print(f"{lgDel}")
        print("Etre vous sur de vouloir supprimer cette ligne ")
        print(" OUI ou NON ")
        print("Tapez O pour oui ,N pour non")
        self.qtVerfEff = str(input(": ")).upper()
        if self.qtVerfEff == "O":
            self.curso_db_materiel.execute('''DELETE FROM STOCK_MATERIEL WHERE rowid = ?''',(self.nLigneEff))
            self.connection_db.commit()
        else:
            pass

def main():
    try:
     #testEnvvoi = Suivi()
     #testEnvvoi.envoi_materiel()
     testBD = Base_Donnee_Materiel()
     testBD.creation_db_materiel()
     testBD.affichage_db_materiel
     testBD.enregistrement_materiel_db()

     testBD.effacement_materiel_db()
    except KeyboardInterrupt:
        print("\nstop de l'APP")

# Execution de l'application

main()


#!/usr/bin/env python
from colour import Color
import system.settings as settings
from math import sqrt
from random import randint
from random import shuffle

_led_mapping = None

def get_unpacked_model(model):
        name = model['name']
        if name == "large_cube":
            sides = ['top', 'north', 'west', 'south', 'east']
            mapping = [None] * 5
            for i in range(5):
                mapping[i] = [-1] * 50
                for j in range(5):
                    side = sides[j]
                    for k in range(10):
                        mapping[i][10*j + k] = model['led-groups'][side][i][k]
            return mapping
        else:
            return None

def create_electrode_mapping(presenter):
    global _led_mapping
    model = settings.LED_MODEL
    n_elct = settings.NEURAL_ELECTRODES_TOTAL
    n_leds = settings.LEDS_TOTAL

    mapping = get_unpacked_model(settings.LED_MODEL)
    if mapping is None:
        print("No dot mapping for model, neural data will be stripy")
        return

    leds_per_electrode = n_leds//n_elct
    leds_last_electrode = leds_per_electrode
    if n_leds % n_elct != 0:
        leds_last_electrode += 1

    _led_mapping = [None] * n_elct
    led_pos = [None] * n_elct
    last_index = [0,0]
    step = int(sqrt(settings.NEURAL_ELECTRODES_TOTAL*len(mapping)*len(mapping[0])))
    for i in range(n_elct):
        x = last_index[0]
        y = last_index[1]
        last_index[1] += step
        if last_index[1] >= 5:
            last_index[1] = 0
            last_index[0] += step

        if x >= 50 or mapping[y][x] == -1:
            x = randint(0,49)
            y = randint(0,4)
            while mapping[y][x] == -1:
                x = randint(0,49)
                y = randint(0,4)

        _led_mapping[i] = [mapping[y][x]]
        led_pos[i] = [[x,y]]
        mapping[y][x] = -1

    # Grow each electrode seed

    check_pattern = [[-1,0],[1,0],[0,-1],[0,1]]
    while True:
        temp = check_pattern.pop(0)
        check_pattern.append(temp)
        change = False
        for i in range(n_elct):
            done = False
            led_chosen = -1
            x = -1
            y = -1
            for j in range(len(_led_mapping[i])):
                #shuffle(check_pattern)
                for move in check_pattern:
                    x = led_pos[i][j][0] + move[0]
                    y = led_pos[i][j][1] + move[1]
                    if not (0 <= y <= 4 and 0 <= x <= 49):
                        continue
                    led_chosen = mapping[y][x]
                    if led_chosen != -1:
                        change = True
                        done = True
                        _led_mapping[i].append(led_chosen)
                        led_pos[i].append([x,y])
                        mapping[y][x] = -1
                        break
                if done:
                    break

        if not change:
            break

    """
    electrodes = leds_per_electrode
    if i == n_elct - 1:
        electrodes = leds_last_electrode
    _led_mapping[i] = [-1] * electrodes
    while mapping[last_index[1]][last_index[0]] == -1:
        last_index[1] += 1
        if last_index[1] >= 5:
            last_index[1] = 0
            last_index[0] += 1
            if last_index[0] >= 50:
                print('LEDs out of bounds when creating mapping!')
                exit(-1)
    for j in range(electrodes):
    """

def color_grouping(index, values, value_per_group):
    if values[index] <= value_per_group:
        return 0
    elif value_per_group < values[index] <= 2 * value_per_group:
        return 1
    elif 2 * value_per_group < values[index] <= 3 * value_per_group:
        return 2
    elif 3 * value_per_group < values[index] <= 4 * value_per_group:
        return 3
    elif 4 * value_per_group < values[index] <= 5 * value_per_group:
        return 4
    elif 5 * value_per_group < values[index] <= 6 * value_per_group:
        return 5
    elif 6 * value_per_group < values[index] <= 7 * value_per_group:
        return 6
    elif 7 * value_per_group < values[index] <= 8 * value_per_group:
        return 7
    elif 8 * value_per_group < values[index] <= 9 * value_per_group:
        return 8
    else:
        return 9

def generate_color_gradient():
    color1 = Color(settings.PLOT_COLOR_FROM)
    return list(color1.range_to(Color(settings.PLOT_COLOR_TO), 10))

def data_to_hex(data):
    colors = generate_color_gradient()
    hex_data = [0] * settings.NEURAL_ELECTRODES_TOTAL
    for i in range(len(data)):
        hex_data[i] = colors[int(data[i])].get_hex_l()
    return hex_data

def data_to_bytearray(input_data, output_data):
    global _led_mapping
    hex_array = data_to_hex(input_data)
    num_leds = settings.LEDS_TOTAL
    num_leds_cluster = int(num_leds / settings.NEURAL_ELECTRODES_TOTAL)

    if _led_mapping is not None:
        for i in range(len(hex_array)):
            leds = _led_mapping[i]
            for j in range(len(leds)):
                index = leds[j]*3
                output_data[index:index+3] = bytearray.fromhex(hex_array[i][1:])
    else:
        for i in range(len(hex_array)):
            for j in range(num_leds_cluster):
                index = i * 3 * num_leds_cluster + 3 * j
                output_data[index:index + 3] = bytearray.fromhex(hex_array[i][1:])

'''
def handle_large_cube(hex_array, output_data):
    electrodes_per_side = int(settings.NEURAL_ELECTRODES_TOTAL/5)
    last_side = electrodes_per_side + settings.NEURAL_ELECTRODES_TOTAL - electrodes_per_side*5
    sides = ['top', 'north', 'west', 'south', 'east']
    model = settings.LED_MODEL['led-groups']
    for i in range(5):
        side_leds = model[sides[i]]
        height = len(side_leds)
        width = len(side_leds[0])
        begin = electrodes_per_side*i
        electrodes_for_side = electrodes_per_side
        if i == 5:
            electrodes_for_side = last_side

        leds_per_electrode = height*width/electrodes_for_side
        led_cube_edge = sqrt(leds_per_electrode)

        for i in range(electrodes_for_side):
            electrode = hex_array[begin + i][1:]
            curr_hor = i%(width / led_cube_edge)
            curr_vert = i/(width / led_cube_edge)
            for k in range(int(led_cube_edge+0.5)):
                for l in range(int(led_cube_edge+0.5)):
                    led_ver = int(led_cube_edge*curr_vert+k)
                    if led_ver >= width:
                        led_ver = width-1
                    led_hor = int(leds_per_electrode*curr_hor+l)
                    if led_hor >= height:
                        led_hor = height-1
                    index = side_leds[led_hor][led_ver]
                    output_data[index:index+3] = bytearray.fromhex(electrode)
'''