from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from frozendict import frozendict
from googlecloudsdk.command_lib.run import exceptions

# TODO(b/233097220) Update this tuple to be only runapps once prod is setup
BASELINE_APIS = (
    'cloudbuild.googleapis.com',
    'iam.googleapis.com',
    'run.googleapis.com',
    'runapps.googleapis.com',
    'storage.googleapis.com',
)

_INTEGRATION_TYPES = frozenset([
    frozendict({
        'name':
            'custom-domain',
        'resource_name':
            'router',
        'description':
            'Configure a custom domain for Cloud Run services with Google Cloud '
            'Load Balancer.',
        'example_command':
            '$ gcloud run integrations create --service=[SERVICE] '
            '--type=custom-domain --parameters=domain=example.com',
        'parameters':
            frozendict({
                'domain': frozendict({
                    'description':
                        'The domain to configure for your Cloud Run service. This '
                        'must be a domain you can configure DNS for.',
                    'type': 'domain',
                    'required': True,
                    'update_allowed': False,
                }),
                'paths': frozendict({
                    'description':
                        'The paths at the domain for your Cloud Run service. '
                        'Defaults to "/" if not specified. (e.g. "/foo/*" for '
                        '"example.com/foo/*")',
                    'type': 'path_matcher',
                }),
                'dns-zone': frozendict({
                    'description':
                        'The ID of the Cloud DNS Zone already configured for this '
                        'domain. If not specified, manual DNS configuration is '
                        'expected.',
                    'type': 'string',
                    'hidden': True,
                }),
            }),
        'required_apis': frozenset({
            'compute.googleapis.com'
        }),
    }),
    frozendict({
        'name':
            'redis',
        'description':
            'Configure a Redis instance (Cloud Memorystore) and connect it '
            'to a Cloud Run Service.',
        'example_command':
            '$ gcloud run integrations create --service=[SERVICE] '
            '--type=redis --parameters=memory-size-gb=2',
        'parameters':
            frozendict({
                'memory-size-gb': frozendict({
                    'description': 'Memory capacity of the Redis instance.',
                    'type': 'int',
                    'default': 1,
                }),
                'tier': frozendict({
                    'description':
                        'The service tier of the instance. '
                        'Supported options include BASIC for standalone '
                        'instance and STANDARD_HA for highly available '
                        'primary/replica instances.',
                    'type': 'string',
                    'hidden': True,
                }),
                'version': frozendict({
                    'description':
                        'The version of Redis software. If not '
                        'provided, latest supported version will be used. '
                        'Supported values include: REDIS_6_X, REDIS_5_0, '
                        'REDIS_4_0 and REDIS_3_2.',
                    'type': 'string',
                    'update_allowed': False,
                    'hidden': True,
                }),
            }),
        'required_apis': frozenset({
            'redis.googleapis.com',
            'vpcaccess.googleapis.com'
        }),
    }),
])

def IntegrationTypes(client):
  """Gets the type definitions for Cloud Run Integrations.

  Currently it's just returning some builtin defnitions because the API is
  not implemented yet.

  Args:
    client: GAPIC API client, the api client to use.

  Returns:
    array of integration type.
  """
  del client
  return _INTEGRATION_TYPES

def GetIntegration(integration_type):
  """Returns values associated to an integration type.

  Args:
    integration_type: str

  Returns:
    frozendict() of values associated to the integration type.
    If the integration does not exist, then None is returned.
  """
  for integration in _INTEGRATION_TYPES:
    if integration['name'] == integration_type:
      return integration
  return None

def GetIntegrationType(resource_type):
  """Returns the integration type associated to the given resource type.

  Args:
    resource_type: string, the resource type.

  Returns:
    The integration type.
  """
  for t in _INTEGRATION_TYPES:
    if t.get('resource_name', None) == resource_type:
      return t['name']
  return resource_type

def CheckValidIntegrationType(integration_type):
  """Checks if IntegrationType is supported.

  Args:
    integration_type: str, integration type to validate.
  Rasies: ArgumentError
  """
  if integration_type not in [
      integration['name'] for integration in _INTEGRATION_TYPES
  ]:
    raise exceptions.ArgumentError(
        'Integration of type {} is not supported'.format(integration_type))


from django.shortcuts import render, redirect, get_object_or_404
from django.conf import settings
from django.views.generic import ListView, DetailView, CreateView,DeleteView
from personal.models import Post, Like, Comment
from account.models import Account
from django.urls import reverse, reverse_lazy
from django.http import HttpResponseRedirect, JsonResponse
from .forms import *

def home_screen_view(request, *args, **kwargs):
    user=request.user
    posts=Post.objects.all()
    context ={'posts': posts}
    if not request.user.is_authenticated:
        return redirect('login')
    return render(request, "personal/home.html", context)

def addPostView(request):
    user=request.user
    form=PostForm()
    if request.method=='POST':
        form=PostForm(request.POST, request.FILES)
        if form.is_valid():
            p=form.save()
            p.post_image=form.cleaned_data.get('post_image')
            p.author=user
            p.save()
            return redirect('home')
    context={'form': form}
    return render(request, "personal/add_post.html", context)

def editPostView(request, pk):
    post=Post.objects.get(id=pk)
    form=PostForm(instance=post)
    if request.method=='POST':
        form=PostForm(request.POST, request.FILES, instance=post)
        if form.is_valid():
            p=form.save()
            p.post_image=form.cleaned_data.get('post_image')
            p.save()
            return redirect('home')
    context={'form': form}
    return render(request, "personal/edit_post.html", context)

def deletePostView(request, pk):
    post=Post.objects.get(id=pk)
    if request.method=='POST':
        post.delete()
        next = request.POST.get('next', '/')
        return HttpResponseRedirect(next)
    context={}
    return render(request, "personal/delete_post.html", context)

def like_unlike_post(request):
    user=request.user
    if request.method == 'POST':
        post_id=request.POST.get('post_id')
        post_obj=Post.objects.get(id=post_id)
        account=Account.objects.get(username=user.username)

        if account in post_obj.liked.all():
            post_obj.liked.remove(account)
        else:
            post_obj.liked.add(account)

        like, created = Like.objects.get_or_create(user=account, post_id=post_id)

        if not created:
            if like.value=='Like':
                like.value='Unlike'
            else:
                like.value == 'Like'
        else:
            like.value='Like'

        post_obj.save()
        like.save()

        data = {
            'value':like.value,
            'likes':post_obj.liked.all().count()
        }

        return JsonResponse(data, safe=False)

    return redirect ('home')

def save_comment(request):
    if request.method=='POST':
        body=request.POST['comment']
        post=request.POST['post']
        author=request.user
        post=Post.objects.get(pk=post)
        Comment.objects.create(
            post=post,
            author=author,
            body=body
        )

    return JsonResponse({'bool':True})


# Adaptado desde https://github.com/whathelll/DeepRLBootCampLabs/tree/master/pytorch/utils
from collections import namedtuple
import random
import numpy as np

Transition = namedtuple("Transition", ["s", "a", "s_1", "r", "done"])

class ReplayMemory(object):
    """Experience replay buffer que muestrea de manera uniforme."""
    def __init__(self, capacity):
        self.capacity = capacity
        self.memory = []
        self.position = 0

    def __len__(self):
        return len(self.memory)

    def __str__(self):
        result = []
        for i in range(self.__len__()):
            result.append(self.memory[i].__str__() + " \n")
        return "".join(result)

    def push(self, item):
        """Guarda las transiciones en el buffer considerando el tamaño maximo."""
        if len(self.memory) < self.capacity:
            self.memory.append(None)
        self.memory[self.position] = item
        self.position = (self.position + 1) % self.capacity

    def sample(self, batch_size):
        """Devuelve 256 (batch_size) transiciones aleatorias guardadas en el buffer."""
        out = random.sample(self.memory, batch_size)
        batched = Transition(*zip(*out))
        s = np.array(list(batched.s))
        a = np.array(list(batched.a))
        # a = np.expand_dims(np.array(list(batched.a)), axis=1)
        s_1 = np.array(list(batched.s_1))
        r = np.expand_dims(np.array(list(batched.r)), axis=1)
        done = np.expand_dims(np.array(list(batched.done)), axis=1)
        return [s, a, s_1, r, done]


import keras
from keras.models import Sequential
from keras.utils import to_categorical
#from keras.utils import sparse_categorical_crossentropy
from keras.layers import Dense, Activation, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.layers.normalization import  BatchNormalization
from keras.optimizers import Adam
from keras import backend as K
import numpy as np
import pickle
import cv2

x_train = pickle.load( open("x_train.pickle", "rb"))
#x_train = to_categorical(x_train)
#x_train = sparse_categorical_crossentropy(x_train)
y_train = pickle.load( open("y_train.pickle", "rb"))
#y_train = to_categorical(y_train)
#y_train = sparse_categorical_crossentropy(y_train)

x_test = pickle.load( open("x_test.pickle", "rb"))
#x_test = to_categorical(x_test)
#x_test = sparse_categorical_crossentropy(x_test)
y_test = pickle.load( open("y_test.pickle", "rb"))
#y_test = to_categorical(y_test)
#y_test = sparse_categorical_crossentropy(y_test)

np.random.seed(1000)

# (3) Create a sequential model
model = Sequential()

# 1st Convolutional Layer
model.add(Conv2D(filters=96, input_shape=(224,224,3), kernel_size=(11,11), strides=(4,4), padding='valid'))
model.add(Activation('relu'))
# Max Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))

# 2nd Convolutional Layer
model.add(Conv2D(filters=256, kernel_size=(11,11), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Max Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))

# 3rd Convolutional Layer
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))

# 4th Convolutional Layer
model.add(Conv2D(filters=384, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))

# 5th Convolutional Layer
model.add(Conv2D(filters=256, kernel_size=(3,3), strides=(1,1), padding='valid'))
model.add(Activation('relu'))
# Max Pooling
model.add(MaxPooling2D(pool_size=(2,2), strides=(2,2), padding='valid'))

# Passing it to a Fully Connected layer
model.add(Flatten())
# 1st Fully Connected Layer
model.add(Dense(4096, input_shape=(224*224*3,)))
model.add(Activation('relu'))
# Add Dropout to prevent overfitting
model.add(Dropout(0.4))

# 2nd Fully Connected Layer
model.add(Dense(4096))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))

# 3rd Fully Connected Layer
model.add(Dense(1000))
model.add(Activation('relu'))
# Add Dropout
model.add(Dropout(0.4))

