# %%
"""
DacDataStructureIngestor ingests mock data into Hazelcast data structures other than
Map and ReplicatedMap.
"""
import pandas as pd
import panel as pn
import param
from panel.viewable import Viewer
from threading import Thread

from padogrid.hazelcast.playground.DacBase import DacBase
from padogrid.hazelcast.playground.Progress import Progress
from padogrid.hazelcast.playground.hazelcast_util import HazelcastUtil

class DacDataStructureIngestor(DacBase, Viewer):

    default_operation = param.String('add')
    default_key = param.String('random')
    default_key_range = param.Integer(100_000)
    default_object = param.String('Customer')
    default_er = param.String('N/A')
    default_delta = param.Integer(1)
    default_count = param.Integer(1000)
    default_batch_size = param.Integer(100)
    default_delay_in_msec = param.Integer(1000)

    value = None

    def __init__(self, **params):
        super().__init__(**params)

        if "parent" in params:
            self._parent = params["parent"]
        else:
            self._parent = None

        if "ds_type" in params:
            self.ds_type = params["ds_type"]
        else:
            self.ds_type = 'Unspecified'

        if self.ds_type == 'FlakeIdGenerator':
            operation_list = ['new_id']
            self.default_operation = 'new_id'
        elif self.ds_type == 'List':
            operation_list = ['add']
            self.default_operation = 'add'
        elif self.ds_type == 'MultiMap':
            operation_list = ['put']
            self.default_operation = 'put'
        elif self.ds_type == 'PNCounter':
            operation_list = ['get_and_add', 'add_and_get', 'get_and_subtract', 'subtract_and_get']
            self.default_operation = 'get_and_add'
        elif self.ds_type == 'ReliableTopic':
            operation_list = ['publish']
            self.default_operation = 'publish'
        elif self.ds_type == 'Queue':
            operation_list = ['offer']
            self.default_operation = 'offer'
        elif self.ds_type == 'Ringbuffer':
            operation_list = ['add']
            self.default_operation = 'add'
        elif self.ds_type == 'Set':
            operation_list = ['add']
            self.default_operation = 'add'
        elif self.ds_type == 'Topic':
            operation_list = ['publish']
            self.default_operation = 'publish'
        else:
            operation_list = ['add']
        blotter_name = self.ds_type
        key_list = [ 'random', 'uuid' ]

        self._status_text = pn.widgets.input.TextInput(disabled=True)
        self._new_button = pn.widgets.Button(name='New', width=self.button_width, button_type='primary')
        self._new_button.on_click(self.__new_execute__)
        self._new_text = pn.widgets.TextInput(width=300)
        self._new_text.param.watch(self.__new_execute__, 'value')

        if self.ds_type == 'flake_id_generator':
            self._df = pd.DataFrame({
                'Name': [''],
                'Operation': [''],
                'Count': [-1],
                'Call Delay (msec)': [-1],
                'Ingest': [False]
            })
        elif self.ds_type == 'pn_counter':
            self._df = pd.DataFrame({
                'Name': [''],
                'Operation': [''],
                'Delta': [-1],
                'Count': [-1],
                'Call Delay (msec)': [-1],
                'Ingest': [False]
            })
        elif self.ds_type == 'multi_map':
            self._df = pd.DataFrame({
                'Name': [''],
                'Operation': [''],
                'Key': [''],
                'Key Range': [-1],
                'Object': [''],
                'ER': [''],
                'Count': [-1],
                'Call Delay (msec)': [-1],
                'Ingest': [False]
            })
        else:
            self._df = pd.DataFrame({
                'Name': [''],
                'Operation': [''],
                'Object': [''],
                'ER': [''],
                'Count': [-1],
                'Call Delay (msec)': [-1],
                'Ingest': [False]
            })
        tabulator_formatters = {
            'Ingest': {'type': 'tickCross'}
        }
        blotter_editors = {
            'Name': None,
            'Operation': {'type': 'list', 'values': operation_list},
            'Key': {'type': 'list', 'values': key_list},
            'Key Range': {'type': 'number', 'min': 100, 'max': 100_000_000, 'step': 100, 'set': self.default_key_range},
            'Object': {'type': 'list', 'values': self.get_object_name_list()},
            'ER': {'type': 'list', 'values': self.get_er_name_list()},
            'Delta': {'type': 'number', 'min': 1, 'max': 1000, 'step': 1, 'set': 1},
            'Count': {'type': 'number', 'min': 1, 'max': 100000, 'step': 10, 'set': 100},
            'Call Delay (msec)': {'type': 'number', 'min': 10, 'max': 100000, 'step': 10, 'set': 1000},
            'Ingest': {'type': 'tickCross'}
        }

        self._blotter = pn.widgets.Tabulator(self._df, name=blotter_name, editors=blotter_editors,
                                             layout='fit_columns',
                                             buttons={'Destroy': "<i class='fa fa-trash'></i>"},
                                             formatters=tabulator_formatters)

        self._blotter.on_edit(self.__blotter_on_edit__)
        self._blotter.on_click(self.__blotter_on_click__)
        self.reset(self.hazelcast_cluster)
        self._layout = pn.Column(self._status_text,
                                 pn.Row(self._new_button, self._new_text),
                                 self._blotter)
        self._sync_widgets()

    def refresh(self, is_reset=False):
        '''Refreshes this component with the latest data from Hazelcast.
        '''
        if self.hazelcast_cluster != None:
            ds_name_list = self.hazelcast_cluster.get_ds_names(self.ds_type)
        else:
            ds_name_list = []
        ds_name_list.sort()
        old_df = self._df
        old_name_list = old_df['Name'].tolist()
        old_name_list.sort()
        if ds_name_list == old_name_list:
            return

        # A workaround for a bug in Tabulator: If the table is initially empty
        # and new rows are added later, Panel does not display table contents.
        # A workaround is to initialize it with a single empty row.
        len_list = len(ds_name_list)
        if len_list == 0:
            name_list = ['']
            operation_list = ['']
            key_list = ['']
            key_range_list = ['']
            object_list = ['']
            er_list = ['N/A']
            delta_list = [-1]
            count_list = [-1]
            delay_list = [-1]
            ingest_list = [False]
        else:
            name_list = []
            operation_list = []
            key_list = []
            key_range_list = []
            object_list = []
            er_list = []
            delta_list = []
            count_list = []
            delay_list = []
            ingest_list = []

        # Retain the previously running tasks
        for name in ds_name_list:
            name_list.append(name)
            if name in old_name_list:
                for index, row in old_df.iterrows():
                    old_name = row['Name']
                    if old_name == name:
                        operation_list.append(old_df.iloc[index]['Operation'])
                        if self.ds_type == 'PNCounter':
                            delta_list.append(old_df.iloc[index]['Delta'])
                        elif self.ds_type != 'FlakeIdGenerator':
                            if self.ds_type == 'MultiMap':
                                key_list.append(old_df.iloc[index]['Key'])
                                key_range_list.append(old_df.iloc[index]['Key Range'])
                            object_list.append(old_df.iloc[index]['Object'])
                            er_list.append(old_df.iloc[index]['ER'])
                        count_list.append(old_df.iloc[index]['Count'])
                        delay_list.append(old_df.iloc[index]['Call Delay (msec)'])
                        ingest_list.append(old_df.iloc[index]['Ingest'])
                        break
            else:
                operation_list.append(self.default_operation)
                if self.ds_type == 'PNCounter':
                    delta_list.append(self.default_delta)
                elif self.ds_type != 'FlakeIdGenerator':
                    if self.ds_type == 'MultiMap':
                        key_list.append(self.default_key)
                        key_range_list.append(self.default_key_range)
                    ds = self.__get_ds__(name)
                    object_type_in_ds = self.get_object_name_in_ds(ds)
                    if object_type_in_ds == None:
                        object_list.append(self.default_object)
                    else:
                        object_list.append(object_type_in_ds)
                    er_list.append(self.default_er)
                count_list.append(self.default_count)
                delay_list.append(self.default_delay_in_msec)
                ingest_list.append(False)

        # Stop and remove existing threads that are not part of the new map list.
        # This cleans up the existing thread events in case the maps are destroyed
        # by other clients.
        DacBase.thread_pool.refresh(self.ds_type, ds_name_list)

        if self.ds_type == 'FlakeIdGenerator':
            new_df = pd.DataFrame({
                'Name': name_list,
                'Operation': operation_list,
                'Count': count_list,
                'Call Delay (msec)': delay_list,
                'Ingest' : ingest_list,
            })
        elif self.ds_type == 'PNCounter':
            new_df = pd.DataFrame({
                'Name': name_list,
                'Operation': operation_list,
                'Delta': delta_list,
                'Count': count_list,
                'Call Delay (msec)': delay_list,
                'Ingest' : ingest_list,
            })
        elif self.ds_type == 'MultiMap':
            new_df = pd.DataFrame({
                'Name': name_list,
                'Operation': operation_list,
                'Key': key_list,
                'Key Range': key_range_list,
                'Object': object_list,
                'ER': er_list,
                'Count': count_list,
                'Call Delay (msec)': delay_list,
                'Ingest' : ingest_list,
            })
        else:
            new_df = pd.DataFrame({
                'Name': name_list,
                'Operation': operation_list,
                'Object': object_list,
                'ER': er_list,
                'Count': count_list,
                'Call Delay (msec)': delay_list,
                'Ingest' : ingest_list,
            })
        self._df = new_df
        self._blotter.value = new_df
        self._sync_widgets()

    def __panel__(self):
        return self._layout

    @param.depends('value', watch=True)
    def _sync_widgets(self):
        self.value = self._df

    @param.depends('value', watch=True)
    def _sync_params(self):
        self.value = self._df

    def get_ds_from_hz(self, ds_name):
        '''Returns the specified data structure. The data structure is created if it does not exist.
        '''
        ds = None
        if self.hazelcast_cluster != None:
            if self.ds_type == 'FlakeIdGenerator':
                ds = self.hazelcast_cluster.hazelcast_client.get_flake_id_generator(ds_name)
            if self.ds_type == 'List':
                ds = self.hazelcast_cluster.hazelcast_client.get_list(ds_name)
            elif self.ds_type == 'MultiMap':
                ds = self.hazelcast_cluster.hazelcast_client.get_multi_map(ds_name)
            elif self.ds_type == 'PNCounter':
                ds = self.hazelcast_cluster.hazelcast_client.get_pn_counter(ds_name)
            elif self.ds_type == 'ReliableTopic':
                ds = self.hazelcast_cluster.hazelcast_client.get_reliable_topic(ds_name)
            elif self.ds_type == 'Ringbuffer':
                ds = self.hazelcast_cluster.hazelcast_client.get_ringbuffer(ds_name)
            elif self.ds_type == 'Set':
                ds = self.hazelcast_cluster.hazelcast_client.get_set(ds_name)
            elif self.ds_type == 'Queue':
                ds = self.hazelcast_cluster.hazelcast_client.get_queue(ds_name)
            elif self.ds_type == 'Topic':
                ds = self.hazelcast_cluster.hazelcast_client.get_topic(ds_name)
        return ds

    def __new_execute__(self, event):
        self.__clear_status__()
        name = self._new_text.value.strip()
        if len(name) == 0:
            return
        found = False
        for index, row in self._df.iterrows():
            if name == row['Name']:
                found = True
                break
        # Update df if a new name
        if found == False:
            if self.hazelcast_cluster != None and self.hazelcast_cluster.hazelcast_client != None:
                ds = self.get_ds_from_hz(name)

            name_list = self._df['Name'].to_list()
            # Replace the place holder (empty) row  used as a workaround to a Panel bug
            is_place_holder = len(name_list) == 1 and name_list[0] == ''
            if is_place_holder:
                name_list = [name]
                operation_list = [self.default_operation]
                key_list = [self.default_key]
                key_range_list = [self.default_key_range]
                object_list = [self.default_object]
                er_list = [self.default_er]
                delta_list = [self.default_delta]
                count_list = [self.default_count]
                delay_list = [self.default_delay_in_msec]
                ingest_list = [False]
            else:
                name_list.append(name)
                name_list.sort()
                index = 0
                for n in name_list:
                    if n == name:
                        break
                    index += 1
                operation_list = self._df['Operation'].to_list()
                operation_list.insert(index, self.default_operation)
                count_list = self._df['Count'].to_list()
                count_list.insert(index, self.default_count)
                delay_list = self._df['Call Delay (msec)'].to_list()
                delay_list.insert(index, self.default_delay_in_msec)
                ingest_list = self._df['Ingest'].to_list()
                ingest_list.insert(index, False)
                if self.ds_type == 'FlakeIdGenerator':
                    pass
                elif self.ds_type == 'PNCounter':
                    delta_list = self._df['Delta'].to_list()
                    delta_list.insert(index, self.default_delta)
                else:
                    if self.ds_type == 'MultiMap':
                        key_list = self._df['Key'].to_list()
                        key_list.insert(index, self.default_key)
                        key_range_list = self._df['Key Range'].to_list()
                        key_range_list.insert(index, self.default_key_range)
                    object_list = self._df['Object'].to_list()
                    object_list.insert(index, self.default_object)
                    er_list = self._df['ER'].to_list()
                    er_list.insert(index, self.default_er)

            if self.ds_type == 'FlakeIdGenerator':
                new_df = pd.DataFrame({
                    'Name': name_list,
                    'Operation': operation_list,
                    'Count': count_list,
                    'Call Delay (msec)': delay_list,
                    'Ingest' : ingest_list,
                })
            elif self.ds_type == 'PNCounter':
                new_df = pd.DataFrame({
                    'Name': name_list,
                    'Operation': operation_list,
                    'Delta': delta_list,
                    'Count': count_list,
                    'Call Delay (msec)': delay_list,
                    'Ingest' : ingest_list,
                })
            elif self.ds_type == 'MultiMap':
                new_df = pd.DataFrame({
                    'Name': name_list,
                    'Operation': operation_list,
                    'Key': key_list,
                    'Key Range': key_range_list,
                    'Object': object_list,
                    'ER': er_list,
                    'Count': count_list,
                    'Call Delay (msec)': delay_list,
                    'Ingest' : ingest_list,
                })
            else:
                new_df = pd.DataFrame({
                    'Name': name_list,
                    'Operation': operation_list,
                    'Object': object_list,
                    'ER': er_list,
                    'Count': count_list,
                    'Call Delay (msec)': delay_list,
                    'Ingest' : ingest_list,
                })
            self._df = new_df
            self._blotter.value = new_df

        # Select the new row
        for index, row in self._df.iterrows():
            if name == row['Name']:
                self._blotter.selection = [index]
                break

    def __click_remove_button__(self, event):
        return

    def __get_ds__(self, ds_name):
        '''Returns the specified data structure from the cached list in HazelcastCluster.
        If not found, then returns None.
        '''
        if self.hazelcast_cluster != None:
            return self.hazelcast_cluster.get_ds(self.ds_type, ds_name)
        else:
            return None

    def __clear_status__(self):
        self._status_text.value = ''

    def __blotter_on_edit__(self, event):
        name = self._df.iloc[event.row]['Name']
        operation = event.column
        operation_value = event.value
        if name == '':
            ds = None
        else:
            ds = self.__get_ds__(name)
            # ds may be None if it is newly created
            if ds == None:
                ds = self.get_ds_from_hz(name)
        if ds != None:
            if operation == 'Ingest':
                if operation_value == True:
                    # Abort if max threads reached
                    if DacBase.thread_pool.is_max():
                        self._status_text.value = f'ERROR: Max number of jobs reached [{DacBase.thread_pool.get_max()}]. Command aborted.'
                        self._blotter.patch({
                            'Ingest' : [
                                (event.row, False)
                            ]})
                        return

                    # Get a single object to check whether the selected object type
                    # is same as the object in the data structure
                    object_type_in_ds = self.get_object_name_in_ds(ds)

                    # Offload publishing task to a thread
                    ds_method_name = self._df.iloc[event.row]['Operation']
                    delta = None
                    key_type = None
                    key_range = None
                    object_type = None
                    er_object_name = None
                    if self.ds_type == 'PNCounter':
                        delta = self._df.iloc[event.row]['Delta']
                    elif self.ds_type != 'FlakeIdGenerator':
                        if self.ds_type == 'MultiMap':
                            key_type = self._df.iloc[event.row]['Key']
                            key_range = self._df.iloc[event.row]['Key Range']
                            if key_range < 100:
                                key_range = 100
                            elif key_range > 100_000_000:
                                key_range = 100_000_000
                        object_type = self._df.iloc[event.row]['Object']
                        if object_type_in_ds != None and object_type != object_type_in_ds:
                            self._status_text.value = f'ERROR: Invalid Object. Data structure has {object_type_in_ds} but your selection is {object_type}. Command aborted.'
                            self._blotter.patch({
                                'Ingest' : [
                                    (event.row, False)
                                ]})
                            return
                        er_object_name = self._df.iloc[event.row]['ER']
                        if er_object_name == 'N/A':
                            er_object_name = None
                    max = self._df.iloc[event.row]['Count']
                    batch_size = -1
                    delay_in_msec = self._df.iloc[event.row]['Call Delay (msec)']
                    # A bug in Tabulator. Min value not honored if number entered manually
                    if delay_in_msec < 10:
                        delay_in_msec = 10
                        self._blotter.patch({
                            'Call Delay (msec)' : [
                                (event.row, delay_in_msec)
                            ]})
                    thread, thread_event = DacBase.thread_pool.get_thread(self.ds_type, name,
                                                                          self.__ingest_task__,
                                                                          args=(name, key_type, key_range, object_type, er_object_name, delta, ds_method_name, max, batch_size, delay_in_msec))
                    if thread.is_alive() == False:
                        try:
                            thread.start()
                        except Exception as ex:
                            self._status_text.value = f'ERROR: {repr(ex)}'
                else:
                    # Stop thread and remove it from the thread pool
                    DacBase.thread_pool.stop_thread(self.ds_type, name)
                    if self._parent != None:
                        self._parent.remove_progress_by_name(self.ds_type, name)

    def __ingest_task__(self, ds_name, key_type, key_range, object_type, er_object_name, delta, ds_method_name, max, batch_size, delay_in_msec, thread_event):
        '''Thread task for ingesting data.
        '''
        # Ingest objects
        create_function = self.get_obj_creation_function(object_type)
        progress = Progress(self.ds_type, ds_name, key_type, key_range, object_type, er_object_name, delta, ds_method_name, max, batch_size, delay_in_msec)
        if self._parent != None:
            self._parent.add_progress(progress)

        try:
            if self.ds_type == 'FlakeIdGenerator':
                self.ingestor.ingest_flake_id_generator(ds_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
            elif self.ds_type == 'List':
                self.ingestor.ingest_list(ds_name, create_function, er_object_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
            elif self.ds_type == 'PNCounter':
                self.ingestor.ingest_pn_counter(ds_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress, ds_method_name=ds_method_name, delta=delta)
            elif self.ds_type == 'MultiMap':
                self.ingestor.ingest_multi_map(ds_name, create_function, er_object_name, key_type=key_type, key_range=key_range, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
            elif self.ds_type == 'Queue':
                self.ingestor.ingest_queue(ds_name, create_function, er_object_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
            elif self.ds_type == 'ReliableTopic':
                self.ingestor.ingest_reliable_topic(ds_name, create_function, er_object_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
            elif self.ds_type == 'Ringbuffer':
                self.ingestor.ingest_ringbuffer(ds_name, create_function, er_object_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
            elif self.ds_type == 'Set':
                self.ingestor.ingest_set(ds_name, create_function, er_object_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
            elif self.ds_type == 'Topic':
                self.ingestor.ingest_topic(ds_name, create_function, er_object_name, count=max, delay_in_msec=delay_in_msec, thread_event=thread_event, progress=progress)
        except Exception as ex:
            self._status_text.value = f'ERROR: {repr(ex)}'

        # Deselect Ingest checkbox
        for index, row in self._df.iterrows():
            if row['Name'] == ds_name:
                self._blotter.patch({
                                'Ingest' : [
                                    (index, False)
                                ]})
                break
        DacBase.thread_pool.stop_thread(self.ds_type, ds_name)
        if self._parent != None:
            self._parent.remove_progress(progress)

    def __blotter_on_click__(self, event):
        self.__clear_status__()
        row = event.row
        column = event.column
        if self.hazelcast_cluster != None and self.hazelcast_cluster.hazelcast_client != None:
            name = self._df.iloc[row]['Name']
            if name == '':
                return
            ds = self.__get_ds__(name)
            # ds may be None if it is # newly created
            if ds == None:
                ds = self.get_ds_from_hz(name)
            if column == 'Destroy':
                # Destroy
                is_destroyed = ds.destroy()
                if is_destroyed == True:
                    self.hazelcast_cluster.refresh()
                    DacBase.thread_pool.stop_thread(self.ds_type, name)
                self._status_text.value = f'Destroyed: {name} - {is_destroyed}'


import sys
from niveristand import nivs_rt_sequence, NivsParam
from niveristand import realtimesequencetools
from niveristand.clientapi import ChannelReference, DoubleValue, DoubleValueArray, I32Value
from niveristand.clientapi import RealTimeSequence
from niveristand.errors import TranslateError, VeristandError
from niveristand.library.primitives import arraysize, localhost_wait
import pytest
from testutilities import rtseqrunner, validation

@nivs_rt_sequence
def _return_constant():
    return 10

@nivs_rt_sequence
def _increment_param_by_ref(param):
    param.value = param.value + 1

@nivs_rt_sequence
def for_loop_variable_array():
    a = DoubleValue(0)
    b = DoubleValueArray([1, 2, 3, 4, 5])
    for x in b:
        a.value += x.value
    return a.value

@nivs_rt_sequence
def for_loop_variable_array1():
    a = DoubleValue(0)
    b = DoubleValueArray([1, 2, 3, 4, 5])
    for x in b.value:
        a.value += x.value
    return a.value

@nivs_rt_sequence
def for_loop_modify_collection():
    a = DoubleValueArray([1, 2, 3, 4, 5])
    for x in a.value:
        x.value += 1
    return a[0].value

@nivs_rt_sequence
def for_loop_modify_elements():
    a = DoubleValueArray([1, 2, 3, 4, 5])
    for x in a.value:
        _increment_param_by_ref(x)
    return a[0].value

@nivs_rt_sequence
def for_loop_constant_array():
    a = DoubleValue(0)
    for x in [1, 2, 3, 4, 5]:
        a.value += x
    return a.value

@nivs_rt_sequence
def for_loop_range():
    a = DoubleValue(0)
    for x in range(10):
        a.value += x
    return a.value

@nivs_rt_sequence
def for_loop_range_with_start():
    a = DoubleValue(0)
    for x in range(2, 10):
        a.value += x
    return a.value

@nivs_rt_sequence
def for_loop_range_with_step():
    a = DoubleValue(0)
    for x in range(2, 10, 2):
        a.value += x
    return a.value

@nivs_rt_sequence
def for_loop_range_with_variable():
    a = DoubleValue(0)
    b = I32Value(10)
    for x in range(b.value):
        a.value += x
    return a.value

@nivs_rt_sequence
def for_loop_range_with_channel_ref():
    a = DoubleValue(0)
    b = ChannelReference("Aliases/DesiredRPM")
    b.value = 10.0
    localhost_wait(0.2)
    for x in range(b.value):
        a.value += x
    return a

@nivs_rt_sequence
def for_loop_range_with_call():
    a = DoubleValue(0)
    for x in range(_return_constant()):
        a.value += x
    return a.value

@nivs_rt_sequence
def for_loop_iterate_on_array():
    a = DoubleValueArray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
    for i in range(10):
        a[0].value += a[i].value
    return a[0].value

@nivs_rt_sequence
def for_loop_else():
    a = DoubleValue(0)
    b = DoubleValueArray([1, 2, 3, 4, 5])
    for x in b.value:
        a.value += x
    else:
        a.value = -1
    return a.value

@nivs_rt_sequence
def nested_for_loop():
    a = DoubleValueArray([1, 2, 3, 4, 5])
    b = DoubleValueArray([1, 2, 3, 4, 5])
    for i in range(5):
        for j in b.value:
            a[i].value += j.value
    return a[3].value

@nivs_rt_sequence
def nested_for_loop_body():
    a = DoubleValueArray([1, 2, 3, 4, 5])
    b = DoubleValueArray([1, 2, 3, 4, 5])
    for i in range(5):
        for j in b.value:
            if j.value % 2 == 0:
                a[i].value += j.value
            else:
                a[i].value -= j.value
    return a[3].value

@nivs_rt_sequence
def looping_over_invalid_var():
    a = DoubleValue(0)
    for x in a.value:
        a.value += x
    return a.value

@nivs_rt_sequence
def for_return_in_body():
    for i in range(5):
        return i

@nivs_rt_sequence
def for_try_in_body():
    for i in range(5):
        try:
            pass
        finally:
            pass

@nivs_rt_sequence
def for_funcdef_in_body():
    for i in range(5):

        def func():
            pass

        pass

@nivs_rt_sequence
@NivsParam("array", DoubleValueArray([0]), NivsParam.BY_REF)
def _average(array):
    average_var = DoubleValue(0)
    for x in array:
        average_var.value += x.value
    average_var.value /= arraysize(array.value)
    return average_var.value

@nivs_rt_sequence
def call_average():
    a = DoubleValueArray([1, 2, 3, 4, 5])
    res = DoubleValue(0)
    res.value = _average(a)
    return res.value

run_tests = [
    (for_loop_variable_array, (), 15),
    (for_loop_variable_array1, (), 15),
    (for_loop_modify_collection, (), 2),
    (for_loop_modify_elements, (), 2),
    (for_loop_range, (), 45),
    (for_loop_range_with_variable, (), 45),
    (for_loop_range_with_call, (), 45),
    (for_loop_iterate_on_array, (), 45),
    (nested_for_loop, (), 19),
    (nested_for_loop_body, (), 1),
    (call_average, (), 3),
]

fail_transform_tests = [
    (for_loop_else, (), TranslateError),
    (for_loop_range_with_start, (), TranslateError),
    (for_loop_range_with_step, (), TranslateError),
    (looping_over_invalid_var, (), TranslateError),
    (for_return_in_body, (), TranslateError),
    (for_try_in_body, (), TranslateError),
    (for_funcdef_in_body, (), TranslateError),
    (for_loop_range_with_channel_ref, (), VeristandError),
    (for_loop_constant_array, (), VeristandError),
]

def idfunc(val):
    try:
        return val.__name__
    except AttributeError:
        return str(val)

@pytest.mark.parametrize("func_name, params, expected_result", run_tests, ids=idfunc)
def test_transform(func_name, params, expected_result):
    RealTimeSequence(func_name)

@pytest.mark.parametrize("func_name, params, expected_result", run_tests, ids=idfunc)
def test_runpy(func_name, params, expected_result):
    actual = func_name(*params)
    assert actual == expected_result

@pytest.mark.parametrize("func_name, params, expected_result", run_tests, ids=idfunc)
def test_run_py_as_rts(func_name, params, expected_result):
    actual = realtimesequencetools.run_py_as_rtseq(func_name)
    assert actual == expected_result

@pytest.mark.parametrize("func_name, params, expected_result", run_tests, ids=idfunc)
def test_run_in_VM(func_name, params, expected_result):
    actual = rtseqrunner.run_rtseq_in_VM(func_name)
    assert actual == expected_result

@pytest.mark.parametrize("func_name, params, expected_result", fail_transform_tests, ids=idfunc)
def test_failures(func_name, params, expected_result):
    with pytest.raises(expected_result):
        RealTimeSequence(func_name)
    with pytest.raises(expected_result):
        func_name(*params)

def test_check_all_tested():
    validation.test_validate(sys.modules[__name__])


from __future__ import print_function
import os.path
import base64
import email
from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials

# If modifying these scopes, delete the file token.json.
SCOPES = ["https://www.googleapis.com/auth/gmail.readonly"]

#Getting all the messages
def get_messages(service, user_id):
    try:
        return service.users().messages().list(userId=user_id).execute()
    except Exception as error:
        print("An error occurred: %s" % error)

#Getting single message
def get_message(service, user_id, msg_id):
    try:
        return (
            service.users()
                .messages()
                .get(userId=user_id, id=msg_id, format="metadata")
                .execute()
        )
    except Exception as error:
        print("An error occurred: %s" % error)

#Exposing the content of messages
def get_content_message(service, user_id, msg_id):
    try:
        message = service.users().messages().get(userId=user_id, id=msg_id, format='raw').execute()
        msg_str = base64.urlsafe_b64decode(message['raw'].encode("utf-8")).decode("utf-8")
        mime_msg = email.message_from_string(msg_str)
        return mime_msg
    except Exception as error:
        print('An error occurred: %s' % error)

def main():
    creds = None
    if os.path.exists("token.json"):
        creds = Credentials.from_authorized_user_file("token.json", SCOPES)
    # If there are no (valid) credentials available, let the user log in.
    if not creds or not creds.valid:
        if creds and creds.expired and creds.refresh_token:
            creds.refresh(Request())
        else:
            flow = InstalledAppFlow.from_client_secrets_file("credentials.json", SCOPES)
            creds = flow.run_local_server(port=0)
        # Save the credentials for the next run
        with open("token.json", "w") as token:
            token.write(creds.to_json())

    service = build("gmail", "v1", credentials=creds)

    # Call the Gmail API
    results = get_messages(service, "me")
    messages = results.get("messages", [])
    if not messages:
        print("No messages found.")
    else:
        print("Most Recent Email: ")
        message = messages[0]
        msg = get_content_message(service, "me", message["id"])
        print(msg)
        print("\n")

if __name__ == "__main__":
    main()


"""
Logging
-------
This module provides custom logging functionality for other amici modules
"""

import functools
import logging
import os
import platform
import socket
import time
import warnings
from inspect import currentframe, getouterframes

import amici

LOG_LEVEL_ENV_VAR = "AMICI_LOG"
BASE_LOGGER_NAME = "amici"
# Supported values for LOG_LEVEL_ENV_VAR
NAMED_LOG_LEVELS = {
    "NOTSET": logging.NOTSET,
    "DEBUG": logging.DEBUG,
    "INFO": logging.INFO,
    "WARNING": logging.WARNING,
    "ERROR": logging.ERROR,
    "CRITICAL": logging.CRITICAL,
}

from typing import Callable, Optional, Union

def _setup_logger(
    level: Optional[int] = logging.WARNING,
    console_output: Optional[bool] = True,
    file_output: Optional[bool] = False,
    capture_warnings: Optional[bool] = True,
) -> logging.Logger:
    """
    Set up a new logging.Logger for AMICI logging

    :param level:
        Logging level, typically using a constant like logging.INFO or
        logging.DEBUG

    :param console_output:
        Set up a default console log handler if True (default)

    :param file_output:
        Supply a filename to copy all log output to that file, or
        set to False to disable (default)

    :param capture_warnings:
        Capture warnings from Python's warnings module if True (default)

    :return:
        A :class:`logging.Logger` object for AMICI logging. Note that other
        AMICI modules
        should use a logger specific to their namespace instead by calling
        :func:`get_logger`.
    """
    log = logging.getLogger(BASE_LOGGER_NAME)

    # Logging level can be overridden with environment variable
    if LOG_LEVEL_ENV_VAR in os.environ:
        try:
            level = int(os.environ[LOG_LEVEL_ENV_VAR])
        except ValueError:
            # Try parsing as a name
            level_name = os.environ[LOG_LEVEL_ENV_VAR]
            if level_name in NAMED_LOG_LEVELS.keys():
                level = NAMED_LOG_LEVELS[level_name]
            else:
                raise ValueError(
                    f"Environment variable {LOG_LEVEL_ENV_VAR} "
                    f'contains an invalid value "{level_name}".'
                    f" If set, its value must be one of "
                    f'{", ".join(NAMED_LOG_LEVELS.keys())}'
                    f" (case-sensitive) or an integer log level."
                )

    log.setLevel(level)

    # Remove default logging handler
    log.handlers = []

    log_fmt = logging.Formatter(
        "%(asctime)s.%(msecs).3d - %(name)s - " "%(levelname)s - %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S",
    )

    if console_output:
        stream_handler = logging.StreamHandler()
        stream_handler.setFormatter(log_fmt)
        log.addHandler(stream_handler)

    if file_output:
        file_handler = logging.FileHandler(file_output)
        file_handler.setFormatter(log_fmt)
        log.addHandler(file_handler)

    log.info("Logging started on AMICI version %s", amici.__version__)

    log.debug("OS Platform: %s", platform.platform())
    log.debug("Python version: %s", platform.python_version())
    log.debug("Hostname: %s", socket.getfqdn())

    logging.captureWarnings(capture_warnings)

    return log

def set_log_level(logger: logging.Logger, log_level: Union[int, bool]) -> None:
    if log_level is not None and log_level is not False:
        if isinstance(log_level, bool):
            log_level = logging.DEBUG
        elif not isinstance(log_level, int):
            raise ValueError("log_level must be a boolean, integer or None")

        if logger.getEffectiveLevel() != log_level:
            logger.debug(
                "Changing log_level from %d to %d"
                % (logger.getEffectiveLevel(), log_level)
            )
            logger.setLevel(log_level)

def get_logger(
    logger_name: Optional[str] = BASE_LOGGER_NAME,
    log_level: Optional[int] = None,
    **kwargs,
) -> logging.Logger:
    """
    Returns (if extistant) or creates an AMICI logger

    If the AMICI base logger has already been set up, this method will
    return it or any of its descendant loggers without overriding the
    settings - i.e. any values supplied as kwargs will be ignored.

    :param logger_name:
        Get a logger for a specific namespace, typically __name__
        for code outside of classes or self.__module__ inside a class

    :param log_level:
        Override the default or preset log level for the requested logger.
        None or False uses the default or preset value. True evaluates to
        logging.DEBUG. Any integer is used directly.

    :param console_output:
        Set up a default console log handler if True (default). Only used when
        the AMICI logger hasn't been set up yet.

    :param file_output:
        Supply a filename to copy all log output to that file, or set to
        False to disable (default). Only used when the AMICI logger hasn't
        been set up yet.

    :param capture_warnings:
        Capture warnings from Python's warnings module if True (default).
        Only used when the AMICI logger hasn't been set up yet..

    :return:
        A logging.Logger object with the requested name
    """
    if BASE_LOGGER_NAME not in logging.Logger.manager.loggerDict.keys():
        _setup_logger(**kwargs)
    elif kwargs:
        warnings.warn(
            "AMICI logger already exists, ignoring keyword "
            "arguments to setup_logger"
        )

    logger = logging.getLogger(logger_name)

    set_log_level(logger, log_level)

    return logger

def log_execution_time(description: str, logger: logging.Logger) -> Callable:
    """
    Parameterized function decorator that enables automatic execution time
    tracking

    :param description:
        Description of what the decorated function does

    :param logger:
        Logger to which execution timing will be printed
    """

    def decorator_timer(func):
        @functools.wraps(func)
        def wrapper_timer(*args, **kwargs):
            # append pluses to indicate recursion level
            recursion_level = sum(
                frame.function == "wrapper_timer"
                and frame.filename == __file__
                for frame in getouterframes(currentframe(), context=0)
            )

            recursion = ""
            level = logging.INFO
            level_length = len("INFO")
            if recursion_level > 1:
                recursion = "+" * (recursion_level - 1)
                level = logging.DEBUG
                level_length = len("DEBUG")

            tstart = time.perf_counter()
            rval = func(*args, **kwargs)
            tend = time.perf_counter()
            spacers = " " * max(
                59
                - len(description)
                - len(logger.name)
                - len(recursion)
                - level_length,
                0,
            )
            logger.log(
                level,
                f"Finished {description}{spacers}{recursion} ({(tend - tstart):.2E}s)",
            )
            return rval

        return wrapper_timer

    return decorator_timer


from rest_framework.response import Response
from rest_framework.decorators import api_view
import pandas as pd
import random
from pathlib import Path

root = Path('.')
try:
    moviesPath = root / 'data'/'5kMovies_11.06.pkl'
    CBpath = root / 'data'/'CB_SimilarityMatrix_14.05.pkl'
    CFpath = root / 'data'/'CF_SimilarityMatrix.pkl'
    print("in-reco", moviesPath)
    movies = pd.read_pickle(moviesPath)
    cb_df = pd.read_pickle(CBpath)
    collab_df = pd.read_pickle(CFpath)

except Exception as e:
    print("error:", str(e))

def loadPickles():
    try:
        moviesPath = root / 'data'/'5kMovies_11.06.pkl'
        CBpath = root / 'data'/'CB_SimilarityMatrix_14.05.pkl'
        CFpath = root / 'data'/'CF_SimilarityMatrix.pkl'
        global movies
        global cb_df
        global collab_df

    except Exception as e:
        print("error:", str(e))

def getRelatedMovies(movieId, rating):
    # movieId = movie[0]
    # rate = movie[1]
    row = collab_df[movieId]*rating
    return row.sort_values(ascending=False)[1:11]

@api_view(['GET'])
def contentBased(request, movieId):
    try:

        ids = cb_df.index.tolist()
        if movieId not in ids:
            msg = 'id not found'
            result = []
        else:
            msg = 'content based'
            row = cb_df[movieId]
            ids = row.sort_values(ascending=False)[1:19].index.tolist()

            rlist = {}
            for id in ids:
                movie = movies[movies['movieId'] == id]
                rlist[id] = movie.imdbRating.values[0]

            result = dict(
                sorted(rlist.items(), key=lambda x: x[1], reverse=True)[0:12]).keys()

        return Response({'message': msg, 'result': result})
    except:
        return Response({'message': 'error', "result": []})

@api_view(['POST'])
def collaborativeFilter(request):
    try:

        data = request.data['movies']
        ids = collab_df.index.tolist()
        result = []
        if len(data) > 0:
            similar_movies = pd.DataFrame()

            for movieId, rating in data:
                if movieId in ids:
                    similar_movies = pd.concat([similar_movies,
                                                getRelatedMovies(movieId, rating)], ignore_index=True, axis=1)

            movies = [i for i, j in data]
            similar_movies = similar_movies.sum(
                axis=1).sort_values(ascending=False)
            result = list(filter(lambda x: x not in movies,
                          similar_movies.index))[0:30]
            random.sample(result, len(result))[0:25]

        return Response({'message': 'collaborative filtering', "result": result[0:25]})

    except:
        return Response({'message': 'error', "result": []})


import scrapy
from scrapy.http.request.form import _urlencode
from scrapy.pipelines.images import ImagesPipeline

from ..items import TutorialItem

class QuotesSpider(scrapy.Spider):
    name = 'quotes'
    start_urls = ['https://quotes.toscrape.com/']

    def parse(self, response):

        quotes = response.css('div.quote')

        for quote in quotes:
            item = {}
            item['text'] = quote.css('span.text::text').get()
            item['author'] = quote.css('small.author::text').get()
            item['tags'] = quote.css('div.tags a.tag::text').getall()
            author_bio_link = quote.css('span a::attr(href)').get()

            yield response.follow(author_bio_link, meta={'item' : item}, callback=self.parse_author, dont_filter=True)

        quote_next_link = response.css('li.next a::attr(href)').get()
        if quote_next_link is not None:
            yield response.follow(quote_next_link, callback=self.parse)

    def parse_author(self, response):

        item = response.meta.get('item')

        born_date = response.css('p span.author-born-date::text').get()
        born_location  = response.css('p span.author-born-location::text').get()

        item['born_date'] = born_date
        item['born_location'] = born_location

        author_clean = "_".join(item['author'].split())

        link_picture = "https://en.wikipedia.org/wiki/" + item['author']

        yield response.follow(link_picture, meta={'item' : item}, callback=self.parse_picture, dont_filter=True)

        #yield item

    def parse_picture(self, response):

        item = response.meta.get('item')

        url_picture = response.css('div a.image img::attr(src)').get()

        if url_picture is not None:
            url_picture = 'https:' + url_picture.replace('220px', '1280px')
            item['image_urls'] = [url_picture]

        yield item


from django.shortcuts import render
from .models import *
from rest_framework.generics import *
from rest_framework import mixins
from .serializers import CommentSerializer,LikeSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.exceptions import ValidationError

class All_Comment(ListCreateAPIView):

    queryset = Comment1.objects.all()
    serializer_class = CommentSerializer
    def perform_create(self, serializer):
        serializer.save(author1=self.request.user)

class CommentRetrieveDestroy(RetrieveDestroyAPIView):
    queryset = Comment1.objects.all()
    serializer_class = CommentSerializer

    def delete(self, request, *args, **kwargs):
        comment = Comment1.objects.filter(pk=kwargs['pk'],author1=self.request.user)
        if comment.exists():
            return self.destroy(request,*args,**kwargs)
        raise ValidationError('this comment not own you.')

class DeleteUpdateGet(APIView):

    def delete(self,request,pk):
        query = Comment1.objects.filter(pk=pk,author1=self.request.user)
        if query.exists():
            query.delete()
            return Response(status=status.HTTP_204_NO_CONTENT)
        raise ValidationError('not you comment')

@api_view(['POST'])
def sendlike(request,pk):
    user = request.user
    comment = Comment1.objects.get(pk=pk)
    query = Like1.objects.filter(liker1=user,comment1=comment)
    serializers = LikeSerializer(data=request.data)
    if serializers.is_valid():
        if query.exists():
            raise ValidationError('like past')
        serializers.save(liker=request.user,comment1=Comment1.objects.get(pk=pk))
        return Response(serializers.data,status=status.HTTP_200_OK)

class SendLike(CreateAPIView,mixins.DestroyModelMixin):
    serializer_class = LikeSerializer

    def get_queryset(self):
        user = self.request.user
        comment = Comment1.objects.get(pk=self.kwargs['pk'])
        return Like1.objects.filter(liker1=user,comment1=comment)

    def perform_create(self, serializer):
        if self.get_queryset().exists():
            raise ValidationError('you liked this comment in past')
        serializer.save(liker1=self.request.user,comment1=Comment1.objects.get(pk=self.kwargs['pk']))#ADD MOKNAD METHOD performe_create haman kar add kardan ra mikonad
    def delete(self,request,*args,**kwargs):
        like = Like1.objects.filter(liker1=request.user,comment1=Comment1.objects.get(pk=self.kwargs['pk']))
        if like.exists():
            like.delete()
        raise ValidationError('this is not your like')

class Posst(APIView):#input data in browsable_api json exampe {"text1":"something"} text1 field name in model.py
    def post(self,request):
        serializers = CommentSerializer(data=request.data)
        if serializers.is_valid():
            serializers.save(author1=self.request.user)
            return Response(serializers.data,status=status.HTTP_201_CREATED)

class Sendlike(APIView):
    def post(self,request,pk):
        user = self.request.user
        comment = Comment1.objects.get(pk=pk)
        like = Like1.objects.filter(liker1=user,comment1=comment)
        serializers = LikeSerializer(data=request.data)
        if serializers.is_valid() & like.exists():
            print('xx')
            raise ValidationError('you like past time this comment')
        elif serializers.is_valid():
            serializers.save(Like1.objects.filter(liker1=user,comment1=comment))
            return Response(serializers.data,status=status.HTTP_200_OK)


import click
from asreviewlib.classifiers import SvmClassifier
from .._epilog import epilog

name = SvmClassifier.name

@click.command(epilog=epilog,
               help="Use Support Vector Machine classifier",
               name=f"cls:{name}")
@click.option("--c", "c",
              default=15.4,
              help="hyperparameter.",
              show_default=True,
              type=click.FLOAT)
@click.option("--class_weight", "class_weight",
              default=0.249,
              help="hyperparameter",
              show_default=True,
              type=click.FLOAT)
@click.option("-f", "--force", "force",
              help="Force setting the querier configuration, even if that me" +
              "ans overwriting a previous configuration.",
              is_flag=True)
@click.option("--gamma", "gamma",
              default="auto",
              help="hyperparameter",
              show_default=True,
              type=click.Choice(["auto", "scale"]))
@click.option("--kernel", "kernel",
              default="linear",
              help="hyperparameter",
              show_default=True,
              type=click.Choice(["linear", "rbf", "poly", "sigmoid"]))
@click.option("--seed", "seed",
              default=535,
              help="Random seed",
              show_default=True,
              type=click.INT)
@click.pass_obj
def svm_classifier(obj, c, class_weight, gamma, force, kernel, seed):
    if not force:
        assert obj.provided.classifier is False, "Attempted reassignment of classifier"
    obj.classifier.model = name
    obj.classifier.params = {
        "c": c,
        "class_weight": class_weight,
        "gamma": gamma,
        "kernel": kernel,
        "seed": seed
    }
    obj.provided.classifier = True


import typing as tp

from aiogram.types.reply_keyboard import (
    ReplyKeyboardMarkup,
)

class BaseKeyboardWithTextButtons(ReplyKeyboardMarkup):
    BUTTONS: list = list()

    @classmethod
    def create_with_buttons(cls, buttons: tp.List[str] = None, *args, **kwargs) -> ReplyKeyboardMarkup:
        keyboard = ReplyKeyboardMarkup(*args, resize_keyboard=True, **kwargs)
        if buttons:
            keyboard.add(*buttons)
        else:
            keyboard.add(*cls.BUTTONS)
        return keyboard

class PositiveNegativeUAKeyboard(BaseKeyboardWithTextButtons):
    BUTTONS = ["Так", "Ні"]


"""
这个脚本的目的对训练数据进行处理和压缩
生成最后的 4_compressed_training_data.json ，用于训练的数据
"""

import json

# 读取数据
with open('数据处理\\训练数据获取与处理\\3_training_data.json', 'r', encoding='utf-8') as f:
    training_data_dict = json.loads(f.read())

with open('数据处理\\处理到最后投入使用的数据\\输入神经元与序号.json', 'r', encoding='utf-8') as f:
    keyword_and_order_dict = json.loads(f.read())

new_data_list = []

for i in training_data_dict.keys():

    # 点击量过小的数据剔除掉
    if training_data_dict[i]['click_times'] <= 50:
        continue

    # 点击量过大也扔掉
    if training_data_dict[i]['click_times'] >= 1000:
        continue

    # 获取关键词列表
    keyword_list = training_data_dict[i]['keyword']

    # 用来装每一则训练数据
    training_datum_set = []

    # 遍历列表中每一则关键词
    for j in keyword_list:

        if keyword_and_order_dict.__contains__(j):

            # 规定training_datum_set中第一个元素为期望值，后面元素为每个词对应的位置，以达到压缩效果
            # 将keyword数据转化为对应编号存储
            training_datum_set.append(keyword_and_order_dict[j])

    # 遍历完成后
    else:
        # 如果数据量不为0
        if len(keyword_and_order_dict):

            # 在training_datum_set第一号元素插入click_times
            training_datum_set.insert(0, training_data_dict[i]['click_times'])

            # 最后完成
            new_data_list.append(training_datum_set)

# 写入数据
with open('数据处理\\训练数据获取与处理\\4_compressed_training_data.json', 'a+', encoding='utf-8') as f:
    f.write(json.dumps(new_data_list, ensure_ascii=False))


import sys
from collections import deque
si = sys.stdin.readline

n = int(si())
queue = deque([i for i in range(1, n + 1)])

while(len(queue) > 1):
    queue.popleft()
    temp = queue.popleft()
    queue.append(temp)

print(queue[0])


from flask import Flask, render_template, request
import subprocess

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def dashboard():
    if request.method == 'GET':
        result = None
    if request.method == 'POST':
        query = request.form['query']
        cmd = 'th generate-lines.lua \
            -path experiments/fullyconv/model_best_cpu.th7 \
            -sourcedict data/raw/tokenized.sen-que/dict.sen.th7 \
            -targetdict data/raw/tokenized.sen-que/dict.que.th7 \
            -beam 5'.split()
        proc = subprocess.run(cmd, stdout=subprocess.PIPE, input=query.encode())
        result = proc.stdout.decode().split('\t')[1]

    return render_template('index.html', result=result)

if __name__ == '__main__':
	app.run(host='0.0.0.0', debug=True, threaded=True)


from os import path
from glob import glob
from tqdm import tqdm

from matdb import msg
from matdb.utility import chdir
from matdb.transforms import _get_supers
from matdb.atoms import Atoms

def examples():
    """Prints examples of using the script to the console using colored output.
    """
    from matdb import msg
    script = "MATDB Supercell Generator"
    explain = ("When producing hessians with the Hessian group, a supercell "
               "needs to be selected. This script streamlines the selection "
               "process for multiple seeds and sizes.")
    contents = [(("Select supercells for all the seeds and sizes 32 and 64."),
                 "matdb_supercell.py * --sizes 32 64",
                 "")]
    required = ("Seed files in the `seed` directory.")
    output = ("")
    details = ("")
    outputfmt = ("")

    msg.example(script, explain, contents, required, output, outputfmt, details)

_script_options = {
    "seeds": {"help": ("File patterns for choosing seeds."),
              "nargs": '+'},
    "--sizes": {"help": ("Target cell sizes to find for."),
                "nargs": '+', "type": int, "required": True},
    }
"""dict: default command-line arguments and their
    :meth:`argparse.ArgumentParser.add_argument` keyword arguments.
"""

def _parser_options():
    """Parses the options and arguments from the command line."""
    #We have two options: get some of the details from the config file,
    import argparse
    import sys
    from matdb import base
    pdescr = "MATDB Supercell Selector"
    parser = argparse.ArgumentParser(parents=[base.bparser], description=pdescr)
    for arg, options in _script_options.items():
        parser.add_argument(arg, **options)

    args = base.exhandler(examples, parser)
    if args is None:
        return

    return args

def run(args):
    """Runs the matdb setup and cleanup to produce database files.
    """
    print("matdb  Copyright (C) 2019  HALL LABS")
    print("This program comes with ABSOLUTELY NO WARRANTY.")
    print("This is free software, and you are welcome to redistribute it under "
          "certain conditions.")
    if args is None:
        return

    targets = {}
    with chdir("seed"):
        for pattern in args["seeds"]:
            #Handle the default file type, which is vasp.
            if ':' in pattern:
                fmt, pat = pattern.split(':')
            else:
                fmt, pat = "vasp", pattern
            for filename in glob(pat):
                targets[filename] = Atoms(filename, format=fmt)

    result = {}
    for filename, at in tqdm(list(targets.items())):
        result[filename] = _get_supers(at, args["sizes"])

    items = [
        ("Filename", 20, "cokay"),
        ("Supercell", 40, "cstds"),
        ("Req.", 6, "cinfo"),
        ("Act.", 6, "cgens"),
        ("rmin", 8, "cerrs"),
        ("pg", 6, "cwarn")
    ]

    msg.blank(2)
    heading = '|'.join(["{{0: ^{0}}}".format(size).format(name)
                        for name, size, color in items])
    msg.arb(heading, [msg.cenum[i[2]] for i in items], '|')
    msg.std(''.join('-' for i in range(len(heading)+1)))
    for filename, hs in result.items():
        for size, hnf in hs.items():
            names = (filename, hnf.hnf.flatten().tolist(), size,
                     hnf.size, hnf.rmin, hnf.pg)
            text = '|'.join(["{{0: <{0}}}".format(item[1]).format(name)
                                for name, item in zip(names, items)])
            msg.arb(text, [msg.cenum[i[2]] for i in items], '|')
        msg.blank(2)

    return result

if __name__ == '__main__': # pragma: no cover
    run(_parser_options())


import re
from datetime import datetime

from django import forms
from django.utils import timezone

class BaseForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setup_bootstrap_class()

    def setup_bootstrap_class(self):
        for field_name, field in self.fields.items():
            if "class" in field.widget.attrs:
                class_list = [field.widget.attrs["class"]]
            elif (
                isinstance(field.widget, forms.RadioSelect)
                or isinstance(field.widget, forms.CheckboxInput)
                or isinstance(field.widget, forms.CheckboxSelectMultiple)
            ):
                class_list = ["custom-control-input"]
            else:
                class_list = ["form-control"]

            if self.has_error(field_name):
                class_list.append("is-invalid")

            field.widget.attrs["class"] = " ".join(class_list)

class SplitDateTimeWidget(forms.SplitDateTimeWidget):
    def value_from_datadict(self, data, files, name):
        date_str, time_str = super().value_from_datadict(data, files, name)

        if not date_str and not time_str:
            return

        value = (date_str or "") + (time_str or "")
        try:
            if self.is_HMS(time_str):
                return datetime.strptime(value, "%Y-%m-%d%H:%M:%S").astimezone(timezone.get_default_timezone())
            elif self.is_HM(time_str):
                return datetime.strptime(value, "%Y-%m-%d%H:%M").astimezone(timezone.get_default_timezone())
            return value
        except:
            return value

    def is_HMS(self, time_str):
        pattern = r"^((0?|1)[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$"
        return re.compile(pattern).match(time_str)

    def is_HM(self, time_str):
        pattern = r"^((0?|1)[0-9]|2[0-3]):[0-5][0-9]$"
        return re.compile(pattern).match(time_str)

    def decompress(self, value):
        try:
            return super().decompress(value.replace(second=0) if value else value)
        except:
            return value


import random, copy, sys, pygame
from pygame.locals import *
from random import randint
pygame.init()
pygame.display.set_caption('Primary Diablo 2 Gameplay')
BOARDWIDTH = 10  # how many spaces wide the board is
BOARDHEIGHT = 6 # how many spaces tall the board is
WINDOWWIDTH = 800 # width of the program's window, in pixels
WINDOWHEIGHT = 800 # height in pixels

DISPLAYSURF = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT))

FPS = 60 # frames per second to update the screen
global SPACESIZE
SPACESIZE = 56 # size of the tokens and individual board spaces in pixels
global XMARGIN
XMARGIN = int((WINDOWWIDTH - BOARDWIDTH * SPACESIZE) / 2)
global YMARGIN
YMARGIN = int((WINDOWHEIGHT - BOARDHEIGHT * SPACESIZE) / 2)

XRightSide = WINDOWWIDTH - XMARGIN
YBottomSide = WINDOWHEIGHT - YMARGIN
WHITE = (255, 255, 255)
BGCOLOR = (70,70,70)

listception = []
for x in range(BOARDWIDTH):
        listception.append([])
        for y in range(BOARDHEIGHT):
                listception[x].append([randint(0,0),randint(0,150),randint(200,255)])
                # if listception[x]>0 and listception[x-1][y][1] < listception[x][y][1] :
                #         if listception[x][y][1] - (listception[x-1][y][1]) > 6:
                #                 listception[x][y][1] +=6
                #                 if listception[x][y][1] > 150:
                #                         listception[x][y][1] = listception[x][y][1] -150

REDTOKENIMG = pygame.image.load('4row_red.png')
REDTOKENIMG = pygame.transform.smoothscale(REDTOKENIMG, (SPACESIZE, SPACESIZE))
SwordPic = pygame.image.load('Sword.gif').convert_alpha()
SwordPic = pygame.transform.scale2x(SwordPic)
SwordPic = pygame.transform.smoothscale(SwordPic, (SPACESIZE, SPACESIZE* 3))

TopazPic = pygame.image.load('Topaz.gif').convert_alpha()
TopazPic = pygame.transform.scale2x(TopazPic)
TopazPic = pygame.transform.smoothscale(TopazPic, (SPACESIZE, SPACESIZE))

BookPic = pygame.image.load('book.gif').convert_alpha()
BookPic = pygame.transform.scale2x(BookPic)
BookPic = pygame.transform.smoothscale(BookPic, (SPACESIZE, SPACESIZE*2))

ShieldPic = pygame.image.load('stormGuild.gif').convert_alpha()
ShieldPic = pygame.transform.scale2x(ShieldPic)
ShieldPic = pygame.transform.smoothscale(ShieldPic, (SPACESIZE*2, SPACESIZE*3))

SpikedPic = pygame.image.load('SpikedShield.gif').convert_alpha()
SpikedPic = pygame.transform.scale2x(SpikedPic)
SpikedPic = pygame.transform.smoothscale(SpikedPic, (SPACESIZE*2, SPACESIZE*3))

AerinPic = pygame.image.load('AerinShield.gif').convert_alpha()
AerinPic = pygame.transform.scale2x(AerinPic)
AerinPic = pygame.transform.smoothscale(AerinPic, (SPACESIZE*2, SPACESIZE*4))

SabrePic = pygame.image.load('LightSabre.gif').convert_alpha()
SabrePic = pygame.transform.scale2x(SabrePic)
SabrePic = pygame.transform.smoothscale(SabrePic, (SPACESIZE*2, SPACESIZE*3))

RunePic = pygame.image.load('OhmRune.png').convert_alpha()
RunePic = pygame.transform.scale2x(RunePic)
RunePic = pygame.transform.smoothscale(RunePic, (SPACESIZE*1, SPACESIZE*1))

OrbPic = pygame.image.load('Orb.gif').convert_alpha()
OrbPic = pygame.transform.scale2x(OrbPic)
OrbPic = pygame.transform.smoothscale(OrbPic, (SPACESIZE*1, SPACESIZE*3))

SteelPic = pygame.image.load('SteelArmor.gif').convert_alpha()
SteelPic = pygame.transform.scale2x(SteelPic)
SteelPic = pygame.transform.smoothscale(SteelPic, (SPACESIZE*2, SPACESIZE*3))

VictorPic = pygame.image.load('VictorArmor.gif').convert_alpha()
VictorPic = pygame.transform.scale2x(VictorPic)
VictorPic = pygame.transform.smoothscale(VictorPic, (SPACESIZE*2, SPACESIZE*3))

JavelinPic = pygame.image.load('Javelin.gif').convert_alpha()
JavelinPic = pygame.transform.scale2x(JavelinPic)
JavelinPic = pygame.transform.smoothscale(JavelinPic, (SPACESIZE*1, SPACESIZE*4))

s1x1 = [[0,0]]
s1x2 = [[0,0],[0,1]]
s1x3 = [[0,0],[0,1],[0,2]]
s1x4 = [[0,0],[0,1],[0,2],[0,3]]
s2x2 = [[0,0],[0,1],[1,1],[1,0]]
s2x3 = [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2]]
s2x4 = [[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3]]

itemList = [[s1x1,TopazPic],[s1x2,BookPic],[s1x3,SwordPic],[s2x3,ShieldPic],[s2x3,SpikedPic]\
,[s2x4,AerinPic],[s2x3,SabrePic],[s1x1,RunePic],[s1x3,OrbPic],[s2x3,SteelPic],[s2x3,VictorPic],[s1x4,JavelinPic]]

nameList = ['TopazPic','BookPic','SwordPic','ShieldPic','SpikedPic','AerinPic','SabrePic','RunePic','OrbPic','SteelPic','VictorPic','JavelinPic']
picList = [TopazPic,BookPic,SwordPic,ShieldPic,SpikedPic,AerinPic,SabrePic,RunePic,OrbPic,SteelPic,VictorPic,JavelinPic]

global testList
testList = [[2,6],[0,5],[0,2],[0,3]]

objectList = []
boardList   = [[]] * BOARDWIDTH

NewItem = False

for x in range(BOARDWIDTH):
    boardList[x] = [0]* BOARDHEIGHT

class Object():
    def __init__(self):

        global XMARGIN
        global YMARGIN
        global SPACESIZE
        global testList
        self.SpotList = []
        self.Map = []
        self.doOnce = True

    def func(self,xf,yf,XOffset,YOffset,boardList,mapList,Pic,ItemIndex):

        if self.doOnce:
            self.SpotList = copy.copy(boardList)
            #                   |
            #                   | this F'er
            #                   V
            self.Map = copy.copy(mapList)

            self.doOnce = False
        self.Index = ItemIndex
        self.Pic = Pic
        self.column = int((xf - XOffset - (XMARGIN)) / SPACESIZE)
        self.row    = int((yf - YOffset - (YMARGIN)) / SPACESIZE)

        self.posX = (self.column * SPACESIZE) + XMARGIN
        self.posY = (self.row    * SPACESIZE) + YMARGIN

def main():
    CurrentItem = 0
    NewItem = False
    xh = 0
    yh = 0

    while True:

        xp, yp = pygame.mouse.get_pos()

        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN and event.button == 3:
                #print objectList
                if NewItem == True:
                    NewItem = False
                else:
                    NewItem = True

            if ((xp > XMARGIN) and (xp < (WINDOWWIDTH-XMARGIN))) and ((yp > YMARGIN) and (yp < (WINDOWHEIGHT-YMARGIN))):

                if event.type == MOUSEBUTTONDOWN and (event.button == 4 or event.button == 5):
                    NewItem = True
                    if CurrentItem == len(itemList)-1:
                        CurrentItem = 0
                    else:
                        CurrentItem += 1
                    xh, yh = hoverPlace(CurrentItem)
                    XSelect = ((xh * 2) - SPACESIZE)/2
                    YSelect = ((yh * 2) - SPACESIZE)/2

                if event.type == MOUSEBUTTONDOWN and event.button == 1:
                    Occupied = False
                    ObjectSwitch = True
                    ObjectInSpot = 0

                    if NewItem:
                        currentList = copy.deepcopy(itemList[CurrentItem][0])
                        objectList.append(Object())
                        objectList[-1].func(xp,yp,XSelect,YSelect,copy.deepcopy(itemList[CurrentItem][0]), currentList, itemList[CurrentItem][1],CurrentItem)
                        Obj = objectList[-1]

                        for spot in Obj.SpotList:
                            SpotX = (spot[0] + Obj.column)
                            SpotY = (spot[1] + Obj.row)

                            if (SpotX > -1 and SpotX < BOARDWIDTH) and (SpotY > -1 and SpotY < BOARDHEIGHT):

                                if boardList[SpotX][SpotY] != 0:
                                    Occupied = True

                                if ObjectInSpot == 0:
                                    ObjectInSpot = boardList[SpotX][SpotY]

                                if ((ObjectInSpot != boardList[SpotX][SpotY]) and (ObjectInSpot != 0)) and boardList[SpotX][SpotY] != 0:
                                    ObjectSwitch = False
                                    Occupied = True
                                    #print "NEIN!"

                                #print ObjectInSpot

                                # if ObjectInSpot == boardList[SpotX][SpotY] and ObjectInSpot != 0:
                                #     ObjectSwitch = True

                                # if ObjectInSpot == 0:
                                #     ObjectSwitch = False

                            else:
                                Occupied = True
                                ObjectSwitch = False
                                #print "NIEMALS!"

                        #Placing New Object
                        if Occupied == False:
                            count = 0
                            for spot in Obj.SpotList:
                                SpotX = (spot[0] + Obj.column)
                                SpotY = (spot[1] + Obj.row)

                                boardList[SpotX][SpotY] = Obj

                                Obj.Map[count][0] = SpotX
                                Obj.Map[count][1] = SpotY

                                count += 1
                                NewItem = False

                        else:
                            del objectList[-1]

                    #Picking Up Object
                    elif NewItem == False:
                        column = (int)((xp - XMARGIN)/SPACESIZE)
                        row    = (int)((yp - YMARGIN)/SPACESIZE)

                        Map = boardList[column][row].Map
                        for spot in Map:
                            ExiledObject = boardList[spot[0]][spot[1]]
                            boardList[spot[0]][spot[1]] = 0

                        ExiledIndex = objectList.index(ExiledObject)
                        NewItem = True
                        CurrentItem = ExiledObject.Index
                        del objectList[ExiledIndex]

                    #Switching Objects
                    if Occupied == True and ObjectSwitch == True:
                        for spot in Obj.SpotList:
                            SpotX = (spot[0] + Obj.column)
                            SpotY = (spot[1] + Obj.row)
                            if boardList[SpotX][SpotY] != 0:
                                Map = boardList[SpotX][SpotY].Map

                        column = (xp - XMARGIN) / SPACESIZE
                        row = (yp - YMARGIN) / SPACESIZE

                        for spot in Map:
                            ExiledObject = boardList[spot[0]][spot[1]]
                            boardList[spot[0]][spot[1]] = 0

                        ExiledIndex = objectList.index(ExiledObject)

                        CurrentItemTemp = ExiledObject.Index
                        del objectList[ExiledIndex]

                        objectList.append(Object())
                        objectList[-1].func(xp, yp, XSelect, YSelect, copy.deepcopy(itemList[CurrentItem][0]),currentList, itemList[CurrentItem][1], CurrentItem)
                        Obj = objectList[-1]

                        count = 0
                        for spot in Obj.SpotList:
                            SpotX = (spot[0] + Obj.column)
                            SpotY = (spot[1] + Obj.row)

                            boardList[SpotX][SpotY] = Obj

                            Obj.Map[count][0] = SpotX
                            Obj.Map[count][1] = SpotY

                            count += 1

                        #currentList = copy.deepcopy(itemList[CurrentItem][0])

                        CurrentItem = CurrentItemTemp

                        NewItem = True

        DISPLAYSURF.fill(BGCOLOR)
        for xb in range(BOARDWIDTH):
            for yb in range(BOARDHEIGHT):
                pygame.draw.rect(DISPLAYSURF, listception[xb][yb],(XMARGIN + (xb * SPACESIZE), YMARGIN + (yb * SPACESIZE), SPACESIZE, SPACESIZE))
        if len(objectList) > 0:
            for obj in objectList:
                DISPLAYSURF.blit(obj.Pic, (obj.posX, obj.posY))

        #xh, yh = hoverPlace(CurrentItem)
        if NewItem == True:
            DISPLAYSURF.blit(itemList[CurrentItem][1], (xp -xh, yp -yh))

        pygame.display.update()

def hoverPlace(CurrentItem):

    Rect = pygame.Surface.get_rect(itemList[CurrentItem][1])
    xh = Rect[2]
    yh = Rect[3]

    return xh / 2, yh / 2

main()


"""
==============================================
Face completion with a multi-output estimators
==============================================

This example shows the use of multi-output estimator to complete images.
The goal is to predict the lower half of a face given its upper half.

The first column of images shows true faces. The next columns illustrate
how extremely randomized trees, k nearest neighbors, linear
regression and ridge regression complete the lower half of those faces.

"""

import matplotlib.pyplot as plt
import numpy as np

from sklearn.datasets import fetch_olivetti_faces
from sklearn.ensemble import ExtraTreesRegressor
from sklearn.linear_model import LinearRegression, RidgeCV
from sklearn.neighbors import KNeighborsRegressor
from sklearn.utils.validation import check_random_state

# Load the faces datasets
data, targets = fetch_olivetti_faces(return_X_y=True)

train = data[targets < 30]
test = data[targets >= 30]  # Test on independent people

# Test on a subset of people
n_faces = 5
rng = check_random_state(4)
face_ids = rng.randint(test.shape[0], size=(n_faces,))
test = test[face_ids, :]

n_pixels = data.shape[1]
# Upper half of the faces
X_train = train[:, : (n_pixels + 1) // 2]
# Lower half of the faces
y_train = train[:, n_pixels // 2 :]
X_test = test[:, : (n_pixels + 1) // 2]
y_test = test[:, n_pixels // 2 :]

# Fit estimators
ESTIMATORS = {
    "Extra trees": ExtraTreesRegressor(
        n_estimators=10, max_features=32, random_state=0
    ),
    "K-nn": KNeighborsRegressor(),
    "Linear regression": LinearRegression(),
    "Ridge": RidgeCV(),
}

y_test_predict = dict()
for name, estimator in ESTIMATORS.items():
    estimator.fit(X_train, y_train)
    y_test_predict[name] = estimator.predict(X_test)

# Plot the completed faces
image_shape = (64, 64)

n_cols = 1 + len(ESTIMATORS)
plt.figure(figsize=(2.0 * n_cols, 2.26 * n_faces))
plt.suptitle("Face completion with multi-output estimators", size=16)

for i in range(n_faces):
    true_face = np.hstack((X_test[i], y_test[i]))

    if i:
        sub = plt.subplot(n_faces, n_cols, i * n_cols + 1)
    else:
        sub = plt.subplot(n_faces, n_cols, i * n_cols + 1, title="true faces")

    sub.axis("off")
    sub.imshow(
        true_face.reshape(image_shape), cmap=plt.cm.gray, interpolation="nearest"
    )

    for j, est in enumerate(sorted(ESTIMATORS)):
        completed_face = np.hstack((X_test[i], y_test_predict[est][i]))

        if i:
            sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j)

        else:
            sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j, title=est)

        sub.axis("off")
        sub.imshow(
            completed_face.reshape(image_shape),
            cmap=plt.cm.gray,
            interpolation="nearest",
        )

plt.show()


from aiogram_dialog import Dialog

from aiogram_dialog import Window
from aiogram_dialog.widgets.input import MessageInput
from aiogram_dialog.widgets.kbd import Checkbox, Button
from aiogram_dialog.widgets.text import Const

from handlers.users.admin_panel import bool_settings, button_settings, set_text_ad
from loader import registry
from states.admin_panel import StatesAP
from utils.dbworker import get_settings

async def settings_dialog():
    settings = await get_settings()
    window_settings = []

    for k, v in settings.items():
        if v['type'] == 'bool':
            window_settings.append(
                Checkbox(
                    Const(f"✓  {v['view_name']}"),
                    Const(f" {v['view_name']}"),
                    id=k,
                    default=v['value'],
                    on_state_changed=bool_settings,
                )
            )
        elif v['type'] == 'text':
            window_settings.append(
                Button(
                    Const(f"{v['view_name']}"),
                    id=k,
                    on_click=button_settings
                )
            )

    registry.register(
        Dialog(
            Window(
                Const("Настройки:"),
                *window_settings,
                Button(
                    Const("Закрыть меню"),
                    id='delete',
                    on_click='delete'
                ),
                state=StatesAP.start
            ),
            Window(
                Const("Введи текст:"),
                MessageInput(set_text_ad),
                state=StatesAP.set_text
            )
        )
    )


import numpy as np
import yaml

def load_data(yaml_file_path):
    with open(yaml_file_path,'r') as f:
        content = yaml.load(f.read())
    c = type('myobj', (object,), content)
    return c

def get_monthly_mortgage(
    loan_amount,
    loan_interest_rate,
    amortized_over_how_many_years,):

    monthly_mortgage_payment_markdown=\
    '''
    \begin{equation}
    c = \frac{rP(1+r)^N}{(1+r)^N-1}     ,r \neq 0;
    \end{equation}
    c = monthly payment
    N = number of monthly payments
    P = amount borrowed
    r = monthly interest rate
    r = (R/12)/100
    R = annual interest rate
    https://en.wikipedia.org/wiki/Mortgage_calculator
    '''

    monthly_interest_rate = loan_interest_rate/12
    amortized_over_how_many_months = 12*amortized_over_how_many_years
    monthly_mortgage_payment = \
        (monthly_interest_rate*loan_amount*(1+monthly_interest_rate)**amortized_over_how_many_months)/\
        ((1+monthly_interest_rate)**amortized_over_how_many_months-1)

    return monthly_mortgage_payment

def calculate(c, is_print=False):

    c.total_project_cost = \
        c.purchase_price \
        + c.purchase_closing_cost \
        + c.estimated_repair_cost

    c.down_payment_dollar = c.purchase_price*c.down_payment_of_purchase_price

    if c.down_payment_of_purchase_price == 1:
        c.loan_amount = 0
        c.monthly_mortgage_payment = 0
    else:
        c.loan_amount = \
            c.purchase_price \
            - c.down_payment_dollar \
            - c.purchase_closing_cost

        c.monthly_mortgage_payment = get_monthly_mortgage(
            c.loan_amount,
            c.loan_interest_rate,
            c.amortized_over_how_many_years,)

    c.total_cash_needed = \
        c.down_payment_dollar \
        + c.estimated_repair_cost \
        + c.purchase_closing_cost \
        + c.point_charged_by_lender*c.loan_amount \
        + c.other_charges_from_the_lender

    if getattr(c,'line_of_credit',None):
        c.monthly_line_of_credit_payment = get_monthly_mortgage(
            c.total_cash_needed,
            c.line_of_credit['loan_interest_rate'],
            c.line_of_credit['amortized_over_how_many_years'])
        c.line_of_credit_payment = 0
    else:
        c.monthly_line_of_credit_payment = 0

    c.monthly_income = \
        c.total_gross_monthly_rent \
        + c.other_montly_income

    c.annual_property_tax = c.annual_property_taxes_prct*c.purchase_price
    c.monthly_property_tax = c.annual_property_tax / 12

    c.monthly_expenses = \
        + c.monthly_line_of_credit_payment \
        + c.monthly_mortgage_payment \
        + c.monthly_property_tax \
        + c.fixed_monthly_landlord_paid_expenses_electricity \
        + c.fixed_monthly_landlord_paid_expenses_water_sewer \
        + c.fixed_monthly_landlord_paid_expenses_pmi \
        + c.fixed_monthly_landlord_paid_expenses_garbage \
        + c.fixed_monthly_landlord_paid_expenses_hoas \
        + c.fixed_monthly_landlord_paid_expenses_insurance \
        + c.repairs_and_maintenance * c.monthly_income \
        + c.capital_expenditures * c.monthly_income \
        + c.management_fees * c.monthly_income \
        + c.vacancy * c.monthly_income\
        + c.other_monthly_expenses

    c.monthly_cashflow = c.monthly_income - c.monthly_expenses

    c.net_operating_income = \
        12 * ( c.monthly_income \
        - c.monthly_expenses
        + c.monthly_line_of_credit_payment \
        + c.monthly_mortgage_payment \
        )

    c.purchase_cap_rate_prct = 100*c.net_operating_income/c.purchase_price

    if is_print:
        key_list = [
            # entered
            'purchase_price',
            'purchase_closing_cost',
            'estimated_repair_cost',
            # computed/
            'total_project_cost',
            'down_payment_dollar',
            'loan_amount',
            # entered
            'point_charged_by_lender',
            # computed
            'monthly_line_of_credit_payment',
            'monthly_mortgage_payment',
            'total_cash_needed',
            'monthly_income',
            'monthly_expenses',
            'monthly_cashflow',
            'net_operating_income',
            'purchase_cap_rate_prct',
        ]
        for k in key_list:
            if k.endswith('_prct'):
                print('{} {:1.2f}'.format(k,getattr(c,k)))
            else:
                print('{} {:1.0f}'.format(k,getattr(c,k)))

    return c


"""
    Simple resources monitoring script

    Author: L1ttl3S1st3r
    Date: 14 April 2020
"""
from psutil import cpu_percent
from psutil import cpu_count
from psutil import virtual_memory

OUTPUT_DELAY = 0.4

def format_columns(columns):
    formatted_columns = ["{0:^23}".format(column) for column in columns]
    return '|'.join(formatted_columns)

def resources_header():
    columns = [f'cpu {number+1} usage (%)' for number in range(cpu_count())]
    columns += ['memory occupied (%)']

    return format_columns(columns)

def resourses_row():
    columns = cpu_percent(interval=OUTPUT_DELAY, percpu=True)
    columns += [virtual_memory().percent]

    return format_columns(columns)

if __name__ == '__main__':
    print(resources_header())
    while True:
        print(resourses_row())


from tkinter import *
import PyPDF2
from tkinter import filedialog,messagebox
import pyttsx3
import pygame
import pymongo
import gridfs
import logging
import os

logging.basicConfig(filename="audiobook.log", level=logging.INFO,format="%(asctime)s %(levelname)s %(message)s")
root = Tk()
root.title('ineuron-audio-books')
root.geometry("500x500")

location = "E:\\ineuron\\pyaudiobook\\media\\"

def delete_audio():
    '''
    This Function is used to delete the Audiobook present in the media folder
    This function does not require any argument to be passed during the call
    It delete the Active or selected audiobook when called
    It does not return anything
    :return: NONE
    '''
    try:
        file_to_delete = book_box.get(ACTIVE)
        book_box.delete(ACTIVE)
        os.remove(location+file_to_delete)
        logging.info(f"{file_to_delete} have been removed")

    except WindowsError:
        messagebox.showinfo(title= "CANNOT DELETE THE FILE" ,message="The File cannot be deleted because it is currently is being used try restarting the app")

    except Exception as e:
        logging.error(e)

def load_database():
    '''
    This function is Used to Load the audiobook stored in the MongoDB
    This function does not require any argument to be passed during the call
    It download all the files that are not prensent in the Media Folder when called
    It does not return anything
    :return: NONE
    '''
    try:
        list_of_files_present_in_media = os.listdir(location)
        db=mongo_conn()
        for i in db.fs.files.find():
            if i['filename']  not in list_of_files_present_in_media:
                data = i
                my_id = data['_id']
                fs = gridfs.GridFS(db)
                outputdata = fs.get(my_id).read()
                download_location = location +i['filename']
                output = open(download_location, "wb")
                output.write(outputdata)
                output.close()
                logging.info(f"the file is not found so {i} downloaded from the mongoDB")
        load_audio()
    except Exception as e:
        logging.error(e)

def load_audio():
    '''
    This function is Used to Load the audiobook stored in the Media Folder
    This function does not require any argument to be passed during the call
    It does not return anything
    :return: NONE
    '''
    try:
        list_of_files_present_in_media = os.listdir(location)
        list_of_files_Displaying = book_box.get(0,END)
        for i in list_of_files_present_in_media:
            if ".wav" in i and i not in list_of_files_Displaying:
                book_box.insert(END,i)
    except Exception as e:
        logging.error(e)

def mongo_conn():
    '''
    This Function is used to connect the Program to MONGODB
    Its only functionality is to create a connection with MONGODB
    It returns the database from the MongoDB in which the audiobooks are stored
    :return:<class 'pymongo.database.Database'>
    '''
    try:
        conn = pymongo.MongoClient( 'mongodb://localhost:27017')
        logging.info("MongoDB is connected")
        return conn['pyaudio']
    except Exception as e:
        logging.error(e)

def save_audio(audio_file):
    '''
    This Function is Used to save the Audiobook
    The Audiobooks are stored in the MONGODB
    It takes the help of GRIDFS to store the audio file
    :param audio_file: <class 'str'> Name and Location of the File
    :return: NONE
    '''
    try:
        db = mongo_conn()
        file_data = open(audio_file, "rb")
        data = file_data.read()
        fs = gridfs.GridFS(db)
        fs.put(data, filename = audio_file)
        logging.info("data saved in the data base")
    except Exception as e:
        logging.error(e)

def play_book():
    '''
    This function is Used to provide functionality to the Play button
    This is done with the help of pygame module
    :return: NONE
    '''
    try:
        os.chdir(location)
        book = book_box.get(ACTIVE)
        pygame.mixer.music.load(book)
        pygame.mixer.music.play(loops = 0)
        logging.info(f"the Play function is used and {book} is played")

    except Exception as e:
        logging.error(e)
def stop_book():
    '''
    This function is Used to provide functionality to the STOP button
    This is done with the help of pygame module
    :return: NONE
    '''
    try:
        pygame.mixer.music.stop()
        book_box.selection_clear(ACTIVE)
        logging.info(f"the Stop is called")
    except EXCEPTION as e:
        logging.error(e)

global paused
paused =False

def pause(is_paused):
    '''
    This function is Used to provide functionality to the STOP button
    This is done with the help of pygame module
    :param is_paused: <class 'bool'>
    :return: NONE
    '''
    global paused
    paused = is_paused
    try:
        if paused:
            pygame.mixer.music.unpause()
            paused = False
            logging.info("The audio is paused")
        else:
            pygame.mixer.music.pause()
            paused = True
            logging.info("The audio is continued")
    except Exception as e:
        logging.error(e)

def Text_to_speech(file_content, open_file):
    '''
    This Function is used to convert the PDF file to an audio File
    The Pyttsx3 module is used to convert text to speech
    the converted speech is then saved in media folder
    :param file_content: <class 'str'> text present in the File
    :param open_file:<class 'str'> file name with location
    :return: NONE
    '''
    try:
        engine = pyttsx3.init()
        file_name = open_file.split("/")[-1]
        book_name = file_name.replace('.pdf', '.wav')
        logging.info("the pdf is converted")
        os.chdir(location)
        engine.save_to_file(file_content,book_name)
        engine.runAndWait()
        logging.info("the audiobook is saved")
        book_box.insert(END,book_name)
        save_audio(book_name)
    except Exception as e:
        logging.error(e)

def open_pdf():
    '''
    This function is used to open and extract the text from the PDF file
    The PYPDF2 module is used in this function
    :return: NONE
    '''
    try:
        open_file = filedialog.askopenfilename(
            initialdir="E:\\Downloads\\",
            title = "Open PDF File",
            filetypes=([('PDF Files', '*.pdf')]))
        page_text =''
        list_of_book_display = book_box.get(0, END)
        if open_file:
            n = open_file.split("/")[-1].replace(".pdf", '.wav')
            if n not in list_of_book_display:
                pdf_file = PyPDF2.PdfFileReader(open_file)
                num_page = pdf_file.numPages
                for i in range(num_page):
                    page = pdf_file.getPage(i)
                    page_text += page.extractText()
                logging.info(f"The PDF is opened {open_file}")
                Text_to_speech(page_text,open_file)

    except Exception as e:
        logging.error(e)
try:
    # creation of a menu
    my_menu = Menu(root)
    root.config(menu=my_menu)

    # adding drop downs
    file_menu = Menu(my_menu, tearoff=False)
    my_menu.add_cascade(label='File', menu=file_menu)
    file_menu.add_command(label='Open', command=open_pdf)

    file_menu.add_separator()
    file_menu.add_command(label='Delete', command=delete_audio)

    file_menu.add_separator()
    file_menu.add_command(label='Load From DB', command=load_database)

    file_menu.add_separator()
    file_menu.add_command(label='Exit', command=root.quit)

    pygame.mixer.init()

    book_box = Listbox(root, bg="black", fg='white', width=60)
    book_box.pack(pady=20)

    play_btn_img = PhotoImage(file='audio button images/play50.png')
    pause_btn_img = PhotoImage(file='audio button images/pause50.png')
    stop_btn_img = PhotoImage(file='audio button images/stop50.png')

    control_frame = Frame(root)
    control_frame.pack()
    load_audio()
    play_btn = Button(control_frame, image=play_btn_img, borderwidth=0, command=play_book)
    pause_btn = Button(control_frame, image=pause_btn_img, borderwidth=0, command=lambda: pause(paused))
    stop_btn = Button(control_frame, image=stop_btn_img, borderwidth=0, command=stop_book)

    play_btn.grid(row=0, column=2, padx=10)
    pause_btn.grid(row=0, column=3, padx=10)
    stop_btn.grid(row=0, column=4, padx=10)
    logging.info("The application is created")

    root.mainloop()
except Exception as e:
    logging.error(e)


import matplotlib.pyplot as plt
plt.style.use('ggplot')#这里我使用的是ggplot风格
customers = ['ABC','DEF','GHI','JKL','MNO']#横轴
customers_index = range(len(customers))
sale_amounts = [127,90,201,111,232]
fig = plt.figure()
#添加一个子图1，1，1表示创建一个一行一列的子图
ax1 = fig.add_subplot(1,1,1)
#customers_index设置条形左侧在x轴上的坐标，sale_amounts设置条形的高度，align='center'设置条形与标签中间对齐，color即为设置颜色。
ax1.bar(customers_index,sale_amounts,align='center',color='darkblue')
#设置刻度线位置在x轴底部和y轴左侧，使图形的上部和右侧不显示刻度线
ax1.xaxis.set_ticks_position('bottom')
ax1.yaxis.set_ticks_position('left')
#rotation=0表示刻度标签是水平的，fontsize = 'small'将刻度标签的字体设为小字体
plt.xticks(customers_index,customers,rotation=0,fontsize = 'small')
plt.xlabel('Custmoer Name')
plt.ylabel('Sale Amount')
plt.title('Sale Amount per Customer')
#dpi=400设置图形分辨率，bbox_inches = 'tight'表示保存图片时，将四周的空白去掉
plt.savefig('bar_plot.png',dpi=400,bbox_inches = 'tight')
plt.show()