from deepsnap.hetero_graph import HeteroGraph
import numpy as np
import h5py
import pickle
import torch
from torch_geometric.data import Dataset, Data
import pdb
import sys, os
sys.path.append(os.path.join(os.path.dirname("__file__"), '..', '..'))
from le_pde.utils import PDE_PATH, KARMAN3D_PATH
from le_pde.pytorch_net.util import plot_matrices
from le_pde.utils import get_root_dir, to_tuple_shape
from le_pde.utils import read_zipped_array, write_zipped_array

class Karman3D(Dataset):
    def __init__(
        self,
        dataset="karman3d",
        input_steps=1,
        output_steps=1,
        time_interval=1,
        is_y_diff=True,
        is_train=True,
        show_missing_files=False,
        data_format="pyg",
        verbose=False,
        transform=None,
        pre_transform=None,
    ):
        self.dataset = dataset
        if dataset in ["karman3d", "karman3d-small", "karman3d-large", "karman3d-large-s", "karman3d-large-d", "karman3d-large-s-d"]:
            self.root = os.path.join(KARMAN3D_PATH)
        else:
            raise
        self.input_steps = input_steps
        self.output_steps = output_steps
        self.time_interval = time_interval
        self.is_y_diff = is_y_diff
        self.is_train = is_train
        self.data_format = data_format

        self.t_cushion_input = self.input_steps * self.time_interval if self.input_steps * self.time_interval > 1 else 1
        self.t_cushion_output = self.output_steps * self.time_interval if self.output_steps * self.time_interval > 1 else 1

        self.verbose = verbose
        if dataset in ["karman3d", "karman3d-small"]:
            if self.is_train:
                self.dirname = "train"
            else:
                self.dirname = "test"
        elif dataset in ["karman3d-large", "karman3d-large-s", "karman3d-large-d", "karman3d-large-s-d"]:
            self.dirname = "raw"
        else:
            raise

        self.original_shape = (256, 128, 128)
        self.dyn_dims = 3
        if self.dataset == "karman3d-large-s-d":
            self.dyn_dims = 4
        if dataset in ["karman3d", "karman3d-small"]:
            self.n_simu = 5 if self.is_train else 5
            if self.is_train:
                self.time_stamps = 80
            else:
                self.time_stamps = 20
            self.time_stamps_effective = (self.time_stamps - self.t_cushion_input - self.t_cushion_output + 1) // self.time_interval
        elif dataset in ["karman3d-large", "karman3d-large-s", "karman3d-large-d", "karman3d-large-s-d"]:
            if self.is_train:
                self.start_time = {
                    "sim_Re_90989": 2000,
                    "sim_Re_92989": 2000,
                    "sim_Re_94989": 2000,
                    "sim_Re_95489": 1501,
                    "sim_Re_95989": 2000,
                }
                self.time_stamps = {
                    "sim_Re_90989": 500,
                    "sim_Re_92989": 500,
                    "sim_Re_94989": 500,
                    "sim_Re_95489": 400,
                    "sim_Re_95989": 500,
                }
                self.n_simu = len(self.start_time)
            else:
                self.start_time = {
                    "sim_Re_93989": 2000,
                    "sim_Re_94989_2": 1501,
                }
                self.time_stamps = {
                    "sim_Re_93989": 500,
                    "sim_Re_94989_2": 500,
                }
                self.n_simu = len(self.start_time)
        else:
            raise
        self.show_missing_files = show_missing_files
        print("root: ", self.root)
        super(Karman3D, self).__init__(self.root, transform, pre_transform)

    @property
    def raw_file_names(self):
        return [self.root + self.dirname]

    @property
    def processed_dir(self):
        return os.path.join(self.root, self.dirname)

    @property
    def processed_file_names(self):
        if self.dataset in ["karman3d", "karman3d-small"]:
            return ["sim_{:06d}/dens_{:06d}.npz".format(k, i) for k in range(self.n_simu) for i in range(1000, 1000 + self.time_stamps)] + [
                    "sim_{:06d}/velo_{:06d}.npz".format(k, i) for k in range(self.n_simu) for i in range(1000, 1000 + self.time_stamps)]
        elif self.dataset in ["karman3d-large", "karman3d-large-s", "karman3d-large-d", "karman3d-large-s-d"]:
            return ["{}/dens_{:06d}.npz".format(traj_name, i) for traj_name, time_stamps in self.time_stamps.items() for i in range(self.start_time[traj_name], self.start_time[traj_name] + time_stamps)] + [
                    "{}/velo_{:06d}.npz".format(traj_name, i) for traj_name, time_stamps in self.time_stamps.items() for i in range(self.start_time[traj_name], self.start_time[traj_name] + time_stamps)]
        else:
            raise

    def download(self):
        # Download to `self.raw_dir`.
        pass

    def _process(self):
        import warnings
        from typing import Any, List
        from torch_geometric.data.makedirs import makedirs
        def _repr(obj: Any) -> str:
            if obj is None:
                return 'None'
                return re.sub('(<.*?)\\s.*(>)', r'\1\2', obj.__repr__())

        def files_exist(files: List[str]) -> bool:
            # NOTE: We return `False` in case `files` is empty, leading to a
            # re-processing of files on every instantiation.
            return len(files) != 0 and all([os.path.exists(f) for f in files])

        f = os.path.join(self.processed_dir, 'pre_transform.pt')
        if os.path.exists(f) and torch.load(f) != _repr(self.pre_transform):
            warnings.warn(
                f"The `pre_transform` argument differs from the one used in "
                f"the pre-processed version of this dataset. If you want to "
                f"make use of another pre-processing technique, make sure to "
                f"sure to delete '{self.processed_dir}' first")

        f = os.path.join(self.processed_dir, 'pre_filter.pt')
        if os.path.exists(f) and torch.load(f) != _repr(self.pre_filter):
            warnings.warn(
                "The `pre_filter` argument differs from the one used in the "
                "pre-processed version of this dataset. If you want to make "
                "use of another pre-fitering technique, make sure to delete "
                "'{self.processed_dir}' first")

        if files_exist(self.processed_paths):  # pragma: no cover
            return

        if self.show_missing_files:
            missing_files = [file for file in self.processed_paths if not os.path.exists(file)]
            print("Missing files:")
            pp.pprint(sorted(missing_files))

        print('Processing...')

        makedirs(self.processed_dir)
        self.process()

        path = os.path.join(self.processed_dir, 'pre_transform.pt')
        if not os.path.isfile(path):
            torch.save(_repr(self.pre_transform), path)
        path = os.path.join(self.processed_dir, 'pre_filter.pt')
        if not os.path.isfile(path):
            torch.save(_repr(self.pre_filter), path)

        print('Done!')

    def get_edge_index(self, traj_name, start_time):
        edge_index_filename = os.path.join(self.processed_dir, "edge_index.p")
        mask_valid_filename = os.path.join(self.root, self.dirname, traj_name, "mask_index.p")
        if os.path.isfile(edge_index_filename) and os.path.isfile(mask_valid_filename):
            edge_index = pickle.load(open(edge_index_filename, "rb"))
            mask_valid = pickle.load(open(mask_valid_filename, "rb"))
            return edge_index, mask_valid
        velo_array = read_zipped_array(os.path.join(self.root, self.dirname, traj_name, "velo_{:06d}.npz".format(start_time)))
        velo_invalid_mask = velo_array[:, :-1, :-1, :-1, 0] == 0
        mask_valid = torch.BoolTensor(~velo_invalid_mask).flatten()
        depth, rows, cols = self.original_shape
        cube = np.arange(depth * rows * cols).reshape(depth, rows, cols)
        edge_list = []
        for h in range(depth):
            for i in range(rows):
                for j in range(cols):
                    if h + 1 < depth:
                        edge_list.append([cube[h, i, j], cube[h+1, i, j]])
                        edge_list.append([cube[h+1, i, j], cube[h, i, j]])
                    if i + 1 < rows: #and cube[i, j] not in velo_invalid_ids and cube[i+1, j] not in velo_invalid_ids:
                        edge_list.append([cube[h, i, j], cube[h, i+1, j]])
                        edge_list.append([cube[h, i+1, j], cube[h, i, j]])
                    if j + 1 < cols: #and cube[i, j]: #not in velo_invalid_ids and cube[i, j+1] not in velo_invalid_ids:
                        edge_list.append([cube[h, i, j], cube[h, i, j+1]])
                        edge_list.append([cube[h, i, j+1], cube[h, i, j]])
        edge_index = torch.LongTensor(edge_list).T
        pickle.dump(edge_index, open(edge_index_filename, "wb"))
        pickle.dump(mask_valid, open(mask_valid_filename, "wb"))
        return edge_index, mask_valid

    def process(self):
        pass

    def len(self):
        if self.dataset in ["karman3d", "karman3d-small"]:
            return self.time_stamps_effective * self.n_simu
        elif self.dataset in ["karman3d-large", "karman3d-large-s", "karman3d-large-d", "karman3d-large-s-d"]:
            return sum([(time_stamp - self.t_cushion_input - self.t_cushion_output + 1) // self.time_interval for time_stamp in self.time_stamps.values()])

    def get(self, idx):
        """
        The idx encodes both the id and time step of the data.
        """
        effective_time_stamps = (np.array(list(self.time_stamps.values())) - self.t_cushion_input - self.t_cushion_output + 1) // self.time_interval
        cum_time_stamps = np.cumsum(effective_time_stamps)
        gt = idx - cum_time_stamps >= 0
        if gt.any():
            sim_id = np.where(gt)[0][-1] + 1
            cum_time = cum_time_stamps[sim_id - 1]
        else:
            sim_id = 0
            cum_time = 0
        time_id = idx - cum_time

        traj_name = list(self.start_time)[sim_id]  # sim_Re_{Re}...
        traj_name_split = traj_name.split("_")
        reynolds_number = int(traj_name_split[traj_name_split.index("Re") + 1])
        nu_norm = torch.FloatTensor([1e5 / reynolds_number])
        start_time = self.start_time[traj_name]
        if self.verbose:
            print(f"sim_id: {sim_id}  traj_name: {traj_name}   start_time: {start_time}   time_id: {time_id}   input: ({start_time + time_id * self.time_interval + self.t_cushion_input -self.input_steps * self.time_interval}, {start_time + time_id * self.time_interval + self.t_cushion_input})  output: ({start_time + time_id * self.time_interval + self.t_cushion_input}, {start_time + time_id * self.time_interval + self.t_cushion_input + self.output_steps * self.time_interval})")
        x_velo = torch.FloatTensor(np.stack([read_zipped_array(os.path.join(self.root, self.dirname, traj_name, "velo_{:06d}.npz".format(start_time + time_id * self.time_interval + self.t_cushion_input + j))) for j in range(-self.input_steps * self.time_interval, 0, self.time_interval)], -2))  # [1, rows, cols, input_steps, 3]
        x_dens = torch.FloatTensor(np.stack([read_zipped_array(os.path.join(self.root, self.dirname, traj_name, "dens_{:06d}.npz".format(start_time + time_id * self.time_interval + self.t_cushion_input + j)))[...,None] for j in range(-self.input_steps * self.time_interval, 0, self.time_interval)], -2))  # [1, rows, cols, input_steps, 1]
        y_velo = torch.FloatTensor(np.stack([read_zipped_array(os.path.join(self.root, self.dirname, traj_name, "velo_{:06d}.npz".format(start_time + time_id * self.time_interval + self.t_cushion_input + j))) for j in range(0, self.output_steps * self.time_interval, self.time_interval)], -2))  # [1, rows, cols, output_steps, 3]
        y_dens = torch.FloatTensor(np.stack([read_zipped_array(os.path.join(self.root, self.dirname, traj_name, "dens_{:06d}.npz".format(start_time + time_id * self.time_interval + self.t_cushion_input + j)))[...,None] for j in range(0, self.output_steps * self.time_interval, self.time_interval)], -2))  # [1, rows, cols, output_steps, 1]
        x_velo = x_velo[:, :-1, :-1, :-1, :, :]
        y_velo = y_velo[:, :-1, :-1, :-1, :, :]
        col_mesh, row_mesh, depth_mesh = np.meshgrid(range(self.original_shape[2]), range(self.original_shape[1]), range(self.original_shape[0]))
        x_pos = torch.FloatTensor(np.stack([depth_mesh, row_mesh, col_mesh], -1).reshape(-1, 1, 3))
        if self.dataset == "karman3d-large-s":
            nu_tensor = nu_norm.expand(x_velo[...,-1:].shape)
            x_velo = torch.cat([nu_tensor, x_velo], -1)
        elif self.dataset == "karman3d-large-d":
            x_velo = torch.cat([x_dens, x_velo], -1)
            y_velo = torch.cat([y_dens, y_velo], -1)
        elif self.dataset == "karman3d-large-s-d":
            nu_tensor = nu_norm.expand(x_velo[...,-1:].shape)
            x_velo = torch.cat([nu_tensor, x_dens, x_velo], -1)
            y_velo = torch.cat([y_dens, y_velo], -1)
        x_pos = x_pos / x_pos.max() * 2
        edge_index, mask_valid = self.get_edge_index(traj_name, start_time)
        data = Data(
            x=x_velo.reshape(-1, *x_velo.shape[-2:]).clone(), # [number_nodes: 256 * 128 * 128, input_steps, 4]
            x_pos=x_pos.clone(),  # [number_nodes: 128 * 128, 2]
            y=y_velo.reshape(-1, *y_velo.shape[-2:]).clone(),
            edge_index=edge_index,
            mask=mask_valid,
            original_shape=self.original_shape,
            dyn_dims=self.dyn_dims,
            compute_func=(0, None),
            param=nu_norm,
        )
        if self.data_format == "deepsnap":
            data = HeteroGraph(
                edge_index={("n0", "0", "n0"): data.edge_index},
                node_feature={"n0": data.x},
                node_label={"n0": data.y},
                mask={"n0": data.mask},
                directed=True,
                original_shape=(("n0", data.original_shape),),
                dyn_dims=(("n0", to_tuple_shape(data.dyn_dims)),),
                compute_func=(("n0", to_tuple_shape(data.compute_func)),),
                param={"n0": data.param[None]} if hasattr(data, "param") else {"n0": torch.ones(1,1)},
                grid_keys=("n0",),
                part_keys=(),
            )
        return data

# In[ ]:

if __name__ == "__main__":
    import matplotlib.pylab as plt
    dataset = Karman3D(
        dataset="karman3d-large-s-d",
        input_steps=1,
        output_steps=1,
        time_interval=1,
        is_y_diff=True,
        is_train=False,
        show_missing_files=False,
        data_format="pyg",
        verbose=True,
        transform=None,
        pre_transform=None
    )
    data = dataset[0]
    x = data.x
    x_reshape = x[...,2].reshape(256, 128, 128)
    plt.imshow(x_reshape[:,:,60], cmap="jet")
    plt.show()

    # space:
    for tailin in range(10,200,1):
        data = dataset[0]
        x = data.x
        x_reshape = x[...,2].reshape(256, 128, 128)
        x = data.x
        x_reshape = x[...,1].reshape(256, 128, 128)
        plt.imshow(x_reshape[:,:,tailin], cmap="jet")
        plt.show()

    # time:
    for tailin in range(10,200,80):
        data = dataset[tailin]
        x = data.x
        x_reshape = x[...,1].reshape(256, 128, 128)
        plt.imshow(x_reshape[:,:,60], cmap="jet")
        plt.show()


"""
Simple bootstrapper intended to be used used to start the API as a daemon process
"""
import sys
import uvicorn

from lrp_fastapi_wrapper import FastAPI_Wrapper

API_HOST='localhost'
API_PORT=5000

def stand_up(host=API_HOST, port=API_PORT):
    app = FastAPI_Wrapper()
    uvicorn.run(app, host=host, port=port)

if __name__ == "__main__":
    stand_up(host=sys.argv[1], port=int(sys.argv[2]))


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

#Step1匯入自備餐具優惠餐廳csv檔
import csv
print("""
全台各地自備餐具與飲料袋享優惠之餐廳統計表

輸入0離開程式
輸入1查看餐廳優惠方式比例
輸入2查看優惠方式為集點之餐廳
輸入3查看優惠方式為折價之餐廳
輸入4查看優惠方式為贈送餐飲之餐廳
選擇查詢內容:
""")
#Step2讀取資料
#fn1 = r'C:\Allie\FinalProject\OwnedCutlery.csv'
fn1 = r'/Users/aichung/Desktop/final_project/OwnedCutlery.csv'
with open(fn1,encoding='utf8') as csvFile:
    csvReader = csv.reader(csvFile)
    cutleryData = list(csvReader)
    #print(cutleryData)
#Step3撈出資料並統計
#Step4 import plt以圖示比例

import matplotlib.pyplot as plt

GBType = list(set([cutleryData[i][7] for i in range(1,len(cutleryData))]))
count = [0]*len(GBType)#list
supplierName = list(set(cutleryData[i][1] for i in range(1,len(cutleryData))))
#整理完的labels

for i in range(1,len(cutleryData)):
    count[GBType.index(cutleryData[i][7])]+=1
#GBType = [[GBType[i],count[i]]for i in range(len(GBType))]

'''
while True:
    keyin =eval(input())
    if keyin ==0:
        print('Bye')
        break;
    elif keyin ==1:
        x = GBType#x = labels
        y = count
        plt.title('餐廳優惠方式統計表')
        plt.pie(y,labels=x, autopct="%1.1f%%")
        plt.show()
    elif keyin ==2:
        for i in range(1,len(cutleryData)):
            if '集點' in cutleryData[i][7]:
                print(cutleryData[i][1])
    elif keyin ==3:
        for i in range(1,len(cutleryData)):
            if '折價' in cutleryData[i][7]:
                print(cutleryData[i][1])
    elif keyin ==4:
        for i in range(1,len(cutleryData)):
            if '贈送餐飲' in cutleryData[i][7]:
                print(cutleryData[i][1])
    else:
        print('輸入錯誤')
'''

while True:
    keyin =eval(input())
    if keyin ==0:
        print('Bye')
        break;
    elif keyin ==1:
        x = GBType#x = labels
        y = count
        plt.title('餐廳優惠方式統計表')
        plt.pie(y,labels=x, autopct="%1.1f%%")
        plt.show()
    elif keyin ==2:
        for i in range(1,len(cutleryData)):
            if '集點' in cutleryData[i][7]:
                print(cutleryData[i][1])
    elif keyin ==3:
        for i in range(1,len(cutleryData)):
            if '折價' in cutleryData[i][7]:
                print(cutleryData[i][1])
    elif keyin ==4:
        for i in range(1,len(cutleryData)):
            if '贈送餐飲' in cutleryData[i][7]:
                print(cutleryData[i][1])
    else:
        print('輸入錯誤')


import urllib
from math import sqrt
import os

def mean(alist):
    mean = sum(alist) / len(alist)
    return mean
def standardDeviation(alist):
    theMean = mean(alist)
    sum = 0
    for item in alist:
        difference = item - theMean
        diffsq = difference ** 2
        sum = sum + diffsq
    sdev = sqrt(sum/(len(alist)-1))
    return sdev

def correlation(xlist, ylist):
    xbar = mean(xlist)
    ybar = mean(ylist)
    xstd = standardDeviation(xlist)
    ystd = standardDeviation(ylist)
    num = 0.0
    for i in range(len(xlist)):
        num = num + (xlist[i]-xbar) * (ylist[i]-ybar)
    corr = num / ((len(xlist)-1) * xstd * ystd)
    return corr

def stockCorrelate( ticker1, ticker2):
	url1 = urllib.urlopen('http://ichart.finance.yahoo.com/table.csv?s=%s' %ticker1)
	url2 = urllib.urlopen('http://ichart.finance.yahoo.com/table.csv?s=%s' %ticker2)

	t1Data = url1.readlines()
	t1Data = [line.split(',') for line in t1Data[1:]]
	t2Data = url2.readlines()
	t2Data = [line.split(',') for line in t2Data[1:]]
	t1Close= []
	t2Close= []

	for i in range(min(len(t1Data), len(t2Data))):
		if t1Data[i][0] == t2Data[i][0]:
			t1Close.append(float(t1Data[i][4]))
			t2Close.append(float(t2Data[i][4]))
	return correlation(t1Close, t2Close)


import os
import pandas
import sys
import time
data=[]
i1=[]
cnt=-1
word_list=[]
class estateDetails:
    def __init__(self,estateName,estateAddress,estateSize,estatePrice,estateOwner,estateCondition):
        self.estateName=estateName
        self.estateAddress=estateAddress
        self.estateSize=estateSize
        self.estatePrice=estatePrice
        self.estateOwner=estateOwner
        self.estateCondition=estateCondition

    def display_data(self):
        print("\nESTATE NAME -"+self.estateName+"\nESTATE ADDRESS - "+self.estateAddress+"\nESTATE SIZE -"+self.estateSize+"\nESTATE PRICE - "+self.estatePrice+"\nESTATE OWNER -"+self.estateOwner+"\nESTATE CONDITION -"+self.estateCondition)

    def pack(self,file):
        global cnt,i1
        pos=file.tell()
        buf=self.estateName+"|"+self.estateAddress+"|"+self.estateSize+"|"+self.estatePrice+"|"+self.estateOwner+"|"+self.estateCondition+"|"
        buf+="\n"
        file.write(buf)
        cnt+=1
        i1.append(index(self.estateName,pos))
        i1.sort(key = lambda x:x.estateName)

class index:
    def __init__(self,name,addr):
        self.estateName=name
        self.addr=addr

    def pack(self,file):
        buf1=self.estateName
        buf1+="\n"
        file.write(buf1)

def create_index():
    global cnt, pos, i1
    pos = 0
    try:
        with open("fulldetails.txt","r") as fp:
            line = fp.readline()
            while line:
                if line.startswith('*') or len(line) == 0:#if the record is deleted, dont add to index and read the next record
                    line = fp.readline()
                    pos = fp.tell()
                else:
                    fields=line.strip('\n').split("|")[:-1]
                    i1.append(index(fields[0], pos))
                    pos = fp.tell()
                    cnt += 1
                    line = fp.readline() #needed since when we delete, extra blank line is present at the end of the file
                    # i1.append(index(self.estateName,pos))
                    i1.sort(key = lambda x:x.estateName)#sort index list based on usn
    #        for y in i1:#to check if i1 is correct when prog. closedand opened and if it prints in sorted order
    #            print(y.usn,y.addr)
    except:
        pass

def find_index(name_srch):
    ind = -1
    for i in range(cnt+1):
        # print(i)
        if i1[i].estateName == name_srch:
            ind = i
            print(ind)
    return ind

def search():
    global i1,x
    name_srch = input("Enter the name of the estate to be found")
    ind = find_index(name_srch)
    if ind == -1:
        print('Record not found')
        return
    else:
        print('Record found and Updated\n')
        with open("fulldetails.txt","r") as fp:
            fp.seek(i1[ind].addr)
            line = fp.readline()
            fields=line.split("|")
            print("\nESTATE NAME -"+fields[0]+"\nESTATE ADDRESS - "+fields[1]+"\nESTATE SIZE -"+fields[2]+"\nESTATE PRICE - "+fields[3]+"\nESTATE OWNER -"+fields[4]+"\nESTATE CONDITION -"+fields[5])

            # print(line.strip('\n'))

    ch=input("Do you wish to modify ( y/n)\n")
    if ch=="y":
        for x in s:
            if name_srch==x.estateName:
                ch=input("Select the field to modify\n1.Address\n2.Size\n3.Price\n4.Owner\n5.Condition\n")
                if ch=='1':
                    newadd=input("Enter the new address\n")
                    x.estateAddress=newadd
                elif ch=='2':
                    newsize=input("Enter the new size\n")
                    x.estateSize=newsize
                elif ch=='3':
                    newprice=input("Enter the new price\n")
                    x.estatePrice=newprice
                elif ch=='4':
                    newowner=input("Enter the new owner\n")
                    x.estateOwner=newowner
                elif ch=='5':
                    newcond=input("Enter the new condition\n")
                    x.estateCondition=newcond
                else:
                    print("invalid option")

        with open("fulldetails.txt","w+") as fp:
            for x in s:
                x.pack(fp)

def unpack():
    with open("fulldetails.txt","r") as fp:
        for line in fp:
            fields=line.strip('\n').split("|")[:-1]#[:-1] is needed to not include last | char
            s.append(estateDetails(fields[0],fields[1],fields[2],fields[3],fields[4],fields[5]))
    with open("index.txt","r") as fp:
        for line in fp:
            fields=line.strip('\n')#[:-1] is needed to not include last | char
            p.append(index(fields,0))

create_index()
print("\n**************************WELCOME TO ESTATE PORTAL***************************")
print("\nENTER YOUR CHOICE")
while True:
    print()
    print()
    choice=input("1.Insert a record\n2.Search and Modify a record\n3.Delete record\n4.Visualize\n5.Exit\n")
    if choice=='1':
        estateName=input("Enter Estate Name\n")
        estateAddress=input("Enter Estate Address\n")
        estateSize=input("Enter Estate Size ( in Sqft)\n")
        estatePrice=input("Enter Estate Price (in  Rupees)\n")
        estateOwner=input("Enter Estate Owner\n")
        estateCondition=input("Enter Estate Condition ( Sale,Resale,Rent)\n")
        temp=estateDetails(estateName,estateAddress,estateSize,estatePrice,estateOwner,estateCondition)
        with open("fulldetails.txt","a+") as fp:
            temp.pack(fp)

        txt_fil = open("fulldetails.txt", "r")

        words2=[]
        word_occurrences = {}
        line_num = 0

        for lin in txt_fil:
            line_num += 1
            words = lin.split('|')
            words2.append(words[0])
        fp=open("index.txt","w").close()
        for word in sorted(words2):
            temp1=index(word,0)
            with open("index.txt","a+") as fp:
                temp1.pack(fp)
        txt_fil.close()
    elif choice == "2":
        s=[]
        p=[]
        unpack()
        search()
        # print("Record Updated")

    elif choice=="3":
        s=[]
        p=[]
        unpack()
        name_srch=input("Enter the Name of the house to be Deleted\n")
        flag=0
        with open("index.txt",'r') as fp2:
            for line in fp2:
                field=line.split("\n")[:-1]
                if name_srch==field[0]:
                    for x in s:
                    # field2=line1.split("|")[:-1]
                        if name_srch==x.estateName:
                            flag=1
                            print("Record found and deleted")
                            with open("fulldetailsdup.txt","w+") as fp:
                            #            fp.seek(0)
                            #            fp.truncate()
                                for x in s:
                                    if name_srch!=x.estateName:
                                        x.pack(fp)

                            with open("indexdup.txt","w+") as fp:
                            #            fp.seek(0)
                            #            fp.truncate()
                                for x in p:
                                    if name_srch!=x.estateName:
                                        x.pack(fp)

                            with open("fulldetailsdup.txt","r") as fp, open('fulldetails.txt', 'w') as fp1:
                                for line in fp:
                                    fp1.write(line)

                            with open("indexdup.txt","r") as fp, open('index.txt', 'w') as fp1:
                                for line in fp:
                                    fp1.write(line)

        if flag==0:
            print("House does not exist")

    elif choice=="4":
        os.system("python mixvisualize.py")

    elif choice=="5":
        exit()

    else :
        print("Invalid Input")


import random
import pandas as pd
from sklearn.datasets import make_classification

def create_fake_table_dataframe(
    n_samples: int,
    n_features: int,
    n_classes: int,
    n_repeated: int = 0,
) -> pd.DataFrame:
    X, y = make_classification(
        n_samples=n_samples,
        n_features=n_features,
        n_classes=n_classes,
        n_repeated=n_repeated,
        n_clusters_per_class=1,
        n_informative=5,
        scale=[
            random.choice([random.randint(50, 1000), random.randint(1, 5)])
            for _ in range(n_features)
        ],
    )

    dataset = {}
    for i in range(n_features):
        dataset[f"feature_{i+1}"] = X[:, i]
    dataset["label"] = y
    return pd.DataFrame(dataset)

if __name__ == "__main__":
    create_fake_table_dataframe(10000, 10, 5, 0).to_csv(
        "ten_thousand_samples.csv", index=False
    )


import streamlit as st
import pandas as pd
from DBconnect import get_database_session
from json import loads
from pathlib import Path

st.write("Test File")
df=pd.read_csv(Path("./extras/stock_info.csv"), encoding='utf8')
st.table(df)
result = df.to_json(orient="records")
st.write(result)

# test = poms_db()
# client=test.get_client()
# st.write("Hi : ",client.list_database_names())

test = get_database_session()
st.write("Databases details: ",test.list_database_names())

pims_db = test["pims_db"]
st.write("POMS collection details: ",pims_db.list_collection_names())

stock_table = pims_db['stock_table']
if not stock_table.count_documents({}):
    stock_table.insert_many(loads(result))
    # st.write(type(loads(result)))
st.write("Stock table row count: ",stock_table.count_documents({}))

test_frommongo = pd.DataFrame(list(stock_table.find({},{"_id": 0})))
st.table(test_frommongo)

# Update a value

# if stock_table.count_documents({'stock':'Bread'}):
#     st.write(stock_table.find({'stock':'Bread'})[0])

stock_table.update_one(
    { 'stock' : 'Bread'},
    {
      '$set' : { 'quantity' : 7 }
    }
)


from typing import Callable

import pytest
from alembic import command
from alembic.config import Config
from mixer.backend.sqlalchemy import mixer
from sqlalchemy.future import Connection
from sqlalchemy.orm import Session
from starlette.testclient import TestClient

from config.settings import settings
from database.db import SessionFactory, engine_factory
from database.models import Product
from main import create_app

@pytest.fixture(scope='session')
def engine():
    return engine_factory()

@pytest.fixture(scope='session', autouse=True)
def apply_migrations():
    config = Config(settings.BASE_DIR / 'alembic.ini')
    config.set_section_option('alembic', 'script_location', str(settings.BASE_DIR / 'migrations'))
    command.downgrade(config, 'base')
    command.upgrade(config, 'head')
    yield
    command.downgrade(config, 'base')
    command.upgrade(config, 'head')

@pytest.fixture(scope='session')
def test_app():
    app = create_app()
    return TestClient(app)

@pytest.fixture(scope='session')
def url_for(test_app) -> Callable:
    app = create_app()

    def inner(url_path: str) -> str:
        return app.url_path_for(url_path)

    return inner

@pytest.fixture
def xlsx_link():
    return 'https://docs.google.com/spreadsheets/d/11hqrBYKDtxTe7-NbPGDYMSVks-SO6f9b/export?format=xlsx&gid=1225459015'

@pytest.fixture
def db_session(engine) -> Session:
    with SessionFactory(bind=engine) as session:
        session.begin()
        try:
            yield session
        finally:
            session.rollback()

@pytest.fixture
def conn(engine) -> Connection:
    with engine.connect() as conn:
        yield conn

@pytest.fixture
def get_product():
    def inner(**kwargs):
        kwargs.setdefault('quantity', 1)
        kwargs.setdefault('price', 100)
        kwargs.setdefault('offer_id', 1)
        kwargs.setdefault('available', True)
        return mixer.blend(Product, **kwargs)

    return inner


import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)

wallinstances = UnwrapElement(IN[0])
methodlist = list()
for item in wallinstances:
	typename = item.GetType().Name
	if typename == 'Wall':
		methodlist.append('Standard')
	elif typename == 'FaceWall':
		methodlist.append('By Face')
	elif typename == 'FamilyInstance':
		methodlist.append('In-Place')
	else: methodlist.append(None)
OUT = methodlist


import math
import re
import pandas as pd
import serial

coordinateColumns = ['Gx', 'Gy', 'Gz', 'Ax', 'Ay', 'Az',
                     'Mx', 'My', 'Mz', 'H', 'T', 'Bv', 'Fa', 'Fb', 'Fc', 'Fd']

def read_line(arduino):
    data = arduino.readline()

    currentData = re.split('/', str(data))
    seriesData = dict()

    for row in currentData:
        params = re.split(':', row)

        if (len(params) is not 2):
            # End of list
            continue

        # Get key value pair
        key = params[0]
        try:
            value = float(params[1])
        except ValueError:
            # Not setting invalid not-float coordinates
            continue

        if (value is "" or math.isnan(float(value))):
            # Beggining of list
            continue

        if key in ['Mx', 'My', 'Mz', 'T', 'Bv']:
            seriesData[key] = round(float(value), 1)
        else:
            seriesData[key] = round(float(value), 2)

    return seriesData


"""
With these settings, tests run faster.
"""
import os

from .base import *  # noqa
from .base import ROOT_DIR

SECRET_KEY = os.getenv(
    "DJANGO_SECRET_KEY",
    default="kY2h68D0TgYGFibh1GiRlZ1PLE52zTKpbIFIymEsNc5zoauSn6asnnSr2dtOiOf1",
)

# CACHES
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#caches
CACHES = {
    "default": {
        "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
        "LOCATION": "",
    }
}

# PASSWORDS
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#password-hashers
PASSWORD_HASHERS = ["django.contrib.auth.hashers.MD5PasswordHasher"]

# EMAIL
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#email-backend
EMAIL_BACKEND = "django.core.mail.backends.locmem.EmailBackend"

# DATABASES
# ------------------------------------------------------------------------------
# https://docs.djangoproject.com/en/dev/ref/settings/#databases
DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.sqlite3",
        "NAME": os.path.join(ROOT_DIR, "db.sqlite3"),
    }
}


