from modelo.direccion import Direccion
from modelo.estudiante_nacional import EstudianteNacional
from modelo.servicio_residencia import ServicioResidencia
from vista.gestionar_ests_nacs import CRUDEstsNacs

class PresentadorEstudiantesNacionales:
    def __init__(self, repo):
        self.__repositorio = repo
        self.__servicio_residencia = ServicioResidencia(self.__repositorio)

    def iniciar(self):
        self.__vista = CRUDEstsNacs(self)
        self.cargar_datos()
        self.__vista.show()

    def cargar_datos(self):
        self.__vista.vaciar_tabla()
        for est_nac in self.__repositorio.lista_ests_nacionales():
            contrato = 'No'
            if est_nac.tiene_contrato:
                contrato = 'Sí'
            i = self.__vista.tabla_est.rowCount()
            self.__vista.tabla_est.insertRow(i)
            self.__vista.agregar_elemento_tabla(i, 0, est_nac.nombre)
            self.__vista.agregar_elemento_tabla(i, 1, est_nac.ci)
            self.__vista.agregar_elemento_tabla(i, 2, str(est_nac.edad()))
            self.__vista.agregar_elemento_tabla(i, 3, est_nac.sexo)
            self.__vista.agregar_elemento_tabla(i, 4, est_nac.carrera)
            self.__vista.agregar_elemento_tabla(i, 5, est_nac.facultad)
            self.__vista.agregar_elemento_tabla(i, 6, str(est_nac.num_becado))
            self.__vista.agregar_elemento_tabla(i, 7, str(est_nac.albergue))
            self.__vista.agregar_elemento_tabla(i, 8, str(est_nac.cuarto))
            self.__vista.agregar_elemento_tabla(i, 9, str(est_nac.anio))
            self.__vista.agregar_elemento_tabla(i, 10, str(est_nac.direccion))
            self.__vista.agregar_elemento_tabla(i, 11, contrato)
        self.__vista.tabla_est.resizeColumnsToContents()

    def insertar_est_nac(self):
        try:
            self.__vista.validar_controles()
            nombre = self.__vista.valor_nombre
            ci = self.__vista.valor_ci
            sexo = self.__vista.valor_sexo
            carrera = self.__vista.valor_carrera
            facultad = self.__vista.valor_facultad
            num_becado = self.__vista.valor_num_becado
            num_albergue = self.__vista.valor_num_albergue
            num_cuarto = self.__vista.valor_num_cuarto
            anio = self.__vista.valor_anio_esc
            calle = self.__vista.valor_calle
            numero = self.__vista.valor_numero
            reparto = self.__vista.valor_reparto
            mun = self.__vista.valor_municipio
            prov = self.__vista.valor_provincia
            tiene_contrato = self.__vista.valor_tiene_trans
            direccion = Direccion(calle, numero, reparto, mun, prov)
            est = EstudianteNacional(nombre, ci, sexo, carrera, facultad, num_becado, num_albergue, num_cuarto, anio, direccion, tiene_contrato)
            self.__repositorio.insertar_estudiante(est)
            self.cargar_datos()
            self.__vista.restablecer_controles()
        except Exception as e:
            self.__vista.mostrar_error(e.args[0])

    def actualizar_est_nac(self):
        try:
            ind = self.__vista.tabla_est.currentRow()
            if ind == -1:
                raise Exception('Debe seleccionar una fila para actualizarla.')
            ci_ant = self.__vista.tabla_est.item(ind, 1).text()

            self.__vista.validar_controles()
            nombre = self.__vista.valor_nombre
            ci = self.__vista.valor_ci
            sexo = self.__vista.valor_sexo
            carrera = self.__vista.valor_carrera
            facultad = self.__vista.valor_facultad
            num_becado = self.__vista.valor_num_becado
            num_albergue = self.__vista.valor_num_albergue
            num_cuarto = self.__vista.valor_num_cuarto
            anio = self.__vista.valor_anio_esc
            calle = self.__vista.valor_calle
            numero = self.__vista.valor_numero
            reparto = self.__vista.valor_reparto
            mun = self.__vista.valor_municipio
            prov = self.__vista.valor_provincia
            tiene_contrato = self.__vista.valor_tiene_trans
            direccion = Direccion(calle, numero, reparto, mun, prov)
            est = EstudianteNacional(nombre, ci, sexo, carrera, facultad, num_becado, num_albergue, num_cuarto, anio, direccion, tiene_contrato)
            self.__repositorio.actualizar_estudiante(ci_ant, est)
            self.cargar_datos()
            self.__vista.restablecer_controles()
        except Exception as e:
            self.__vista.mostrar_error(e.args[0])

    def eliminar_est_nac(self):
        try:
            ind = self.__vista.tabla_est.currentRow()
            if ind == -1:
                raise Exception('Debe seleccionar una fila para eliminarla.')
            ci = self.__vista.tabla_est.item(ind, 1).text()

            self.__repositorio.eliminar_estudiante(ci)
            self.cargar_datos()
            self.__vista.restablecer_controles()
        except Exception as e:
            self.__vista.mostrar_error(e.args[0])

    def llenar_formulario_x_tabla(self):
        ind = self.__vista.tabla_est.currentRow()
        if ind != -1:
            nombre = self.__vista.tabla_est.item(ind, 0).text()
            ci = self.__vista.tabla_est.item(ind, 1).text()
            sexo = self.__vista.tabla_est.item(ind, 3).text()
            carrera = self.__vista.tabla_est.item(ind, 4).text()
            facultad = self.__vista.tabla_est.item(ind, 5).text()
            num_becado = self.__vista.tabla_est.item(ind, 6).text()
            num_albergue = self.__vista.tabla_est.item(ind, 7).text()
            num_cuarto = self.__vista.tabla_est.item(ind, 8).text()
            anio = self.__vista.tabla_est.item(ind, 9).text()
            direccion = self.__vista.tabla_est.item(ind, 10).text().split(',')
            tiene_reparto = False
            if len(direccion) == 3:
                calle, mun, prov = direccion
            else:
                tiene_reparto = True
                calle, reparto, mun, prov = direccion
            direccion = calle.split('#')
            calle, numero = direccion
            tiene_contrato = True
            if self.__vista.tabla_est.item(ind, 11).text() == 'No':
                tiene_contrato = False
            self.__vista.valor_nombre = nombre
            self.__vista.valor_ci = ci
            self.__vista.valor_sexo = sexo
            self.__vista.valor_carrera = carrera
            self.__vista.valor_facultad = facultad
            self.__vista.valor_num_becado = int(num_becado)
            self.__vista.valor_num_albergue = int(num_albergue)
            self.__vista.valor_num_cuarto = int(num_cuarto)
            self.__vista.valor_anio_esc = int(anio)
            self.__vista.valor_calle = calle.strip()
            self.__vista.valor_numero = numero.strip()
            if tiene_reparto:
                self.__vista.valor_reparto = reparto.strip()[5:].strip()
            else:
                self.__vista.valor_reparto = ''
            self.__vista.valor_municipio = mun.strip()
            self.__vista.valor_provincia = prov.strip()
            self.__vista.valor_tiene_trans = tiene_contrato


import re
from PIL import Image

#选出数量最多的100个标签
def select_100(path):

    #path: label文件的路

    with open(path,'r') as f:
        pattern = re.compile(r'\s\d{1,3}')
        labels = [0]*375
        line = f.readlines()
        for i in range(len(line)):
            match = pattern.findall(line[i])
            for x in match:
                labels[int(x)] += 1
        ran = list(range(375))
        dicts = dict(zip(ran, labels))
        f.close()
        res = sorted(dicts.items(), key=lambda d: d[1], reverse=True)
        return res[:100]
#print(len(select_100('./labels/training_label')))


#coding=UTF-8
'''
Created on 2012-10-12

@author: s00228753
'''
import os,sys

#===============================================================================
# 访问控制列表
#===============================================================================
class ACL(object):

    def __init__(self, owner, grants):
        self.owner = owner     #资源拥有者
        self.entries = grants  #访问控制列表

    #===========================================================================
    # 添加授权对象
    #===========================================================================
    def add_grant(self, grant):
        self.entries.append(grant)

    #===========================================================================
    # 将访问控制列表转换为xml字符串  保存到文件中
    # @return String 返回文件的路径
    #===========================================================================
    def to_xml(self):

        if not self.owner:
            raise Exception("Invalid AccessControlList: missing an S3 Owner")

        str_list = []
        str_list.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>")
        str_list.append("<AccessControlPolicy xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Owner><ID>")
        str_list.append(self.owner.owner_id + "</ID><DisplayName>" + self.owner.owner_name + "</DisplayName>")
        str_list.append("</Owner><AccessControlList>")

        for acl in self.entries:
            grantee = acl.grantee
            permission = acl.permission
            str_list.append("<Grant>" + grantee.to_xml() + "<Permission>" + str(permission) + "</Permission></Grant>")

        str_list.append("</AccessControlList></AccessControlPolicy>")

        s = ''.join(item for item in str_list)

        path = os.path.abspath(os.path.dirname(sys.argv[0]))
        with open(path + "\\acl.xml", 'wb') as f:
            f.write(s)

        return path + "\\acl.xml"  #返回文件的路径名


# -*- coding: utf-8 -*-
"""
Created on Fri Mar 13 00:38:48 2020

@author: meizihang
"""

# 加载相关库
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_curve
import pandas as pd
import numpy as np
import random
import math
import warnings
warnings.filterwarnings("ignore")
# 读取数据
data = pd.read_csv('Acard_reject.txt')
data.sample(5)

# 有真实标签
kgb = data[data['bad_ind']!=-1].copy()
# 无标签拒绝样本
reject = data[data['bad_ind']==-1].copy()
# 所有样本
agb = data.copy()
# 指定变量名，使用LR模型进行拟合
feature_lst = ['person_info', 'finance_info',
                  'credit_info', 'act_info']
x = kgb[feature_lst]
y = kgb['bad_ind']
lr_model = LogisticRegression(C=0.1)
lr_model.fit(x, y)

# 负样本概率，越大越可能是负样本
reject['y_pred'] = lr_model.predict_proba(reject[feature_lst])[:,1]
# 0.8分位点
thd = reject['y_pred'].quantile(0.8)
# 阈值以上硬截断为负样本
reject['bad_ind'] = reject['y_pred'].map(
                        lambda x :1 if x >= thd else -1)
