#!/usr/bin/env python

import json
import numpy as np
from scipy import stats
import os
import sys
from pathlib import Path
import pandas as pd
#from sklearn.cluster import KMeans
from scipy.cluster.vq import vq, kmeans2

# Choosing config file
configFilename = "config-sample.json"
argCount = len(sys.argv)
if(argCount > 1):
    configFilename = sys.argv[1]

# Defining paths
outputDirectory = "output/csv"

if(not os.path.exists(outputDirectory)):
    os.makedirs(outputDirectory)

# Reading config file
with open(configFilename, "r") as fd:
    config = json.load(fd)

print("Loading time series...")

timeseriesFilename = config["tsv"]
nclus = config["nclus"]

print("Loading time series...")
ts = pd.read_csv(timeseriesFilename,sep="\t")

K = np.sum(ts, axis=0)
columns=ts.columns
ts=ts.drop(columns[np.where(K == 0)[0]],axis=1)

# z-scored time series
z = stats.zscore(np.asarray(ts),1)

print("Building edge time series...")
T, N= ts.shape
u,v = np.where(np.triu(np.ones(N),1))           # get edges
# element-wise prroduct of time series
ets = (z[:,u]*z[:,v])
edgeids = {"edgeid"+str(e):edge for e,edge in enumerate(zip(columns[u],columns[v]))}

nclus=int(config['nclus'])
#Clustering edge time series
#etsclus_original=KMeans(n_clusters=nclus, random_state=0).fit(ets).labels_
etsclus=kmeans2(ets,k=nclus)[1]

np.savetxt('output/csv/clustered-edge_timeseries.csv',etsclus,delimiter=',')
with open('output/label.json', 'w') as outfile:
    json.dump(edgeids,outfile)


# OFT network module

import math
import os
from typing import Dict, List, Optional, Tuple, Type, Union
from diffusers import AutoencoderKL
from transformers import CLIPTextModel
import numpy as np
import torch
import re

RE_UPDOWN = re.compile(r"(up|down)_blocks_(\d+)_(resnets|upsamplers|downsamplers|attentions)_(\d+)_")

class OFTModule(torch.nn.Module):
    """
    replaces forward method of the original Linear, instead of replacing the original Linear module.
    """

    def __init__(
        self,
        oft_name,
        org_module: torch.nn.Module,
        multiplier=1.0,
        dim=4,
        alpha=1,
    ):
        """
        dim -> num blocks
        alpha -> constraint
        """
        super().__init__()
        self.oft_name = oft_name

        self.num_blocks = dim

        if "Linear" in org_module.__class__.__name__:
            out_dim = org_module.out_features
        elif "Conv" in org_module.__class__.__name__:
            out_dim = org_module.out_channels

        if type(alpha) == torch.Tensor:
            alpha = alpha.detach().numpy()
        self.constraint = alpha * out_dim
        self.register_buffer("alpha", torch.tensor(alpha))

        self.block_size = out_dim // self.num_blocks
        self.oft_blocks = torch.nn.Parameter(torch.zeros(self.num_blocks, self.block_size, self.block_size))

        self.out_dim = out_dim
        self.shape = org_module.weight.shape

        self.multiplier = multiplier
        self.org_module = [org_module]  # moduleにならないようにlistに入れる

    def apply_to(self):
        self.org_forward = self.org_module[0].forward
        self.org_module[0].forward = self.forward

    def get_weight(self, multiplier=None):
        if multiplier is None:
            multiplier = self.multiplier

        block_Q = self.oft_blocks - self.oft_blocks.transpose(1, 2)
        norm_Q = torch.norm(block_Q.flatten())
        new_norm_Q = torch.clamp(norm_Q, max=self.constraint)
        block_Q = block_Q * ((new_norm_Q + 1e-8) / (norm_Q + 1e-8))
        I = torch.eye(self.block_size, device=self.oft_blocks.device).unsqueeze(0).repeat(self.num_blocks, 1, 1)
        block_R = torch.matmul(I + block_Q, (I - block_Q).inverse())

        block_R_weighted = self.multiplier * block_R + (1 - self.multiplier) * I
        R = torch.block_diag(*block_R_weighted)

        return R

    def forward(self, x, scale=None):
        x = self.org_forward(x)
        if self.multiplier == 0.0:
            return x

        R = self.get_weight().to(x.device, dtype=x.dtype)
        if x.dim() == 4:
            x = x.permute(0, 2, 3, 1)
            x = torch.matmul(x, R)
            x = x.permute(0, 3, 1, 2)
        else:
            x = torch.matmul(x, R)
        return x

class OFTInfModule(OFTModule):
    def __init__(
        self,
        oft_name,
        org_module: torch.nn.Module,
        multiplier=1.0,
        dim=4,
        alpha=1,
        **kwargs,
    ):
        # no dropout for inference
        super().__init__(oft_name, org_module, multiplier, dim, alpha)
        self.enabled = True
        self.network: OFTNetwork = None

    def set_network(self, network):
        self.network = network

    def forward(self, x, scale=None):
        if not self.enabled:
            return self.org_forward(x)
        return super().forward(x, scale)

    def merge_to(self, multiplier=None, sign=1):
        R = self.get_weight(multiplier) * sign

        # get org weight
        org_sd = self.org_module[0].state_dict()
        org_weight = org_sd["weight"]
        R = R.to(org_weight.device, dtype=org_weight.dtype)

        if org_weight.dim() == 4:
            weight = torch.einsum("oihw, op -> pihw", org_weight, R)
        else:
            weight = torch.einsum("oi, op -> pi", org_weight, R)

        # set weight to org_module
        org_sd["weight"] = weight
        self.org_module[0].load_state_dict(org_sd)

def create_network(
    multiplier: float,
    network_dim: Optional[int],
    network_alpha: Optional[float],
    vae: AutoencoderKL,
    text_encoder: Union[CLIPTextModel, List[CLIPTextModel]],
    unet,
    neuron_dropout: Optional[float] = None,
    **kwargs,
):
    if network_dim is None:
        network_dim = 4  # default
    if network_alpha is None:
        network_alpha = 1.0

    enable_all_linear = kwargs.get("enable_all_linear", None)
    enable_conv = kwargs.get("enable_conv", None)
    if enable_all_linear is not None:
        enable_all_linear = bool(enable_all_linear)
    if enable_conv is not None:
        enable_conv = bool(enable_conv)

    network = OFTNetwork(
        text_encoder,
        unet,
        multiplier=multiplier,
        dim=network_dim,
        alpha=network_alpha,
        enable_all_linear=enable_all_linear,
        enable_conv=enable_conv,
        varbose=True,
    )
    return network

# Create network from weights for inference, weights are not loaded here (because can be merged)
def create_network_from_weights(multiplier, file, vae, text_encoder, unet, weights_sd=None, for_inference=False, **kwargs):
    if weights_sd is None:
        if os.path.splitext(file)[1] == ".safetensors":
            from safetensors.torch import load_file, safe_open

            weights_sd = load_file(file)
        else:
            weights_sd = torch.load(file, map_location="cpu")

    # check dim, alpha and if weights have for conv2d
    dim = None
    alpha = None
    has_conv2d = None
    all_linear = None
    for name, param in weights_sd.items():
        if name.endswith(".alpha"):
            if alpha is None:
                alpha = param.item()
        else:
            if dim is None:
                dim = param.size()[0]
            if has_conv2d is None and param.dim() == 4:
                has_conv2d = True
            if all_linear is None:
                if param.dim() == 3 and "attn" not in name:
                    all_linear = True
        if dim is not None and alpha is not None and has_conv2d is not None:
            break
    if has_conv2d is None:
        has_conv2d = False
    if all_linear is None:
        all_linear = False

    module_class = OFTInfModule if for_inference else OFTModule
    network = OFTNetwork(
        text_encoder,
        unet,
        multiplier=multiplier,
        dim=dim,
        alpha=alpha,
        enable_all_linear=all_linear,
        enable_conv=has_conv2d,
        module_class=module_class,
    )
    return network, weights_sd