# Output Layer
model.add(Dense(1))
model.add(Activation('softmax'))

model.summary()

# Compile the model
model.compile(loss= 'binary_crossentropy', optimizer='adam', metrics=["accuracy"])
# (5) Train
model.fit(x_train, y_train, batch_size=64, epochs=1, verbose=1, validation_data= (x_test, y_test), shuffle=True)

fer_json = model.to_json()
with open("fer.json", "w") as json_file:
    json_file.write(fer_json)
model.save_weights("Weights_AlexNet.h5")
#model.save("AlexNet.model")


import logging
from typing import Any, List

from bson.objectid import ObjectId
from fastapi import APIRouter, Depends

from crud import project as crud
from crud.client import find_one as find_client
from crud.contract import find_one as find_contract
from crud.license import find_one as find_license
from models.base import Msg
from models.module import Module, ModuleInfo
from models.project import Project, ProjectCreate, ProjectUpdate
from models.user import User
from utils.utils import raise_bad_request, raise_not_found
from api.v1.deps import get_current_active_user, get_current_project_admin

router = APIRouter()

# async def test_license(current_user: User = Depends(get_current_active_user)):

@router.get("", response_model=List[Project])
async def read_projects(
    slug: str,
    limit: int=20,
    skip: int=0,
    current_user: User = Depends(get_current_active_user)
) -> List[Project]:
    '''Read projects without modules sub documents.'''
    slug = slug.strip().lower()
    return await crud.find_many_by_license(slug, limit, skip)

# license: str,
# creator: str,
# data: ProjectCreate,
# client: str,
# contract: str

@router.post("", response_model=Project)
async def create_project(
    slug: str,
    data: ProjectCreate,
    current_user: User = Depends(get_current_project_admin),
    client: str = None,
    contract: str = None,
) -> Any:
    logging.info(">>> " + __name__ + ":create_project")
    slug = slug.strip().lower()

    if client:
        client = client.strip().lower()
        if not ObjectId.is_valid(client):
            raise_bad_request("Not valid client id.")
        db_client = await find_client(slug, id=client)
        if not db_client:
            raise_bad_request("Client reference not found.")

    if contract:
        contract = contract.strip().lower()
        if not ObjectId.is_valid(contract):
            raise_bad_request("Not valid contract id.")
        db_client = await find_contract(slug, id=contract)
        if not db_client:
            raise_bad_request("Contract reference not found.")

    creator = current_user.username
    if not data.admin:
        data.admin = creator
    return await crud.insert(slug, creator, data, client, contract)

@router.get("/{id}", response_model=Project)
async def find_project(
    slug: str,
    id: str,
    current_user: User = Depends(get_current_active_user)
) -> Any:
    slug = slug.strip().lower()
    id = id.strip().lower()

    if not ObjectId.is_valid(id):
        raise_bad_request("Not valid project ID.")

    project = await crud.find_one(slug, id)
    if not project:
        raise_not_found()

    return project

# @router.post("/{id}/modules", response_model=List[Module])
async def set_project_modules(
    slug: str,
    id: str,
    modules: List[str],
    current_user: User = Depends(get_current_project_admin)
) -> Any:
    slug = slug.strip().lower()

    if not crud.is_valid_project_admin(current_user, id):
        raise HTTPException(status_code=400, detail="You'r not the admin of the project.")
    return await crud.add_modules(slug, id, modules)

# @router.put("/{id}/modules", response_model=Module)
async def update_module(
    slug: str,
    id: str,
    module: str,
    data: ModuleInfo,
    current_user: User = Depends(get_current_project_admin)
) -> Any:
    slug = slug.strip().lower()
    module = module.strip().lower()
    id = id.strip().lower()

    if not crud.is_valid_project_admin(current_user, id):
        raise HTTPException(status_code=400, detail="You'r not the admin of the project.")

    return await crud.update_module(slug, id, module, data)

@router.put("/{id}", response_model=Project)
async def update_project(
    slug: str,
    id: str,
    data: ProjectUpdate,
    current_user: User = Depends(get_current_project_admin)
) -> Any:
    slug = slug.strip().lower()
    id = id.strip().lower()

    if not crud.is_valid_project_admin(current_user, id):
        raise HTTPException(status_code=400, detail="You'r not the admin of the project.")

    if not ObjectId.is_valid(id):
        raise_bad_request("Not valid project ID.")

    project = await crud.find_one(slug, id)
    if not project:
        raise_not_found()

    return await crud.update(slug, id, data)

@router.delete("/{id}", response_model=Msg)
async def delete_project(
    slug: str,
    id: str,
    current_user: User = Depends(get_current_project_admin)
) -> Any:
    slug = slug.strip().lower()
    id = id.strip().lower()

    if not crud.is_valid_project_admin(current_user, id):
        raise HTTPException(status_code=400, detail="You'r not the admin of the project.")

    if not ObjectId.is_valid(id):
        raise_bad_request("Not valid license ID.")

    project = await crud.find_one(slug, id)
    if not project:
        raise_not_found()

    return await crud.delete(slug, id)


# Date: August 2023
# Author: Jiayu Zheng
# Email: jiayu_zheng@brown.edu
# Most of implementations were adopted from my final project for Deep Learning CSCI2470, which is written in TensforFlow
# Also influenced by Karpathy's implementation of NanoGPT
#

import os
import pickle
import requests
import numpy as np
import matplotlib.pyplot as plt
import math
import torch
import torch.nn as nn
from torch.nn import functional as F

#
# Single Attention Heads
#

class SelfAttentionHead(nn.Module):
    ''' A self-attention head where the input gather weight sum from itself.
    Can be used on its own or as a building block of multihead attention.

    Keyword arguments:
    embed_size -- the hidden size of embeddings
    head_size -- the size of query, key, and value vectors
    mask -- whether to use causal mask (if to perform next token prediction) or not
    '''
    def __init__(self, embed_size, head_size, mask, ctx_length, dropout):
        super().__init__()
        self.M_key   = nn.Linear(embed_size, head_size, bias=False)
        self.M_query = nn.Linear(embed_size, head_size, bias=False)
        self.M_value = nn.Linear(embed_size, head_size, bias=False)
        self.attn_dropout = nn.Dropout(dropout)
        # masked attention or not
        self.mask = mask
        if self.mask:
            # used to generate the causal mask
            self.register_buffer(name="tril", tensor=torch.tril(torch.ones(ctx_length, ctx_length)).view(1, ctx_length, ctx_length))

    def forward(self, x):
        seq_len = x.shape[1]
        ebd_dim = x.shape[-1]
        # get key, query, value embeddings
        k = self.M_key(x)
        q = self.M_query(x)
        v = self.M_value(x)
        # calculate weight and apply causal mask to it
        weight = q @ k.transpose(-2, -1) / ebd_dim**0.5
        if self.mask:
            weight = weight.masked_fill(self.tril[:, :seq_len, :seq_len] == 0, value=float("-inf"))
        weight = F.softmax(weight, dim=-1)
        weight = self.attn_dropout(weight)
        output = weight @ v
        return output

class CrossAttentionHead(nn.Module):
    ''' A cross-attention head where input gather weighted sum from the context

    Keyword arguments:
    embed_size -- the hidden size of embeddings
    head_size -- the size of query, key, and value vectors
    mask -- whether to use causal mask (if to perform next token prediction) or not
    '''
    def __init__(self, embed_size, head_size, dropout):
        super().__init__()
        self.M_key   = nn.Linear(embed_size, head_size, bias=False)
        self.M_query = nn.Linear(embed_size, head_size, bias=False)
        self.M_value = nn.Linear(embed_size, head_size, bias=False)
        self.attn_dropout = nn.Dropout(dropout)

    def forward(self, x, context):
        B, T, C = x.shape
        # get key, query, value embeddings
        q = self.M_query(x)
        k = self.M_key(context)
        v = self.M_value(context)
        # calculate weight and apply causal mask to it
        weight = q @ k.transpose(-2, -1) / C**0.5

        weight = F.softmax(weight, dim=-1)
        weight = self.attn_dropout(weight)

        output = weight @ v
        return output

#
# Multi Head Attention Blocks
#