# 只保留负样本
labeled = reject[reject['bad_ind']==1]
labeled = labeled.drop('y_pred', axis=1)
# 合后并重新建模
final = pd.concat([labeled, kgb], ignore_index=True)
x = final[feature_lst]
y = final['bad_ind']
lr_hard = LogisticRegression(C=0.1)
lr_hard.fit(x,y)

# 复制样本
reject1 = reject.copy()
reject2 = reject.copy()
# 按照正负样本概率加权
reject1['weight'] = lr_model.predict_proba(reject1[feature_lst])[:,1]
reject2['weight'] = lr_model.predict_proba(reject2[feature_lst])[:,0]
# 合并
labeled = pd.concat([reject1, reject2], ignore_index=True)
# 为KGB样本设置权重
kgb['weight'] = 1
# 合后并重新建模
final = pd.concat([labeled, kgb], ignore_index=True)
x = final[feature_lst]
y = final['bad_ind']
lr_fuzz = LogisticRegression(C=0.1)
lr_fuzz.fit(x, y, sample_weight=final['weight'])

# 负样本概率，越大越可能是负样本
agb['y_pred'] = lr_model.predict_proba(agb[feature_lst])[:,1]
# 等频分箱
agb['range'] = pd.qcut(agb['y_pred'], 10)
# 分组计算权重
final = pd.DataFrame()
for i in list(set(agb['range'])):
    tt = agb[agb['range']==i].copy()
    good = sum(tt['bad_ind']==1)
    bad = sum(tt['bad_ind']==0)
    re = sum(tt['bad_ind']==-1)
    # 权重计算
    tt['weight'] = (good+bad+re)/(good+bad)
    final = final.append(tt)
# 带入权重，重新拟合模型
x = final[feature_lst]
y = final['bad_ind']
lr_weighted = LogisticRegression(C=0.1)
lr_weighted.fit(x, y, sample_weight=final['weight'])

# 负样本概率，越大越可能是负样本
kgb['y_pred'] = lr_model.predict_proba(kgb[feature_lst])[:,1]
# 等频分箱
kgb['range'] = pd.qcut(kgb['y_pred'], 10)
# 在AGB有标记样本上计算等频分箱阈值和负样本占比
pmax = kgb['y_pred'].max()
cutpoints = list(set(kgb['y_pred'].quantile(
                    [0.1 * n for n in range(1, 10)]))) + [pmax + 1]
cutpoints.sort(reverse=False)
dct = {}
for i in range(len(cutpoints) - 1):
    # 分箱
    data = kgb.loc[np.logical_and(kgb['y_pred'] >= cutpoints[i],
                                  kgb['y_pred'] < cutpoints[i + 1]),
                                         ['bad_ind']]
    good = sum(data['bad_ind']==0)
    bad = sum(data['bad_ind']==1)
    # 通过递增的步长，使得经验风险因子从2增长至4
    step = (i + 1) * 0.2
    dct[i] = bad / (bad + good) * 2 * step
# 拒绝样本按照阈值进行划分
reject['y_pred'] = lr_model.predict_proba(reject[feature_lst])[:,1]
rejectNew = pd.DataFrame()
for i in range(len(cutpoints) - 1):
    # 分箱
    data = reject.loc[np.logical_and(reject['y_pred']>=cutpoints[i],
                      reject['y_pred']<cutpoints[i+1])]
    data['badrate'] = dct[i]
    rejectNew.append(data)
    if rejectNew is None:
        rejectNew= data
    else:
        rejectNew = rejectNew.append(data)
# 定义随机打分函数
def assign(x):
    tt = random.uniform(0, 1)
    if tt < x:
        return 1
    else:
        return 0
# 按照加权负样本占比随机赋值
rejectNew['bad_ind'] = rejectNew['badrate'].map(lambda x:assign(x))
# 合后并重新建模
final = pd.concat([rejectNew,kgb], ignore_index=True)
x = final[feature_lst]
y = final['bad_ind']
lr_Extra = LogisticRegression(C=0.1)
lr_Extra.fit(x,y)

maxKS = 0
n = 0
x = kgb[feature_lst]
y = kgb['bad_ind']
lr_hard = LogisticRegression(C=0.1)
lr_hard.fit(x,y)
reject['y_pred'] = lr_hard.predict_proba(reject[feature_lst])[:,1]
while True:
    # 负样本概率，越大越可能是负样本
    reject['y_pred'] = lr_hard.predict_proba(reject[feature_lst])[:,1]
    # 0.8分位点
    thd = reject['y_pred'].quantile(0.4)
    # 阈值以上硬截断为负样本
    reject['bad_ind'] = reject['y_pred'].map(
                             lambda x :1 if x >= thd else -1)
    # 只保留负样本
    labeled = reject[reject['bad_ind']==1]
    labeled = labeled.drop('y_pred', axis=1)
    # 合后并重新建模
    final = pd.concat([labeled,kgb], ignore_index=True)
    x = final[feature_lst]
    y = final['bad_ind']
    lr_hard = LogisticRegression(C=0.1)
    lr_hard.fit(x,y)
    y_pred = lr_hard.predict_proba(kgb[feature_lst])[:,1]
    fpr_lr_train,tpr_lr_train,_ = roc_curve(kgb['bad_ind'],y_pred)
    ks = abs(fpr_lr_train - tpr_lr_train).max()
    if maxKS <= ks:
        maxKS = ks
        n+=1
        print('迭代第%s轮，ks值为%s' % (n,ks))
    else:
        break


import os
import argparse
import datetime
import math

from config import Config

import numpy as np
import pickle

import torch
import torch.nn as nn
from torch.nn.utils.rnn import pack_padded_sequence
from torchvision import transforms

from data_loader import get_loader
from build_vocab import Vocabulary
from model import EncoderCNN, DecoderRNN

# Device configuration
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

def main():
    config = Config()
    if not os.path.exists(config.model_path):
        os.mkdir(config.model_path)

    # Sửa đổi biến đổi hình ảnh - image augmentation
    transform = transforms.Compose([
        transforms.RandomCrop(config.crop_size),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize((0.485, 0.456, 0.406),
                             (0.229, 0.224, 0.225))])

    with open(config.vocab_path, 'rb') as f:
        vocab = pickle.load(f)

    data_loader = get_loader(config.img_path,
                            config.train_path,
                            vocab,
                            transform,
                            config.tokenizer,
                            config.batch_size,
                            shuffle=True,
                            num_workers=config.num_workers)

    # Build the models
    encoder = EncoderCNN(config.embed_size).to(device)
    decoder = DecoderRNN(config.embed_size, config.hidden_size, len(vocab), config.num_layers).to(device)

    # Loss and optimizers
    criterion = nn.CrossEntropyLoss()
    params = list(decoder.parameters()) + list(encoder.linear.parameters()) + list(encoder.bn.parameters())
    if config.optimizer == "adam":
        optimizer = torch.optim.Adam(params, lr = config.learning_rate)
    else:
        raise NotImplementedError("Other optimizers not implemented.")

    # encoder's state_dict
    for param_tensor in encoder.state_dict():
        print(f"{param_tensor} \t {encoder.state_dict()[param_tensor].size()}")
    # decoder's state_dict
    for param_tensor in decoder.state_dict():
        print(f"{param_tensor} \t {decoder.state_dict()[param_tensor].size()}")
    # optimizer's state_dict
    for var_name in optimizer.state_dict():
        print(f"{var_name} \t {optimizer.state_dict()[var_name]}")

    # Let's train the model
    best_valid_loss = float('inf')

    # Xác định số bước huấn luyện trong một epoch
    total_step = len(data_loader)

    for epoch in range(config.num_epochs):
        for i, (images, captions, lengths) in enumerate(data_loader):

            # Set mini-batch dataset
            images = images.to(device)
            captions = captions.to(device)
            targets = pack_padded_sequence(captions, lengths, batch_first=True)[0]

            # Forward, backward and optimize
            features = encoder(images)
            outputs = decoder(features, captions, lengths)
            loss = criterion(outputs, targets)
            decoder.zero_grad()
            encoder.zero_grad()
            loss.backward()
            optimizer.step()

            # https://stackoverflow.com/questions/61988776/how-to-calculate-perplexity-for-a-language-model-using-pytorch
            # Print log info
            if i % config.log_step == 0:
                print('Epoch [{}/{}], Step [{}/{}], Loss: {:.4f}, Perplexity: {:5.4f}'
                      .format(epoch, config.num_epochs, i, total_step, loss.item(), np.exp(loss.item())))

            # Save each model's components checkpoints
            if (i+1) % config.save_step == 0:
                torch.save(decoder.state_dict(), os.path.join(
                    config.model_path, 'decoder-{}-{}-{}.ckpt'.format(epoch+1, i+1, datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))))
                torch.save(encoder.state_dict(), os.path.join(
                    config.model_path, 'encoder-{}-{}-{}.ckpt'.format(epoch+1, i+1, datetime.datetime.now().strftime("%Y%m%d_%H%M%S"))))

                # save model checkpoint
                torch.save({
                            'epoch': epoch+1,
                            'encoder_state_dict': encoder.state_dict(),
                            'decoder_state_dict': decoder.state_dict(),
                            'optimizer_state_dict': optimizer.state_dict(),
                            'loss': criterion,
                            }, './outputs/model.pth')

if __name__ == "__main__":
    main()


# Split .m4b to multiple files
# -----------------------------------------------------------------------------
# module imports

from common import *

# -----------------------------------------------------------------------------
# add split points to end of log file in human-readable format
# for checking only

def printSpltPts(logDict, spltPts, fn):
  # filenames for each filetype accessed
  fileLog = fn.parents[0].joinpath(fn.stem + '.log')

  sf = open(fileLog, 'w')

  for key in logDict:
    sf.write('Start time = ' + str(key) + ', End time = ' + str(logDict[key]) + '\n')

  sf.write('\n===============================================================================\n\n')
  sf.write('SPLIT POINTS\n')

  for pt in spltPts:
    sf.write(str(pt) + ' secs - ' + str(datetime.timedelta(seconds=pt)) + '\n')

  sf.close()

  return

# -----------------------------------------------------------------------------
# split by chapters