class OFTNetwork(torch.nn.Module):
    UNET_TARGET_REPLACE_MODULE_ATTN_ONLY = ["CrossAttention"]
    UNET_TARGET_REPLACE_MODULE_ALL_LINEAR = ["Transformer2DModel"]
    UNET_TARGET_REPLACE_MODULE_CONV2D_3X3 = ["ResnetBlock2D", "Downsample2D", "Upsample2D"]
    OFT_PREFIX_UNET = "oft_unet"  # これ変えないほうがいいかな

    def __init__(
        self,
        text_encoder: Union[List[CLIPTextModel], CLIPTextModel],
        unet,
        multiplier: float = 1.0,
        dim: int = 4,
        alpha: float = 1,
        enable_all_linear: Optional[bool] = False,
        enable_conv: Optional[bool] = False,
        module_class: Type[object] = OFTModule,
        varbose: Optional[bool] = False,
    ) -> None:
        super().__init__()
        self.multiplier = multiplier

        self.dim = dim
        self.alpha = alpha

        print(
            f"create OFT network. num blocks: {self.dim}, constraint: {self.alpha}, multiplier: {self.multiplier}, enable_conv: {enable_conv}"
        )

        # create module instances
        def create_modules(
            root_module: torch.nn.Module,
            target_replace_modules: List[torch.nn.Module],
        ) -> List[OFTModule]:
            prefix = self.OFT_PREFIX_UNET
            ofts = []
            for name, module in root_module.named_modules():
                if module.__class__.__name__ in target_replace_modules:
                    for child_name, child_module in module.named_modules():
                        is_linear = "Linear" in child_module.__class__.__name__
                        is_conv2d = "Conv2d" in child_module.__class__.__name__
                        is_conv2d_1x1 = is_conv2d and child_module.kernel_size == (1, 1)

                        if is_linear or is_conv2d_1x1 or (is_conv2d and enable_conv):
                            oft_name = prefix + "." + name + "." + child_name
                            oft_name = oft_name.replace(".", "_")
                            # print(oft_name)

                            oft = module_class(
                                oft_name,
                                child_module,
                                self.multiplier,
                                dim,
                                alpha,
                            )
                            ofts.append(oft)
            return ofts

        # extend U-Net target modules if conv2d 3x3 is enabled, or load from weights
        if enable_all_linear:
            target_modules = OFTNetwork.UNET_TARGET_REPLACE_MODULE_ALL_LINEAR
        else:
            target_modules = OFTNetwork.UNET_TARGET_REPLACE_MODULE_ATTN_ONLY
        if enable_conv:
            target_modules += OFTNetwork.UNET_TARGET_REPLACE_MODULE_CONV2D_3X3

        self.unet_ofts: List[OFTModule] = create_modules(unet, target_modules)
        print(f"create OFT for U-Net: {len(self.unet_ofts)} modules.")

        # assertion
        names = set()
        for oft in self.unet_ofts:
            assert oft.oft_name not in names, f"duplicated oft name: {oft.oft_name}"
            names.add(oft.oft_name)

    def set_multiplier(self, multiplier):
        self.multiplier = multiplier
        for oft in self.unet_ofts:
            oft.multiplier = self.multiplier

    def load_weights(self, file):
        if os.path.splitext(file)[1] == ".safetensors":
            from safetensors.torch import load_file

            weights_sd = load_file(file)
        else:
            weights_sd = torch.load(file, map_location="cpu")

        info = self.load_state_dict(weights_sd, False)
        return info

    def apply_to(self, text_encoder, unet, apply_text_encoder=True, apply_unet=True):
        assert apply_unet, "apply_unet must be True"

        for oft in self.unet_ofts:
            oft.apply_to()
            self.add_module(oft.oft_name, oft)

    # マージできるかどうかを返す
    def is_mergeable(self):
        return True

    # TODO refactor to common function with apply_to
    def merge_to(self, text_encoder, unet, weights_sd, dtype, device):
        print("enable OFT for U-Net")

        for oft in self.unet_ofts:
            sd_for_lora = {}
            for key in weights_sd.keys():
                if key.startswith(oft.oft_name):
                    sd_for_lora[key[len(oft.oft_name) + 1 :]] = weights_sd[key]
            oft.load_state_dict(sd_for_lora, False)
            oft.merge_to()

        print(f"weights are merged")

    # 二つのText Encoderに別々の学習率を設定できるようにするといいかも
    def prepare_optimizer_params(self, text_encoder_lr, unet_lr, default_lr):
        self.requires_grad_(True)
        all_params = []

        def enumerate_params(ofts):
            params = []
            for oft in ofts:
                params.extend(oft.parameters())

            # print num of params
            num_params = 0
            for p in params:
                num_params += p.numel()
            print(f"OFT params: {num_params}")
            return params

        param_data = {"params": enumerate_params(self.unet_ofts)}
        if unet_lr is not None:
            param_data["lr"] = unet_lr
        all_params.append(param_data)

        return all_params

    def enable_gradient_checkpointing(self):
        # not supported
        pass

    def prepare_grad_etc(self, text_encoder, unet):
        self.requires_grad_(True)

    def on_epoch_start(self, text_encoder, unet):
        self.train()

    def get_trainable_params(self):
        return self.parameters()

    def save_weights(self, file, dtype, metadata):
        if metadata is not None and len(metadata) == 0:
            metadata = None

        state_dict = self.state_dict()

        if dtype is not None:
            for key in list(state_dict.keys()):
                v = state_dict[key]
                v = v.detach().clone().to("cpu").to(dtype)
                state_dict[key] = v

        if os.path.splitext(file)[1] == ".safetensors":
            from safetensors.torch import save_file
            from library import train_util

            # Precalculate model hashes to save time on indexing
            if metadata is None:
                metadata = {}
            model_hash, legacy_hash = train_util.precalculate_safetensors_hashes(state_dict, metadata)
            metadata["sshs_model_hash"] = model_hash
            metadata["sshs_legacy_hash"] = legacy_hash

            save_file(state_dict, file, metadata)
        else:
            torch.save(state_dict, file)

    def backup_weights(self):
        # 重みのバックアップを行う
        ofts: List[OFTInfModule] = self.unet_ofts
        for oft in ofts:
            org_module = oft.org_module[0]
            if not hasattr(org_module, "_lora_org_weight"):
                sd = org_module.state_dict()
                org_module._lora_org_weight = sd["weight"].detach().clone()
                org_module._lora_restored = True

    def restore_weights(self):
        # 重みのリストアを行う
        ofts: List[OFTInfModule] = self.unet_ofts
        for oft in ofts:
            org_module = oft.org_module[0]
            if not org_module._lora_restored:
                sd = org_module.state_dict()
                sd["weight"] = org_module._lora_org_weight
                org_module.load_state_dict(sd)
                org_module._lora_restored = True

    def pre_calculation(self):
        # 事前計算を行う
        ofts: List[OFTInfModule] = self.unet_ofts
        for oft in ofts:
            org_module = oft.org_module[0]
            oft.merge_to()
            # sd = org_module.state_dict()
            # org_weight = sd["weight"]
            # lora_weight = oft.get_weight().to(org_weight.device, dtype=org_weight.dtype)
            # sd["weight"] = org_weight + lora_weight
            # assert sd["weight"].shape == org_weight.shape
            # org_module.load_state_dict(sd)

            org_module._lora_restored = False
            oft.enabled = False


import numpy as np
import matplotlib.pyplot as plt