#! /bin/python3

# Run Program:
# utorrent-postprocess.pyw "%L" "%S" "%N" "%K" "%F" "%D"
#
# Test with Console:
# utorrent-postprocess.pyw "Movie" "5" "Avatar" "multi" "" "X:\Files\Avatar"

import sys
import subprocess

# configuration
output = '/mnt/diskpool/NoMirror/Media'

# custom formats (use / instead of \ as directory separator)
movieFormat  = '''{plex}'''
seriesFormat = '''{plex}'''
animeFormat  = '''{plex}'''
musicFormat  = '''{plex}'''

# required args
label, state, title, kind, file, directory = sys.argv[1:7]

if label == "X":
    quit()

command = [
	'filebot', '-rename','-script', 'fn:amc',
	'--output', output,
	'--action', 'move',
	'--conflict', 'auto',
	'-non-strict',
	'--log-file', output + '/amc.log',
	'--def',
		'excludeList=amc.txt',
		'subtitle=en',
		'plex=127.0.0.1:V6zq1wd1L7sXpmNLC9Qn',
		'deleteAfterExtract=n',
		'clean=y',
		'minFileSize=10',
		'unsorted=y',
		'music=n',
		'artwork=y',
		'movieFormat='  + movieFormat,
		'seriesFormat=' + seriesFormat,
		'animeFormat='  + animeFormat,
		'musicFormat='  + musicFormat,
		'ut_label=' + label,
		'ut_state=' + state,
		'ut_title=' + title,
		'ut_kind='  + kind,
		'ut_file='  + file,
		'ut_dir='   + directory

]