def splitByChapters(fn, fileVar):
  # handle existing files/directories
  splitDir = str(fn.parents[0].joinpath(fileVar['ext'].upper()))
  dirExists(splitDir)
  os.mkdir(splitDir)
  os.chdir(splitDir)

  counter = 1

  # command line for ffprobe chapter data
  a = []
  a.append('"' + fileVar['ffprobe'] + '"')
  a.append(' -show_chapters -print_format json ')
  a.append('"' + str(fn) + '"')

  # extract chapter data from M4B file using FFPROBE
  p = runCommand(concat_args(a), None)
  chapterData = json.loads(p[0])

  # zeroes needed to pad file number
  sp = len(chapterData['chapters'])
  result = 10 ** (math.floor(math.log10(sp)))
  digits = len(str(result))

  # create scrolling text box for command output
  root = Tk()
  root.title('Writing audio files')
  textbox = scrolledtext.ScrolledText(root, height=30, width=80)
  textbox.config(wrap='word')
  textbox.pack()
  textbox.insert(END, 'Writing audio files\n\n')   # add output to end of textbox content
  textbox.see(END)                                    # move cursor to end of textbox content
  Tk.update(textbox)                                  # update textbox

  # split by chapter start/end times
  for i in chapterData['chapters']:
    first, last = splitCmd(fn, i['start_time'], i['end_time'], counter, digits, sp)
    textbox.insert(END, 'Writing... ' + str(fn.stem) + ' - ' + str(counter).zfill(digits) + '.' + fileVar['ext'].lower() + '\n')
    textbox.see(END)
    Tk.update(textbox)
    # run external command
    p = runCommand(concat_args(first), None)
    counter += 1

  root.destroy()                  # close textbox

# -----------------------------------------------------------------------------
# split to M4A/MP3

def splitCmd(fn, startTime, secs, counter, digits, maxtrk):

  # create cmd line for file export from time1 to time2
  a = []
  a.append('"' + fileVar['ffmpeg'] + '"')
  a.append(' -i ')
  a.append('"' + str(fn) + '"')
  a.append(' -map_metadata 0 -metadata track="')
  a.append(str(counter) + '/' + str(maxtrk) + '"')
  if fileVar['ext'] == 'm4a':
    a.append(' -vn -acodec copy -ss ' + str(startTime))
  else:   # assume mp3
    a.append(' -vn -vsync 0 -acodec libmp3lame -q 3 -ss ' + str(startTime))
  a.append('s -to ' + str(secs) + 's ')
  a.append('"' + str(fn.stem) + ' - ' + str(counter).zfill(digits) + '.' + fileVar['ext'].lower() + '"')

  # create cmd line for file export from time1 to EOF
  b = []
  b.append('"' + fileVar['ffmpeg'] + '"')
  b.append(' -i ')
  b.append('"' + str(fn) + '"')
  b.append(' -map_metadata 0 -metadata track="')
  b.append(str(counter) + '/' + str(maxtrk) + '"')
  if fileVar['ext'] == 'm4a':
    b.append(' -vn -acodec copy -ss ' + str(startTime))
  else:   # assume mp3
    b.append(' -vn -vsync 0 -acodec libmp3lame -q 3 -ss ' + str(startTime))
  b.append('s ')
  b.append('"' + str(fn.stem) + ' - ' + str(counter).zfill(digits) + '.' + fileVar['ext'].lower() + '"')

  return a, b

# -----------------------------------------------------------------------------
# get duration of audio file

def duration(fn):
  # command line for ffprobe - audio duration
  a = []
  a.append('"' + fileVar['ffprobe'] + '"')
  a.append(' -hide_banner -show_entries format=duration -of default=noprint_wrappers=1 ')
  a.append('"' + str(fn) + '"')

  # extract chapter data from M4B file using FFPROBE
  p = runCommand(concat_args(a), 't')
  durSecs = float(p[0].split('=')[1])

  return durSecs

# -----------------------------------------------------------------------------
# split into X minute files (.m4b to .m4a)
# - need to add metadata (incl image) and track number to output files

## start time to end time:
##   ffmpeg -i input.mp3 -vn -acodec copy -ss 00:00:00 -to 00:01:32 output.mp3
## start time + duration time:
##   ffmpeg -i input.mp3 -vn -acodec copy -ss 00:00:00 -t 00:01:32 output.mp3
## start of audio to end time:
##   ffmpeg -i input.mp3 -vn -acodec copy -to 00:01:32 output.mp3
## start time till end of audio:
##   ffmpeg -i input.mp3 -vn -acodec copy -ss 00:01:32 output.mp3

def splitByMinutes(spltPts, fn):
  # handle existing files/directories
  splitDir = str(fn.parents[0].joinpath(fileVar['ext'].upper()))
  dirExists(splitDir)
  os.mkdir(splitDir)
  os.chdir(splitDir)

  counter = 1
  startTime = 0
  # get length of m4b file in seconds
  maxSecs = duration(fn)
  # add length to end of spltPts list (ensures that last file is always produced)
  spltPts.append(maxSecs)

  # zeroes needed to pad file number
  sp = max(len(spltPts) - 1, 1)
  result = 10 ** (math.floor(math.log10(sp)))
  digits = len(str(result))

  # create scrolling text box for command output
  root = Tk()
  root.title('Writing audio files')
  textbox = scrolledtext.ScrolledText(root, height=30, width=80)
  textbox.config(wrap='word')
  textbox.pack()
  textbox.insert(END, 'Writing audio files\n\n')   # add output to end of textbox content
  textbox.see(END)                                 # move cursor to end of textbox content
  Tk.update(textbox)                               # update textbox

# split files
  secs = spltPts[counter-1]
  while True:
    # 3 minutes minimum size for last file
    if maxSecs - secs > 180:
      # create file from time1 to time2
      first, last = splitCmd(fn, startTime, secs, counter, digits, len(spltPts))

      textbox.insert(END, 'Writing... ' + str(fn.stem) + ' - ' + str(counter).zfill(digits) + '.' + fileVar['ext'].lower() + '\n')
      textbox.see(END)
      Tk.update(textbox)

      # run external command
      p = runCommand(concat_args(first), None)

      counter += 1
      startTime = secs
      secs = spltPts[counter-1]
    else:
      # create file from time1 to EOF
      first, last = splitCmd(fn, startTime, secs, counter, digits, len(spltPts))

      textbox.insert(END, 'Writing... ' + str(fn.stem) + ' - ' + str(counter).zfill(digits) + '.' + fileVar['ext'].lower() + '\n')
      textbox.see(END)
      Tk.update(textbox)

      # run external command
      p = runCommand(concat_args(last), None)

      root.destroy()                  # close textbox
      break

# -----------------------------------------------------------------------------
# identify nearest silence point to required cut-off point (e.g. 10 minutes)

def splitPoints(ld, minutes, lastSilence):
  # convert minutes to seconds
  fileLen = float(minutes * 60)
  fileSecs = fileLen
  splitPoints = []

  # calculate the nearest silence to cut-off point and set split point to middle of silence
  while True:
    # returns ld.result_key and ld.result_value
    startTime, endTime = min(ld.items(), key=lambda x: abs(fileSecs - x[1]))
    splitPoints.append(round(startTime + (endTime - startTime) / 2, 3))
    fileSecs += fileLen

    if fileSecs > lastSilence:
      break

  return splitPoints

# -----------------------------------------------------------------------------
# detect silence in audio file (parameters defined in text file)

def silenceDetect(fn, fileVar):
  logDict = {}

  # command line for ffmpeg silence detection
  a = []
  a.append('"' + fileVar['ffmpeg'] + '"')
  a.append(' -i')
  a.append(' "' + str(fn) + '"')
  a.append(' -loglevel quiet -af silencedetect=n=')
  a.append(fileVar['db'])
  a.append('dB:d=')
  a.append(fileVar['silencelength'])
  a.append(",ametadata=mode=print:direct=1:file='-' -f null -")   # direct=1 - prints continuously; file='-' - prints to stdout

  # extract chapter data from M4B file using FFPROBE (grab stdout for this dataset)
  logList = runCommand(concat_args(a), 'w')

  # create dictionary with start and end as key/value pairs
  for start, end in zip(logList[::2], logList[1::2]):
    logDict[start] = end
    lastSilence = end

  return logDict, lastSilence

# -----------------------------------------------------------------------------
# main
# -----------------------------------------------------------------------------
if __name__ == "__main__":

# get variables from external file
  fileVar = getFileVariable()

# iterate over selected files to produce output

  fileNames = selectFiles(fileVar['defaultdir'])

  while fileNames:
    for fn in fileNames:
      fn = Path(fn)

      if fileVar['split'] == 'Y':
        if fileVar['splitby'] == 'minutes':
          # detect silence
          logDict, lastSilence = silenceDetect(fn, fileVar)
          # calculate split points
          spltPts = splitPoints(logDict, int(fileVar['minutes']), lastSilence)
          # split into X minutes file
          splitByMinutes(spltPts, fn)
        else:   # assume chapters
          splitByChapters(fn, fileVar)
      else:   # assume silence log
        # detect silence
        logDict, lastSilence = silenceDetect(fn, fileVar)
        # calculate split points
        spltPts = splitPoints(logDict, int(fileVar['minutes']), lastSilence)
        # print split points to log file
        printSpltPts(logDict, spltPts, fn)

    fileNames = selectFiles(fileVar['defaultdir'])
    if not fileNames:
      break

# -----------------------------------------------------------------------------
# exit program
# -----------------------------------------------------------------------------


# funkcje z argumentami args i kwargs

# "*" w funkcji mowi że mozemy miec do czynienia z pewna lista dodatkowych
# elementow, ktore moga sie pojawic
# "**" argumenty poprzedzone nazwa (slowem kluczowym)
#wieksza ilosc argumentow
'''
def BuyMe(prefix, what = "something nice", *args, **kwatgs):
    print(prefix,what)
    print(args)
    print(kwatgs)

BuyMe("Please buy me", "a new car", "a cat", "a dog", "a dragon", shop = "mraket", color = "any")

products = ["milk", "bread", "flakes"]
parameters = {"price" : "low", "time" : "now"}

BuyMe("Buy me", "newspaper", *products, **parameters)
'''

def calculatePaint (efficencyLtrPerM2, *argumets):
    allArguments = sum(argumets)
    print(allArguments * efficencyLtrPerM2)

calculatePaint(3, 10, 10, 5)
listAgrum = [10, 10, 5]
calculatePaint(3, *listAgrum)

def logIt(pahtName, *arguments):
    try:
        with open(pahtName, 'a') as file:
            for argument in arguments:
                file.write(argument + " ")
            file.write("\n")

    except:
        print("Something was wrong")

logIt(r"N:\temp\zad16.txt",'Starting processing forecasting')
logIt(r"N:\temp\zad16.txt",'ERROR', 'Not enough data', 'invoices', '2020')