def MC_Ising_model(beta, vis = False, N = 50, rng = 3000):
  s = np.random.choice([-1, 1],[N,N])
  numbers = np.arange(N*N).reshape(N,N)
  M_list = []
  blacks = ((numbers//N + numbers%N)%2).astype(bool)
  whites = np.logical_not(blacks)

  if vis == True:
    plt.rcParams['image.cmap'] = 'Wistia'
    fig, ax = plt.subplots(figsize=(16, 9))
    ax.imshow(s, vmin=0, vmax=1)
    ax.axis(False);

  for j in range(rng):
    m_i = np.roll(s, 1, axis=0)
    m_i += np.roll(s, -1, axis=0)
    m_i += np.roll(s, 1, axis=1)
    m_i += np.roll(s, -1, axis=1)

    p = 1/(1+np.exp(-2*beta*m_i))
    p = p.reshape(N,N)

    rand = np.random.random([N,N])
    up = np.where(p >= rand, True, False).reshape(N,N)

    steps = np.random.choice([0, 1],2)

    for i in steps:
      if i == 0:
        s[whites] = -1
        s[whites & up] = +1
      else:
        s[blacks] = -1
        s[blacks & up] = +1

    if j > rng/2:
      M = np.abs(np.mean(s))
      M_list.append(M)

  if vis == True:
    plt.rcParams['image.cmap'] = 'Wistia'
    fig, ax = plt.subplots(figsize=(16, 9))
    ax.imshow(s, vmin=0, vmax=1)
    ax.axis(False);

  M_mean = np.mean(M_list)
  chi = np.var(M_list)*beta

  M_list.clear()

  return M_mean, chi

betas = np.linspace(0.2,2,num=40)
print(betas)
data = []

for beta in betas:
  mb = []
  cb = []
  for i in range(10):
    values = (MC_Ising_model(beta))
    mb.append(values[0])
    cb.append(values[1])
  print(beta, np.mean(mb), np.mean(cb))
  data.append([beta, np.mean(mb), np.mean(cb)])

data = np.array(data)
b = data[:,0]
m = data[:,1]
c = data[:,2]

plt.plot(b, m)
plt.show()
plt.plot(b, c)
plt.show()


# -*- coding: utf-8 -*-
"""
Created on Wed Oct 26 09:28:19 2022

@author: bjk_a
"""

#1.kutuphaneler
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# veri yukleme
veriler = pd.read_csv('maaslar.csv')

x = veriler.iloc[:,1:2]
y = veriler.iloc[:,2:]
X = x.values
Y = y.values

#linear regression
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()
lin_reg.fit(X,Y)

plt.scatter(X,Y,color='red')
plt.plot(x,lin_reg.predict(X), color = 'blue')
plt.show()

#polynomial regression
from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree = 2)
x_poly = poly_reg.fit_transform(X)
print(x_poly)
lin_reg2 = LinearRegression()
lin_reg2.fit(x_poly,y)
plt.scatter(X,Y,color = 'red')
plt.plot(X,lin_reg2.predict(poly_reg.fit_transform(X)), color = 'blue')
plt.show()

from sklearn.preprocessing import PolynomialFeatures
poly_reg = PolynomialFeatures(degree = 4)
x_poly = poly_reg.fit_transform(X)
print(x_poly)
lin_reg2 = LinearRegression()
lin_reg2.fit(x_poly,y)
plt.scatter(X,Y,color = 'red')
plt.plot(X,lin_reg2.predict(poly_reg.fit_transform(X)), color = 'blue')
plt.show()

#tahminler

print(lin_reg.predict([[11]]))
print(lin_reg.predict([[6.6]]))

print(lin_reg2.predict(poly_reg.fit_transform([[6.6]])))
print(lin_reg2.predict(poly_reg.fit_transform([[11]])))

#verilerin olceklenmesi
from sklearn.preprocessing import StandardScaler

sc1=StandardScaler()

x_olcekli = sc1.fit_transform(X)

sc2=StandardScaler()
y_olcekli = np.ravel(sc2.fit_transform(Y.reshape(-1,1)))

from sklearn.svm import SVR

svr_reg = SVR(kernel='rbf')
svr_reg.fit(x_olcekli,y_olcekli)

plt.scatter(x_olcekli,y_olcekli,color='red')
plt.plot(x_olcekli,svr_reg.predict(x_olcekli),color='blue')

plt.show()
print(svr_reg.predict([[11]]))
print(svr_reg.predict([[6.6]]))

from sklearn.tree import DecisionTreeRegressor
r_dt = DecisionTreeRegressor(random_state=0)
#veriyi fit ediyoruz (X ve Y numpy arrayleri x ve y olan df leri değil)
#yani X,Y arasında ilişki kuruyor, eğitim seviyesine (x) göre aldığı maaş (y)
r_dt.fit(X,Y)

# 3 farklı değer de x z k aynı sonucu veriyor, çünkü aynı aralıktalar
Z = X + 0.5
K = X - 0.4

# X ve Y arası plotu çiz
plt.scatter(X,Y, color='red')

# X değerini çiz r.dt nin tahminini kullan
plt.plot(x,r_dt.predict(X), color='blue')

plt.plot(x,r_dt.predict(Z),color='green')
plt.plot(x,r_dt.predict(K),color='yellow')
print(r_dt.predict([[11]]))
print(r_dt.predict([[6.6]]))


from datetime import datetime       # needed to read and compare dates

class item:     # initiates item class for all inventory elements

    def __init__(self, itemID=0, manuF='none', itemT='none', itemP=0.0, serv=datetime.today(), dmg='False'):
        self.itemID = itemID
        self.manuF = manuF
        self.itemT = itemT
        self.itemP = itemP
        self.serv = serv
        self.dmg = dmg

if __name__ == "__main__":
    full_table = {}     # Dictionary to hold all inventory elements for retrieval
    item_type = []
    itemID_List = []
    dmg_inv = []        # Lists for sorting
    manuF_list = []
    date_list = []
    price_list = []

    import csv      # Needed for csv manipulation

    with open('ManufacturerList.csv', 'r') as csvfile:      # Opens/reads manufacturer list
        list_reader = csv.reader(csvfile)
        for row in list_reader:     # Takes rows from csv and adds them to line
            line = item()           # Classifies line as an item
            line.itemID = row[0]
            line.manuF = row[1]     # Places elements in required organizational structure in line
            line.itemT = row[2]
            line.dmg = row[3]
            full_table[line.itemID] = line  # Defines ItemID as key and adds line items to Full Table dictionary

    with open('PriceList.csv', 'r') as csvfile:     # Opens/reads price list and add missing elements to Full table dictionary
        list_reader = csv.reader(csvfile)
        for row in list_reader:                     # Adds any missing elements
            full_table[row[0]].itemP = row[1]

    with open('ServiceDatesList.csv','r') as csvfile:       # Opens/reads service list and adds missing elements
        list_reader = csv.reader(csvfile)
        date_format = '%m/%d/%Y'    # Format for datetime
        for row in list_reader:
            new_date = datetime.strptime(row[1], date_format).date()    # strips dates
            full_table[row[0]].serv = new_date                          # adds elements to table

    for i in full_table:    # creates a list of just manufacturers
        manuF_list.append(full_table[i].manuF)
    manuF_list.sort()       # sorts manufacturer list
    manuF = {}              # placed in dictionary

    for i in manuF_list:    # specified key to ensure unique values
        manuF[i] = i
    with open('FullInventory.csv', 'w', newline='') as csvfile:     # opens for writing
        line_writer = csv.writer(csvfile)
        for i in manuF:                                            # iterates and adds sorted elements to csv
            for j in full_table:
                if full_table[j].manuF == i:
                    line_writer.writerow([full_table[j].itemID, full_table[j].manuF,
                                            full_table[j].itemT, full_table[j].itemP,
                                            full_table[j].serv, full_table[j].dmg])

    for i in full_table:                        # creates list for item type
        item_type.append(full_table[i].itemT)
    item_type.sort()                            # sorts item types
    itemT = {}
    for i in item_type:                         # ensures unique values
        itemT[i] = i
    for i in full_table:                        # creates list for ItemID
        itemID_List.append(full_table[i].itemID)
    itemID_List.sort()                          # sorts item ID
    for i in itemT:
        with open(f'{i.capitalize()}Inventory.csv', 'w', newline='') as csvfile:  # opens capitalized variable named csv for writing
            line_writer = csv.writer(csvfile)
            for j in itemID_List:
                for k in full_table:
                    if full_table[k].itemID == j:   # iterates and writes needed elements to file
                        line_writer.writerow([full_table[k].itemID, full_table[k].manuF,
                                              full_table[k].itemP, full_table[k].serv,
                                              full_table[k].dmg])

    for i in full_table:                       # creation of date list table
        date_list.append(full_table[i].serv)
    date_list.sort()
    dates = {}
    for i in date_list:                        # ensure unique values
        dates[i] = i

    with open('PastServiceDateInventory.csv', 'w', newline='') as csvfile:  # opens past service csv for writing
        line_writer = csv.writer(csvfile)
        for i in dates:
            for j in full_table:
                if datetime.today().date() > full_table[j].serv and full_table[j].serv == i:    #compared today's date with the service due date
                    line_writer.writerow([full_table[j].itemID, full_table[j].manuF,
                                          full_table[j].itemT, full_table[j].itemP,
                                          full_table[j].serv, full_table[j].dmg],)

    for i in full_table:        # adds prices to list
        price_list.append(full_table[i].itemP)

    price_list.sort()           # sorts prices
    prices = {}
    for i in price_list:        # ensures unique price values
        prices[i] = i

    with open('DamagedInventory.csv','w', newline='') as csvfile:   # opens csv to write damaged inventory
        line_writer = csv.writer(csvfile)
        for i in prices:
            for j in full_table:
                if full_table[j].dmg == 'damaged' and full_table[j].itemP == i:     # checks if item flagged as damaged
                    line_writer.writerow([full_table[j].itemID, full_table[j].manuF,    # writes rows with relevant information
                                          full_table[j].itemT, full_table[j].itemP,
                                          full_table[j].serv])
    print('Reports generated.')

FinalProject - Part 1/FinalProjectPart1.py


"""empty message

Revision ID: 0e84780c08ce
Revises:
Create Date: 2023-06-25 00:48:55.259558

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '0e84780c08ce'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('puzzles',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('quote', sa.String(length=255), nullable=True),
    sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('users',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('username', sa.String(), nullable=True),
    sa.Column('email', sa.String(), nullable=True),
    sa.Column('password', sa.String(), nullable=True),
    sa.Column('score', sa.Integer(), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_table('messages',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('body', sa.String(), nullable=True),
    sa.Column('user_id', sa.Integer(), nullable=True),
    sa.Column('score', sa.Integer(), nullable=True),
    sa.Column('created_at', sa.DateTime(), server_default=sa.text('(CURRENT_TIMESTAMP)'), nullable=False),
    sa.Column('updated_at', sa.DateTime(), nullable=False),
    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    # ### end Alembic commands ###

def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('messages')
    op.drop_table('users')
    op.drop_table('puzzles')
    # ### end Alembic commands ###


"""
East Text detection
"""
import cv2
import numpy as np
from imutils.object_detection import non_max_suppression
from cfir_game_lens.utils import Box, GameCoverImage, ImageSize
from dataclasses import astuple

class EAST:  # pylint: disable=too-few-public-methods
    """East Class
    """

    LAYER_NAMES = ["feature_fusion/Conv_7/Sigmoid", "feature_fusion/concat_3"]
    EAST_MODEL_FILE = "frozen_east_text_detection.pb"
    SCALE_FACTOR = 1.0
    MEAN_SUBSTRACTION = (123.68, 116.78, 103.94)
    MIN_CONFIDENCE = 0.5

    def __init__(self):
        self._net = cv2.dnn.readNet(self.EAST_MODEL_FILE)

    @classmethod
    def _resize_image(cls, img: GameCoverImage):
        new_size = ImageSize()
        new_size.height = round(img.size.height / 32) * 32
        new_size.width = round(img.size.width / 32) * 32
        new_img = GameCoverImage(img=cv2.resize(img.img, new_size.get_rev_tuple()))
        return new_img

    def _get_blob(self, img: GameCoverImage):
        blob_args = [img.img, self.SCALE_FACTOR, img.size.get_rev_tuple(), self.MEAN_SUBSTRACTION]
        blob = cv2.dnn.blobFromImage(*blob_args, swapRB=True, crop=False)
        return blob

    @classmethod
    def _build_box(cls, offset_x, offset_y, angle, loc_data):
        (offset_x, offset_y) = (offset_x * 4.0, offset_y * 4.0)
        cos = np.cos(angle)
        sin = np.sin(angle)
        height = loc_data[0] + loc_data[2]
        width = loc_data[1] + loc_data[3]
        end_x = int(offset_x + (cos * loc_data[1]) + (sin * loc_data[2]))
        end_y = int(offset_y - (sin * loc_data[1]) + (cos * loc_data[2]))
        start_x = int(end_x - width)
        start_y = int(end_y - height)
        res = Box(start_x, start_y, end_x, end_y)
        return res

    def _build_boxes(self, scores, geometry):
        boxes = []
        confidences = []
        (num_rows, num_cols) = scores.shape[2:4]
        for y in range(0, num_rows):  # pylint: disable=invalid-name
            # extract the scores (probabilities), followed by the
            # geometrical data used to derive potential bounding box
            # coordinates that surround text
            scores_data = scores[0, 0, y]
            loc_data_arr = [geometry[0, 0, y], geometry[0, 1, y], geometry[0, 2, y], geometry[0, 3, y]]
            angles_data = geometry[0, 4, y]

            # loop over the number of columns
            for x in range(0, num_cols):  # pylint: disable=invalid-name
                if scores_data[x] < self.MIN_CONFIDENCE:
                    continue
                loc_data_arr_x = [loc_data[x] for loc_data in loc_data_arr]
                box = self._build_box(x, y, angles_data[x], loc_data_arr_x)
                boxes.append(box)
                confidences.append(scores_data[x])
        return boxes, confidences

    def find_text(self, image: GameCoverImage):
        """Find boxes of text in image

        Arguments:
            image {GameCoverImage} -- [description]

        Returns:
            List[Box] -- Boxes with text
        """
        # run east model
        resized_img = self._resize_image(image)
        self._net.setInput(self._get_blob(resized_img))
        (scores, geometry) = self._net.forward(self.LAYER_NAMES)

        # create boxes from east output and filter according to confidences\scores
        boxes, confidences = self._build_boxes(scores, geometry)
        boxes_as_tuple = [astuple(x) for x in boxes]
        boxes = non_max_suppression(np.array(boxes_as_tuple), probs=confidences)
        boxes_res = [Box(*x) for x in boxes]

        # fix  images ratio
        ratio_width = image.size.width / float(resized_img.size.width)
        ratio_height = image.size.height / float(resized_img.size.height)
        for box in boxes_res:
            box.fix_sizes(ratio_width, ratio_height)
        return boxes_res


#!/usr/bin/env python3
import gym
from gym import wrappers
import gym_gazebo
import time
import numpy
import random
import time

import qlearn
import liveplot

from matplotlib import pyplot as plt

def render():
    render_skip = 0  # Skip first X episodes.
    render_interval = 50  # Show render Every Y episodes.
    render_episodes = 10  # Show Z episodes every rendering.

    if (x % render_interval == 0) and (x != 0) and (x > render_skip):
        env.render()
    elif (((x-render_episodes) % render_interval == 0) and (x != 0) and
          (x > render_skip) and (render_episodes < x)):
        env.render(close=True)

if __name__ == '__main__':

    env = gym.make('Gazebo_Lab06-v0')

    outdir = '/tmp/gazebo_gym_experiments'
    env = gym.wrappers.Monitor(env, outdir, force=True)
    plotter = liveplot.LivePlot(outdir)

    last_time_steps = numpy.ndarray(0)

    qlearn = qlearn.QLearn(actions=range(env.action_space.n),
                           alpha=0.2, gamma=0.8, epsilon=0.9)

    # qlearn.loadQ("QValues_A+")

    initial_epsilon = qlearn.epsilon

    epsilon_discount = 0.9986 # each episode, we're going to reduce epsilon by this much (transition from explore to greedy)

    start_time = time.time()
    total_episodes = 10000
    highest_reward = 0

    for x in range(total_episodes):
        done = False
        cumulated_reward = 0
        observation = env.reset()

        #decrease chance of random action
        if qlearn.epsilon > 0.05: #stop reducing epsilon at a certain point (don't want all greedy)
            qlearn.epsilon *= epsilon_discount #reduce epsilon each episode

        state = ''.join(map(str, observation)) #state holds "old" observation (state we're in before we take action)

        # To change max episode steps, go to gym_gazebo/__init__.py
        i = -1
        while True:
            i += 1

            # Pick an action based on the current state
            action = qlearn.chooseAction(state)
            # Execute the action and get feedback
            observation, reward, done, info = env.step(action)
            #new state after action, reward associated with action, whether we're done or not, and any info parameters
            cumulated_reward += reward

            if highest_reward < cumulated_reward:
                highest_reward = cumulated_reward

            nextState = ''.join(map(str, observation)) #if observation was [0,0,1], this would give 001 (single string)
            #nextState is state we've transitioned into (the current state)

            #learn based on start state, action we took, reward from taking that action, and state we've transitioned into from that action
            qlearn.learn(state, action, reward, nextState)

            env._flush(force=True)

            if not(done):
                state = nextState #set current state to state we've transitioned into
            else:
                last_time_steps = numpy.append(last_time_steps, [int(i + 1)])
                break

        print("===== Completed episode {}".format(x))

        if (x > 0) and (x % 5 == 0):
            qlearn.saveQ("QValues")
            plotter.plot(env)

        m, s = divmod(int(time.time() - start_time), 60)
        h, m = divmod(m, 60)
        print ("Starting EP: " + str(x+1) +
               " - [alpha: " + str(round(qlearn.alpha, 2)) +
               " - gamma: " + str(round(qlearn.gamma, 2)) +
               " - epsilon: " + str(round(qlearn.epsilon, 2)) +
               "] - Reward: " + str(cumulated_reward) +
               "     Time: %d:%02d:%02d" % (h, m, s))

    # Github table content
    print ("\n|"+str(total_episodes)+"|"+str(qlearn.alpha)+"|" +
           str(qlearn.gamma)+"|"+str(initial_epsilon)+"*" +
           str(epsilon_discount)+"|"+str(highest_reward) + "| PICTURE |")

    l = last_time_steps.tolist()
    l.sort()

    # print("Parameters: a="+str)
    print("Overall score: {:0.2f}".format(last_time_steps.mean()))
    print("Best 100 score: {:0.2f}".
          format(reduce(lambda x, y: x + y, l[-100:]) / len(l[-100:])))

    env.close()


from django.shortcuts import render

from articles.models import Article

def articles_list(request):
    template = 'articles/news.html'
    acricles = Article.objects.all().prefetch_related('scopes')
    ordering = '-published_at'
    context = {'object_list': acricles.order_by(ordering)}
    return render(request, template, context)


from rpython.rlib.rarithmetic import r_singlefloat, r_uint
from rpython.rtyper.lltypesystem import lltype, rffi
from rpython.translator.tool.cbuild import ExternalCompilationInfo

r_uint32 = rffi.r_uint
assert r_uint32.BITS == 32
UINT32MAX = 2 ** 32 - 1

# keep in sync with the C code in pypy__decay_jit_counters below
ENTRY = lltype.Struct('timetable_entry',
                      ('times', lltype.FixedSizeArray(rffi.FLOAT, 5)),
                      ('subhashes', lltype.FixedSizeArray(rffi.USHORT, 5)))

class JitCounter:
    """A process translated with the JIT contains one prebuilt instance
    of this class.  It is used for three things:

    * It maps greenkey hashes to counters, to know when we have seen this
      greenkey enough to reach the 'threshold' or 'function_threshold'
      parameters.  This is done in a lossy way by a fixed-size 'timetable'.

    * It handles the counters on the failing guards, for 'trace_eagerness'.
      This is done in the same 'timetable'.

    * It records the JitCell objects that are created when we compile
      a loop, in a non-lossy dictionary-like strurcture.  This is done
      in the 'celltable'.

    The 'timetable' is a table of DEFAULT_SIZE entries, each of which
    containing 5 entries.  From a hash value, we use the index number
    '_get_index(hash)', and then we look in all five entries for a
    matching '_get_subhash(hash)'.  The five entries are roughly kept
    sorted by decreasing recorded time.  The hash value itself should be
    computed accordingly: we only use bits 21:32 for _get_index and
    bits 0:16 for _get_subhash.  (This organization is "probably good"
    to get not-too-random behavior; another motivation for it was for
    the STM branch, to avoid pointless conflicts between threads.)

    The time value stored in the timetable is a (short-precision)
    floating-point number.  The idea is that a value of 0.0 means
    absent, and values go up to the maximum of 1.0.

    'compute_threshold(threshold)' returns basically the fraction
    1.0/threshold, corresponding to the 'increment' value for the
    following APIs.

    'tick(hash, increment)' adds 'increment' to the time value stored
    with the 'hash'.  Remember that only bits 0:16,21:32 of the hash
    are used; in case of collision between two hashes, they will grow
    twice as fast, because each tick() call will contribute to the
    colliding time value.

    'fetch_next_hash()' returns a "random" hash value suitable for
    using in tick() later.  Used when compiling guards; when the
    guard actually fails, we'll tick() the guard's stored random hash.

    'reset(hash)', 'change_current_fraction(hash, new_time_value)'
    change the time value associated with a hash.  The former resets
    it to zero, and the latter changes it to the given value (which
    should be a value close to 1.0).

    'set_decay(decay)', 'decay_all_counters()' is used to globally
    reduce all the stored time values.  They all get multiplied by
    a fraction close to (but smaller than) 1.0, computed from the
    'decay' parameter.

    'install_new_cell(hash, newcell)' adds the new JitCell to the
    celltable, at the index given by 'hash' (bits 21:32).  Unlike
    the timetable, the celltable stores a linked list of JitCells
    for every entry, and so it is not lossy.

    'lookup_chain(hash)' returns the first JitCell at 'hash'.  You can
    then walk the chain by following the '.next' attributes until you
    reach None.

    'cleanup_chain(hash)' resets the timetable's 'hash' entry and
    cleans up the celltable at 'hash'.  It removes those JitCells
    for which 'cell.should_remove_jitcell()' returns True.
    """
    DEFAULT_SIZE = 2048

    def __init__(self, size=DEFAULT_SIZE, translator=None):
        "NOT_RPYTHON"
        self.size = size
        self.shift = 16
        while (UINT32MAX >> self.shift) != size - 1:
            self.shift += 1
            assert self.shift < 999, "size is not a power of two <= 2**16"
        #
        # The table of timings.  This is a 5-ways associative cache.
        # We index into it using a number between 0 and (size - 1),
        # and we're getting a 32-bytes-long entry; then this entry
        # contains 5 possible ways, each occupying 6 bytes: 4 bytes
        # for a float, and the 2 lowest bytes from the original hash.
        self.timetable = lltype.malloc(rffi.CArray(ENTRY), self.size,
                                       flavor='raw', zero=True,
                                       track_allocation=False)
        self._nexthash = r_uint(0)
        #
        # The table of JitCell entries, recording already-compiled loops
        self.celltable = [None] * size
        #
        if translator is not None:
            class Glob:
                step = 0
            glob = Glob()
            def invoke_after_minor_collection():
                # After 32 minor collections, we call decay_all_counters().
                # The "--jit decay=N" option measures the amount the
                # counters are then reduced by.
                glob.step += 1
                if glob.step == 32:
                    glob.step = 0
                    self.decay_all_counters()
            if not hasattr(translator, '_jit2gc'):
                translator._jit2gc = {}
            translator._jit2gc['invoke_after_minor_collection'] = (
                invoke_after_minor_collection)

    def compute_threshold(self, threshold):
        """Return the 'increment' value corresponding to the given number."""
        if threshold <= 0:
            return 0.0   # no increment, never reach 1.0
        return 1.0 / (threshold - 0.001)

    def _get_index(self, hash):
        """Return the index (< self.size) from a hash.  This truncates
        the hash to 32 bits, and then keep the *highest* remaining bits.
        Be sure that hash is computed correctly, by multiplying with
        a large odd number or by fetch_next_hash()."""
        hash32 = r_uint(r_uint32(hash))  # mask off the bits higher than 32
        index = hash32 >> self.shift     # shift, resulting in a value < size
        return index                     # return the result as a r_uint
    _get_index._always_inline_ = True

    @staticmethod
    def _get_subhash(hash):
        return hash & 65535

    def fetch_next_hash(self):
        result = self._nexthash
        # note: all three "1" bits in the following constant are needed
        # to make test_counter.test_fetch_next_index pass.  The first
        # is to increment the "subhash" (lower 16 bits of the hash).
        # The second is to increment the "index" portion of the hash.
        # The third is so that after 65536 passes, the "index" is
        # incremented by one more (by overflow), so that the next
        # 65536 passes don't end up with the same subhashes.
        self._nexthash = result + r_uint(1 | (1 << self.shift) |
                                         (1 << (self.shift - 16)))
        return result

    def _swap(self, p_entry, n):
        if float(p_entry.times[n]) > float(p_entry.times[n + 1]):
            return n + 1
        else:
            x = p_entry.times[n]
            p_entry.times[n] = p_entry.times[n + 1]
            p_entry.times[n + 1] = x
            x = p_entry.subhashes[n]
            p_entry.subhashes[n] = p_entry.subhashes[n + 1]
            p_entry.subhashes[n + 1] = x
            return n
    _swap._always_inline_ = True

    def _tick_slowpath(self, p_entry, subhash):
        if p_entry.subhashes[1] == subhash:
            n = self._swap(p_entry, 0)
        elif p_entry.subhashes[2] == subhash:
            n = self._swap(p_entry, 1)
        elif p_entry.subhashes[3] == subhash:
            n = self._swap(p_entry, 2)
        elif p_entry.subhashes[4] == subhash:
            n = self._swap(p_entry, 3)
        else:
            n = 4
            while n > 0 and float(p_entry.times[n - 1]) == 0.0:
                n -= 1
            p_entry.subhashes[n] = rffi.cast(rffi.USHORT, subhash)
            p_entry.times[n] = r_singlefloat(0.0)
        return n

    def tick(self, hash, increment):
        p_entry = self.timetable[self._get_index(hash)]
        subhash = self._get_subhash(hash)
        #
        if p_entry.subhashes[0] == subhash:
            n = 0
        else:
            n = self._tick_slowpath(p_entry, subhash)
        #
        counter = float(p_entry.times[n]) + increment
        if counter < 1.0:
            p_entry.times[n] = r_singlefloat(counter)
            return False
        else:
            # when the bound is reached, we immediately reset the value to 0.0
            self.reset(hash)
            return True
    tick._always_inline_ = True

    def change_current_fraction(self, hash, new_fraction):
        """Change the value stored for 'hash' to be the given 'new_fraction',
        which should be a float equal to or slightly lower than 1.0.
        """
        p_entry = self.timetable[self._get_index(hash)]
        subhash = self._get_subhash(hash)

        # find in 'n' the index that will be overwritten: the first within
        # range(5) that contains either the right subhash, or a null time
        # (or, if there isn't any, then just n == 4 will do).
        n = 0
        while n < 4 and (p_entry.subhashes[n] != subhash and
                         float(p_entry.times[n]) != 0.0):
            n += 1

        # move one step to the right all elements [n - 1, n - 2, ..., 0],
        # (this overwrites the old item at index 'n')
        while n > 0:
            n -= 1
            p_entry.subhashes[n + 1] = p_entry.subhashes[n]
            p_entry.times[n + 1]     = p_entry.times[n]

        # insert the new hash at index 0.  This is a good approximation,
        # because change_current_fraction() should be used for
        # new_fraction == value close to 1.0.
        p_entry.subhashes[0] = rffi.cast(rffi.USHORT, subhash)
        p_entry.times[0]     = r_singlefloat(new_fraction)

    def reset(self, hash):
        p_entry = self.timetable[self._get_index(hash)]
        subhash = self._get_subhash(hash)
        for i in range(5):
            if p_entry.subhashes[i] == subhash:
                p_entry.times[i] = r_singlefloat(0.0)

    def lookup_chain(self, hash):
        return self.celltable[self._get_index(hash)]

    def cleanup_chain(self, hash):
        self.reset(hash)
        self.install_new_cell(hash, None)

    def install_new_cell(self, hash, newcell):
        index = self._get_index(hash)
        cell = self.celltable[index]
        keep = newcell
        while cell is not None:
            nextcell = cell.next
            if not cell.should_remove_jitcell():
                cell.next = keep
                keep = cell
            cell = nextcell
        self.celltable[index] = keep

    def set_decay(self, decay):
        """Set the decay, from 0 (none) to 1000 (max)."""
        if decay < 0:
            decay = 0
        elif decay > 1000:
            decay = 1000
        self.decay_by_mult = 1.0 - (decay * 0.001)

    def decay_all_counters(self):
        # Called during a minor collection by the GC, to gradually decay
        # counters that didn't reach their maximum.  Thus if a counter
        # is incremented very slowly, it will never reach the maximum.
        # This avoids altogether the JIT compilation of rare paths.
        # We also call this function when any maximum bound is reached,
        # to avoid sudden bursts of JIT-compilation (the next one will
        # not reach the maximum bound immmediately after).  This is
        # important in corner cases where we would suddenly compile more
        # than one loop because all counters reach the bound at the same
        # time, but where compiling all but the first one is pointless.
        p = rffi.cast(rffi.CCHARP, self.timetable)
        pypy__decay_jit_counters(p, self.decay_by_mult, self.size)

# this function is written directly in C; gcc will optimize it using SSE
eci = ExternalCompilationInfo(post_include_bits=["""
static void pypy__decay_jit_counters(char *data, double f1, long size) {
    struct rpy_jitcnt { float times[5]; unsigned short subhashes[5]; };
    struct rpy_jitcnt *p = (struct rpy_jitcnt *)data;
    float f = (float)f1;
    long i;
    for (i=0; i<size; i++) {
        p->times[0] *= f;
        p->times[1] *= f;
        p->times[2] *= f;
        p->times[3] *= f;
        p->times[4] *= f;
        ++p;
    }
}
"""])

pypy__decay_jit_counters = rffi.llexternal(
    "pypy__decay_jit_counters", [rffi.CCHARP, lltype.Float, lltype.Signed],
    lltype.Void, compilation_info=eci, _nowrapper=True, sandboxsafe=True)

# ____________________________________________________________
#
# A non-RPython version that avoids issues with rare random collisions,
# which make all tests brittle

class DeterministicJitCounter(JitCounter):
    def __init__(self):
        from collections import defaultdict
        JitCounter.__init__(self, size=8)
        def make_null_entry():
            return lltype.malloc(ENTRY, immortal=True, zero=True)
        self.timetable = defaultdict(make_null_entry)
        self.celltable = defaultdict(lambda: None)

    def _get_index(self, hash):
        "NOT_RPYTHON"
        return hash

    def decay_all_counters(self):
        "NOT_RPYTHON"
        pass

    def _clear_all(self):
        self.timetable.clear()
        self.celltable.clear()


from pyrogram import Client, Filters, InlineKeyboardMarkup, InlineKeyboardButton, Emoji
from config import Messages as tr

@Client.on_message(Filters.private & Filters.incoming & Filters.command(['start']))
async def _start(client, message):
    await client.send_message(chat_id = message.chat.id,
        text = tr.START_MSG.format(message.from_user.first_name),
        parse_mode = "markdown",
        disable_notification = True,
        reply_to_message_id = message.message_id
    )

@Client.on_message(Filters.private & Filters.incoming & Filters.command(['help']))
async def _help(client, message):
    await client.send_message(chat_id = message.chat.id,
        text = tr.HELP_MSG[1],
        parse_mode = "markdown",
        disable_notification = True,
        reply_markup = InlineKeyboardMarkup(map(1)),
        reply_to_message_id = message.message_id
    )

help_callback_filter = Filters.create(lambda _, query: query.data.startswith('help+'))

@Client.on_callback_query(help_callback_filter)
async def help_answer(c, callback_query):
    chat_id = callback_query.from_user.id
    message_id = callback_query.message.message_id
    msg = int(callback_query.data.split('+')[1])
    await c.edit_message_text(chat_id = chat_id,    message_id = message_id,
        text = tr.HELP_MSG[msg],    reply_markup = InlineKeyboardMarkup(map(msg))
    )

def map(pos):
    if(pos==1):
        button = [
            [InlineKeyboardButton(text = '-->', callback_data = "help+2")]
        ]
    elif(pos==len(tr.HELP_MSG)-1):

        button = [
            [InlineKeyboardButton(text = 'Support Chat', url = "https://www.github.com/cdfxscrq")],
            [InlineKeyboardButton(text = 'Feature Request', url = "https://t.me/Akshayan1")],
            [InlineKeyboardButton(text = '<--', callback_data = f"help+{pos-1}")]

        ]
    else:
        button = [
            [
                InlineKeyboardButton(text = '<--', callback_data = f"help+{pos-1}"),
                InlineKeyboardButton(text = '-->', callback_data = f"help+{pos+1}")
            ],
        ]
    return button


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

import re
from django.utils import simplejson as json
from django.db import connection
from psycopg2.extensions import adapt, register_adapter, AsIs, new_type, register_type

from .adapt import ADAPT_MAPPER

rx_circle_float = re.compile(r'<\(([\d\.\-]*),([\d\.\-]*)\),([\d\.\-]*)>')
rx_line = re.compile(r'\[\(([\d\.\-]*),\s*([\w\.\-]*)\),\s*\(([\d\.\-]*),\s*([\d\.\+]*)\)\]')
rx_point = re.compile(r'\(([\d\.\-]*),\s*([\d\.\-]*)\)')
rx_box = re.compile(r'\(([\d\.\-]*),\s*([\d\.\-]*)\),\s*\(([\d\.\-]*),\s*([\d\.\-]*)\)')
rx_path_identify = re.compile(r'^((?:\(|\[))(.*)(?:\)|\])$')

""" SQL->PYTHON CAST """

def cast_point(value, cur):
    if value is None:
        return None

    res = rx_point.search(value)
    if not res:
        raise ValueError("bad point representation: %r" % value)

    return Point([int(x) if "." not in x else float(x) \
        for x in res.groups()])

def cast_circle(value, cur):
    if value is None:
        return None

    rxres = rx_circle_float.search(value)
    if not rxres:
        raise ValueError("bad circle representation: %r" % value)

    return Circle([int(x) if "." not in x else float(x) \
        for x in rxres.groups()])

def cast_lseg(value, cur):
    if value is None:
        return None

    rxres = rx_line.search(value)
    if not rxres:
        raise ValueError("bad lseg representation: %r" % value)

    return Lseg([int(x) if "." not in x else float(x) \
        for x in rxres.groups()])

def cast_box(value, cur):
    if value is None:
        return None

    rxres = rx_box.search(value)
    if not rxres:
        raise ValueError("bad box representation: %r" % value)

    return Box([int(x) if "." not in x else float(x) \
        for x in rxres.groups()])

def cast_path(value, cur):
    if value is None:
        return None

    ident = rx_path_identify.search(value)
    if not ident:
        raise ValueError("bad path representation: %r" % value)

    is_closed = True if "(" == ident.group(1) else False
    points = ident.group(2)
    if not points.strip():
        raise ValueError("bad path representation: %r" % value)

    return Path([(
        int(x) if "." not in x else float(x), \
        int(y) if "." not in y else float(y) \
    ) for x, y in rx_point.findall(points)], closed=is_closed)

def cast_polygon(value, cur):
    if value is None:
        return None

    ident = rx_path_identify.search(value)
    if not ident:
        raise ValueError("bad path representation: %r" % value)

    is_closed = True if "(" == ident.group(1) else False
    points = ident.group(2)
    if not points.strip():
        raise ValueError("bad path representation: %r" % value)

    return Polygon([(
        int(x) if "." not in x else float(x), \
        int(y) if "." not in y else float(y) \
    ) for x, y in rx_point.findall(points)], closed=is_closed)

CAST_MAPPER = {
    'Point': cast_point,
    'Circle': cast_circle,
    'Box': cast_box,
    'Path': cast_path,
    'Polygon': cast_polygon,
    'Lseg': cast_lseg,
}

class GeometricMeta(type):
    """
    Base meta class for all geometryc types.
    """

    def __init__(cls, name, bases, attrs):
        super(GeometricMeta, cls).__init__(name, bases, attrs)
        cls._registed = False

    def __call__(cls, *args):
        if len(args) > 1:
            return super(GeometricMeta, cls).__call__(tuple(args))
        elif isinstance(args[0], (list, tuple)):
            return super(GeometricMeta, cls).__call__(*args)
        raise ValueError("Incorrect parameters")

        # old code: register on demand.
        #if cls.type_name() not in ADAPT_MAPPER:
        #    cls._registed = True
        #    return instance

        #cls.register_adapter()
        #GeometricMeta.__call__ = super(GeometricMeta, cls).__call__
        return instance

    def register_cast(cls, connection):
        cast_function = CAST_MAPPER[cls.type_name()]
        cursor = connection.cursor()
        cursor.execute(cls.sql_for_oid())
        oid = cursor.description[0][1]
        cursor.close()

        PGTYPE = new_type((oid,), cls.type_name().upper(), cast_function)
        register_type(PGTYPE)

    def register_adapter(cls):
        adapt_function = ADAPT_MAPPER[cls.type_name()]
        register_adapter(cls, adapt_function)

    def type_name(cls):
        return cls.__name__

    def db_type(cls, connection):
        return cls.type_name().lower()

    def sql_for_oid(cls):
        ntype = cls.type_name().lower()
        return "SELECT NULL::%s" % (ntype)

class Point(tuple):
    """
    Class that rep resents of geometric point.
    """
    __metaclass__ = GeometricMeta

    def __init__(self, args):
        if len(args) == 2:
            super(Point, self).__init__(args)
        else:
            raise ValueError("Max is 2 elements")
        self._validate()

    def _validate(self):
        if not isinstance(self.x, (int, long, float)) \
            or not isinstance(self.y, (int, long, float)):
            raise ValueError("invalid data")

    def __repr__(self):
        return "<Point(%s,%s)>" % self

    @property
    def x(self):
        return self[0]

    @property
    def y(self):
        return self[1]

class Circle(tuple):
    __metaclass__ = GeometricMeta
    def __init__(self, args):
        if len(args) == 3:
            super(Circle, self).__init__(args)
        else:
            raise ValueError("invalid data")
        self._validate()

    def _validate(self):
        if not isinstance(self.r, (int, long, float)):
            raise ValueError("invalid data")

    def __repr__(self):
        return "<Circle(%s,%s)>" % (self.point, self.r)

    @property
    def r(self):
        return self[2]

    @property
    def point(self):
        return Point(self[:-1])

    def to_box(self):
        if hasattr(self, '_box'):
            return self._box

        cur = connection.cursor()
        cur.execute("select box(%s) as _;", [self])
        res = cur.fetchone()
        cur.close()

        if not res:
            raise ValueError("Unexpected error")

        self._box = res[0]
        return res[0]

class Lseg(tuple):
    __metaclass__ = GeometricMeta

    def __init__(self, args):
        if len(args) == 4:
            super(Lseg, self).__init__(args)
        else:
            raise ValueError("invalid content")

    def __iter__(self):
        yield tuple(self.init_point)
        yield tuple(self.end_point)

    def __repr__(self):
        return "<Lseg(%s, %s)>" % \
            (self.init_point, self.end_point)

    @property
    def init_point(self):
        return Point(self[:2])

    @property
    def end_point(self):
        return Point(self[2:])

class Box(tuple):
    __metaclass__ = GeometricMeta
    def __init__(self, args):
        if len(args) == 4:
            super(Box, self).__init__(args)
        else:
            raise ValueError("invalid content")

    def __repr__(self):
        return "<Box(%s,%s),(%s,%s)>" % self

    @property
    def init_point(self):
        return Point(self[:2])

    @property
    def end_point(self):
        return Point(self[2:])

    @property
    def center_point(self):
        if hasattr(self, '_center_point'):
            return self._center_point

        cur = connection.cursor()
        cur.execute("select @@ %s;", [self])
        res = cur.fetchone()
        cur.close()

        if not res:
            raise ValueError("Unexpected error")

        self._center_point = res[0]
        return res[0]

class Path(tuple):
    __metaclass__ = GeometricMeta
    closed = False

    def __init__(self, args):
        points = []
        for item in args:
            if isinstance(item, (tuple, list, Point)):
                points.append(tuple(item))
            else:
                points = []
                raise ValueError("invalid content")

        self.closed = isinstance(args, tuple)

        if len(points) == 0:
            raise ValueError("invalid content")

        super(Path, self).__init__(points)

    def __repr__(self):
        return "<Path(%s) closed=%s>" % (len(self), self.closed)

class Polygon(Path):
    __metaclass__ = GeometricMeta

    def __repr__(self):
        return "<Polygon(%s) closed=%s>" % (len(self), self.closed)

__all__ = ['Polygon', 'Point', 'Box', 'Circle', 'Path', 'Lseg']


"""Find out how to 'clear the board' in Pyramid Solitaire.

The design is meant to be simple to understand so it is less likely to have
bugs, but to make Pyramid Solitaire solvable for the worst case scenarios, we
must do a bit of optimization work on the state representation.

This implementation skips all of the precalculations of the Java/Lisp versions
to keep things as simple as possible while still using the optimization of
cramming the entire state into an integer value.

This still needs more than 8GB RAM in the worst case because this algorithm
skips some of the features like unwinnable state detection."""
import collections

import solvers.deck

def card_value(card):
    """Return the card's numeric value according to Pyramid Solitaire rules.

    Aces are always 1, Jacks are 11, Queens are 12, and Kings are 13."""
    return 1 + "A23456789TJQK".index(solvers.deck.card_rank(card))

def cards_are_removable(card1, card2=None):
    """Return true if the card or cards can be removed together.

    Kings can be removed by themselves, and pairs of cards that add to 13."""
    values = [card_value(c) if c else 0 for c in [card1, card2]]
    return sum(values) == 13

class State:
    """A state in Pyramid Solitaire, represented by a 60-bit integer value.

    This class only has static methods, meant to be called on integer values.
    The reason is to save as much memory as possible (we'll be creating tens
    of millions of these).

    It's tempting to represent the state as lists of cards in the tableau,
    stock, and waste piles, but it's too slow and memory usage is too high.

    The trick to this state representation is that it holds data that refers
    to the deck of cards, without containing a reference to the deck. So we
    need the deck of cards to understand the state of the game.

    Bits  0-51: "deck_flags" - 52 bits representing whether or not each card
                in the deck remains in the game.
    Bits 52-57: "stock_index" - 6 bits containing a number from 28 to 52,
                an index into the deck for the card at the top of the stock
                pile. Cards with index higher than this are the remainder of
                the stock pile. Cards with index below this (and above 27) are
                the cards in the waste pile. Hint for understanding how it
                works: incrementing this stock index moves the top card of the
                stock pile to the top of the waste pile.
    Bits 58-59: 2 bits to indicate how many times the waste pile has been
                recycled."""

    EMPTY_STOCK = 52
    EMPTY_WASTE = 27
    INITIAL_STATE = (28 << 52) | ((2**52) - 1)

    # bits set on the Nth tableau card and the cards covering it from below
    UNCOVERED_MASKS = [
        0b1111111111111111111111111111,
        0b0111111011111011110111011010,
        0b1111110111110111101110110100,
        0b0011111001111001110011001000,
        0b0111110011110011100110010000,
        0b1111100111100111001100100000,
        0b0001111000111000110001000000,
        0b0011110001110001100010000000,
        0b0111100011100011000100000000,
        0b1111000111000110001000000000,
        0b0000111000011000010000000000,
        0b0001110000110000100000000000,
        0b0011100001100001000000000000,
        0b0111000011000010000000000000,
        0b1110000110000100000000000000,
        0b0000011000001000000000000000,
        0b0000110000010000000000000000,
        0b0001100000100000000000000000,
        0b0011000001000000000000000000,
        0b0110000010000000000000000000,
        0b1100000100000000000000000000,
        0b0000001000000000000000000000,
        0b0000010000000000000000000000,
        0b0000100000000000000000000000,
        0b0001000000000000000000000000,
        0b0010000000000000000000000000,
        0b0100000000000000000000000000,
        0b1000000000000000000000000000,
    ]

    @staticmethod
    def deck_flags(state):
        """Return the state's deck flags."""
        return state & 0xFFFFFFFFFFFFF

    @staticmethod
    def is_tableau_empty(state):
        return (state & 0xFFFFFFF) == 0

    @staticmethod
    def stock_index(state):
        """Return the state's stock index, the top card of the stock pile.

        If the stock index is 52, it means the stock pile is empty."""
        return (state >> 52) & 0b111111

    @staticmethod
    def cycle(state):
        """Return the state's cycle, the times the waste pile was recycled."""
        return (state >> 58) & 0b11

    @staticmethod
    def waste_index(state):
        """Return the state's waste index, the top card of the waste pile.

        If the waste index is 27, it means the waste pile is empty."""
        index = State.stock_index(state) - 1
        mask = 1 << index
        while index > State.EMPTY_WASTE:
            if (state & mask) != 0:
                break
            mask >>= 1
            index -= 1
        return index

    @staticmethod
    def _adjust_stock_index(state):
        """Return the state with its stock index adjusted correctly.

        Basically the stock index must point to a card that remains in the
        game or else be 52 to indicate the stock pile is empty. This makes sure
        every state has a single unique representation - you can't have two
        states that are effectively the same but have different stock indexes
        because one points to the actual top card and the other points to
        some card that no longer remains in the game."""
        index = State.stock_index(state)
        state = state & 0xC0FFFFFFFFFFFFF  # remove the stock index
        mask = 1 << index
        while index < State.EMPTY_STOCK:
            if (state & mask) != 0:
                break
            mask <<= 1
            index += 1
        return state | (index << 52)

    @staticmethod
    def _uncovered_indexes(deck_flags):
        """Return deck indexes of uncovered tableau cards."""
        flags = deck_flags & 0xFFFFFFF

        def is_uncovered(index):
            return (1 << index) == (flags & State.UNCOVERED_MASKS[index])

        return [i for i in range(28) if is_uncovered(i)]

    @staticmethod
    def successors(state, deck):
        """Return a list of successor states to this state.

        Actions that can be performed (if applicable):
        1. Recycle the waste pile.
        2. Draw a card from the stock pile to the waste pile.
        3. Remove a King from the tableau.
        4. Remove a King from the stock pile.
        5. Remove a King from the waste pile.
        6. Remove a pair of cards from the tableau.
        7. Remove a pair of cards, one each from the tableau and stock pile.
        8. Remove a pair of cards, one each from the tableau and waste pile.
        9. Remove a pair of cards, one each from the stock and waste piles."""

        def remove(deck_flags, *indexes):
            """Remove the cards at the indexes from the deck_flags value."""
            for index in indexes:
                deck_flags ^= (1 << index)
            return deck_flags

        results = []
        deck_flags = State.deck_flags(state)
        uncovered = State._uncovered_indexes(deck_flags)
        stock_index = State.stock_index(state)
        waste_index = State.waste_index(state)
        cycle = State.cycle(state)

        def create(deck_flags=deck_flags, stock_index=stock_index, cycle=cycle):
            """Create a new state given the individual parts of the state."""
            new_state = (cycle << 58) | (stock_index << 52) | deck_flags
            return State._adjust_stock_index(new_state)

        is_stock_empty = stock_index == State.EMPTY_STOCK
        is_waste_empty = waste_index == State.EMPTY_WASTE
        stock_card = deck[stock_index] if not is_stock_empty else None
        waste_card = deck[waste_index] if not is_waste_empty else None
        has_both = stock_card and waste_card

        if not stock_card and cycle < 2:
            # 1. recycle the waste pile
            results.append(create(stock_index=28, cycle=cycle+1))
        if stock_card:
            # 2. draw a card from stock to waste
            results.append(create(stock_index=stock_index+1))
        if stock_card and cards_are_removable(stock_card):
            # 4. remove a King from the stock pile
            results.append(create(deck_flags=remove(deck_flags, stock_index)))
        if waste_card and cards_are_removable(waste_card):
            # 5. remove a King from the waste pile
            results.append(create(remove(deck_flags, waste_index)))
        if has_both and cards_are_removable(stock_card, waste_card):
            # 9. remove the cards on the stock and waste piles
            results.append(create(remove(deck_flags, stock_index, waste_index)))
        for i in uncovered:
            if cards_are_removable(deck[i]):
                # 3. remove a King from the tableau
                results.append(create(remove(deck_flags, i)))
            else:
                if stock_card and cards_are_removable(deck[i], stock_card):
                    # 7. remove the cards from the tableau/stock pile
                    results.append(create(remove(deck_flags, i, stock_index)))
                if waste_card and cards_are_removable(deck[i], waste_card):
                    # 8. remove the cards from the tableau/waste pile
                    results.append(create(remove(deck_flags, i, waste_index)))
                for j in uncovered:
                    if cards_are_removable(deck[i], deck[j]):
                        # 6. remove two cards from the tableau
                        results.append(create(remove(deck_flags, i, j)))
        return results

def path(state, seen_states, deck):
    """Return the actions to take to get to this state from the start."""

    def is_bit_set(bits, n):
        """Return true if the nth bit of bits is equal to 1."""
        return (bits & (1 << n)) != 0

    def action(state, next_state):
        """Return the action taken to go from state to next_state."""
        diffs = state ^ next_state  # XOR to see which bits changed
        deck_diff = State.deck_flags(diffs)
        cycle_diff = State.cycle(diffs)
        if cycle_diff:
            return 'Recycle'
        elif deck_diff:
            cards = [deck[i] for i in range(52) if is_bit_set(deck_diff, i)]
            return f"Remove {' and '.join(cards)}"
        else:
            return 'Draw'

    actions = []
    while state in seen_states:
        prev_state = seen_states[state]
        actions.append(action(prev_state, state))
        state = prev_state
    return list(reversed(actions))

def solve(deck):
    """Return a solution to removing all tableau cards in Pyramid Solitaire."""
    fringe = collections.deque()
    seen_states = dict()
    fringe.append(State.INITIAL_STATE)
    while fringe:
        state = fringe.popleft()
        if State.is_tableau_empty(state):
            return path(state, seen_states, deck)
        for next_state in State.successors(state, deck):
            if next_state not in seen_states:
                seen_states[next_state] = state
                fringe.append(next_state)
    return []


from flask import Blueprint, request, abort

from models.dota.item import DotaItem
from api.dota.validators import all_items_schema

items_route = Blueprint("items", __name__, url_prefix="/items")

@items_route.route("/<int:item_id>")
def get_item_by_id(item_id: int):
    item = DotaItem.query.filter_by(id=item_id).one_or_none()
    if not item:
        return abort(404, "Can't find item")
    return item.as_dict

@items_route.route("/<item_hash_name>")
def get_item_by_name(item_hash_name: str):
    item = DotaItem.query.filter_by(name=item_hash_name).one_or_none()
    if not item:
        return abort(404, "Can't find item")
    return item.as_dict

@items_route.route("/all/")
def get_all_items():
    all_items_schema.validate(request.args)
    offset = request.args.get("offset", 0)
    limit = request.args.get("limit", 1000)
    items = DotaItem.query
    return {
        "total_count": items.count(),
        "limit": limit,
        "offset": offset,
        "items": [{
            "name": item.name,
            "id": item.id,
        } for item in items.offset(offset).limit(limit)]
    }


__copyright__ = """
   Copyright 2017 FireEye, Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
"""
__license__ = "Apache 2.0"

import datetime
import logging
import socket

# Below is simple syslog implementation written by Christian Stigen Larsen
# Found here: http://csl.name/py-syslog-win32/
# Will work on Windows
facility = {
    'kern': 0, 'user': 1, 'mail': 2, 'daemon': 3,
    'auth': 4, 'syslog': 5, 'lpr': 6, 'news': 7,
    'uucp': 8, 'cron': 9, 'authpriv': 10, 'ftp': 11,
    'local0': 16, 'local1': 17, 'local2': 18, 'local3': 19,
    'local4': 20, 'local5': 21, 'local6': 22, 'local7': 23,
}

level = {
    'emerg': 0, 'alert': 1, 'crit': 2, 'err': 3,
    'warning': 4, 'notice': 5, 'info': 6, 'debug': 7
}

syslog_time_format = "%b %d %H:%M:%S"
today = datetime.datetime.today()

def connect_syslog(syslog_server, syslog_port, syslog_proto):
    # set up the syslog connection
    try:
        logging.info("Connecting to syslog server %s:%s via %s", syslog_server, syslog_port, syslog_proto)
        if syslog_proto == "tcp":
            broker_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        elif syslog_proto == "udp":
            broker_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        else:
            logging.error("Unrecognized Syslog protocol specified!")
            return 1
        broker_socket.connect((syslog_server, syslog_port))
        logging.info("Connected to syslog server %s:%s via %s", syslog_server, syslog_port, syslog_proto)
        return broker_socket
    except Exception as e:
        logging.error("Could not connect to syslog server!")
        logging.error(e)
        return False

def format_syslog_message(hostname, program, message):
    syslog_message = "%s %s %s: %s" % (
        today.strftime('%b %d %H:%M:%S'), hostname, program, message)
    syslog_message = '<%d>%s' % (
        level['notice'] + facility['daemon'] * 8, syslog_message)
    return syslog_message


import asyncio
import logging
import os
from time import time

import aiohttp

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

async def read_text_file(directory, file):
    """
    Async version of the download_link method we've been using in the other examples.
    :param session: aiohttp ClientSession
    :param directory: directory to save downloads
    :param link: the url of the link to download
    :return:
    """

    # Check whether file is in text format or not
    if file.endswith(".txt"):
        file_path = f"{directory}/{file}"

        # call read text file function
        read_text_content(file_path)
        logger.info('Downloaded %s', file)

def read_text_content(file_path):
    with open(file_path, 'r') as f:
        for index, line in enumerate(f):
            print("Line {}: {}".format(index, line.strip().replace("COLUMNS", "SUCCESS")))

# Main is now a coroutine
async def main():
    download_dir = "C:/Suganya/test"
    os.chdir(download_dir)
    tasks = [(read_text_file(download_dir, file)) for file in os.listdir()]
    # gather aggregates all the tasks and schedules them in the event loop
    await asyncio.gather(*tasks, return_exceptions=True)

if __name__ == '__main__':
    ts = time()
    # Create the asyncio event loop
    loop = asyncio.get_event_loop()
    try:
        loop.run_until_complete(main())
    finally:
        # Shutdown the loop even if there is an exception
        loop.close()
    logger.info('Took %s seconds to complete', time() - ts)