# execute command only for certain conditions (disabled by default)
'''
if state not in ['5', '11']:
	print('Illegal state: %s' % state)
	sys.exit(0)
'''

# execute command (and hide cmd window)
# creation flag on windows
# subprocess.run(command, creationflags=0x08000000)
subprocess.run(command)


def best_sum(number, list_of_numbers):
	return best_sum_helper(number, list_of_numbers, {})

def best_sum_helper(number, list_of_numbers, memo):

	if number in memo:
		return memo[number]

	if number == 0:
		return []

	if number < 0:
		return None

	short_comb = None

	for sub_value in list_of_numbers:

		sum_value = number - sub_value

		get_list = best_sum_helper(sum_value, list_of_numbers, memo)

		if get_list != None:
			new_list = get_list[:] + [sub_value]

			if short_comb == None or len(new_list) < len(short_comb):
				short_comb = new_list

	memo[number] = short_comb

	return memo[number]

print(best_sum(7, [5, 3, 4, 7]))
print(best_sum(8, [2, 3, 5]))
print(best_sum(8, [1, 4, 5]))
print(best_sum(100, [1, 2, 5, 25]))


"""
En un Hospital se realiza una investigación para determinar las patologías respiratorias en
época invernal. A tal efecto se cargan los siguientes datos de N voluntarios:
✓ EDAD
✓ SEXO (1 = Masculino, 2= Femenino).
✓ PATOLOGÍA (0 = Gripe Estacional, 1 = Gripe A, 2 = Neumonía, 3 = Bronquitis).

Se desea conocer:
a. La cantidad de personas de sexo masculino mayores a 58 años que padecen
Bronquitis o Gripe A.
b. La cantidad de personas de sexo femenino y masculino que padecen Gripe Estacional

"""
users = int(input('Ingrese la cantidad de pacientes: '))
x = 0 #Controlador del ciclo while
contA = 0 #Contador del primer item
contB = 0 #Contador del segundo item