def log_it(*args):
    path = r'N:\temp\log_it.txt'
    with open(path, "a") as f:
        for line in args:
            f.write(line)
            f.write(' ')

        f.write("\n")

log_it('Starting processing forecasting')
log_it('ERROR', 'Not enough data', 'invoices', '2020')


# https://leetcode.com/problems/sum-of-distances-in-tree/

def sumOfDistancesInTree(n: int, edges: list):
    adj = [[] for _ in range(n)]

    for i, j in edges:
        adj[i].append(j)
        adj[j].append(i)

    dp = [0] * n
    size = [0] * n
    ans = [0] * n

    def dfs(node: int, parent: int):
        size[node] = 1
        dp[node] = 0

        for each in adj[node]:
            if each == parent:
                continue
            dfs(each, node)
            dp[node] += dp[each] + size[each]
            size[node] += size[each]

    def dfs2(node: int, parent: int):
        ans[node] = dp[node]

        for each in adj[node]:
            if each == parent:
                continue
            pu = dp[node]
            pv = dp[each]
            su = size[node]
            sv = size[each]

            dp[node] -= dp[each] + size[each]
            size[node] -= size[each]
            dp[each] += dp[node] + size[node]
            size[each] += size[node]

            dfs2(each, node)

            dp[node] = pu
            dp[each] = pv
            size[node] = su
            size[each] = sv

    dfs(0, -1)
    dfs2(0, -1)
    return ans

if __name__ == "__main__":
    edges = [[0, 1], [0, 2], [2, 3], [2, 4], [2, 5]]
    print(sumOfDistancesInTree(6, edges))


from django.urls import path

from .services.auth import sign_in, sign_up, sign_out, er, profile_edit
from .services.auto import gets, auto_form, auto_del
from .services.client import client_doc
from .services.direc import list_members, banner, grader, spammer
from .views import index, contact

urlpatterns = [
    path("", index, name="home"),

    # auth
    path("auth/login/", sign_in, name="sign_in"),
    path("auth/regis/", sign_up, name="regis"),
    path("auth/logout/", sign_out, name="sign_out"),
    # path("auth/profile/", profile, name="profile"),
    path("edit", profile_edit, name="profile_edit"),
    path("auth/contacts/" , contact , name="contacts"),

    # auto
    path("auto/<key>/", gets, name="dashboard-auto-list"),
    path("auto/<key>/detail/<int:pk>/", gets, name="dashboard-auto-detail"),
    path("auto/<key>/add/", auto_form, name="dashboard-auto-add"),
    path("auto/<key>/edit/<int:pk>/", auto_form, name="dashboard-auto-edit"),
    path("auto/<key>/del/<int:pk>/", auto_del, name="dashboard-auto-delete"),

    path("member/<int:type>/", list_members, name="members"),
    path("member/new/<int:new>/", list_members, name="members-new"),
    path("grader/<int:pk>/<int:ut>/<int:dut>/", grader, name="grader"),
    path("banner/u-<int:user_id>/<int:type>/<int:status>/", banner, name="banner"),
    path("error/404.html/", er, name="404.html"),
    path("spam/<int:pk>/<int:dut>/", spammer, name="spammer"),

    # client
    path("client/doc/<int:service>/", client_doc, name="client_doc")

]


import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

import configparser
import os
import re
import signal
import subprocess

import psutil