class MultiHeadSelfAttention(nn.Module):
    '''Multihead self-attention
    '''

    def __init__(self, embed_size, num_heads, mask, ctx_length, dropout):
        super().__init__()
        self.heads = nn.ModuleList([
            SelfAttentionHead(embed_size, embed_size//num_heads, mask, ctx_length, dropout) for i in range(num_heads)
        ])

        self.projection = nn.Linear(embed_size//num_heads*num_heads, embed_size)
        self.resid_dropout = nn.Dropout(dropout)

    def forward(self, x):
        # concatenate outputs from multiple attention heads
        output = torch.cat([h(x) for h in self.heads], dim=-1)
        output = self.resid_dropout(self.projection(output))
        return output

class MultiHeadCrossAttention(nn.Module):
    '''Multihead cross-attention
    '''

    def __init__(self, num_heads, embed_size, dropout):
        super().__init__()
        self.heads = nn.ModuleList([
            CrossAttentionHead(embed_size, embed_size//num_heads, dropout) for i in range(num_heads)
        ])

        self.projection = nn.Linear(embed_size//num_heads*num_heads, embed_size)
        self.resid_dropout = nn.Dropout(dropout)

    def forward(self, x, context):
        # concatenate outputs from multiple attention heads
        output = torch.cat([h(x, context) for h in self.heads], dim=-1)
        output = self.resid_dropout(self.projection(output))
        return output

class FeedForward(nn.Module):
    '''Feedforward network in Transformer layer
    '''

    def __init__(self, embed_size, dropout):
        super().__init__()
        self.ffn = nn.Sequential(
            nn.Linear(embed_size, 4*embed_size),
            nn.GELU(),
            nn.Linear(4*embed_size, embed_size),
            nn.Dropout(dropout)
        )

    def forward(self, x):
        return self.ffn(x)

#
# Transformer Layers
# In practice, a model is made of stacked such layers

class EncoderLayer(nn.Module):
    """A single layer of transformer encoder
    This is typically used in encoder-only and encoder-decoder Transformers

    """
    def __init__(self, embed_size, num_heads, ctx_length, dropout):
        super().__init__()
        self.self_attn = MultiHeadSelfAttention(embed_size, num_heads, False, ctx_length, dropout)
        self.ffn = FeedForward(embed_size, dropout)
        self.layer_norm1 = nn.LayerNorm(embed_size)
        self.layer_norm2 = nn.LayerNorm(embed_size)

    def forward(self, x):
        # There is a slight deviation from the original Transformer
        # as a common practice, we move the layernorm before each transformation
        # so-called pre_normalization
        #
        x = x + self.self_attn(self.layer_norm1(x))
        x = x + self.ffn(self.layer_norm2(x))
        return x

class DecoderLayer(nn.Module):
    """A single layer of transformer decoder without context or cross-attention.
    This is typically used in a decoder-only Transformer like GPTs

    """
    def __init__(self, embed_size, num_heads, ctx_length, dropout):
        super().__init__()
        self.self_attn = MultiHeadSelfAttention(embed_size, num_heads, True, ctx_length, dropout)
        self.ffn = FeedForward(embed_size, dropout)
        self.layer_norm1 = nn.LayerNorm(embed_size)
        self.layer_norm2 = nn.LayerNorm(embed_size)

    def forward(self, x):
        x = x + self.self_attn(self.layer_norm1(x))
        x = x + self.ffn(self.layer_norm2(x))
        return x

class DecoderLayerWithContext(nn.Module):
    """A single layer of transformer decoder with contex and corss-attention
    This is typically used in a Encoder-Decoder Transformer for Seq2Seq tasks
    """
    def __init__(self, embed_size, num_heads, ctx_length, dropout):
        super().__init__()
        self.self_attn = MultiHeadSelfAttention(embed_size, num_heads, True, ctx_length, dropout)
        self.cross_attn = MultiHeadCrossAttention(embed_size, num_heads, dropout)
        self.ffn = FeedForward(embed_size, dropout)
        self.layer_norm1 = nn.LayerNorm(embed_size)
        self.layer_norm2 = nn.LayerNorm(embed_size)
        self.layer_norm3 = nn.LayerNorm(embed_size)

    def forward(self, x, context):
        x = x + self.self_attn(self.layer_norm1(x))
        x = x + self.cross_attn(self.layer_norm2(x), context)
        x = x + self.ffn(self.layer_norm3(x))
        return x

#
# Position Embeddings
# to impose spatial information to embeddings
# the attention operating itself is unordered
#

class PositionEmbedding(nn.Module):
    """The sinusoidal position embedding used in the original Transformer
    """
    def __init__(self, embed_size):
        super().__init__()
        depth = int(embed_size / 2)
        self.factor = torch.cat([torch.arange(0, embed_size, 2).view(-1, 1), torch.arange(0, embed_size, 2).view(-1, 1)], dim=-1).view(-1)
        self.factor = self.factor.to(torch.float16)/embed_size
        self.factor = 1 / 1000 ** self.factor
        # cos(x) = sin(x + pi/2) so we only use sine function
        self.offset = torch.cat([torch.zeros(depth, 1), torch.ones(depth, 1)*math.pi/2], dim=-1).view(-1)

    def forward(self, x):
        # This step should be completed before the function call
        # length = x.shape[1]
        # pos = torch.arange(length).view(-1, 1)
        position_embedding = torch.sin(pos*self.factor + self.offset)
        return position_embedding

class LearnablePositionEmbedding(nn.Module):
    """A learnable position embedding

    """
    def __init__(self, ctx_length, embed_size):
        super().__init__()
        self.PE = nn.Embedding(ctx_length, embed_size)

    def forward(self, x):
        return self.PE(x)

class LayerNorm(nn.Module):
    """Layer Norm with an optional bias.
    PyTorch doesn't support layer norm with bias=False
    """
    def __init__(self, ndim, bias):
        self.weight = nn.Parameter(torch.ones(ndim))
        self.bias = nn.Parameter(torch.zeros(ndim)) if bias else None
    def forward(self, input):
        return F.layer_norm(input, self.weight.shape, self.weight, self.bias, 1e-5)

# class RotaryPositionEmbedding(nn.Module):
#     """A rotary position embedding (RoPE), which encode position information of tokens with a rotation matrix that naturally incorporates explicit relative position dependency.
#     Introduced by Su et. al. in https://arxiv.org/abs/2104.09864

#     Here's a good explanation of the advantages of RoPE, https://nn.labml.ai/transformers/rope/index.html#:~:text=This%20is%20an%20implementation%20of,incorporates%20explicit%20relative%20position%20dependency.
#     """
#     def __init__(self, length: int = 10_000, base: int):
#         self.length = length
#         self.embed_size = embed_size

#         self.cos_cached = None
#         self.sin_cached = None

#     def _build_cache(self, x: torch.Tensor):
#         if self.cos_cached is not None and x.shape[0] <= self.cos_cached.shape[0]:
#             return
#         seq_len = x.shape[0]
#         theta = 1. / (self.length ** (torch.arange(0, self.embed_size, 2).float()/self/embed_size))
#         seq_idx = torch.arange(seq_len).float().to(x.device)
#         idx_theta = torch.einsum('n,d->nd', seq_idx, theta)
#         idx_theta2 = torch.cat([idx_theta, idx_theta]. dim=1)
#         self.cos_cached = idx_theta2.cos()[:, None, None, :]
#         self.sin_cached = idx_theta.sin()[:, None, None, :]
#     def _neg_half(self, x: torch.Tensor):

#     def forward(self, x: torch.Tensor):
#         self._build_cache(x)
#         x_ropem, x_pass = x[..., :self, d]


from typing import (
    Sequence,
)

from eth_typing import (
    Hash32,
)
from eth_utils import (
    encode_hex,
)

import rlp
from rlp.sedes import (
    binary,
    CountableList,
)

from eth.rlp.sedes import (
    uint24,
    uint64,
    hash32,
)
from eth.beacon._utils.hash import (
    hash_eth2,
)
from eth.beacon.typing import (
    SlotNumber,
    Bitfield,
    Timestamp,
    Gwei,
    ValidatorIndex,
)

from .pending_attestation_records import PendingAttestationRecord
from .candidate_pow_receipt_root_records import CandidatePoWReceiptRootRecord
from .custody_challenges import CustodyChallenge
from .crosslink_records import CrosslinkRecord
from .fork_data import ForkData
from .shard_committees import ShardCommittee
from .shard_reassignment_records import ShardReassignmentRecord
from .validator_records import ValidatorRecord

class BeaconState(rlp.Serializable):
    """
    Note: using RLP until we have standardized serialization format.
    """
    fields = [
        # Misc
        ('slot', uint64),
        ('genesis_time', uint64),
        ('fork_data', ForkData),  # For versioning hard forks

        # Validator registry
        ('validator_registry', CountableList(ValidatorRecord)),
        ('validator_balances', CountableList(uint64)),
        ('validator_registry_latest_change_slot', uint64),
        ('validator_registry_exit_count', uint64),
        ('validator_registry_delta_chain_tip', hash32),  # For light clients to easily track delta

        # Randomness and committees
        ('latest_randao_mixes', CountableList(hash32)),
        ('latest_vdf_outputs', CountableList(hash32)),
        ('shard_committees_at_slots', CountableList(CountableList((ShardCommittee)))),
        ('persistent_committees', CountableList(CountableList(uint24))),
        ('persistent_committee_reassignments', CountableList(ShardReassignmentRecord)),

        # Custody challenges
        ('custody_challenges', CountableList(CustodyChallenge)),

        # Finality
        ('previous_justified_slot', uint64),
        ('justified_slot', uint64),
        # TODO: check if justification_bitfield is bytes or int
        ('justification_bitfield', binary),
        ('finalized_slot', uint64),

        # Recent state
        ('latest_crosslinks', CountableList(CrosslinkRecord)),
        ('latest_block_roots', CountableList(hash32)),  # Needed to process attestations, older to newer  # noqa: E501
        ('latest_penalized_exit_balances', CountableList(uint64)),  # Balances penalized at every withdrawal period  # noqa: E501
        ('latest_attestations', CountableList(PendingAttestationRecord)),
        ('batched_block_roots', CountableList(Hash32)),  # allow for a log-sized Merkle proof from any block to any historical block root"  # noqa: E501

        # PoW receipt root
        ('processed_pow_receipt_root', hash32),
        ('candidate_pow_receipt_roots', CountableList(CandidatePoWReceiptRootRecord)),
    ]

    def __init__(
            self,
            slot: SlotNumber,
            genesis_time: Timestamp,
            fork_data: ForkData,
            validator_registry_latest_change_slot: SlotNumber,
            validator_registry_exit_count: int,
            validator_registry_delta_chain_tip: Hash32,
            previous_justified_slot: SlotNumber,
            justified_slot: SlotNumber,
            justification_bitfield: Bitfield,
            finalized_slot: SlotNumber,
            processed_pow_receipt_root: Hash32,
            validator_registry: Sequence[ValidatorRecord]=(),
            validator_balances: Sequence[Gwei]=(),
            latest_randao_mixes: Sequence[Hash32]=(),
            latest_vdf_outputs: Sequence[Hash32]=(),
            shard_committees_at_slots: Sequence[Sequence[ShardCommittee]]=(),
            persistent_committees: Sequence[Sequence[ValidatorIndex]]=(),
            persistent_committee_reassignments: Sequence[ShardReassignmentRecord]=(),
            custody_challenges: Sequence[CustodyChallenge]=(),
            latest_crosslinks: Sequence[CrosslinkRecord]=(),
            latest_block_roots: Sequence[Hash32]=(),
            latest_penalized_exit_balances: Sequence[Gwei]=(),
            batched_block_roots: Sequence[Hash32]=(),
            latest_attestations: Sequence[PendingAttestationRecord]=(),
            candidate_pow_receipt_roots: Sequence[CandidatePoWReceiptRootRecord]=()
    ) -> None:
        super().__init__(
            # Misc
            slot=slot,
            genesis_time=genesis_time,
            fork_data=fork_data,
            # Validator registry
            validator_registry=validator_registry,
            validator_balances=validator_balances,
            validator_registry_latest_change_slot=validator_registry_latest_change_slot,
            validator_registry_exit_count=validator_registry_exit_count,
            validator_registry_delta_chain_tip=validator_registry_delta_chain_tip,
            # Randomness and committees
            latest_randao_mixes=latest_randao_mixes,
            latest_vdf_outputs=latest_vdf_outputs,
            shard_committees_at_slots=shard_committees_at_slots,
            persistent_committees=persistent_committees,
            persistent_committee_reassignments=persistent_committee_reassignments,
            # Proof of Custody
            custody_challenges=custody_challenges,
            # Finality
            previous_justified_slot=previous_justified_slot,
            justified_slot=justified_slot,
            justification_bitfield=justification_bitfield,
            finalized_slot=finalized_slot,
            # Recent state
            latest_crosslinks=latest_crosslinks,
            latest_block_roots=latest_block_roots,
            latest_penalized_exit_balances=latest_penalized_exit_balances,
            latest_attestations=latest_attestations,
            batched_block_roots=batched_block_roots,
            # PoW receipt root
            processed_pow_receipt_root=processed_pow_receipt_root,
            candidate_pow_receipt_roots=candidate_pow_receipt_roots,
        )

    def __repr__(self) -> str:
        return 'BeaconState #{0}>'.format(
            encode_hex(self.root)[2:10],
        )

    _hash = None

    @property
    def hash(self) -> Hash32:
        if self._hash is None:
            self._hash = hash_eth2(rlp.encode(self))
        return self._hash

    @property
    def root(self) -> Hash32:
        # Alias of `hash`.
        # Using flat hash, might change to SSZ tree hash.
        return self.hash

    @property
    def num_validators(self) -> int:
        return len(self.validator_registry)

    @property
    def num_crosslinks(self) -> int:
        return len(self.latest_crosslinks)

    def update_validator(self,
                         validator_index: ValidatorIndex,
                         validator: ValidatorRecord,
                         balance: Gwei) -> 'BeaconState':
        validator_registry = list(self.validator_registry)
        validator_registry[validator_index] = validator

        validator_balances = list(self.validator_balances)
        validator_balances[validator_index] = balance

        updated_state = self.copy(
            validator_registry=tuple(validator_registry),
            validator_balances=tuple(validator_balances),
        )
        return updated_state


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Nov 30 00:56:48 2020

@author: ivanduran
"""

from sklearn import datasets
import pandas as pd
import scipy.stats
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_validate

iris = datasets.load_iris()
iris

# print labels
print(iris.target_names)

# print features
print(iris.feature_names)

# print the iris labels (0:setosa, 1:versicolor, 2:virginica)
print(iris.target)

df = pd.DataFrame({
    'sepal_length':iris.data[:,0],
    'sepal_width':iris.data[:,1],
    'petal_length':iris.data[:,2],
    'petal_width':iris.data[:,3],
    'species':iris.target
})

# features
X = df[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']]

# labels
y = df['species']

# create random forest classifier
model = RandomForestClassifier(n_estimators=500, random_state =1)

# fit model w/ 10-fold CV, use StratifiedKFold CrossVal
scoring=["accuracy", "precision_macro", "recall_macro", "f1_macro"]
scores = cross_validate(model, X, y, cv=9, scoring=scoring)

print("Average Accuracy (w/ 95% Confidence Interval):")
for metric in scores.keys():
    se = scipy.stats.sem(scores[metric])
    ci = se * scipy.stats.t.ppf((1 + 0.95) / 2., len(scores[metric]) - 1)
    print(f"{metric}: %0.2f (+/- %0.2f)" % (scores[metric].mean()*100, ci*100))
print("Accuracy for each fold: ", scores["test_accuracy"])


#!/usr/bin/env python3
# coding: utf-8

import click
import pandas as pd
import numpy as np
from itertools import combinations, product
import csv

def flatten_to_n_features(features, target_n):
    """Truncates feature sets with size close to target_n"""
    total_per_class = features.shape[0]
    trunc_per_class = 0
    if len(features.shape) == 1:
        features = features.copy().reshape(-1, 1)
    k = features.shape[1]
    trunc_per_class = int(np.ceil(target_n / k))
    featureset = set()
    while len(featureset) < target_n and trunc_per_class <= total_per_class:
        featureset = set(features[:trunc_per_class].flatten())
        trunc_per_class += 1
    if len(featureset) < target_n:
        print(f"Not enough features: {len(featureset)}, {features.size}")
    return featureset

@click.command()
@click.argument("dataset")
def main(dataset):
    datasets = dataset.split(",")
    if dataset == "all":
        datasets = ["paul", "green", "zheng", "zeisel"]

    demethods = ["logreg", "t-test_overestim_var", "wilcoxon", "rfc"]
    mimethods = ["jmi", "mim", "cife"]
    binmimethods = ["bin" + m for m in mimethods]
    allmethods = demethods + mimethods + binmimethods
    n_methods = len(allmethods)
    method2readable = {
        "binjmi": "JMI(B)",
        "bincife": "CIFE(B)",
        "binmim": "MIM(B)",
        "cife": "CIFE",
        "jmi": "JMI",
        "mim": "MIM",
        "logreg": "LogReg",
        "wilcoxon": "Wilcoxon",
        "t-test_overestim_var": "t-Test",
        "rfc": "RForest",
    }

    for dataset in datasets:
        print(f"Computing for {dataset} Dataset")
        features = {}
        for method in allmethods:
            f = np.load(f"output/{dataset}_{method}_markers_full.npz")
            features[method] = flatten_to_n_features(f["markers"], 100)
        intersections = pd.DataFrame(
            np.zeros((n_methods, n_methods), dtype=int),
            index=allmethods,
            columns=allmethods,
        )
        for i, j in product(allmethods, allmethods):
            w = len(features[i].intersection(features[j]))
            intersections[j][i] = w
        intersections.rename(
            index=method2readable, columns=method2readable, inplace=True
        )
        intersections.to_csv(
            f"output/{dataset}_intersection.csv", quoting=csv.QUOTE_MINIMAL
        )

if __name__ == "__main__":
    main()


"""
Implementation of TAMER (Knox + Stone, 2009)
When training, use 'W' and 'A' keys for positive and negative rewards
"""

import asyncio
import gym

from tamer.agent import Tamer

async def main():

	env_name = "CartPole-v1" # 'MountainCar-v0'
	env = gym.make(env_name)

	# hyperparameters
	discount_factor = 1
	epsilon = 0  # vanilla Q learning actually works well with no random exploration
	min_eps = 0
	num_episodes = 10
	tame = True  # set to false for vanilla Q learning

	# set a timestep for training TAMER
	# the more time per step, the easier for the human
	# but the longer it takes to train (in real time)
	# 0.2 seconds is fast but doable
	tamer_training_timestep = 5

	agent = Tamer(env, num_episodes, discount_factor, epsilon, min_eps, tame,
				tamer_training_timestep, model_file_to_load=None, env_name=env_name)

	reward_training,ep_train= await agent.train(model_file_to_save='autosave')
	agent.play(n_episodes=1, render=True)
	reward_evaluating,ep_eval=agent.evaluate(n_episodes=30)

	for i in range(len(ep_train)) :
		f.write(str(reward_training[i]) + " "  + (str(ep_train[i])) + "\n")
	f.close()
	for i in range(len(ep_eval)) :
		b.write(str(reward_evaluating[0][i]) + " "  + (str(ep_eval[i])) + "\n")
	b.close()

if __name__ == '__main__':
	f=open('train.txt','w')
	b=open('ev.txt','w')
	asyncio.run(main())


import pathlib
import random
import json

from typing import List, Optional, Tuple

Cell = Tuple[int, int]
Cells = List[int]
Grid = List[Cells]

class GameOfLife:

    def __init__(
        self,
        size: Tuple[int, int],
        randomize: bool = True,
        max_generations: Optional[float] = float('inf')
    ) -> None:
        # Размер клеточного поля
        self.rows, self.cols = size
        # Предыдущее поколение клеток
        self.prev_generation = self.create_grid()
        # Текущее поколение клеток
        self.curr_generation = self.create_grid(randomize=randomize)
        # Максимальное число поколений
        self.max_generations = max_generations
        # Текущее число поколений
        self.n_generation = 1

    def create_grid(self, randomize: bool = False) -> Grid:
        self.curr_generation = []
        temp = []
        for i in range(self.rows):
            for j in range(self.cols):
                if not randomize:
                    temp.append(0)
                else:
                    temp.append(random.randint(0, 1))
                if j == self.cols - 1:
                    self.curr_generation.append(temp)
                    temp = []
        return self.curr_generation

    def get_neighbours(self, cell: Cell) -> Cells:
        neighbours = []
        row, col = cell
        if row-1 >= 0:
            if col-1 >= 0:
                neighbours.append(self.curr_generation[row-1][col-1])
            if col+1 <= self.cols-1:
                neighbours.append(self.curr_generation[row-1][col+1])
            neighbours.append(self.curr_generation[row-1][col])
        if row+1 <= self.rows-1:
            if col-1 >= 0:
                neighbours.append(self.curr_generation[row+1][col-1])
            if col+1 <= self.cols-1:
                neighbours.append(self.curr_generation[row+1][col+1])
            neighbours.append(self.curr_generation[row+1][col])
        if col-1 >= 0:
            neighbours.append(self.curr_generation[row][col-1])
        if col+1 <= self.cols-1:
            neighbours.append(self.curr_generation[row][col+1])
        return neighbours

    def get_next_generation(self) -> Grid:
        new_grid = []
        temp = []
        for i in range(self.rows):
            for j in range(self.cols):
                amount = sum(self.get_neighbours((i, j)))
                if self.curr_generation[i][j] == 0:
                    if amount == 3:
                        temp.append(1)
                    else:
                        temp.append(0)
                else:
                    if amount == 2 or amount == 3:
                        temp.append(1)
                    else:
                        temp.append(0)
                if j == self.cols-1:
                    new_grid.append(temp)
                    temp = []
        self.curr_generation = new_grid
        return self.curr_generation

    def step(self) -> None:
        """
        Выполнить один шаг игры.
        """
        self.prev_generation = self.curr_generation
        self.get_next_generation()
        self.n_generation += 1

    @property
    def is_max_generations_exceed(self) -> bool:
        """
        Не превысило ли текущее число поколений максимально допустимое.
        """
        if self.n_generation < self.max_generations:
            return False
        return True

    @property
    def is_changing(self) -> bool:
        """
        Изменилось ли состояние клеток с предыдущего шага.
        """
        if self.curr_generation == self.prev_generation:
            return False
        return True

    @staticmethod
    def from_file(filename: pathlib.Path) -> 'GameOfLife':
        """
        Прочитать состояние клеток из указанного файла.
        """
        with open(filename, 'r') as f:
            ff = json.load(f)
        rows = len(ff)
        cols = len(ff[0])
        game = GameOfLife(size=(rows, cols), randomize=True)
        game.curr_generation = ff
        return game

    def save(self, filename: pathlib.Path) -> None:
        """
        Сохранить текущее состояние клеток в указанный файл.
        """
        with open(filename, 'w') as f:
            json.dump(self.curr_generation, f)


#################### library import ##################

import pyttsx3
import datetime
import speech_recognition as sr
import wikipedia as wiki
import time
import webbrowser
import os
import random
import smtplib
from validate_email import validate_email
import pyjokes
import requests
import json
import wolframalpha
from tkinter import *
from threading import Thread
# import sys
import urllib.request
import re
import pandas as pd
# import PIL
from PIL import Image, ImageTk

# from tkinter import simpledialog
# from tkinter import ttk

# library import part ends here
############################################
############# variable declaration #########
############################################
textheight = 20
browserpath = "C:\Program Files\Google\Chrome\Application\chrome.exe"
browsername="chrome"
music_dir = "D:\\direc\\chatbot music"
codeblockpath = "C:\Program Files (x86)\CodeBlocks\codeblocks.exe"
vscodepath = "C:\\Users\\PINTU SINHA\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe"
pycharmpath = "C:\\Program Files\\JetBrains\\PyCharm Community Edition 2020.1.2\\bin\\pycharm64.exe"
atompath = "C:\\Users\\PINTU SINHA\\AppData\\Local\\atom\\atom.exe"
customapps = {
    "intellijidea": "C:\\Program Files\\JetBrains\\PyCharm Community Edition 2020.1.2\\bin\\pycharm64.exe"
}

webbrowser.register(browsername, None, webbrowser.BackgroundBrowser(browserpath))
#########################################
########### SPEAKING ENGINE #############
#########################################

engine = pyttsx3.init()
voices = engine.getProperty('voices')

def speak(audio):
    engine.setProperty("voice", voices[0].id)
    engine.setProperty('rate', 170)
    engine.say(audio)
    engine.runAndWait()

def speakf(audio):
    engine.setProperty("voice", voices[1].id)
    engine.setProperty('rate', 170)
    engine.say(audio)
    engine.runAndWait()

################################################
################# SUPPORTING FUNCTIONS #########
################################################

def newline(text):
    # align builder for text
    # any text before printing on gui canvas passes from here
    final = ""
    linecount = 0
    for i in range(len(text)):
        final += text[i]
        if i % 20 == 0 and i != 0:
            final += "\n"
            linecount += 1

    return final

def write(text, size=10):
    # write test on canvas on gui

    global textheight
    size = str(size)
    canvas2.create_text(70, textheight, anchor=NW, text=newline(text), font="Helvetica " + size + " bold", fill="white")
    textheight += (len(text) // 20) * 20

def wishme():
    # starter function
    hour = int(datetime.datetime.now().hour)
    if hour >= 0 and hour < 12:
        speak("good morning tirtho")
    elif hour > 12 and hour < 18:
        speak("good afternoon tirtho!!")
    else:
        speak("good Evening tirtho")
    speak("This is leeo,Your personal helping hand,   how may i help you ?")

###################################################################
##################### SPEAK RECOGNITION fucntion ##################
###################################################################

def takecommand():
    global textheight
    # it will take mic input from user and return command as string
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("Listening....")
        canvas2.create_text(70, textheight, anchor=NW, text="Listening.....", font="Helvetica 15 bold", fill="white")
        textheight += 40
        r.pause_threshold = .6
        r.energy_threshold = 200
        audio = r.listen(source)
    try:
        print("Recognising....")

        query = r.recognize_google(audio, language="en-in")
        print(f"You said..... {query}\n")

        canvas2.create_text(350, textheight, anchor=NW, text=newline(query), font="Helvetica 15 bold", fill="white")
        textheight += 40

    except Exception as e:
        # print(e)
        print("please,say that again.......")
        canvas2.create_text(70, textheight, anchor=NW, text="please,say that again.......", font="Helvetica 15 bold",
                            fill="green")
        textheight += 40

        return "NONE"
    return query

# main conditional part starts here
####################################################|
############### MAIN APPLICATION ###################|
####################################################|

def startleo(con=True):
    global textheight
    wishlist = ["hi", "hello", "good morning", "good evening", "good night", "hey"]

    if __name__ == "__main__":
        wishme()
        while (True):
            if (con == False):
                canvas2.create_text(70, textheight, anchor=NW, text=newline("you are not connected"),
                                    font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                speak("Looks like you are not connected to internet,")
                speakf("as you are connected let me know.     bye for now.")
                break
            query = takecommand().lower()
            query = query.replace("leo", "")
            wishele = [ele for ele in wishlist if (ele in query)]
            if wishele:
                speak("hello tirtho, nice to meet you.")

            if "thank" in query:
                speak("Welcome tirtho, your satisfaction is my perfection")
            elif "are you ok" in query or "how are you" in query:
                speak("absolutely fine,  remember me for any need,  i'm always here for you")
            elif "by" in query or "stop" in query or "goodbye" in query or "buy" in query or "bye" in query:
                speak("goodbuy,   see you later")
                break

            if "who am i" in query or "know me" in query:
                speak(
                    "you are   tirthoraj sinha  , softwre developer ,web developer, multilanguage programmer and  creator of me.")
            elif "who are you" in query or "who is you" in query or "who you" in query or "your name" in query:
                speak(
                    "hi, This is leeo  ,Tirtho's personal assistent,    built by tirtharaj,   always here for your need")
            elif "can do" in query or "you do" in query or "your work" in query:
                speak(
                    "i help tirtho in his work,    i find answer of your any relevent question and reply according to your query.")
                speak("ask anything")
            elif "time" in query or "date" in query:
                t = datetime.datetime.now().strftime("%H:%M:%S")
                ti = "it is " + t
                d = time.asctime(time.localtime(time.time())).split()
                date = " and date is " + d[0] + " " + d[1] + " " + d[2]
                current = ti + date
                print(current)
                canvas2.create_text(70, textheight, anchor=NW, text=newline(current), font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                speak(current)
            elif ("computer" in query or "system" in query) and "name" in query:
                speak("yes tirtho, you are using hp envy 13 x 360 ")

            elif " my brother" in query:
                speak(
                    "i never met your brother,jyotisko but he is well known for his foolishness,uselessness,   i also know he is called as hen")
            elif "repeat" in query:
                query = query.replace("repeat", "")
                query = query.replace("me", "")
                speak(query)
            elif "search" in query or "find" in query or "solve" in query or "what" in query or "who" in query:

                query = query.replace("tell", "")
                query = query.replace("search", "")
                query = query.replace("find", "")
                query = query.replace("wikipedia", "")
                f = open("apis.txt", "r")
                api = f.readlines()
                app_id = api[4].split(":")[1].strip()
                f.close()
                speak("searching......")

                if query.strip() == "":
                    speak("no query found,speak again")
                    continue

                if "google" in query:
                    query = query.replace("google", "")
                    webbrowser.get("chrome").open("https://www.google.com/search?q=" + query)
                    continue

                try:
                    client = wolframalpha.Client(app_id)
                    res = client.query(query)
                    result = next(res.results).text
                    speak("got it")
                    print(query, "\n", result)
                    write(result)
                    speak("according to web search      ")
                    speak(result)
                except Exception:
                    try:
                        result = wiki.summary(query, sentences=2)
                        print(query, "\n", result)
                        write(result)
                        speak("according to wikipedia  ")
                        speak(result)
                        pass
                    except:
                        speak("I have not understand, please say again")
                        continue

            elif "open" in query and "youtube" in query:
                speak("opening youtube....")
                print("opening youtube.....")
                canvas2.create_text(70, textheight, anchor=NW, text="opening youtube.....", font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                try:
                    webbrowser.get("chrome").open("youtube.com")
                except Exception as e:
                    webbrowser.open("youtube.com")
                button.wait_variable(var)
            elif "open" in query and "google" in query:
                speak("opening google....")
                print("opening google.....")
                canvas2.create_text(70, textheight, anchor=NW, text="opening google.....", font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                try:

                    webbrowser.get("chrome").open("google.com")

                except Exception as e:
                    webbrowser.open("google.com")
                # permission = input("press enter button to continue")
                button.wait_variable(var)
            elif "open" in query and "github" in query:
                speak("opening github....")
                print("opening github.....")
                canvas2.create_text(70, textheight, anchor=NW, text="opening github.....", font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                try:
                    webbrowser.get("chrome").open("github.com")
                except Exception as e:
                    webbrowser.open("github.com")
                button.wait_variable(var)
            elif "open" in query and "instagram" in query:
                speak("opening instagram....")
                print("opening instagram.....")
                canvas2.create_text(70, textheight, anchor=NW, text="opening instagram.....", font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                try:
                    webbrowser.get("chrome").open("instagram.com")
                except Exception as e:
                    webbrowser.open("instagram.com")
                button.wait_variable(var)
            elif ("personal" in query or "portfolio" in query or "my" in query) and "site" in query:
                speak("opening Tirtharaj Sinha official.........")
                try:
                    webbrowser.get("chrome").open("https://tirtharajsinha.github.io/webfiles/portfolio_v2.0")
                except Exception as e:
                    webbrowser.open("https://tirtharajsinha.github.io/webfiles/portfolio_v2.0")
                button.wait_variable(var)
            elif "play" in query and ("music" in query or "song" in query) and "youtube" not in query:

                songs = os.listdir(music_dir)
                music_ind = random.randint(0, len(songs) - 1)
                speak("sure tirtho,  playing music...." + songs[music_ind][:-4])
                os.startfile(os.path.join(music_dir, songs[music_ind]))

                button.wait_variable(var)
            if "app" in query and ("open" in query or "start" in query):
                if "codeblock" in query or "c compiler" in query or "blocks" in query:
                    os.startfile(codeblockpath)
                    speak("sure sir,    launching codeblocks....")
                    button.wait_variable(var)
                elif "visual studio code" in query or "code" in query:

                    os.startfile(vscodepath)
                    speak("sure sir,    launching visual studio code....")
                    button.wait_variable(var)
                elif "pycharm" in query or "python" in query:

                    os.startfile(pycharmpath)
                    speak("sure sir,    launching pycharm....")
                    button.wait_variable(var)
                elif "atom" in query:

                    os.startfile(atompath)
                    speak("sure sir,    launching atom text editor....")
                    button.wait_variable(var)
                else:
                    appname = -1
                    for app in customapps.keys():
                        if app in query:
                            appname = app
                    if appname == -1:
                        speak("application not found")
                    else:
                        os.startfile(customapps[appname])
                        speak("sure sir,    launching "+appname)
                        button.wait_variable(var)
            elif "send" in query and "mail" in query:
                speak("mail wizerd is on")

                f = open("apis.txt", "r")
                api = f.readlines()
                sender = api[1].split(":")[1]
                passward = api[2].split(":")[1]
                f.close()
                speak("Enter the mail whom you want to send mail")
                canvas2.create_text(70, textheight, anchor=NW,
                                    text="Enter the mail whom you want to \nsend mail below text box",
                                    font="Helvetica 15 bold", fill="white")
                button.wait_variable(var)
                reciver = emailentry.get()

                if validate_email(reciver):
                    speak("email address verification done....")
                else:
                    speak("your email address is not valid")
                    print(reciver + " : is not a valid email address")
                    canvas2.create_text(70, textheight, anchor=NW, text=reciver + " : is not a valid email address",
                                        font="Helvetica 15 bold", fill="white")
                    textheight += 40

                speak("what will be your subject ?")
                esub = takecommand()
                sub = "Subject:" + esub + "\n"
                speak("what shold i write in body?")
                body = takecommand()
                if body == "NONE":
                    body = takecommand()
                message = sub + body

                try:

                    smtpObj = smtplib.SMTP('smtp.gmail.com', 587)
                    smtpObj.starttls()
                    smtpObj.login(sender, passward)
                    try:
                        smtpObj.sendmail(sender, reciver, message)
                        speak("sucessfully mail sent")
                        smtpObj.quit()
                    except Exception:
                        speak("looks like some problem has been occured")
                        smtpObj.quit()

                except Exception:
                    speak("i could not able to login")
                    smtpObj.quit()
            elif "tell" in query and "joke" in query:
                speak("sure tirtho      ")
                joke = pyjokes.get_joke()
                print(joke)
                canvas2.create_text(70, textheight, anchor=NW, text=joke, font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                speak(joke)
                speak("do you like the joke ?")
                feed = takecommand()
                if feed == "yes":
                    speak("my pleasure")
                else:
                    speak("i will try better next time")
            elif "weather" in query or "temperature" in query:

                if True:
                    f = open("apis.txt", "r")
                    api = f.readlines()
                    app_id = api[4].split(":")[1].strip()
                    f.close()
                    speak("fetching data......")

                    try:
                        client = wolframalpha.Client(app_id)
                        res = client.query(query)
                        result = next(res.results).text
                        speak("got it")
                        speak("according to web search  :" + result)
                        print(result)
                        canvas2.create_text(70, textheight, anchor=NW, text=result,
                                            font="Helvetica 15 bold", fill="white")
                        textheight += 40
                    except:
                        baseurl = "http://api.openweathermap.org/data/2.5/weather?q="
                        f = open("apis.txt", "r")
                        api = f.readlines()
                        weatherapi = api[3].split(":")[1].strip()
                        speak("please, name the place")
                        place = takecommand()
                        url = baseurl + place + "&appid=" + str(weatherapi) + "&units=metric"
                        res = requests.get(url)
                        data = res.json()
                        if data["cod"] == 200:
                            speak("city found")
                            temp = data["main"]["temp"]
                            hum = data["main"]["humidity"]
                            visi = data["visibility"]
                            des = data["weather"][0]["description"]
                            main = "temparature is {} degree celcious , humidity is {} percent , visibitily is {} ,overall {}".format(
                                temp, hum, visi, des)
                            print("weather : " + main)
                            speak(main)
                            canvas2.create_text(70, textheight, anchor=NW, text=main,
                                                font="Helvetica 15 bold", fill="white")
                            textheight += 40
                        else:
                            speak("looks like some thing went wrong,city not found,try again")
            elif "my" in query and "location" in query:
                try:
                    res = requests.get("https://ipinfo.io/")
                    data = res.json()
                    ans = "city :" + data["city"] + ", country : " + data["country"] + ", region : " + data[
                        "region"] + " and time zone :" + data["timezone"]
                except:
                    ans = "sorry ! may be something wrong has been happend,try again ."

                print(ans)
                canvas2.create_text(70, textheight, anchor=NW, text=ans, font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                speak(ans)
            elif "project " in query:

                df = pd.read_csv("prj_path.csv")

                prlist = df["name"].tolist()
                mypath = ""

                for i in range(len(prlist)):
                    if prlist[i] in query:
                        mypath = df.iloc[i]["path"]
                        print("sure tirtho,  opening " + prlist[i] + " project directory")
                        speak("sure tirtho,  opening " + prlist[i] + " project directory")
                        canvas2.create_text(70, textheight, anchor=NW,
                                            text=newline("opening " + prlist[i] + " project directory"),
                                            font="Helvetica 15 bold",
                                            fill="white")
                        textheight += 40

                        break
                if mypath == "":
                    speak("which project will you like to open ?")
                    pathquery = takecommand()
                    if "project name" in pathquery or "which" in pathquery or "forgot" in pathquery:
                        prjstr = ", ".join(prlist)
                        speak("you have not remembered your own projects, ha ha ha")
                        speak("jokes apart, your projects are" + prjstr)
                        write(prjstr)
                        speak("which project do you want to open?")
                        pathquery = takecommand()

                    for i in range(len(prlist)):
                        if prlist[i] in pathquery:
                            mypath = df.iloc[i]["path"]
                            print("sure tirtho,  opening " + prlist[i] + " project directory")
                            speak("sure tirtho,  opening " + prlist[i] + " project directory")
                            canvas2.create_text(70, textheight, anchor=NW,
                                                text=newline("opening " + prlist[i] + " project directory"),
                                                font="Helvetica 15 bold",
                                                fill="white")
                            textheight += 40
                            break

                if mypath == "":
                    mypath = df.iloc[-1]["path"]
                try:
                    webbrowser.open(mypath + "//")
                except:
                    speak("i have not gotten any project name")
                    break
            elif ("shut" in query or "turn of" in query) and ("computer" in query or "system" in query):
                speak("are you sure, that you want to shutdown your system,please type your final decision.")

                canvas2.create_text(70, textheight, anchor=NW,
                                    text=newline("Do you want to shutdown your system[y/n] : "),
                                    font="Helvetica 15 bold",
                                    fill="white")
                textheight += 40
                button.wait_variable(var)
                shut = emailentry.get()
                if shut.strip().lower() == "y":
                    # speak("sorry,  can't shutdown system")
                    # speak("this feature is currently turned off as application is under development")
                    speak("closing all application")
                    speak("shutting down your system")
                    os.system("shutdown /s /t 1")
                    # os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0")
                    break
                else:
                    speak("discarding shutdown decision")
                    time.sleep(5)
            elif ("play" in query or "search" in query) and "youtube" in query:
                speak("which song you want to listen?")
                rawquery = takecommand()
                if "play" in rawquery:
                    rawquery = rawquery.split("play")[1]
                queryl = rawquery.lower().strip().split()
                getquery = "+".join(queryl)

                if getquery != "":
                    url = "https://www.youtube.com/results?search_query=" + getquery
                    html = urllib.request.urlopen(url)
                    videoids = re.findall(r"watch\?v=(\S{11})", html.read().decode())
                    firstresult = "https://www.youtube.com/watch?v=" + videoids[0]
                    webbrowser.open(firstresult)
                    canvas2.create_text(70, textheight, anchor=NW,
                                        text=newline("press button below to continue...."),
                                        font="Helvetica 15 bold",
                                        fill="white")
                    textheight += 40
                    button.wait_variable(var)
                else:
                    speak("I haven't got proper query , please try again.")
            elif ("read" in query or "tell" in query or "today" in query) and "new" in query:
                f = open("apis.txt", "r")
                api = f.readlines()
                app_id = api[5].split(":")[1].strip()
                url = "http://newsapi.org/v2/top-headlines?country=in&apiKey=" + app_id
                r = requests.get(url)
                data = json.loads(r.content)
                news = data["articles"]
                speak("sure sir, reading todays fresh news.......")
                for i in range(10):
                    print()
                    newstxt = "news" + str(i + 1) + " : " + news[i]["title"]
                    canvas2.create_text(70, textheight, anchor=NW,
                                        text=newline(newstxt),
                                        font="Helvetica 10 bold",
                                        fill="white")
                    textheight += 100
                    if (i + 1) % 2 == 0:
                        speakf(news[i]["title"])
                        if i != 9:
                            speakf("moving to next news.")
                    else:
                        speak(news[i]["title"])
                        if i != 9:
                            speak("moving to next news.")
                speak("that's it for now, hope you enjoyed")

# application build ends here

######################################################
################# application driver #################
######################################################
def start():
    url = "https://www.google.com"
    try:
        res = requests.get(url)
        startleo()
    except:
        startleo(con=False)
    canvas2.create_text(40, textheight, anchor=NW, text="............  Leo Stopped .............",
                        font="Helvetica 15 bold",
                        fill="white")
    print("leo stopped")

# ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# |||||||||||||||||||| GUI DESIGN PORTION ||||||||||||||||
# ||||||||||||||||||||||||||||||||||||||||||||||||||||||||

# gui design strts here

if __name__ == "__main__":
    root = Tk()
    icn = PhotoImage(file="logo.png")
    root.iconphoto(False, icn)
    root.title("Leo - Personal assistant")
    root.geometry("1000x800")
    root.minsize(width=1000, height=800)
    root.maxsize(width=1000, height=800)
    root.configure(background="white")
    f1 = Frame(root, width=400, height=760, bg="green")
    f1.pack(side=LEFT)
    image = Image.open("leointerface.jpg")
    photo = ImageTk.PhotoImage(image)
    labimg1 = Label(f1, image=photo)
    labimg1.pack()
    frame = Frame(root, width=570, height=720)
    frame.pack(side=RIGHT)
    var = IntVar()
    emailentry = Entry(root, textvariable=StringVar(), bg="black", fg="white", font=('Verdana', 15))
    emailentry.place(x=410, y=730, height=50, width=520)
    button = Button(root, text="Click Me", command=lambda: var.set(1))
    button.place(x=920, y=730, height=50, width=60)

    canvas2 = Canvas(frame, bg="goldenrod2", width=570, height=720, scrollregion=(0, 0, 580, 4000))
    vbar = Scrollbar(frame, orient=VERTICAL)
    vbar.pack(side=RIGHT, fill=Y)
    vbar.config(command=canvas2.yview)
    canvas2.config(yscrollcommand=vbar.set)
    canvas2.pack(expand=True, fill=BOTH)
    task = Thread(target=start)
    task.start()
    root.mainloop()

# simple talking bot built with python
# by Tirtharaj Sinha


import pygame, sys
import UI_loader
import Entities#to load the inventory -> entities_UI?
import states_inventory

class Select_menu():
    def __init__(self, game_state):
        self.game_state = game_state
        self.game_objects = game_state.game.game_objects

    def enter_state(self,newstate):
         self.game_state.state = getattr(sys.modules[__name__], newstate)(self.game_state)#make a class based on the name of the newstate: need to import sys

    def update(self):
        pass

    def render(self):
        pass

    def handle_events(self,input):
        pass

    def exit_state(self):
        self.game_state.exit_state()

class Inventory(Select_menu):
    def __init__(self, game_state):
        super().__init__(game_state)
        self.iventory_UI = UI_loader.UI_loader(self.game_objects,'inventory')
        self.letter_frame = 0#for description
        self.state = states_inventory.Items(self)
        self.item_index = [0,0]

        self.define_blit_positions()
        self.define_pointer()

    def define_blit_positions(self):#set positions
        items = self.iventory_UI.items.copy()#a list if empty items
        key_items = self.iventory_UI.key_items#a dict of empty key items
        index = 0
        for key in self.game_objects.player.inventory.keys():#crease the object in inventory and sepeerate between useable items and key items
            item = getattr(sys.modules[Entities.__name__], key)([0,0],self.game_objects)#make the object based on the string
            if hasattr(item, 'use_item'):
                item.rect.topleft = items[index].rect.topleft
                item.number = self.game_objects.player.inventory[key]#number of items euirepped
                items[index] = item
                index += 1
            else:
                item.rect.topleft = key_items[key].rect.topleft
                item.number = self.game_objects.player.inventory[key]#number of items euirepped
                key_items[key] = item

        stones = self.iventory_UI.stones#a dict of emppty stones
        for key in self.game_objects.player.sword.stones.keys():
            self.game_objects.player.sword.stones[key].rect.topleft = stones[key].rect.topleft
            stones[key] = self.game_objects.player.sword.stones[key]

        self.items = {'sword':list(stones.values()),'key_items':list(key_items.values()),'items':items}#organised items: used to select the item

    def define_pointer(self,size = [16,16]):#called everytime we move from one area to another
        self.pointer = pygame.Surface(size,pygame.SRCALPHA,32).convert_alpha()#the length should be fixed determined, putting 500 for now
        pygame.draw.rect(self.pointer,[200,50,50,255],(0,0,size[0],size[1]),width=1,border_radius=5)

    def update(self):
        self.letter_frame += self.game_objects.game.dt

    def render(self):
        self.blit_inventory_BG()
        self.blit_inventory()
        self.blit_sword()
        self.blit_pointer()
        self.blit_description()

    def blit_inventory_BG(self):
        self.iventory_UI.BG.set_alpha(230)
        self.game_objects.game.screen.blit(self.iventory_UI.BG,(0,0))

    def blit_inventory(self):
        for index, item in enumerate(self.items['items']):#items we can use
            item.animation.update()
            self.game_objects.game.screen.blit(pygame.transform.scale(item.image,(16,16)),item.rect.topleft)
            number = self.game_objects.font.render(text = str(item.number))
            number.fill(color=(255,255,255),special_flags=pygame.BLEND_ADD)
            self.game_objects.game.screen.blit(number,item.rect.center)

        for index, item in enumerate(self.items['key_items']):
            item.animation.update()
            self.game_objects.game.screen.blit(pygame.transform.scale(item.image,(16,16)),item.rect.topleft)
            number = self.game_objects.font.render(text = str(item.number))
            number.fill(color=(255,255,255),special_flags=pygame.BLEND_ADD)
            self.game_objects.game.screen.blit(number,item.rect.center)

    def blit_sword(self):
        self.iventory_UI.sword.animation.update()
        self.game_objects.game.screen.blit(self.iventory_UI.sword.image,self.iventory_UI.sword.rect.topleft)

        for stone in self.items['sword']:
            stone.animation.update()
            self.game_objects.game.screen.blit(stone.image,stone.rect.topleft)

    def blit_pointer(self):
        self.game_objects.game.screen.blit(self.pointer,self.items[self.state.state_name][self.item_index[0]].rect.topleft)#pointer

    def blit_description(self):
        self.conv = self.items[self.state.state_name][self.item_index[0]].description
        text = self.game_objects.font.render((152,80), self.conv, int(self.letter_frame//2))
        text.fill(color=(255,255,255),special_flags=pygame.BLEND_ADD)
        self.game_objects.game.screen.blit(text,(380,120))

    def handle_events(self,input):
        if input[0]:#press
            if input[-1] == 'select':
                self.exit_state()
            elif input[-1] == 'rb':#nezt page
                self.enter_state('Omamori')
            elif input[-1] == 'lb':#previouse page
                self.enter_state('Map')
            elif input[-1]=='a' or input[-1]=='return':
                self.use_item()
            self.state.handle_input(input)
            self.letter_frame = 0

    def use_item(self):
        if not hasattr(self.items[self.state.state_name][self.item_index[0]], 'use_item'): return#if it is a item
        if self.items[self.state.state_name][self.item_index[0]].number <= 0: return#if we have more than 0 item
        self.items[self.state.state_name][self.item_index[0]].use_item()

class Omamori(Select_menu):
    def __init__(self, game_state):
        super().__init__(game_state)
        self.omamori_UI = UI_loader.UI_loader(self.game_objects,'omamori')

        self.letter_frame = 0#for description
        self.define_blit_positions()
        self.define_pointer()
        self.omamori_index = 0

    def define_blit_positions(self):
        for index, key in enumerate(self.game_objects.player.omamoris.equipped):#the equiped ones
            pos = self.omamori_UI.equipped[index].rect.center
            self.game_objects.player.omamoris.equipped[key].set_pos(pos)

        omamori_dict = self.omamori_UI.inventory#copy all empty ones and then overwrite with the rellavant ones in inventory
        for index, key in enumerate(self.game_objects.player.omamoris.inventory):#the ones in inventory
            pos = self.omamori_UI.inventory[key].rect.center
            self.game_objects.player.omamoris.inventory[key].set_pos(pos)
            omamori_dict[key] = self.game_objects.player.omamoris.inventory[key]
        self.omamori_list = list(omamori_dict.values())

    def define_pointer(self,size = [16,16]):#called everytime we move from one area to another
        size = self.omamori_list[0].rect.size
        self.pointer = pygame.Surface(size,pygame.SRCALPHA,32).convert_alpha()#the length should be fixed determined, putting 500 for now
        pygame.draw.rect(self.pointer,[200,50,50,255],(size[0]*0.5-8,size[1]*0.5+8,16,16),width=1,border_radius=5)

    def update(self):
        super().update()
        self.letter_frame += self.game_objects.game.dt

    def render(self):
        super().render()
        self.blit_omamori_BG()
        self.blit_omamori_menu()
        self.blit_pointer()
        self.blit_description()

    def blit_omamori_BG(self):
        self.omamori_UI.BG.set_alpha(230)
        self.game_objects.game.screen.blit(self.omamori_UI.BG,(0,0))

    def blit_omamori_menu(self):
        for omamori in self.game_objects.player.omamoris.equipped.values():#equipped ones
            omamori.animation.update()
            self.game_objects.game.screen.blit(omamori.image,omamori.rect.topleft)

        for omamori in self.omamori_list:
            omamori.animation.update()
            self.game_objects.game.screen.blit(omamori.image,omamori.rect.topleft)

    def blit_description(self):
        self.conv = self.omamori_list[self.omamori_index].description
        text = self.game_objects.font.render((152,80), self.conv, int(self.letter_frame//2))
        text.fill(color=(255,255,255),special_flags=pygame.BLEND_ADD)
        self.game_objects.game.screen.blit(text,(380,120))

    def blit_pointer(self):
        pos = self.omamori_list[self.omamori_index].rect.topleft
        self.game_objects.game.screen.blit(self.pointer,pos)#pointer

    def handle_events(self,input):
        if input[0]:#press
            if input[-1] == 'select':
                self.exit_state()
            elif input[-1] == 'rb':#nezt page
                if self.game_objects.world_state.statistics['kill']:#if we have killed something
                    self.enter_state('Journal')
            elif input[-1] == 'lb':#previouse page
                self.enter_state('Inventory')
            elif input[-1]=='a' or input[-1]=='return':
                self.choose_omamori()

            elif input[-1] =='right':
                self.letter_frame = 0
                self.omamori_index += 1
                self.omamori_index = min(self.omamori_index,len(self.omamori_UI.inventory)-1)

            elif input[-1] =='left':
                self.letter_frame = 0
                self.omamori_index -= 1
                self.omamori_index = max(0,self.omamori_index)

            elif input[-1] =='down':
                self.letter_frame = 0
                self.omamori_index += 5
                self.omamori_index = min(self.omamori_index,len(self.omamori_UI.inventory)-1)

            elif input[-1] =='up':
                self.letter_frame = 0
                self.omamori_index -= 5
                self.omamori_index = max(0,self.omamori_index)

    def choose_omamori(self):
        name = type(self.omamori_list[self.omamori_index]).__name__#name of omamori
        if name == 'Omamori': return#if it is an empyu omamori. return
        self.game_objects.player.omamoris.equip_omamori(name)

        for index, omamori in enumerate(self.game_objects.player.omamoris.equipped.values()):#update the positions of the equiped ones
            pos = self.omamori_UI.equipped[index].rect.center
            omamori.set_pos(pos)

class Journal(Select_menu):
    def __init__(self, game_sate):
        super().__init__(game_sate)
        self.journal_UI = UI_loader.UI_loader(self.game_objects,'journal')
        self.letter_frame = 0
        self.journal_index = [0,0]
        self.enemies = []
        self.enemy_index = self.journal_index.copy()
        self.number = 8 #number of enemies per page

        for enemy in self.game_objects.world_state.statistics['kill']:
            self.enemies.append(getattr(sys.modules[Entities.__name__], enemy.capitalize())([0,0],self.game_objects))#make the object based on the string

        self.select_enemies()
        self.define_pointer()

    def select_enemies(self):
        self.selected_enemies = self.enemies[self.enemy_index[0]:self.enemy_index[0]+self.number:1]

    def define_pointer(self):#called everytime we move from one area to another
        size = [48,16]
        self.pointer = pygame.Surface(size,pygame.SRCALPHA,32).convert_alpha()#the length should be fixed determined, putting 500 for now
        pygame.draw.rect(self.pointer,[200,50,50,255],(0,0,size[0],size[1]),width=1,border_radius=5)

    def update(self):
        super().update()
        self.letter_frame += self.game_objects.game.dt

    def render(self):
        super().render()
        self.blit_journal_BG()
        self.blit_names()
        self.blit_pointer()
        self.blit_enemy()
        self.blit_description()

    def blit_journal_BG(self):
        self.journal_UI.BG.set_alpha(230)
        self.game_objects.game.screen.blit(self.journal_UI.BG,(0,0))

    def blit_names(self):
        for index, enemy in enumerate(self.selected_enemies):
            name = enemy.__class__.__name__
            text = self.game_objects.font.render((152,80), name, 100)
            text.fill(color=(255,255,255),special_flags=pygame.BLEND_ADD)
            self.game_objects.game.screen.blit(text,self.journal_UI.name_pos[index])

    def blit_pointer(self):
        pos = [self.journal_UI.name_pos[self.journal_index[0]][0],self.journal_UI.name_pos[self.journal_index[0]][1]-5]#add a offset
        self.game_objects.game.screen.blit(self.pointer,pos)#pointer

    def blit_enemy(self):
        enemy = self.selected_enemies[self.journal_index[0]]
        enemy.rect.midbottom = self.journal_UI.image_pos#allign based on bottom
        enemy.animation.update()
        self.game_objects.game.screen.blit(enemy.image,[enemy.rect.center[0]-enemy.rect.width*0.5,enemy.rect.center[1]-enemy.rect.height*0.5])#it blits the top left courner so need to correct based on the rectanle size

    def blit_description(self):
        self.conv = self.selected_enemies[self.journal_index[0]].description
        text = self.game_objects.font.render((152,80), self.conv, int(self.letter_frame//2))
        text.fill(color=(255,255,255),special_flags=pygame.BLEND_ADD)
        self.game_objects.game.screen.blit(text,(380,120))

    def handle_events(self,input):
        if input[0]:#press
            if input[-1] == 'select':
                self.exit_state()
            elif input[-1] == 'rb':#nezt page
                pass
            elif input[-1] == 'lb':#previouse page
                self.enter_state('Omamori')
            elif input[-1] =='down':
                self.letter_frame = 0
                self.journal_index[0] += 1
                if self.journal_index[0] == self.number:
                    self.enemy_index[0] += 1
                    self.enemy_index[0] = min(self.enemy_index[0],len(self.enemies)-self.number)
                    self.select_enemies()
                self.journal_index[0] = min(self.journal_index[0],len(self.selected_enemies)-1)

            elif input[-1] =='up':
                self.letter_frame = 0
                self.journal_index[0] -= 1
                if self.journal_index[0] == -1:
                    self.enemy_index[0] -= 1
                    self.enemy_index[0] = max(0,self.enemy_index[0])
                    self.select_enemies()
                self.journal_index[0] = max(0,self.journal_index[0])

class Map(Select_menu):
    def __init__(self, game):
        super().__init__(game)
        self.map_UI = UI_loader.UI_loader(self.game_objects,'map')

        self.scroll = [0,0]
        self.index = 0
        self.pos = [-0.5*(self.map_UI.BG.get_width() - self.game_objects.game.WINDOW_SIZE[0]),-0.5*(self.map_UI.BG.get_height() - self.game_objects.game.WINDOW_SIZE[1])]#start offset position

        for object in self.map_UI.objects:
            object.update(self.pos)

    def update(self):
        super().update()
        self.update_pos(self.scroll)
        self.limit_pos()
        for object in self.map_UI.objects:
            object.update(self.scroll)

        self.map_UI.objects[self.index].currentstate.handle_input('Equip')

    def update_pos(self,scroll):
        self.pos = [self.pos[0]+scroll[0],self.pos[1]+scroll[1]]

    def limit_pos(self):
        #self.pos[0] = min(0,self.pos[0])
        #self.pos[0] = max(self.game.WINDOW_SIZE[0] - self.map_UI.BG.get_width(),self.pos[0])
        #self.pos[1] = min(0,self.pos[1])
        #self.pos[1] = max(self.game.WINDOW_SIZE[1] - self.map_UI.BG.get_height(),self.pos[1])
        if self.pos[0] > 0:
            self.pos[0] = 0
            self.scroll[0] = 0
        elif self.pos[0] < self.game_objects.game.WINDOW_SIZE[0] - self.map_UI.BG.get_width():
            self.pos[0] = self.game_objects.game.WINDOW_SIZE[0] - self.map_UI.BG.get_width()
            self.scroll[0] = 0
        if self.pos[1] > 0:
            self.pos[1] = 0
            self.scroll[1] = 0
        elif self.pos[1] < self.game_objects.game.WINDOW_SIZE[1] - self.map_UI.BG.get_height():
            self.pos[1] = self.game_objects.game.WINDOW_SIZE[1] - self.map_UI.BG.get_height()
            self.scroll[1] = 0

    def render(self):
        super().render()
        self.game_objects.game.screen.blit(self.map_UI.BG,self.pos)
        for object in self.map_UI.objects:
            self.game_objects.game.screen.blit(object.image,object.rect.topleft)

    def calculate_position(self):
        scroll = [-self.map_UI.objects[self.index].rect.center[0]+self.game_objects.game.WINDOW_SIZE[0]*0.5,-self.map_UI.objects[self.index].rect.center[1]+self.game_objects.game.WINDOW_SIZE[1]*0.5]
        for object in self.map_UI.objects:
            object.update(scroll)
        self.update_pos(scroll)

    def handle_events(self,input):
        self.scroll = [-2*input[2]['r_stick'][0],-2*input[2]['r_stick'][1]]#right analog stick

        if input[0]:#press
            if input[-1] == 'select':
                self.exit_state()
            elif input[-1] == 'rb':#nezt page
                self.enter_state('Inventory')
            elif input[-1] == 'right':#should it be left analogue stick?
                self.map_UI.objects[self.index].currentstate.handle_input('Idle')
                self.index += 1
                self.index = min(self.index,len(self.map_UI.objects)-1)
                self.calculate_position()
            elif input[-1] == 'left':#should it be left analogue stick?
                self.map_UI.objects[self.index].currentstate.handle_input('Idle')
                self.index -= 1
                self.index = max(0,self.index)
                self.calculate_position()
            elif input[-1] == 'a':#when pressing a
                self.map_UI.objects[self.index].activate()#open the local map. I guess it should be a new state

    def exit_state(self):
        super().exit_state()
        for object in self.map_UI.objects:
            object.revert()


#!/usr/bin/python

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk

from view.view_window import ViewWindow

DB_PATH = '/home/wayne/Documents/school/thesis/unicellular-grn/data/dbs/run0.db'

def main():
    win = ViewWindow(DB_PATH)
    win.connect("destroy", Gtk.main_quit)
    Gtk.main()

main()


import torch
import pandas as pd
import numpy as np
import json
from torch.utils.data import Dataset, DataLoader

from pipeline.torch.Vectorizer import Vectorizer

class BrunchDataset(Dataset):

    def __init__(self,
                 train_df_path="./data/brunch/train.parquet",
                 eval_df_path="./data/brunch/eval.parquet",
                 history_length=128):

        self.history_length = history_length

        self.train_df = pd.read_parquet(train_df_path)
        self.train_size = len(self.train_df)

        self.val_df = pd.read_parquet(eval_df_path)
        self.validation_size = len(self.val_df)

        self._lookup_dict = {
            'train': (self.train_df, self.train_size),
            'valid': (self.val_df, self.validation_size)
        }
        self.set_split('train')

    def set_split(self, split="train"):

        self._target_split = split
        self._target_df, self._target_size = self._lookup_dict[split]

    def __len__(self):
        return self._target_size

    def __getitem__(self, index):

        row = self._target_df.iloc[index]

        length          = row.length
        session_input   = np.pad(row.session_input, (0, self.history_length - length))
        session_output  = np.pad(row.session_output, (0, self.history_length - length))
        session_mask    = np.pad(row.session_mask, (0, self.history_length - length))
        user_mask       = np.pad(row.user_mask, (0, self.history_length - length))
        mask            = np.pad(np.array([1.0] * length), (0, self.history_length - length))

        return {
            'session_input': session_input,
            'session_output': session_output,
            'session_mask': session_mask,
            'user_mask': user_mask,
            'mask': mask
        }

    def get_num_batches(self, batch_size):
        return len(self) // batch_size

def generate_batches(dataset,
                     batch_size,
                     shuffle=True,
                     drop_last=True,
                     device="cpu"):
    dataloader = DataLoader(
        dataset=dataset,
        batch_size=batch_size,
        shuffle=shuffle,
        drop_last=drop_last
    )

    for data_dict in dataloader:
        out_data_dict = {}
        for name, tensor in data_dict.items():
            out_data_dict[name] = data_dict[name].to(device)
        yield out_data_dict


import os, subprocess

from webassets.filter import Filter
from webassets.exceptions import FilterError, ImminentDeprecationWarning

__all__ = ('LiveScript',)

class LiveScript(Filter):

    name = 'livescript'
    max_debug_level = None
    options = {
        'ls_bin': ('binary', 'LS_BIN'),
        'no_bare': 'LS_NO_BARE',
    }

    def output(self, _in, out, **kw):
        binary = self.ls_bin or 'livescript'

        args = "-csp" + ("" if self.no_bare else 'b')
        proc = subprocess.Popen([binary, args],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE)
        stdout, stderr = proc.communicate(_in.read().encode('utf-8'))
        if proc.returncode != 0:
            raise FilterError(('livescript: subprocess had error: stderr=%s, '+
                               'stdout=%s, returncode=%s') % (
                stderr, stdout, proc.returncode))
        elif stderr:
            print("livescript filter has warnings:", stderr)
        out.write(stdout.decode('utf-8'))


import logging
import sys

FORMAT = ("%(process)d.%(threadName)s %(filename)s:%(lineno)s "
          "%(asctime)s %(message)s")

def setup_logger():
    """ Setup the logger """
    the_logger = logging.getLogger("botserver")
    the_logger.setLevel(logging.DEBUG)

    logging.basicConfig(format=FORMAT, stream=sys.stderr)
    logging.captureWarnings(True)
    return the_logger

logger = setup_logger()