while x < users:
    sex = int(input('Ingrese el sexo(1 = Masculino, 2= Femenino): '))
    edad = int(input('Ingrese la edad: '))
    pat = int(input('Ingrese la patologia(0 = Gripe Estacional, 1 = Gripe A, 2 = Neumonía, 3 = Bronquitis): '))

    if edad > 58 and sex == 1 and (pat == 1 or pat == 3):
        contA += 1

    if (sex == 2 or sex == 1) and pat == 0:
        contB += 1

    x += 1

print('\nLa cantidad de personas de sexo masculino mayores a 58 años que padecen Bronquitis o Gripe A es ', contA)
print('\nLa cantidad de personas de sexo femenino y masculino que padecen Gripe Estacional es ', contB)


import filecmp
import logging
import unittest

import os

import sys

import copy
import uuid

from depmgmtsystem.repos import packages
from depmgmtsystem.repos.deps import Repo
from depmgmtsystem.dependencies import Dep
from depmgmtsystem.decoders import DepsDecoder
from depmgmtsystem.trees.dep_tree import DepTree
from depmgmtsystem.trees.pkg_tree import FileSystemPackageTree

root = logging.getLogger()
root.setLevel(logging.DEBUG)

ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
root.addHandler(ch)

def _fixture_path_by_file_name(f_name):
    return os.path.join(
        os.path.dirname(os.path.realpath(__file__)),
        'fixtures',
        f_name,
    )

class StubDecoder(DepsDecoder):

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

    def decode(self):
        return self.deps

class StubDepsRepo(Repo):

    def __init__(self, dep_versions):
        self.dep_version = dep_versions

    def deps(self, package_name):
        return copy.deepcopy(self.dep_version.get(package_name, []))

class StubPackageRepo(packages.Repo):

    def download(self, name, version):
        return open(
            _fixture_path_by_file_name('stub-package.tar.gz'),
            'rb'
        ).read()

class ServiceTestCase(unittest.TestCase):
    def test_parse_file_build_tree(self):

        stub_decoder = StubDecoder(
            deps=[
                Dep(name='package-1', version=None),
                Dep(name='package-2-cli', version='==1.0.0'),
                Dep(name='another-package', version='>=0.9.7'),
            ]
        )

        deps_repo = StubDepsRepo(dep_versions={
            'another-package': [
                Dep('another-package', version='0.9.7'),
            ],
            'package-1': [
                Dep('package-1', version='0.0.1'),
            ],
            'package-2-deps-1-pkg': [
                Dep('package-2-deps-1-pkg', version='0.0.1'),
            ],
            'package-2-deps-2-pkg': [
                Dep('package-2-deps-2-pkg', version='0.0.1'),
            ],
            'package-2-cli': [
                Dep(name='package-2-cli', version='1.0.0', deps=[
                    Dep(name='package-2-deps-1-pkg', version='0.0.1'),
                    Dep(name='package-2-deps-2-pkg', version='0.0.1')
                ])
            ],
            'package-2-deps-1-pkg': [
                Dep(
                    name='package-2-depmgmtsystem-1-pkg',
                    version='0.0.1',
                    deps=[
                        Dep(name='recursive-deps', version='0.0.1'),
                    ]
                )
            ],
            'recursive-deps': [
                Dep('recursive-deps', version='0.0.1'),
            ],
        })

        fs_path = ['/', 'tmp', str(uuid.uuid1())]

        FileSystemPackageTree(
            dep_tree=DepTree(
                stub_decoder.decode(),
                deps_repo,
            ).tree(),
            root_dir_path=fs_path,
            pkg_repo=StubPackageRepo(),
        ).tree()

        comp = filecmp.dircmp(
            os.path.join(*(fs_path + ['deps'])),
            os.path.join(
                os.path.dirname(os.path.realpath(__file__)),
                'fixtures',
                'parse_file_build_tree_oracle',
                'deps',
            )
        )
        self.assertEqual(comp.diff_files, [])