class tools:

    def configparser(self, path):
        self.config = configparser.ConfigParser()
        if os.path.exists(path):
            self.config.read(path)
            for i in self.config:
                logger.debug(i)
        return self.config

    def service(self, service, action):
        try:
            if action == 'start':
                process = subprocess.Popen(['sudo', 'systemctl', action, service, '--quiet'], stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
                output, err = process.communicate()
                try:
                    output = output.decode('utf-8').strip()
                    err = err.decode('utf-8').strip()
                except:
                    pass
                rc = process.returncode
                logger.debug("Start service %s returned: %s" % (service, str(rc)))
                if rc == 0:
                    logger.debug("Started: %s" % service)
                    return True
                else:
                    logger.debug("Failed to start: %s" % service)
                    return False

            elif action == 'stop':
                process = subprocess.Popen(['sudo', 'systemctl', action, service, '--quiet'], stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
                output, err = process.communicate()
                try:
                    output = output.decode('utf-8').strip()
                    err = err.decode('utf-8').strip()
                except:
                    pass
                rc = process.returncode
                logger.debug("Stop service %s returned: %s" % (service, str(rc)))
                if rc == 0 or 5:
                    logger.debug("Stopped: %s" % service)
                    return True
                else:
                    logger.debug("Failed to stop: %s" % service)
                    return False

            elif action == 'enable':
                process = subprocess.Popen(['sudo', 'systemctl', action, service, '--quiet'], stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
                output, err = process.communicate()
                try:
                    output = output.decode('utf-8').strip()
                    err = err.decode('utf-8').strip()
                except:
                    pass
                rc = process.returncode
                logger.debug("Enable service %s returned: %s" % (service, str(rc)))
                if rc == 0:
                    logger.debug("Enabled: %s" % service)
                    return True
                else:
                    logger.debug("Failed to enable: $s" % service)
                    return False

            elif action == 'disable':
                process = subprocess.Popen(['sudo', 'systemctl', action, service, '--quiet'], stdout=subprocess.PIPE,
                                           stderr=subprocess.PIPE)
                output, err = process.communicate()
                try:
                    output = output.decode('utf-8').strip()
                    err = err.decode('utf-8').strip()
                except:
                    pass
                rc = process.returncode
                logger.debug("Disable service %s returned: %s" % (service, str(rc)))
                if rc == 0:
                    logger.debug("Disabled: %s" % service)
                    return True
                else:
                    if 'does not exist' in output or err:
                        logger.debug("%s does not exist" % service)
                        return True
                    logger.debug("Failed to disable: %s" % service)
                    return False

            elif action == 'status':
                process = subprocess.Popen(['sudo', 'systemctl', 'is-active', '--quiet', service],
                                           stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                output, err = process.communicate()
                rc = process.returncode
                logger.debug("Status of service %s returned: %s" % (service, str(rc)))
                if rc == 0:
                    logger.debug("Service %s running" % service)
                    return True
                else:
                    logger.debug("Service %s is not running" % service)
                    return False

        except Exception as e:
            logger.debug("Service processing failure: %s" % e)
            return False

    def app_status(self, application):
        # return True if running
        for proc in psutil.process_iter():
            try:
                # Check if process name contains the given name string.
                if application.lower() in proc.name().lower():
                    logger.debug("%s: running" % application)
                    return True
            except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                pass
        logger.debug("%s: not running" % application)
        return False

    def app_kill(self, application):
        # Return True on success
        process = subprocess.Popen(['sudo', 'pkill', '-f', application], stdout=subprocess.PIPE)
        output, err = process.communicate()
        try:
            output = output.decode('utf-8').strip()
            err = err.decode('utf-8').strip()
        except:
            pass
        rc = process.returncode
        logger.debug("Kill %s return: %s" % (application, str(rc)))
        if rc == 0:
            logger.debug("Killed: %s" % application)
            return True
        else:
            logger.debug("Failed to kill: %s" % application)
            return False

    def app_start(self, application, arguments=None):
        # Return True if completed or long running process (None)
        app = ['sudo', application]
        if arguments is not None:
            args = arguments.split()
            full_command = app + args
            command = subprocess.Popen(full_command, stdout=subprocess.PIPE)
        else:
            command = subprocess.Popen(app, stdout=subprocess.PIPE)
        rc = command.returncode
        if rc != 1:
            logger.debug("Started: %s with args: %s and rc: %s" % (application, arguments, str(rc)))
            return True
        else:
            logger.debug("Failed to start: %s with args: %s and rc: %s" % (application, arguments, str(rc)))
            return False

    def wifi(self):

        # return connected wifi status as dictionary  pairs
        process = subprocess.Popen(['sudo', 'iw', 'dev', 'wlan0', 'link'], stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        output, err = process.communicate(timeout=1)
        output = output.decode('utf-8').strip()
        err = err.decode('utf-8').strip()
        rc = process.returncode

        if rc == 0:
            if 'not connected' in output.lower():
                return 'Not connected'

            else:
                # cleanup mac address
                output = re.sub('(\w+):(\w+):(\w+):(\w+):(\w+):(\w+)', r':\1-\2-\3-\4-\5-\6', output)
                # remove tabs and split into list
                output = re.sub(r'\t', '', output).splitlines()
                # remove empty list items
                output = [x for x in output if x]
                # finally split into dictionary
                output = dict(x.split(':', 1) for x in output)
                # trim whitespace in all items
                output = {k.strip(): v.strip() for k, v in output.items()}
                # add signal %
                signal = int(re.sub(r' dBm', '', output['signal']))
                # calculate signal quality
                if (signal <= -100):
                    quality = 0
                elif (signal >= -50):
                    quality = 100
                else:
                    quality = 2 * (signal + 100)
                # add it to dictionary
                output['quality'] = quality

                return output
        else:
            return err

class app_shutdown:
    kill = False

    def __init__(self):
        signal.signal(signal.SIGINT, self.exit_gracefully)
        signal.signal(signal.SIGTERM, self.exit_gracefully)

    def exit_gracefully(self, signum, frame):
        self.kill = True


__version__ = '0.1'
__author__ = 'Thanos Poulos'
__license__ = 'MIT'

# Author: Thanos Poulos
# Date: October 2016
"""
Calculate the maximum displacement given the mode shape file
and the generalized displacement

"""

# Import packages
#---------------
import sys
import os
import numpy as np

# User Input
#-------------

# Absolute path the the structure file
structure_file_path = "modes.dat"

# Generalized displacement list that should contain a value for each mode shape
# If there are fewer values than mode shapes in the file, the remaining will be
# to zero. If it has more, then the script will stop with an error.
#
# Here the maximum displacement has to be input, not the time profile or the harmonic
# components. For these cases, the maximum has to be found and input here
generalized_disp_list = [0.0005, 0.0004]

# Functions
#----------
def read_structure_file(file_path):
    """
    Takes as an input the structure file in FINE format and creates
    a dictionary with the header line information and an array of the
    mode shapes

    Input:
    - file_path: Path to the structure file including extension

    Output:
    - global_info_dict: Dictionary with the global information of the structure file
    - mode_shapes: mode shape array
    """

    print("<<< Reading structure file for %s >>>") %(os.path.basename(file_path))

    # Get the global information of the structure file
    f = open(file_path,"r")

    # Skip the first line since it is a commentl line
    line = f.readline()

    # Get number of dimensions for the file
    ndim = int(f.readline().split()[4])

    # Get number of modes in the file
    nmodes = int(f.readline().split()[4])

    # Get the number of nodes of the structure mesh
    nnodes = int(f.readline().split()[4])

    # Get initial deformation
    ini_def = int(f.readline().split()[3])

    # Print the global information
    print("<<< Global Information Read Successfully for %s >>>") %(os.path.basename(file_path))
    print("The number of dimensions is %s") %ndim
    print("The number of modes is %s") %nmodes
    print("The number of nodes is %s") %nnodes
    if ini_def == 0:
        print("There is initial deformation present")
    else:
        print("There is no initial deformation present")

    # Put global information in a dictionary
    global_info_dict = {
        'ndim'   : ndim,
        'nmodes' : nmodes,
        'nnodes' : nnodes,
        'ini_def': ini_def
    }

    # Skip two more lines
    line = f.readline()
    line = f.readline()

    # Create the eigenfrequencies list
    eig_freq_list = []

    # Read the list from file
    '''
    line = f.readline()
    while "Mode shapes" not in line:
        if line:
            eig_freq_list.append(float(line))
            print eig_freq_list
        line = f.readline()
    '''

    for i in range(nmodes):
        eig_freq_list.append(float(f.readline()))

    # skip another  lines
    line = f.readline()
    line = f.readline()

    # Read the mode shapes in two arrays: Coordinates and Mode Shapes
    print("<<< Reading mode shapes >>>")
    mode_shapes = []
    line = f.readline()
    while line:
        # Create a array for the mode shapes
        mode_shapes.append(map(float, line.split()))
        line = f.readline()

    mode_shapes_array = np.array(mode_shapes)
    print("<<< Mode shapes have been read successfully >>>")
    f.close()
    return global_info_dict,mode_shapes_array

# Main Program
#--------------

# Check to see if the file exists
if not os.path.isfile(structure_file_path):
    print("****ERROR: File %s does not exist") %(os.path.basename(structure_file_path))
    print("The program will now exit")
    sys.exit()

# Read the structure file information
global_info, array_from_file = read_structure_file(structure_file_path)

# Split the array into coordinates and mode shapes depending on the initial
# deformation
if global_info["ini_def"] == 0:
    coord, mode_shapes = np.hsplit(array_from_file, [global_info["ndim"]])
else:
    coord, mode_shapes = np.hsplit(array_from_file, [global_info["ndim"]*2]) # since we have the coordinates and the initial deformation

# Check to see if the generalized displacement list has the same number of modes
# as the structure file.
if global_info["nmodes"] != len(generalized_disp_list):
    print("WARNING: Then number of modes shapes in the structure file is not equal to the number of generalized displacements given")
    print("WARNING: Zeros will be added in order to fill up the generalized displacement vector\n")
    generalized_disp_list =  generalized_disp_list + [0]*(mode_shapes.shape[1]/global_info["ndim"] - len(generalized_disp_list))

# Create array from generalized displacement list
generalized_disp_array = np.array(generalized_disp_list)

# Create the displacement matrix
# Initialize the array
disp = np.zeros((mode_shapes.shape[0],global_info["ndim"]))

# Loop to create it
c = 0
for gen in generalized_disp_list:
    # Update the displacement array with the product of the generalized
    # displacement for each mode shape
    disp += gen*mode_shapes[:,c:c+global_info["ndim"]]
    c += global_info["ndim"]

# Initialize cylindrical displacement and displacement magnitude arrays
disp_cyl = np.zeros((mode_shapes.shape[0],global_info["ndim"]))
disp_magn = np.zeros((mode_shapes.shape[0]))

# Create the displacement matrix in cylindrical coordinates as well
# Check if it is a 3D case. Effect on the magnitude and the cylindrical
# coordinates
if global_info["ndim"] == 3:
    for i in range(len(disp.shape)):
        disp_cyl[i,0] = np.sqrt(disp[i,0]**2 + disp[i,1]**2)
        disp_cyl[i,1] = np.arctan2(disp[i,1], disp[i,0])
        disp_cyl[i,2] = disp[i,2]
        disp_magn[i] = np.sqrt(disp[i,0]**2 + disp[i,1]**2 + disp[i,2]**2)
else:
    for i in range(len(disp.shape)):
        disp_cyl[i,0] = np.sqrt(disp[i,0]**2 + disp[i,1]**2)
        disp_cyl[i,1] = np.arctan2(disp[i,1], disp[i,0])
        disp_magn[i] = np.sqrt(disp[i,0]**2 + disp[i,1]**2)

#Find the maximum displacement by axis
xmax = np.amax(disp[:,0])
ymax = np.amax(disp[:,1])
# Check if it is a 3D case
if global_info["ndim"] == 3:
    zmax = np.amax(disp[:,2])
rmax = np.amax(disp_cyl[:,0])
thetamax = np.amax(disp_cyl[:,1])
magnmax = np.amax(disp_magn)

print("The maximum displacement along the x axis is: %s")%xmax
print("The maximum displacement along the y axis is: %s")%ymax
# Check if it is a 3D case
if global_info["ndim"] == 3:
    print("The maximum displacement along the z axis is: %s")%zmax
print("The maximum displacement along the radial direction is: %s")%rmax
print("The maximum displacement along the circumferential direction is: %s")%thetamax
print("The maximum of the magnitude of the displacement is: %s")%magnmax


from docx import Document
import os

docname = []
docslist = []
path1 = os.getcwd()
path = os.path.join(path1,'media/')
for files in os.listdir(path):
    if files.endswith('.docx'):
        str2 = files[:-5]
        docname.append(str2)
        docslist.append(path+files)

for doc in docslist:
        doc = Document(doc)
        str = ''
        for para in doc.paragraphs:
            str += (para.text)

        for name in docname:
            text_file = open(os.path.join(path1,"Doc_Extracted_Data/{}.txt".format(name)), "w")
            text_file.write(str)
            text_file.close()

print("Extraction DONE ! ")


import numpy as np
from cv2 import cv2

img = cv2.resize((cv2.imread("faces.jpg",1)) ,(0,0),fx=0.7,fy=0.7)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

path = "haar_cascade_fronalface_default.xml"#Path to our xml file for detecting frontal face , which contains
#various features for classifying ROI as a face or non-face

#Cascade object
face_cascade = cv2.CascadeClassifier(path) #Loads our file and initiates our classifier
#This face_cascade object contains the cascaded classifiers for classification task

faces = face_cascade.detectMultiScale(gray,scaleFactor=1.10,minNeighbors =5,minSize=(40,40))
#scaleFactor =  Compensating factor for making faces closer to camera
#min neighbours = number of nearby object detection required before ROI is face
# min size = Actual min size of face before it's detected as face
#Output is a list of faces detected in form of rectangles
print("Found {} Faces".format(len(faces)) )

for (x,y,w,h) in faces:
    cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
    #top left coner = (x,y)
    #bottom right corner = (x+w,y+h)

cv2.imshow("Faces Detected",img)

cv2.waitKey(0)
cv2.destroyAllWindows()

LyndaOpenCv Exercises and Assignments/Chap4/FaceDetectionHaarC.py


from copy import deepcopy
from typing import Any

from ..state_variables import initial_state

def refund_funder_account(
    sys_params: dict[str, Any],
    substep: int,
    _,
    current_state: dict[str, Any],
    policy_inputs: dict[str, Any],
):
    default = ("deposited", current_state["deposited"])
    if policy_inputs["step"] != "depositing":
        return default

    agent_payloads: list[tuple[dict[str, Any], int]] = policy_inputs["agents"]
    current_deposits: dict[bytes, int] = deepcopy(current_state["deposited"])

    depositer, refund_amount = agent_payloads[-1]
    funder_address: bytes = depositer["address"]

    current_deposits.update(
        {funder_address: current_deposits[funder_address] - refund_amount}
    )

    return ("deposited", current_deposits)

def refund_and_credit_DAI(
    sys_params: dict[str, Any],
    substep: int,
    _,
    current_state: dict[str, Any],
    policy_inputs: dict[str, Any],
):
    default = ("agents", current_state["agents"])
    if policy_inputs["step"] != "depositing":
        return default

    agent_payload: list[tuple[dict[str, Any], int]] = policy_inputs["agents"]
    current_agents: list[dict[str, Any]] = deepcopy(current_state["agents"])

    agent, _ = agent_payload[-1]
    i_agent = current_agents.index(agent)
    current_agents[i_agent].update({"DAI": initial_state["agents"][i_agent]["DAI"]})
    return ("agents", current_agents)

def refund_and_update_total(
    sys_params: dict[str, Any],
    substep: int,
    _,
    current_state: dict[str, Any],
    policy_inputs: dict[str, Any],
):
    default = ("totalDeposited", current_state["totalDeposited"])
    if policy_inputs["step"] != "depositing":
        return default

    agent_payload: list[tuple[dict[str, Any], int]] = policy_inputs["agents"]
    current_agents: list = current_state["agents"]
    agent, _ = agent_payload[-1]
    i_agent = current_agents.index(agent)

    deposit_amount: int = initial_state["agents"][i_agent]["DAI"]

    return ("totalDeposited", current_state["totalDeposited"] - deposit_amount)


# https://leetcode.com/problems/maximum-points-you-can-obtain-from-cards/

def maxScore(cardPoints: list, k: int):
    max_point = 0
    l, r = len(cardPoints) - k, len(cardPoints) - 1
    cur_point = sum(cardPoints[l:r + 1])

    for i in range(k + 1):
        max_point = max(max_point, cur_point)
        cur_point -= cardPoints[l % len(cardPoints)]
        l += 1
        r += 1
        cur_point += cardPoints[r % len(cardPoints)]

    return max_point

if __name__ == "__main__":
    cards = [96, 90, 41, 82, 39, 74, 64, 50, 30]
    print(maxScore(cards, 8))


import os

from file_handler import *

class Dictionary:
    """ Represents a dictionary. """

    def __init__(self, filepath):
        """
        :param filepath: a string
        """
        self._dictionary = None
        self.__load_dictionary(filepath)

    def __load_dictionary(self, filepath):
        """
        Gets and assigns a dict object.
        :param filepath: a string
        :return: none
        """
        ext = os.path.splitext(filepath)[1]
        try:
            self._dictionary = FileHandler.load_data(
                filepath, ext)
        except InvalidFileTypeError as e:
            print(e)

    def query_definition(self, word):
        """
        Tries to find the word in the dictionary. If it finds it,
        appends the query and definition to a text file, otherwise
        it returns None.
        :param word: a string
        :return: a string or None
        """
        definition = None
        try:
            definition = self._dictionary[word.lower()][0]
        except KeyError:
            try:
                definition = self._dictionary[word.title()][0]
            except KeyError:
                print("Could not find " + word + " in dictionary")

        if definition is None:
            return None
        else:
            line = word + ": " + definition + "\n"
            FileHandler.write_lines("queries.txt", line)
            return definition

    def get_dictionary(self):
        """
        Gets the dictionary.
        :return: a dict
        """
        return self._dictionary

def main():
    """
    Drives the program.
    :return: None
    """
    my_dictionary = createDictionary()

    if my_dictionary.get_dictionary() is None:
        return

    user_input = None

    while user_input != "exitprogram":
        print("Dictionary")
        print("----------")
        print("1. Make a query")
        string_input = input("Enter '1' or 'exitprogram': ")

        if string_input == '':
            continue

        try:
            user_input = int(string_input)
        except ValueError:
            user_input = string_input

        if user_input == 1:
            word = input("What word do you want to search for? ")
            result = my_dictionary.query_definition(word)
            if result is not None:
                print(result)
            input("Press ENTER to continue")
        elif user_input == "exitprogram":
            pass
        else:
            print("Please enter a valid input")

def createDictionary():
    """
    Prompts the user for name of file containing the dictionary data.
    :return: a dict
    """
    file = input("Enter the file name: ")
    try:
        dictionary = Dictionary(file)
    except FileNotExistError as e:
        print(e)
        return createDictionary()
    else:
        return dictionary

if __name__ == "__main__":
    main()


# Utwórz dowolną krotkę zawierającą kilka wartości np. 10.
# Pozwól użytkownikowi podać dowolny index oraz wartość.
# Spróbuj w krotce podmienić wartość na zadanym indeksie.
# Obsłuż błąd
tuple=(1,4,2,6,4,7,4,5,3,2,4,6)
index= int(input('Podaj index: '))
value=int(input('Podaj wartosc: '))
try:
    tuple[index]=value
except Exception as err:
    print ("Błąd: ",err)


from __future__ import annotations
from functools import partial
import numpy as np
from typing import TYPE_CHECKING

import panel as pn
from libertem.udf.raw import PickUDF
from libertem.udf.sumsigudf import SumSigUDF

from ..live_plot import AperturePlot
from ..base import UIState, JobResults
from .base import UIWindow, UDFWindowJob, WindowProperties
from ..display.display_base import Cursor
from ..utils import get_initial_pos, PointYX

if TYPE_CHECKING:
    from libertem_live.detectors.base.acquisition import AcquisitionProtocol
    from libertem.udf.base import UDF
    from ..results.results_manager import ResultRow
    from libertem.api import DataSet

class PickUDFBaseWindow(UIWindow):
    pick_cls = PickUDF

    def _pick_base(self, dataset: DataSet):
        self._udf_pick = self.pick_cls()
        roi = np.zeros(dataset.shape.nav, dtype=bool)
        roi[0, 0] = True
        self.sig_plot = AperturePlot.new(
            dataset,
            self._udf_pick,
            roi=roi,
            channel='intensity',
            title=self._pick_title(),
        )
        self._last_pick: PointYX | None = None

        self.nav_plot = AperturePlot.new(
            dataset,
            SumSigUDF(),
            title='Scan grid',
        )

        (ny, nx), _, _ = get_initial_pos(dataset.shape.nav)
        self._nav_cursor = Cursor.new().from_pos(nx, ny)
        self._nav_cursor.on(self.nav_plot.fig)
        self._nav_cursor.editable()
        self._nav_cursor.cds.on_change(
            'data',
            partial(self.run_this_bk, run_from=self._cds_pick_job),
        )
        self.nav_plot.fig.toolbar.active_drag = self.nav_plot.fig.tools[-1]
        self.toolbox = pn.Column()

    def _standard_layout(
        self,
        left_before=(),
        left_after=(),
        right_before=(),
        right_after=(),
    ):
        self.inner_layout.extend((
            pn.Column(
                *left_before,
                self.nav_plot.layout,
                self.toolbox,
                *left_after,
            ),
            pn.Column(
                *right_before,
                self.sig_plot.layout,
                *right_after,
            )
        ))

    def _cds_pick_job(
        self,
        state: UIState,
        dataset: DataSet | AcquisitionProtocol,
        roi: np.ndarray | None,
        quiet: bool = True,
        with_udfs: list[UDF] | None = None,
    ):
        if state == UIState.LIVE:
            return

        # Proceed even if ROI is not None, if this is the only window
        # then the global ROI, if any, will be ignored
        # if roi is not None:
        #     return

        coords = self._nav_cursor.current_pos(
            to_int=True,
            clip_to=dataset.shape.nav,
        )
        if coords is None:
            return
        cx, cy = coords

        # import sparse
        # roi = sparse.COO(
        #     np.asarray([(cy,), (cx,)]),
        #     True,
        #     shape=dataset.shape.nav,
        # )
        # sparse deactivated because of import / first-run lag
        roi = np.zeros(
            dataset.shape.nav,
            dtype=bool,
        )
        roi[cy, cx] = True

        params = {
            'cx': cx,
            'cy': cy,
        }

        if with_udfs is None:
            with_udfs = [self._udf_pick]

        return UDFWindowJob(
            self,
            with_udfs,
            [self.sig_plot],
            result_handler=self._complete_cds_pick_job,
            params=params,
            roi=roi,
            quiet=quiet,
        )

    def reset_title(self):
        self.sig_plot.fig.title.text = self._pick_title(cyx=self._last_pick)

    def _pick_title(
        self,
        cyx: tuple[int, int] | None = None,
        suffix: str | None = None,
        title_stub: str = 'Pick frame',
    ):
        if cyx is None:
            return title_stub
        cy, cx = cyx
        pad_suffix = ''
        if suffix is not None:
            pad_suffix = f' {suffix}'
        return f'{title_stub} (y={cy}, x={cx}){pad_suffix}'

    def _complete_cds_pick_job(
        self,
        job: UDFWindowJob,
        job_results: JobResults,
        with_push: bool = True,
    ) -> tuple[ResultRow, ...]:
        if not job.udfs:
            return tuple()

        cy, cx = job.params['cy'], job.params['cx']
        self._last_pick = PointYX(cy, cx)
        self.reset_title()
        if with_push:
            self.sig_plot.push()
        return tuple()

class PickUDFWindow(PickUDFBaseWindow):
    @staticmethod
    def default_properties():
        return WindowProperties(
            'pick_frame',
            'PickUDF',
            self_run_only=True,
            header_activate=False,
        )

    def initialize(self, dataset: DataSet, with_layout: bool = True):
        self._pick_base(dataset)
        if with_layout:
            self._standard_layout()
        self.link_image_plot('Nav', self.nav_plot, ('nav',))
        return self

    def get_job(
        self,
        state: UIState,
        dataset: DataSet | AcquisitionProtocol,
        roi: np.ndarray | None,
    ):
        return self._cds_pick_job(state, dataset, roi)

    def complete_job(
        self,
        job: UDFWindowJob,
        job_results: JobResults,
    ):
        return self._complete_cds_pick_job(job, job_results)


import discord
import time as t
from discord.ext import commands
from discord.commands import slash_command
from function import time_conv
import asyncio
from typing import Optional
from discord import Member

class mod(commands.Cog,name='mod'):

  def __init__(self,bot):
    self.bot = bot

  @slash_command(name='mute',description='This command mutes people.')
  @commands.has_permissions(administrator=True) #permissions
  async def mute(self, ctx, user:Member,time:Optional[str]= "1i",reason:Optional[str]=None):
    unixCode = int(t.time())

    mute_time= time_conv(time)
    role = discord.utils.get(ctx.guild.roles, name="Muted")
    print_time = unixCode + mute_time
    if role == None:
      await ctx.respond('Created a Mute role')
      role = await ctx.guild.create_role(name="Muted", permissions=discord.Permissions(send_messages=False))
      await role.edit(colour=0x000000)

    if role.position > ctx.author.top_role.position:
      return await ctx.respond('**:x: | That role is above your top role!**')
    if role in user.roles:
      await ctx.respond(f"{user.mention} is already muted")
    else:
      pfp = user.avatar
      await user.add_roles(role) #mutes the user
      embed=discord.Embed(title="Muted", description=f"Muted {user.mention} \n Unmuted: <t:{print_time}:R> \n Reason: {reason}", color=0x1c1c1c)
      embed.set_thumbnail(url=(pfp))
      await ctx.respond(embed=embed)

      await asyncio.sleep(mute_time)
      await user.remove_roles(role)
      await ctx.send(f'{user.mention} was Unmuted <t:{unixCode}:R>')

  @slash_command(name = 'unmute',description='unmutes users who have been muted before')
  @commands.has_permissions(administrator=True) #permissions
  async def unmute(self,ctx, user:Member):
    role = discord.utils.get(ctx.guild.roles, name="Muted")
    pfp = user.avatar

    if role.position > ctx.author.top_role.position:
      return await ctx.respond('**:x: | That role is above your top role!**')

    if role not in user.roles:
      await ctx.respond(f"{user.mention} is already unmuted")

    else:
      await user.remove_roles(role)
      embed = discord.Embed(title="unmute", description=f" unmuted {user.mention}",color=0x1c1c1c)
      embed.set_thumbnail(url=(pfp))
      await ctx.respond(embed=embed)

  @slash_command(name = 'kick',description='this command kicks users')
  @commands.has_permissions(administrator=True) #permissions
  async def kick(self, ctx, user:Member,reason:Optional[str]=None):

    pfp = user.avatar #gets user's pfp

    embedDM=discord.Embed(title="Kicked", description=f"You were Kicked from **{ctx.guild.name}** \n Reason: **{reason}**", color=0x1c1c1c) #sends this embed to the kicked user
    embedDM.set_thumbnail(url=(pfp))
  #if user == bot.user:
    #return
  #else:
    #await user.send(embed=embedDM)
    embed=discord.Embed(title="Kicked", description=f"{user.mention} was Kicked from **{ctx.guild.name}** \n Reason: **{reason}**", color=0x1c1c1c) #sends this embed in the ctx channl
    embed.set_thumbnail(url=(pfp))
    await ctx.respond(embed=embed)
    await user.kick(reason=reason) #kicks the user

  @slash_command(name = 'role',description='Assigns or Unassigns a role to user')
  @commands.has_permissions(administrator=True) #permissions
  async def role(self,ctx,role : discord.Role, user : Optional[Member]=None):

    user = ctx.author if user == None else user
    pfp = user.avatar
    if role.position > ctx.author.top_role.position:
      return await ctx.respond('**:x: | That role is above your top role!**',ephemeral=True)
    if role in user.roles:
      try:
        await user.remove_roles(role) #removes the role if user already has
        embed=discord.Embed(title='',description=f"Removed {role} from {user.mention}")
        embed.set_thumbnail(url=pfp)
        await ctx.respond(embed=embed)
      except:
        embed = discord.Embed(title='Permission Error',description="**I do not have the permission to do that**\n* That role's position is higher than mine",ephemeral=True)
        embed.set_thumbnail(url=pfp)
        return await ctx.respond(embed=embed)
    else:
      try:
        await user.add_roles(role) #adds role if not already has it
        embed=discord.Embed(title='',description=f"Added {role} from {user.mention}")
        embed.set_thumbnail(url=pfp)
        await ctx.respond(embed=embed)
      except:
        embed = discord.Embed(title='Permission Error',description="**I do not have the permission to do that**\n* That role's position is higher than mine", ephemeral=True)
        embed.set_thumbnail(url=pfp)
        return await ctx.respond(embed=embed)

def setup(bot):
	bot.add_cog(mod(bot))


import logging
import sqlite3
from base64 import b64encode
from typing import Optional, Union

from mvt.common.utils import check_for_links, convert_mactime_to_iso

from ..base import IOSExtraction

SMS_BACKUP_IDS = [
    "3d0d7e5fb2ce288813306e4d4636395e047a3d28",
]
SMS_ROOT_PATHS = [
    "private/var/mobile/Library/SMS/sms.db",
]

class SMS(IOSExtraction):
    """This module extracts all SMS messages containing links."""

    def __init__(
        self,
        file_path: Optional[str] = None,
        target_path: Optional[str] = None,
        results_path: Optional[str] = None,
        module_options: Optional[dict] = None,
        log: logging.Logger = logging.getLogger(__name__),
        results: Optional[list] = None,
    ) -> None:
        super().__init__(
            file_path=file_path,
            target_path=target_path,
            results_path=results_path,
            module_options=module_options,
            log=log,
            results=results,
        )

    def serialize(self, record: dict) -> Union[dict, list]:
        text = record["text"].replace("\n", "\\n")
        sms_data = f"{record['service']}: {record['guid']} \"{text}\" from {record['phone_number']} ({record['account']})"
        return [
            {
                "timestamp": record["isodate"],
                "module": self.__class__.__name__,
                "event": "sms_received",
                "data": sms_data,
            },
            {
                "timestamp": record["isodate_read"],
                "module": self.__class__.__name__,
                "event": "sms_read",
                "data": sms_data,
            },
        ]

    def check_indicators(self) -> None:
        for message in self.results:
            alert = "ALERT: State-sponsored attackers may be targeting your iPhone"
            if message.get("text", "").startswith(alert):
                self.log.warning(
                    "Apple warning about state-sponsored attack received on the %s",
                    message["isodate"],
                )

        if not self.indicators:
            return

        for result in self.results:
            message_links = result.get("links", [])
            # Making sure not link was ignored
            if message_links == []:
                message_links = check_for_links(result.get("text", ""))
            ioc = self.indicators.check_domains(message_links)
            if ioc:
                result["matched_indicator"] = ioc
                self.detected.append(result)

    def run(self) -> None:
        self._find_ios_database(backup_ids=SMS_BACKUP_IDS, root_paths=SMS_ROOT_PATHS)
        self.log.info("Found SMS database at path: %s", self.file_path)

        try:
            conn = sqlite3.connect(self.file_path)
            cur = conn.cursor()
            cur.execute(
                """
                SELECT
                    message.*,
                    handle.id as "phone_number"
                FROM message, handle
                WHERE handle.rowid = message.handle_id;
            """
            )
            # Force the query early to catch database issues
            items = list(cur)
        except sqlite3.DatabaseError as exc:
            conn.close()
            if "database disk image is malformed" in str(exc):
                self._recover_sqlite_db_if_needed(self.file_path, forced=True)
                conn = sqlite3.connect(self.file_path)
                cur = conn.cursor()
                cur.execute(
                    """
                    SELECT
                        message.*,
                        handle.id as "phone_number"
                    FROM message, handle
                    WHERE handle.rowid = message.handle_id;
                """
                )
                items = list(cur)
            else:
                raise exc
        names = [description[0] for description in cur.description]

        for item in items:
            message = {}
            for index, value in enumerate(item):
                # We base64 escape some of the attributes that could contain
                # binary data.
                if (
                    names[index] == "attributedBody"
                    or names[index] == "payload_data"
                    or names[index] == "message_summary_info"
                ) and value:
                    value = b64encode(value).decode()

                # We store the value of each column under the proper key.
                message[names[index]] = value

            # We convert Mac's ridiculous timestamp format.
            message["isodate"] = convert_mactime_to_iso(message["date"])
            message["isodate_read"] = convert_mactime_to_iso(message["date_read"])
            message["direction"] = (
                "sent" if message.get("is_from_me", 0) == 1 else "received"
            )

            # Sometimes "text" is None instead of empty string.
            if not message.get("text", None):
                message["text"] = ""

            # Extract links from the SMS message.
            message_links = check_for_links(message.get("text", ""))
            message["links"] = message_links
            self.results.append(message)

        cur.close()
        conn.close()

        self.log.info("Extracted a total of %d SMS messages", len(self.results))


"""Split for course-internal scoring

Create a time-based train-test split from the orders. As in the real evaluation, the test split
comprises exactly four weeks following the training period. We make sure that all user-item
combinations occuring in the test split also appear in the training split.
"""

import pathlib

import pandas as pd

DATA_DIR = pathlib.Path('data/')
LAST_TRAIN_DAY = pd.Timestamp('2020-12-31')

if __name__ == '__main__':
    orders = pd.read_csv(DATA_DIR / 'orders.csv', sep='|', parse_dates=['date'])
    submission = pd.read_csv(DATA_DIR / 'submission.csv', sep='|')

    orders_train = orders[orders['date'] <= LAST_TRAIN_DAY]
    solution = orders_train[['userID', 'itemID']].copy()
    # Remove repeated orders:
    solution.drop_duplicates(inplace=True)
    # Keep only train user-item combinations in test that appear in DMC test set:
    solution = solution.merge(submission[['userID', 'itemID']])
    # Find the first date after training period when item is purchased by a user
    first_replenishment = orders[orders['date'] > LAST_TRAIN_DAY].groupby(
        ['userID', 'itemID'])['date'].min().reset_index()
    # Add this information; note that some items might not be replenished, and replenishment of
    # items not appearing in "solution" is not interesting for us -> therefore LEFT join:
    solution = solution.merge(first_replenishment, how='left')
    # Create target variable by discretizing replenishment date into four weeks + out of test period
    intervals = [LAST_TRAIN_DAY + pd.Timedelta(days=x * 7) for x in range(5)]  # left-open intervals
    solution['prediction'] = pd.cut(solution['date'], bins=intervals, labels=[1, 2, 3, 4])
    solution['prediction'] = solution['prediction'].astype('Int64').fillna(0)
    solution.drop(columns='date', inplace=True)
    # Order by userID and itemID to remove any temporal information:
    solution.sort_values(by=['userID', 'itemID'], inplace=True)
    # Create submission by setting target column emtpy:
    submission = solution[['userID', 'itemID']].copy()
    submission['prediction'] = float('nan')

    orders_train.to_csv(DATA_DIR / 'split_orders.csv', sep='|', index=False)
    submission.to_csv(DATA_DIR / 'split_submission.csv', sep='|', index=False)
    solution.to_csv(DATA_DIR / 'split_solution.csv', sep='|', index=False)


# https://www.hackerrank.com/challenges/s10-least-square-regression-line/problem?isFullScreen=true

def mean(arr):
    return sum(arr)/len(arr)

def lin_reg(x, y, n):

    tot_x = sum(x)
    tot_y = sum(y)

    xsq = [i**2 for i in x]
    tot_xsq = sum(xsq)

    xy = [i*j for i, j in zip(x, y)]
    tot_xy = sum(xy)

    b = (n * tot_xy - tot_x * tot_y)/(n * tot_xsq - tot_x ** 2)
    a = mean(y) - b * mean(x)

    return a, b

def main():
    n = 5
    x, y = [0] * n, [0] * n

    for i in range(n):
        x[i], y[i] = map(int, input().split())

    a, b = lin_reg(x, y, n)

    result = a + b * 80
    print("{:.3f}".format(result))

if __name__ == "__main__":
    main()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/1/30 14:35
# @Author  : qqc
# @File    : threading_tool.py
# @Software: PyCharm

from concurrent.futures import ThreadPoolExecutor, as_completed

def threading_pool_tool(worker, params):
    with ThreadPoolExecutor(4) as executor:
        da = ''
        if params:
            da = [executor.submit(worker, params)
                  ]
        else:
            da = [executor.submit(worker)
                  ]
        for future in as_completed(da):
            data = future.result()
            print(data, "******************************************")
            return data


import numpy as np

import scipy.sparse
from scipy.spatial.distance import cdist

from ase import Atoms

def get_adjacency_matrix(radius, pos1, pos2=None, output_type="coo_matrix"):
    """Calculates a sparse adjacency matrix by only considering distances
    within a certain cutoff. Uses a k-d tree to reach O(n log(N)) time
    complexity.

    Args:
        radius(float): The cutoff radius within which distances are
            calculated. Distances outside this radius are not included.
        pos1(np.ndarray): A list of N-dimensional positions.
        pos2(np.ndarray): A list of N-dimensional positions. If not provided,
            is assumed to be the same as pos1.
        output_type(str): Which container to use for output data. Options:
            "dok_matrix", "coo_matrix", "dict", or "ndarray". Default:
            "dok_matrix".

    Returns:
        dok_matrix | np.array | coo_matrix | dict: Symmetric sparse 2D
        matrix containing the pairwise distances.
    """
    tree1 = scipy.spatial.cKDTree(
        pos1,
        leafsize=16,
        compact_nodes=True,
        copy_data=False,
        balanced_tree=True,
        boxsize=None,
    )
    if pos2 is None:
        pos2 = pos1
    tree2 = scipy.spatial.cKDTree(
        pos2,
        leafsize=16,
        compact_nodes=True,
        copy_data=False,
        balanced_tree=True,
        boxsize=None,
    )
    dmat = tree1.sparse_distance_matrix(tree2, radius, output_type=output_type)

    return dmat

def get_adjacency_list(adjacency_matrix):
    """Used to transform an adjacency matrix into an adjacency list. The
    adjacency list provides much faster access to the neighbours of a node.

    Args:
        adjacency_matrix(scipy.sparse.spmatrix): The adjacency matrix from
            which the adjacency list is constructed from. Any of the scipy
            sparse matrix classes.

    Returns:
        list: A list of neighbouring indices. The list of neighbouring indices
        for atom at index i is given by accessing the ith element of this list.
    """
    # Ensure that we have a coo-matrix
    if type(adjacency_matrix) != scipy.sparse.coo_matrix:
        adjacency_matrix = adjacency_matrix.tocoo()

    # Build adjacency list
    adjacency_list = [[] for i in range(adjacency_matrix.shape[0])]
    for i, j in zip(adjacency_matrix.row, adjacency_matrix.col):
        adjacency_list[i].append(j)

    return adjacency_list

def get_extended_system(system, radial_cutoff, centers=None, return_cell_indices=False):
    """Used to create a periodically extended system. If centers are not
    specified, simply takes returns the original system multiplied by an
    integer amount of times in each direction to cover the radial cutoff. If
    centers are provided, returns the exact atoms that are within the given
    radial cutoff from the given centers.

    Args:
        original_system (ase.Atoms): The original periodic system to duplicate.
        radial_cutoff (float): The radial cutoff to use in constructing the
            extended system.
        centers (np.ndarray): Array of xyz-coordinates from which the distance
            is calculated. If provided, these centers are used to calculate the
            exact distance and only atoms within the radial cutoff from these
            centers are returned.
        return_cell_indices (boolean): Whether to return an array of cell
            indices for each atom in the extended system.

    Returns:
        ase.Atoms | tuple: If return_cell_indices is False, returns the new
        extended system. Else returns a tuple containing the new extended
        system as the first entry and the index of the periodically repeated
        cell for each atom as the second entry.
    """
    # Determine the upper limit of how many copies we need in each cell vector
    # direction. We take as many copies as needed to reach the radial cutoff.
    # Notice that we need to use vectors that are perpendicular to the cell
    # vectors to ensure that the correct atoms are included for non-cubic cells.
    cell = np.asarray(system.get_cell())
    pbc = system.get_pbc()
    a1, a2, a3 = cell[0], cell[1], cell[2]
    b1 = np.cross(a2, a3, axis=0)
    b2 = np.cross(a3, a1, axis=0)
    b3 = np.cross(a1, a2, axis=0)
    p1 = np.dot(a1, b1) / np.dot(b1, b1) * b1  # Projections onto perpendicular vectors
    p2 = np.dot(a2, b2) / np.dot(b2, b2) * b2
    p3 = np.dot(a3, b3) / np.dot(b3, b3) * b3
    xyz_arr = np.linalg.norm(np.array([p1, p2, p3]), axis=1)
    cell_images = np.ceil(radial_cutoff / xyz_arr)
    nx = int(cell_images[0]) if pbc[0] else 0
    ny = int(cell_images[1]) if pbc[1] else 0
    nz = int(cell_images[2]) if pbc[2] else 0
    n_copies_axis = np.array([nx, ny, nz], dtype=int)

    # If no centers are given, and the cell indices are not requested, simply
    # return the multiplied system. This is much faster.
    if centers is None and not return_cell_indices:
        n_atoms = len(system)
        n_rep = np.product(2 * n_copies_axis + 1)  # Number of repeated copies
        ext_pos = np.tile(system.get_positions(), (n_rep, 1))

        # Calculate the extended system positions so that the original cell
        # stays in place: both in space and in index
        i_curr = 0
        for m0 in np.append(np.arange(0, nx + 1), np.arange(-nx, 0)):
            for m1 in np.append(np.arange(0, ny + 1), np.arange(-ny, 0)):
                for m2 in np.append(np.arange(0, nz + 1), np.arange(-nz, 0)):
                    ext_pos[i_curr : i_curr + n_atoms] += np.dot((m0, m1, m2), cell)
                    i_curr += n_atoms

        ext_symbols = np.tile(system.get_atomic_numbers(), n_rep)
        extended_system = Atoms(
            positions=ext_pos,
            symbols=ext_symbols,
        )

        return extended_system

    # If centers are given and/or cell indices are needed, the process is done
    # one cell at a time to keep track of the cell inded and the distances.
    # This is a bit slower.
    else:
        # We need to specify that the relative positions should not be wrapped.
        # Otherwise the repeated systems may overlap with the positions taken
        # with get_positions()
        relative_pos = np.array(system.get_scaled_positions(wrap=False))
        numbers = np.array(system.numbers)
        cartesian_pos = np.array(system.get_positions())

        # Create copies of the cell but keep track of the atoms in the
        # original cell
        num_extended = []
        pos_extended = []
        num_extended.append(numbers)
        pos_extended.append(cartesian_pos)
        a = np.array([1, 0, 0])
        b = np.array([0, 1, 0])
        c = np.array([0, 0, 1])
        cell_indices = [np.zeros((len(system), 3), dtype=int)]

        for i in range(-n_copies_axis[0], n_copies_axis[0] + 1):
            for j in range(-n_copies_axis[1], n_copies_axis[1] + 1):
                for k in range(-n_copies_axis[2], n_copies_axis[2] + 1):
                    if i == 0 and j == 0 and k == 0:
                        continue

                    # Calculate the positions of the copied atoms and filter
                    # out the atoms that are farther away than the given
                    # cutoff.
                    num_copy = np.array(numbers)
                    pos_copy = np.array(relative_pos)

                    pos_shifted = pos_copy - i * a - j * b - k * c
                    pos_copy_cartesian = np.dot(pos_shifted, cell)

                    # Only distances to the atoms within the interaction limit
                    # are considered.
                    distances = cdist(pos_copy_cartesian, centers)
                    weight_mask = distances < radial_cutoff

                    # Create a boolean mask that says if the atom is within the
                    # range from at least one atom in the original cell
                    valids_mask = np.any(weight_mask, axis=1)

                    if np.any(valids_mask):
                        valid_pos = pos_copy_cartesian[valids_mask]
                        valid_num = num_copy[valids_mask]
                        valid_ind = np.tile(
                            np.array([i, j, k], dtype=int), (len(valid_num), 1)
                        )

                        pos_extended.append(valid_pos)
                        num_extended.append(valid_num)
                        cell_indices.append(valid_ind)

        pos_extended = np.concatenate(pos_extended)
        num_extended = np.concatenate(num_extended)
        cell_indices = np.vstack(cell_indices)

        extended_system = Atoms(
            positions=pos_extended, numbers=num_extended, cell=cell, pbc=False
        )

        return extended_system, cell_indices


import json
import os
import requests
import random
import telegram
import map_logic
from telegram.ext import *

TOKEN = os.environ['telegram']

updater = Updater(token=TOKEN)

def init(bot,update):
    name = update.message.chat.first_name
    bot.send_message(chat_id=update.message.chat_id, text="Hi " + name + "!, How may i help? Might want to use /help for a start")

def getLoc(bot,update):
    try:
        loc_key = telegram.KeyboardButton(text="Send Current Location", request_location = True)
        keys = [[loc_key]]
        reply_markup = telegram.ReplyKeyboardMarkup(keys, resize_keyboard = True)
        bot.send_message(chat_id=update.message.chat_id, text="Share Location?", reply_markup=reply_markup)
    except Exception as e:
        print(e)

def help(bot,update):
     try:
        bot.send_message(chat_id=update.message.chat_id, text="Commands: /start, /getLoc                             \
        Enter <latitude,longitude> to query clusters manually")
     except Exception as e:
        print(e)

def current_loc_query(bot,update):
    try:
        print(update)
        bot.send_message(chat_id=update.message.chat_id, text="Here is the result for your current location")
        longitude = update.message.location.longitude
        latitude = update.message.location.latitude
        mh = map_logic.MapHandler(latitude,longitude)
        print(mh.result)

        if(mh.result == None):
            result = "No clusters found"
        else:
            result = mh.result

        bot.send_message(chat_id=update.message.chat_id, text=result)

    except Exception as e:
        print(e)

def manual_loc_query(bot,update):
    try:
        print(update)
        bot.send_message(chat_id=update.message.chat_id, text="Here is the result from manual query")
        text = update.message.text.split(",")
        latitude = float(text[0])
        longitude = float(text[1])
        mh = map_logic.MapHandler(latitude,longitude)
        print(mh.result)

        if(mh.result == None):
            result = "No clusters found"
        else:
            result = mh.result

        bot.send_message(chat_id=update.message.chat_id, text=result)

    except Exception as e:
        print(e)

# add the handlers
updater.dispatcher.add_handler(CommandHandler('start', init))
updater.dispatcher.add_handler(CommandHandler('getLoc', getLoc))
updater.dispatcher.add_handler(CommandHandler('help', help))
updater.dispatcher.add_handler(MessageHandler(Filters.location, current_loc_query))
updater.dispatcher.add_handler(MessageHandler(Filters.text, manual_loc_query))

updater.start_polling()

#allow exit with Ctrl + C
updater.idle()


# http://www.geeksforgeeks.org/given-sorted-array-number-x-find-pair-array-whose-sum-closest-x/
import sys

def closest_sum(arr, summ):
    i = 0
    j = len(arr) - 1
    prev_sum = sys.maxsize
    while i < j:
        print('arr[i] and arr[j]: ', arr[i], arr[j])
        if abs(arr[i] + arr[j] - summ) <= abs(prev_sum - summ):
            prev_sum = arr[i] + arr[j]
            print('The pair contributing to this new closest sum is ', i, j)
        if arr[i] + arr[j] < summ:
            i += 1
        else:
            j -= 1
    print(prev_sum)
    return prev_sum

print("Getting closest sum")
x = [10, 22, 28, 29, 35, 40, 54]
closest_sum(x, 54)
# Observe in the output - we had (22 + 35 = 57 and 57 - 54 = 3) - but this is not the 57 displayed
# Also we had then (22 + 29 = 51 and 51 - 54 = 3) - but 51 was not displayed
# Then we finally had (28 + 29 = 57 and 57 - 54 = 3) - this was the 57 that was displayed!
print("Getting closest sum")
x = [10, 22, 29, 29, 35, 40, 54]
closest_sum(x, 54)