#!/usr/bin/env python

def take_photo():

	"""take_photo: Turns on IR flash and take the photo. Saving the photo under the date and time"""

	import picamera
	import datetime
	import RPi.GPIO as GPIO

	camera = picamera.PiCamera()

	camera.hflip = True
	camera.vflip = True

	GPIO.setmode(GPIO.BCM)
	GPIO.setwarnings(False)
	GPIO.setup(18,GPIO.OUT)

	GPIO.output(18,GPIO.HIGH)

	name = datetime.datetime.now().strftime("%Y-%m-%d-%H:%M:%S") + ".jpg"
	camera.capture(name)

	GPIO.output(18,GPIO.LOW)

	return name


from .models import Category, Blog, Event
import datetime

def post_context(request):
    latest_blogs = Blog.objects.filter(is_archived=False)
    categories = Category.objects.all()
    upcoming_events = Event.objects.filter(
        event_date__gte=datetime.date.today())

    return {'categories': categories, 'upcoming_events': upcoming_events, 'latest_blogs': latest_blogs}


from argparse import ArgumentParser
import torchvision.transforms as transforms
from torch.utils.data import DataLoader
from torchvision.datasets import FashionMNIST
import pytorch_lightning as pl

class FashionMnistData(pl.LightningDataModule):
    def __init__(self, root = '/home/bitwiz/codeden/data/mnist', batch_size = 512,
            workers = 8, debug = False, expt = 'cnn', **kw):
        super().__init__()
        self.batch_size = batch_size
        self.workers = workers
        self.debug = debug
        self.root = root

        if expt == 'cnn':
            self.train_transform = transforms.Compose([
                transforms.ToTensor(),
                transforms.Normalize((0.2859,), (0.3202,))
            ])

            self.val_transform = transforms.Compose([
                transforms.ToTensor(),
                transforms.Normalize((0.2859,), (0.3202,))
            ])
        else:
            self.train_transform = transforms.Compose([
                transforms.ToTensor()
            ])

            self.val_transform = transforms.Compose([
                transforms.ToTensor()
            ])

    def trainset(self):
        return FashionMNIST(root=self.root, train=True, download = True, transform = self.train_transform)

    def valset(self):
        return FashionMNIST(root=self.root, train=False, download = True, transform = self.val_transform)

    @staticmethod
    def add_loader_specific_args(parent_parser):
        parent_parser.add_argument('-b', '--batch_size', type = int, default = 512)
        parent_parser.add_argument('--workers', type = int, default = 8)
        parent_parser.add_argument('--debug', type = int, default = 0)
        parent_parser.add_argument('--mode', type = int, default = 10)

        return parent_parser

    def make_loader(self, split):
        if split == 'train':
            transform = self.train_transform
            dataset = self.trainset()
        elif split == 'val':
            transform = self.val_transform
            dataset = self.valset()
        else:
            transform = self.val_transform
            dataset = self.valset()

        loader = DataLoader(dataset, batch_size = self.batch_size, num_workers = self.workers)

        return loader

    def train_dataloader(self):
        return self.make_loader(split='train')

    def val_dataloader(self):
        return self.make_loader(split='val')

    def test_dataloader(self):
        return self.make_loader(split='val')


from collections import deque, namedtuple

inf = float('inf')
Edge = namedtuple('Edge', 'start, end, cost')

def make_edge(start, end, cost=1):
  return Edge(start, end, cost)

class Graph:
    def __init__(self, edges):
        wrong_edges = [i for i in edges if len(i) not in [2, 3]]
        if wrong_edges:
            raise ValueError('Wrong edges data: {}'.format(wrong_edges))

        self.edges = [make_edge(*edge) for edge in edges]

    @property
    def vertices(self):
        return set(
            sum(
                ([edge.start, edge.end] for edge in self.edges), []
            )
        )

    def get_node_pairs(self, n1, n2, both_ends=True):
        if both_ends:
            node_pairs = [[n1, n2], [n2, n1]]
        else:
            node_pairs = [[n1, n2]]
        return node_pairs

    def remove_edge(self, n1, n2, both_ends=True):
        node_pairs = self.get_node_pairs(n1, n2, both_ends)
        edges = self.edges[:]
        for edge in edges:
            if [edge.start, edge.end] in node_pairs:
                self.edges.remove(edge)

    def add_edge(self, n1, n2, cost=1, both_ends=True):
        node_pairs = self.get_node_pairs(n1, n2, both_ends)
        for edge in self.edges:
            if [edge.start, edge.end] in node_pairs:
                return ValueError('Edge {} {} already exists'.format(n1, n2))

        self.edges.append(Edge(start=n1, end=n2, cost=cost))
        if both_ends:
            self.edges.append(Edge(start=n2, end=n1, cost=cost))

    @property
    def neighbours(self):
        neighbours = {vertex: set() for vertex in self.vertices}
        for edge in self.edges:
            neighbours[edge.start].add((edge.end, edge.cost))

        return neighbours

    def dijkstra(self, source, dest):
        assert source in self.vertices, 'Such source node doesn\'t exist'
        distances = {vertex: inf for vertex in self.vertices}
        previous_vertices = {
            vertex: None for vertex in self.vertices
        }
        distances[source] = 0
        vertices = self.vertices.copy()

        while vertices:
            current_vertex = min(
                vertices, key=lambda vertex: distances[vertex])
            vertices.remove(current_vertex)
            if distances[current_vertex] == inf:
                break
            for neighbour, cost in self.neighbours[current_vertex]:
                alternative_route = distances[current_vertex] + cost
                if alternative_route < distances[neighbour]:
                    distances[neighbour] = alternative_route
                    previous_vertices[neighbour] = current_vertex

        path, current_vertex = deque(), dest
        while previous_vertices[current_vertex] is not None:
            path.appendleft(current_vertex)
            current_vertex = previous_vertices[current_vertex]
        if path:
            path.appendleft(current_vertex)
        return ','.join(path)


'''A phrase is a palindrome if, after converting all uppercase letters into lowercase letters and removing all non-alphanumeric characters, it reads the same forward and backward. Alphanumeric characters include letters and numbers.

Given a string s, return true if it is a palindrome, or false otherwise.

Example 1:

Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.'''

class Solution:
    def isPalindrome(self, s: str) -> bool:
        i=0
        j=len(s)-1
        while(i<j):
            if (s[i].isalpha() and s[j].isalpha()):
                if s[i].lower()!=s[j].lower():
                    return False
                i+=1
                j-=1
            elif (s[i].isdigit() and s[j].isdigit()):
                if s[i]!=s[j]:
                    return False
                i+=1
                j-=1
            elif (s[i].isdigit() and s[j].isalpha()) or (s[i].isalpha() and s[j].isdigit()):
                return False
            elif s[i].isalpha()==False and s[i].isdigit()==False:
                i+=1
            elif s[j].isalpha()==False and s[j].isdigit()==False:
                j-=1

        return True


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

class DownloadRequest(object):
    """
    Representation of a request for a file download.
    """

    def __init__(self, url, destination, data=None, headers=None):
        """
        :param url:         url of the file to be downloaded
        :type  url:         str
        :param destination: specifies where the downloader should store the contents of the URL
                            once they are retrieved. You can provide either a file-system path for
                            this parameter, or an open file-like object. If you provide a file-like
                            object, it is your responsibility to close the file after the download
                            is finished.
        :type  destination: str or file-like object
        :param data:        arbitrary data to be passed back as part of the
                            reports to the listener callbacks
        :param headers:     A dictionary specifying header names and values that will
                            be used for this request. Headers specified here
                            will override any headers of the same key that
                            are specified in the config.
        :type  headers:     dict
        """

        self.url = url
        self.destination = destination
        self.data = data
        self.headers = headers
        self.canceled = False

        self._file_handle = None

    def initialize_file_handle(self):
        """
        Returns a file handle for the request's destination.

        :return: file-like object for writing the download to
        """
        # if the destination is already a file-like object, return it
        if hasattr(self.destination, 'write'):
            return self.destination

        self._file_handle = open(self.destination, 'wb')  # cache the handle
        return self._file_handle

    def finalize_file_handle(self):
        """
        Cleanup the request destination's file handle. This is a no-op if the
        file handle wasn't create with the initialize_file_handle method.
        """
        # don't close the file handle if it wasn't opened by get_file_handle
        if self._file_handle in (None, self.destination):
            return

        self._file_handle.close()
        self._file_handle = None


#!/usr/bin/env python3

import os.path
import numpy as np

from .fitfuncs import FOURIERFITFUNCS, PARAMETERFITFUNCS

__all__ = ["loadParameterFile", "reconstruct_gUprime",
           "getUprime", "reconstruct_gUprime_vectors"]

# -- Internal constants for loading the default parameter file --

SCRIPTDIR = os.path.dirname(os.path.abspath(__file__))
FITPARAMSFILE = "fitparams.csv"
DEFAULTPATH = os.path.join(SCRIPTDIR, FITPARAMSFILE)
DEFAULTPARAMETERS = None  # Lazy loading: will be set when needed

# -- Simulation constants --

EPSILON, SIGMA = 1, 1

# -- File input --

def loadParameterFile(filepath):
    r"""Load a parameter CSV file from a given path.

    Args:
        path (str):
            Path to CSV file.

    Returns:
        **params_alpha, params_beta (dict):**
            Dictionaries containing all fit parameters for both alpha and beta
            Fourier coefficients.
    """
    params_alpha = {}
    params_beta = {}
    # Open file with fit parameters and read line by line every u_i,j
    # or v,w resp.
    with open(filepath) as f:
        for line in f:
            # Extract cells
            cells = line.split(",")
            # Skip lines without label
            if cells[0] == "":
                continue
            # Skip invalid labels
            if not len(cells[0]) in [8, 9]:
                print("Invalid fourier coefficient label: {}".format(cells[0]))
                continue
            coefftype = cells[0][0:4]  # Either "alph" or "beta"

            h, j, k = map(int, cells[0][-3:])

            # Select correct dict
            params = params_alpha if coefftype == "alph" else params_beta

            # Filter empty cells
            cells = list(filter(lambda x: x != "", cells))
            if not (h, j, k) in params:
                params[(h, j, k)] = []
            # Extract data
            params[(h, j, k)].append(list(map(float, cells[2:])))
        return params_alpha, params_beta

# Internally used

def loadDefaultParameterFile():
    global DEFAULTPARAMETERS
    if not DEFAULTPARAMETERS:
        DEFAULTPARAMETERS = loadParameterFile(DEFAULTPATH)
    return DEFAULTPARAMETERS

# -- Reconstruction functions --

def reconstruct_gUprime(
        r, the1, the2, phi2, Phi, Pe, params_alpha=None, params_beta=None):
    r"""Returns an approximation for $-gU'$ in a given range of particle
    distances and positional and orientational angles.

    Args:
        r (float or array_like): Distance(s) at which $-gU'$ will be calculated
        the1, the2, phi2 (float, array_like or meshgrids for all three):
            Positional and orientational angles at which $-gU'$ will be calculated
        Phi, Pe (float): Packing density and Peclet number for which $-gU'$ will be calculated
        params_alpha, params_beta (dict):
            Parameter dictionary containing all fit parameters necessary for
            reconstruction. If not set, the included default values will be used.
    """
    # If params are not set: load default
    if not params_alpha or not params_beta:
        params = loadDefaultParameterFile()
        if not params_alpha:
            params_alpha = params[0]
        if not params_beta:
            params_beta = params[1]
    # r must have dimension 1
    if len(np.shape(r)) == 0:
        r = np.array([r])

    # Allocate array for -gU'
    if len(np.shape(the1)) == 3 and len(np.shape(the2)) == 3 and \
            len(np.shape(phi2)) == 3:
        pass
    elif len(np.shape(the1)) in [0, 1] and len(np.shape(the2)) in [0, 1] and \
            len(np.shape(phi2)) in [0, 1]:
        the1, the2, phi2 = np.meshgrid(the1, the2, phi2, indexing='ij')
    else:
        print("""I dont know how to interpret the input of the1, the2 and phi2.\n
        Please either give only onedimensional arrays or floats""" + """ \
             as input or give only meshgrids. """)

    gU = np.zeros((r.shape[0], the1.shape[0], the2.shape[1], phi2.shape[2]))

    # Calculate all contributions for h,j,k between 0 and 2

    for k in range(3):
        # cos*cos*cos for h,j,k of alpha coefficient
        # sin*sin*cos for h,j,k of beta coefficient
        phi2_func = np.cos
        lowest_freq = 0
        fourierfunc = np.cos
        if k == 1:
            lowest_freq = 1
            fourierfunc = np.sin
        for h in range(lowest_freq, 3, 1):
            for j in range(lowest_freq, 3, 1):

                for params in (
                        [params_beta] if k == 1 else
                        [params_alpha]):
                    # Calculate fit parameters a, mu, sigma, lambda and b,c,d
                    # (if necessary)
                    fitparams = list(map(lambda x: x[0]((Phi, Pe), *x[1]),
                                     zip(PARAMETERFITFUNCS[(h, j, k)],
                                     params[(h, j, k)])))
                    # Calculate Fourier coefficient
                    fouriercoeff = FOURIERFITFUNCS[(h, j, k)](r, *fitparams)
                    # Add contribution to -gU'
                    gU += fouriercoeff[:, None, None, None] * \
                        fourierfunc(the1*h) * fourierfunc(the2*j) * \
                        phi2_func(phi2*k)

    return gU

def reconstruct_gUprime_vectors(
     r, u_1, u_2, u_d, Phi, Pe, params_alpha=None, params_beta=None):
    r"""Returns an approximation for $-gU'$ in a given range of particle
    distances and orientation of the particles and their connecting vector.

    Args:
        r (float or array_like): Distance(s) at which $-gU'$ will be calculated
        u_1, u_2, u_d (array-like, dimension 3):
            Normalized orientation vectors of the particles and
            their connecting vector
        Phi, Pe (float):
            Packing density and Peclet number for which $-gU'$ will
            be calculated
        params_alpha, params_beta (dict):
            Parameter dictionary containing all fit parameters necessary for
            reconstruction. If not set, the included default values will be used.
    """
    # in case u_ are lists, this changes them to arrays
    # u_1 = np.array([u_1[0], u_1[1],u_1[2]])
    # u_2 = np.array([u_2[0], u_2[1],u_2[2]])
    # u_d = np.array([u_d[0], u_d[1],u_d[2]])

    # normalizing the vectors
    u_1 = u_1/np.sqrt(np.sum(u_1*u_1))
    u_2 = u_2/np.sqrt(np.sum(u_2*u_2))
    u_d = u_d/np.sqrt(np.sum(u_d*u_d))

    # Calculation of the angles the1, the2 and phi2
    u1_u2 = np.sum(u_1*u_2)
    u1_ud = np.sum(u_1*u_d)
    the1 = np.arccos(u1_ud)
    the2 = np.arccos(u1_u2)

    # for certain configurations of u1 and u2, phi2 can be chosen arbitrarily
    limit = np.cos(np.pi/180)
    if abs(u1_u2) > limit or abs(u1_ud) > limit:
        phi2 = 0.0
    else:
        ey = np.cross(u_1, u_d)
        ey = ey/np.sqrt(np.sum(ey*ey))
        ex = np.cross(ey, u_1)
        phi2 = np.arccos(np.sum(u_2*ex)/np.sqrt(1-u1_u2*u1_u2))

    return reconstruct_gUprime(
            r, the1, the2, phi2, Phi, Pe, params_alpha=None, params_beta=None)

def getUprime(r):
    r"""Calculate derivative of potential U with respect to r.

    The potential depends on the particle diameter sigma and the Lennard-Jones
    energy epsilon. This function uses values consistent with the simulations
    described in the accompanying article.

    Args:
        r (float or array_like):
            Distance(s) at which the potential derivative will be calculated.
    """
    return 24*EPSILON/SIGMA * (-2*(SIGMA/r)**13 + (SIGMA/r)**7)


# -*- coding: utf-8 -*-
from flask import Flask, render_template, redirect, request, send_from_directory, jsonify, session
from pydub import AudioSegment
from midi2audio import FluidSynth
from mido import Message, MidiFile, MidiTrack

app = Flask(__name__)
with open("secret.key", "rb") as f:
    app.secret_key = f.read()

fs = FluidSynth('/Users/piotrek/Library/Audio/Sounds/Banks/fluid_r3_gm.sf2')

@app.route("/")
def index():
    if not session.get('logged_in'):
        return render_template('loading.html')
    else:
        return redirect('/master_tape')

@app.route("/master_tape")
def master_tape():
    if not session.get('guide_passed') and session.get('logged_in'):
        return render_template('guide.html', username=session.get('name'))
    elif session.get('guide_passed') and session.get('logged_in'):
        session['level'] = 1
        return render_template('master.html', username=session.get('name'), tracks=session.get('tracks'))
    else:
        return redirect('/')

@app.route("/new_track")
def new_track():
    if session.get('guide_passed') and session.get('logged_in'):
        if len(session.get('tracks'))<4:
            type = request.args.get('type')
            length = request.args.get('length')
            session_tracks = session.get('tracks')
            track_nrs = []
            for i in session_tracks:
                track_nrs.append(i[0])
            print(session_tracks)
            for i in range(1,5):
                if i not in track_nrs:
                    session_tracks.append([i, 'Taśma '+str(i),int(type),[], int(length)])
                    print(session_tracks)
                    session['tracks'] = session_tracks
                    break
            return redirect("/master_tape")
        else:
            return render_template('master.html', username=session.get('name'), tracks=session.get('tracks'), err=1)
    else:
        return redirect('/')

@app.route("/sync", methods=['POST'])
def sync():
    result = []
    data = request.get_json()
    session_tracks = session.get('tracks')
    session_tracks[data['track']-1][3].append([int(data['append0']), int(data['append1']), int(data['time']), 0])
    session['tracks'] = session_tracks
    return redirect("/master_tape")

@app.route("/sync_2", methods=['POST'])
def sync_2():
    result = []
    data = request.get_json()
    session_tracks = session.get('tracks')
    session_tracks[data['track']-1][3].remove([int(data['remove0']), int(data['remove1']), int(data['time']), 0])
    session['tracks'] = session_tracks
    return redirect("/master_tape")

@app.route("/sync_3", methods=['POST'])
def sync_3():
    result = []
    data = request.get_json()
    session_tracks = session.get('tracks')
    session_tracks[data['track']-1][3].append([int(data['append0']), int(data['append1']), int(data['time']), 1])
    session['tracks'] = session_tracks
    return redirect("/master_tape")

@app.route("/del_track")
def del_track():
    no = request.args.get('no')
    if session.get('logged_in'):
        session_tracks = session.get('tracks')
        for i in session_tracks:
            if i[0]==int(no):
                session_tracks.remove(i)
        session['tracks'] = session_tracks
        return redirect("/master_tape")
    else:
        return redirect('/')

@app.route("/guide_done")
def guide_done():
    if session.get('logged_in'):
        session['guide_passed'] = True
        session['tracks'] = []
        return redirect('/master_tape')
    else:
        return redirect('/')

@app.route("/guide")
def guide():
    if session.get('logged_in'):
        return render_template('guide.html', username=session.get('name'))

@app.route("/get_note")
def get_note():
    length = int(request.args.get('length'))

    for i in range(24):
        mid = MidiFile()
        track = MidiTrack()
        mid.tracks.append(track)
        track.append(Message('control_change', control=32, value=127, time=0))
        track.append(Message('program_change', program=25, time=0))
        track.append(Message('note_on', note=48+i, velocity=90, time=0))
        track.append(Message('note_off', note=48+i, velocity=90, time=length))
        track.append(Message('note_off', note=48+i, velocity=90, time=2*length))

        mid.save('temp.mid')

        fs = FluidSynth('/Users/piotrek/Library/Audio/Sounds/Banks/fluid_r3_gm.sf2')
        fs.midi_to_audio('temp.mid', "static/audio/guitar/"+str(i)+"_"+str(length)+'.wav')

    return redirect('/')

@app.route("/login", methods=['POST', 'GET'])
def login():
    if session.get('logged_in'):
        return redirect('/')
    else:
        session['logged_in'] = True
        session['name'] = request.form['name']
        return redirect('/')

@app.route("/end_game")
def end():
    if session.get('logged_in'):
        session['logged_in'] = False
        session['guide_passed'] = False
        session['tracks'] = []
        return redirect('/')
    else:
        return redirect('/')

@app.route('/<path:path>')
def send_static(path):
    return send_from_directory('static', path)

@app.route('/render_audio')
def render_audio(path):
    sound1 = AudioSegment.from_mp3("static/sample/sample1.mp3")
    sound2 = AudioSegment.from_mp3("static/sample/sample2.mp3")

    # mix sound2 with sound1, starting at 200ms into sound1
    output = sound1.overlay(sound2, position=200)

    # save the result
    output.export("export.mp3", format="mp3")
    return redirect('/')

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


import fnmatch
import os
import shutil
import csv
import sqlite3

def collectFiles(path, extention='csv'):
     matches = []

     for root, dirnames, filenames in os.walk(path):
         for filename in fnmatch.filter(filenames,'*.{}'.format(extention)):
             matches.append(os.path.join(root, filename))
     return matches

def CsvtoSqlite(dbloc):
    con = sqlite3.connect(dbloc)
    cur = con.cursor()
    files = collectFiles("data/")
    for eachFile in files:
        with open(eachFile,'rb') as fin:
            dr = csv.DictReader(fin)
            to_db = [(i['datetime'], i['host'],i['guid'],i['timings']) for i in dr]
            cur.executemany("INSERT INTO performance_runs (datetime, host, guid, timings) VALUES (?, ?, ?, ?);", to_db)
    con.commit()

def main():
    # print(collectFiles("data/"))
    CsvtoSqlite("db/performancedb.db")

if __name__ == '__main__':
    main()


from django.contrib import admin

from .models import Article, Tag, TagArticle
from django.core.exceptions import ValidationError
from django.forms import BaseInlineFormSet

class TagArticleInlineInlineFormset(BaseInlineFormSet):
    def clean(self):
        is_main = False
        for form in self.forms:
            data = form.cleaned_data
            if not is_main and 'is_main' in data.keys() and data['is_main']:
                is_main = True
            elif is_main and 'is_main' in data.keys() and data['is_main']:
                raise ValidationError('Должен быть только один основной раздел')
        if not is_main:
            raise ValidationError('Выбирете 1 основной раздел')
        return super().clean()  # вызываем базовый код переопределяемого метода

class TagArticleInline(admin.TabularInline):
    model = TagArticle
    formset = TagArticleInlineInlineFormset

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    inlines = [
        TagArticleInline
        ]

@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    pass


import requests, json
import argparse
import hashlib
import os, sys
from environs import Env

env = Env()
env.read_env()  # read .env file, if it exists

METADEFENDER_URL = env('METADEFENDER_URL')
METADEFENDER_API_KEY = env('METADEFENDER_API_KEY')
META_HASH = 'sha256'
META_METADATA = '0'
META_WORKFLOW = None

def _scan_file(api_key, file_stream, file_name=None, user_agent=None):
    url = "{}/file".format(METADEFENDER_URL)
    headers = {'apikey': api_key, 'user_agent': user_agent, 'Content-Type': "application/octet-stream"}
    try:
        print('url - {}'.format(url))
        response = requests.post(url=url, data=file_stream, headers=headers)
        output_data = response.json()
        print('results = {}'.format(output_data))
        return output_data['data_id'], 'Success'
    except requests.exceptions.RequestException as err:
        print("Request Error:", err)
        return '', 'Request Error'
    except:
        print("Unable to scan file.")
        return '', 'Scan error'

def _retrieve_scan(url, api_key, metadata='0'):
    headers = {'apikey': api_key, 'file-metadata': metadata}
    try:
        print('retrieval scan - {}'.format(url))
        response = requests.get(url=url, headers=headers)
        output_data = response.json()
        # print('retrieval scan result - {}'.format(output_data))
    except requests.exceptions.RequestException as err:
        print("Request Error:", err)
        return '', 'Request Error'
    except:
        print("Unable to retrieve file status.")
        sys.exit(0)

    return output_data

def _calculate_hash(hash_type, file_stream, chunk_size=65536):
    try:
        if hash_type == "md5":
            hash = hashlib.md5()
        elif hash_type == "sha1":
            hash = hashlib.sha1()
        elif hash_type == "sha256":
            hash = hashlib.sha256()
        for chunk in iter(lambda: file_stream.read(chunk_size), b""):
            hash.update(chunk)
    except:
        print("Unable to hash file.")
        return ''
    return hash.hexdigest()

def scan_file_sync(file_name, file_stream):
    # Calculate hash of file
    file_hash = _calculate_hash(META_HASH, file_stream).upper()
    if file_hash == '':
        return file_hash, 'Unable to has file'

    # Perform hash lookup for cached results
    url = "{}/hash/{}".format(METADEFENDER_URL, file_hash)
    scan_result = _retrieve_scan(url=url, api_key=METADEFENDER_API_KEY, metadata=META_METADATA)

    # Skip if cache found
    if scan_result == '' or ('error' not in scan_result):
        return scan_result, 'Success'

    # Initiate scan and get data id
    data_id, error_msg = _scan_file(api_key=METADEFENDER_API_KEY, file_stream=file_stream, file_name=file_name,
                                    user_agent=META_WORKFLOW)
    if data_id == '':
        return data_id, error_msg

    # Loop through and check for results because scan_file is async
    url = "{}/file/{}".format(METADEFENDER_URL, data_id)
    scan_result = _retrieve_scan(url=url, api_key=METADEFENDER_API_KEY, metadata=META_METADATA)
    while scan_result['scan_results']['progress_percentage'] != 100:
        scan_result = _retrieve_scan(url=url, api_key=METADEFENDER_API_KEY, metadata=META_METADATA)

    return scan_result, 'Success'


from django.shortcuts import render
from django.contrib.auth.decorators import login_required

from poemese.models import Poema, Usuario, RelacoesAmizade

@login_required(login_url="poemese:sign_in")
def profile(request, pseudonimo):
    profile_user = Usuario.objects.get(pk=pseudonimo)
    poemas = Poema.objects.filter(autor_poema=pseudonimo)

    # Update the likes in profile
    update_likes(profile_user, poemas)

    # Verify if the user that requested the profile is following the profile's user
    is_follower = is_following(request.user, profile_user)

    followers = RelacoesAmizade.objects.filter(destino=profile_user).count()
    following = RelacoesAmizade.objects.filter(origem=profile_user).count()

    return render(request, 'poemese/perfil.html',
                  {'profile_user': profile_user, 'following': following,
                   'followers': followers, 'is_follower': is_follower, 'poem_list': poemas})

def update_likes(user, poemas):
    """ Update the poems' number of likes of the profile that has been open """
    likes = 0
    for poema in poemas:
        likes += poema.qtd_gostei
    user.number_of_likes = likes
    user.save()

def is_following(request_user, profile_user):
    """ Return True in case the user that requested follow the profile's user """
    relationship = RelacoesAmizade.objects.filter(origem=request_user, destino=profile_user)
    if request_user != profile_user:
        if relationship is not None:
            return True
        return False


class Solution:
    def isPalindrome(self, x):
        """
        :type x: int
        :rtype: bool
        """
        if x<0 or (x%10==0 and x!=0):
            return False
        reverse=0
        while x>reverse:
            reverse=10*reverse+x%10
            x=x//10
        if x==reverse or x==reverse//10:
            return True
        else:
            return False

"""
Runtime: 284 ms, faster than 71.74% of Python3 online submissions for Palindrome Number.
point:the reverse algorithm ignores zeros in the end of a number
1700 will be reverse as 71, so 12100 will be cut like 1 and 21, which need to preset an if to exclude such
situation
on the other hand, choosing to just reverse half of the number does not lead to obvious less time.

"""


from django.db import migrations, models
import django.db.models.deletion
import uuid

class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='User',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
                ('email', models.EmailField(max_length=191, unique=True)),
            ],
        ),
        migrations.CreateModel(
            name='Domain',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
                ('owner', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='desecapi.User')),
            ],
        ),
        migrations.CreateModel(
            name='RRset',
            fields=[
                ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
                ('subname', models.CharField(blank=True, max_length=178)),
                ('domain', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='desecapi.Domain')),
            ],
        ),
        migrations.CreateModel(
            name='Token',
            fields=[
                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False)),
                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='desecapi.User')),
            ],
        ),
        migrations.AlterField(
            model_name='rrset',
            name='subname',
            field=models.CharField(blank=False, max_length=178),
        ),
    ]


"""
                                Predicting with a Language Model

This script predicts a word-level
language model, implementation with Tensorflow 1.13, tf.Estimator API

Usage:
  train.py  <log_dir>  <sentence> <k>
  [--gpu_train=<gpu>] [--mode=<md>]
  [--embedding_size=<ems>] [--char_emb_size=<em>]
  [--num_LSTM_layers=<nmlstm>] [--num_layers_char=<nmchar>]
  [--hidden_size_chars=<hsc>]  [--hidden_size_LSTM=<hsn>]
  [--add_char_emb=<add>] [--num_heads=<nmh>]
  [--dropout=<dp>]
  [--learning_rate=<lr>] [--batch_size=<bs>]
  [--n_epochs=<ne>] [--optimizer=<op>] [--checkpoints=<ckpt>]
  [--buffer_size=<bfs>]
  [--deepness_finish=<dpsf>] [--activation_finish=<actf>]
  [--intern_size=<intf>] [--weighted_loss=<wgth>]
[--add_encoder=<addenc>]

Options:
  -h --help
  --version
  --sentence                The start sentence to predict from
  --k                       The number of tokens which must be predicted
  --log_dir                 Logs directory, where the checkpoints will be stored
  --gpu_train=<gpu>         Boolean, True is using a gpu. (Requires tensorflow-gpu) [default: True]
  --mode=<md>               The tensorflow mode, in ['train', 'train_eval', 'eval'] [default: train_eval]
  --embedding_size=<ems>    The word embedding dimension [default: 300]
  --char_emb_size=<em>      The chosen character embedding size [default: 100]
  --num_LSTM_layers=<nmlstm> The number of LSTM units [default:2]
  --num_layers_char=<nmchar> The number of LSTM units for char embedding [default:2]
  --hidden_size_chars=<hsc>  The hidden size of the character embedding Bi-LSTM. [default: 25]
  --hidden_size_LSTM=<hsn>  The hidden size of the LSTM. [default: 600]
  --add_char_emb=<add>      Boolean, True if char embedding is needed [default: True]
  --num_heads=<nmh>         The number of head for the attention encoder layer [default: 10]
  --dropout=<dp>            The dropout value. [default: 0.5]
  --learning_rate=<lr>      The learning rate for the optimizer [default: 1e-3]
  --batch_size=<bs>         The batch size for the training [default: 24]
  --n_epochs=<ne>           Number of epochs to train the network on [default: 100]
  --optimizer=<op>          The chosen tf optimizer, in ['sgd', 'adam', 'adagrad', 'rmsprop'] [default: sgd]
  --checkpoints=<ckpt>      Save checkpoints every ckpt steps [default: 5000]
  --buffer_size=<bfs>       Buffer size for shuffling  [default: 500]
  --deepness_finish=<dpsf>  The layer depth for the dense finish [default: 2]
  --activation_finish=<actf> The activation function for the dense finish [default: leaky_relu]
  --intern_size=<intf>      The internal dimension of finish dense layers [default: 3000]
  --weighted_loss=<wgth>    Boolean, indicates if loss must be weighted or not [default: True]
  --add_encoder=<addenc>     Boolean, indicates if encodre must be kept [default: True]
"""

import os
import logging

import tensorflow as tf
from docopt import docopt
from functools import partial
from numpy import genfromtxt
from glob import glob

from utils import generate_dataset, create_full_vocab
from reader import input_fn_gen
from model import model_fn

logging.basicConfig(level=os.environ.get("LOGLEVEL", "INFO"))

def str_to_bool(s):
    if s == 'True':
        return True
    elif s == 'False':
        return False
    else:
        raise ValueError

if __name__ == "__main__":
    # Get the arguments
    args = docopt(__doc__, version="0.3")
    # print(args)
    # Transform it into a params dic
    params = {}
    for k in args.keys():
        k2 = k.replace("<", "").replace(">", "").replace("-", "")
        try:  # Convert strings to int or floats when required
            params[k2] = int(args[k])
        except:
            try:
                params[k2] = float(args[k])
            except:
                try:
                    params[k2] = str_to_bool(args[k])
                except:
                    params[k2] = args[k]
    print(params)
    if params['num_LSTM_layers'] is None or params['num_layers_char'] is None:
        params['num_LSTM_layers'] = 2
        params['num_layers_char'] = 2
    # Checking if logdir already has the emb files:
    params['embedding_path'] = os.path.join(params['log_dir'], 'embedding')

    # Path to vocabs for indexing
    params["word_emb_vocab"] = os.path.join(
        params["embedding_path"], "vocab.txt"
    )
    params["char_vocab"] = os.path.join(
        params["embedding_path"], "chars.txt"
    )

    # Create dataset files if not already done:
    params['data_path'] = os.path.join(params['log_dir'], 'dataset_lm')

    # Get nb_chars, nb_labels, & nb_words for params (used in model):
    with open(params["word_emb_vocab"], "r", encoding="utf-8") as f:
        lines = f.readlines()
        params["vocab_size"] = len(lines)
        params["max_len_sent"] = max(map(len, lines))
    with open(params["char_vocab"], "r", encoding="utf-8") as f:
        params["nb_chars"] = len(f.readlines())

    params['frequencies'] = genfromtxt(os.path.join(
                                  params['embedding_path'],
                                  'freq.txt'),
                                delimiter="\t")
    params['activation_finish'] = tf.nn.leaky_relu
    # Create input functions
    input_fn = partial(input_fn_gen, mode='train', params=params)
    input_eval = partial(input_fn_gen, mode='eval', params=params)

    # Session config for tensorflow
    config = tf.ConfigProto(
        allow_soft_placement=True, log_device_placement=True
    )
    config.gpu_options.allow_growth = True

    config = (
        tf.estimator.RunConfig(save_checkpoints_steps=params["checkpoints"])
        .replace(save_summary_steps=1)
        .replace(session_config=config)
    )

    # Generate estimator object
    estimator = tf.estimator.Estimator(
        model_fn=model_fn,
        model_dir=params["log_dir"],
        params=params,
        config=config,
    )

    # Decoding indices:
    with open(params['word_emb_vocab'], "r", encoding='utf-8') as f:
        lines = f.readlines()

    dic = {i: lines[i] for i in range(len(lines))}
    n = len(dic)
    dic[n] = 'pad'
    dic[n+1] = 'pad'

    def predict_k(start_sent, k):
        acc_sent = start_sent
        for i in range(k):
            input_predict = partial(input_fn_gen, mode='predict', sent=acc_sent)
            for _, predictions in enumerate(estimator.predict(input_predict)):
                acc_sent = acc_sent + ' ' + dic[predictions['label']].rstrip('\n')
        return acc_sent

    print(predict_k(params['sentence'], params['k']))


def symbols_text(s):
    """
    Подсчет частоты вхождений символов в тексте
    """
    dictionary = {}

    for symbol in s:
        dictionary[symbol] = dictionary.get(symbol, 0) + 1

    for key in sorted(dictionary):
        print(f'{key}: {dictionary[key]}')

def words_text(text):
    '''
    Подсчета количества слов в тексте
    '''
    text = text.replace('\n', ' ').replace(',', ' ').replace(
        '.', ' ').replace('?', ' ').replace('!', ' ')
    words = text.split(' ')
    for w in words:
        if w == '':
            words.remove(w)
    return len(words)

def sentence_text(text):
    """
    Подсчет количества предложений в тексте
    """
    text.replace('\n', ' ')
    dots = text.count('.')
    exclamation_mark = text.count('!')
    question_mark = text.count('?')
    return dots + exclamation_mark + question_mark

def get_data():

    data = input("Введите строку или Enter(за вас придумается строка): ")
    if not data:
        data = """
Shakespeare "Romeo and Juliet" (PROLOGUE)

Two households, both alike in dignity,
In fair Verona, where we lay our scene,
From ancient grudge break to new mutiny,
Where civil blood makes civil hands unclean.
From forth the fatal loins of these two foes
A pair of star-cross'd lovers take their life;
Whose misadventured piteous overthrows
Do with their death bury their parents' strife.
The fearful passage of their death-mark'd love,
And the continuance of their parents' rage,
Which, but their children's end, nought could remove,
Is now the two hours' traffic of our stage;
The which if you with patient ears attend,
What here shall miss, our toil shall strive to mend."""

    return data

def main():
    data = get_data()
    while True:
        print("""\nЧто вы хотите сделать:
    1. Подсчет частоты вхождений символов в тексте
    2. Подсчета количества слов в тексте
    3. Подсчет количества предложений в тексте
    4. Выход""")
        s = input('Ваш выбор (укажите цифру от 1 до 4): ')
        if not s in ['1', '2', '3', '4']:
            print("Неверный выбор, попробуйте еще раз!")
            continue
        if s == '1':
            print('Частота вхождений символов в тексте:')
            symbols_text(data)
        elif s == '2':
            print(f'Количество слов в тексте: {words_text(data)}')
        elif s == '3':
            print(f'Количество предложений в тексте: {sentence_text(data)}')
        else:
            break

if __name__ == '__main__':
    main()


"""
    1st: prefix sum + suffix sum

    Time    O(N)
    Space   O(1)
    610 ms, faster than 100.00%
"""

class Solution:
    def maximumSumScore(self, nums: List[int]) -> int:
        sfs = sum(nums)
        n = len(nums)
        pfs = 0
        res = -(2**32)
        for i in range(n):
            x = nums[i]
            pfs += x
            res = max(res, pfs, sfs)
            sfs -= x
        return res


"""
Task. The goal in this code problem is to implement the binary search algorithm.

Input Format.
The first line of the input contains an integer 𝑛 and a sequence 𝑎0 < 𝑎1 < . . . < 𝑎𝑛−1 of 𝑛 pairwise distinct positive
integers in increasing order.
The next line contains an integer 𝑘 and 𝑘 positive integers 𝑏0, 𝑏1, . . . , 𝑏𝑘−1.

Constraints. 1 ≤ 𝑛, 𝑘 ≤ 104; 1 ≤ 𝑎𝑖 ≤ 109 for all 0 ≤ 𝑖 < 𝑛; 1 ≤ 𝑏𝑗 ≤ 109 for all 0 ≤ 𝑗 < 𝑘;

Output Format. For all 𝑖 from 0 to 𝑘 − 1, output an index 0 ≤ 𝑗 ≤ 𝑛 − 1 such that 𝑎𝑗 = 𝑏𝑖 or −1 if there
is no such index.
"""

def binary_search(array, lookup_value, low=0, high=None):
    high = len(array) if high is None else high

    while low <= high:
        mid = (high+low)//2

        if array[mid] == lookup_value:
            return mid

        elif array[mid] < lookup_value:
            low = mid+1

        else:
            high = mid-1

    return -1

if __name__ == '__main__':
    data = list(map(int, input().split()))
    n = data[0]
    m = data[n + 1]
    a = data[1:n + 1]
    for x in data[n + 2:]:
        print(binary_search(a, x, 0, n-1), end=' ')

Algorithms & Data Structures Specialisation/Algorithmic Toolbox/Week4-Divide and Conquer/1_binary_search.py