import re
import pandas as pd
import nltk
import string
from plotly import graph_objects as go
import plotly.express as px
import numpy as np

nltk.download("stopwords")
stopword_list = nltk.corpus.stopwords.words("english")

def read_file(filename):
    """
    Converts given text file into dataframe with cols of label and
    (positive, negative, neutral)
    """
    tweet_df = pd.read_csv(filename, sep="\t", lineterminator="\n")
    tweet_df.columns = ["label", "tweet"]
    return tweet_df

def clean_tweet(tweet):
    """
    tweet: string
    returns: cleaned tweet (string)
    """
    tweet = tweet.lower()
    # remove punctuation
    tweet = "".join([c for c in tweet if c not in string.punctuation])
    # remove stop words
    tweet = "".join([(c + " ") for c in tweet.split(" ") if c not in stopword_list])
    # remove all @mentions
    tweet = re.sub(r"(@.*?)[\s]", " ", tweet)
    # remove twitter URL at end of tweet (https://t.co/...)
    tweet = re.sub("http[s]?://\S+", "", tweet)
    return tweet

def visualize_tweets(tweet_df):
    """
    tweet_df: dataframe
    """
    index = ["negative", "neutral", "positive"]

    tweet_u, tweet_counts = np.unique(tweet_df["label"], return_counts=True)
    text = [round(x / len(tweet_df), 3) for x in tweet_counts]
    fig = go.Figure(
        data=[
            go.Bar(
                name="Tweets",
                x=index,
                y=tweet_counts / len(tweet_df),
                text=text,
            ),
        ],
        layout=go.Layout(
            title="Proportion of Tweets by Sentiment",
            yaxis_title="Proportion of Total Tweets",
        ),
    )
    fig.show()

def preprocess_tweets(filename):
    tweet_df = read_file(filename)
    tweet_df["tweet"] = tweet_df["tweet"].apply(clean_tweet)
    return tweet_df


from telethon import TelegramClient
from telethon.errors import rpcerrorlist, FloodWaitError, ChatWriteForbiddenError
import time
import os
try:
    import progressbar
except ModuleNotFoundError:
    print("bu kütüphaneyi indir > pip install progressbar2")

if os.path.isfile('spam.txt'):
    with open('spam.txt', 'r') as r:
        data = r.readlines()
    api_id = int(data[0])
    api_hash = data[1]

else:
    api_id = input('API ID gir: ')
    api_hash = input('API HASH gir: ')
    with open('spam.txt', 'w') as a:
        a.write(api_id + '\n' + api_hash)

client = TelegramClient('spamer', api_id, api_hash)

async def main():
    if os.name == "nt":
        os.system("cls")
    else:
        os.system("clear")

    global target
    print("  _____             _      ______                ")
    print(" |  __ \           | |    |  ____|               ")
    print(" | |  | | __ _ _ __| | __ | |__   _ __  ______ _ ")
    print(" | |  | |/ _` | '__| |/ / |  __| | '_ \|_  / _` |")
    print(" | |__| | (_| | |  |   <  | |____| | | |/ / (_| |")
    print(" |_____/ \__,_|_|  |_|\_\ |______|_| |_/___\__,_|")
    print("")
    print('\n\n Bir Hedef Belirle..')
    i = 0
    dialogs = await client.get_dialogs()
    for dialog in dialogs:
        print(i, ':', dialog.name, 'has ID', dialog.id)
        i = i + 1

    confirm = False
    max = len(dialogs) - 1

    while confirm == False:
        target_index = -1

        # Get target chat
        while target_index < 0 or target_index > max:
            print('Hedef seç 0 ile', max)
            target_index = int(input())
            if target_index < 0 | target_index > max:
                print('Hedef yanlış')

        target = dialogs[target_index]
        print('Hedef', target.name, 'with ID', target.id)

        # Wait for confirm
        print('Onaylıyormusun? Y/N')
        reply = input()[0]
        if reply == 'Y' or reply == 'y':
            confirm = True

    msg = input("Spam mesajı girin : ")
    Several = int(input("kaç tane Göndermek istersin?\n"))

    print("Hedef Yanlış ise Ctrl-Z kullanabilirsin.")
    print('3 saniye icinde basliyor...')
    time.sleep(3)
    print("[+] Spam atmaya başlandı..")
    bar = progressbar.ProgressBar(
        widgets=[progressbar.SimpleProgress()],
        max_value=Several,
    ).start()
    try:
        for i in range(int(Several)):
            await client.send_message(target.id, msg)
            bar.update(i + 1)
        bar.finish()
        print("[+] Spam tamamlandı..")
    except rpcerrorlist.ChatAdminRequiredError:
        print("[!] Sohbete mesaj gönderimin kısıtlanmış !")
    except ChatWriteForbiddenError:
        print("[!] Bu Sohbete Mesaj Gönderilemez")
    except FloodWaitError:
        print("[!] Flood'a Takıldın Tamam Yorma kendini Sonra denersin :)")

with client:
    client.loop.run_until_complete(main())


from imdb import Cinemagoer
from csv import writer
import pandas as pd
import os

ia = Cinemagoer()

def addToList(name: str) -> None:
    movies = ia.search_movie(name)
    correct = None

    for movie in movies:
        os.system("clear")
        print("Assert correct found [y/n]")
        response = input(f"{movie['long imdb title']}\n")

        if response == "y":
            correct = movie
            break

    if correct is None:
        print("Series was not found")

    df = pd.read_csv("serier.csv", dtype={"title": "str", "ID": "str"})
    if correct.getID() in df.values:
        return

    with open("serier.csv", "a") as f_object:
        writer_object = writer(f_object)

        title = correct["title"]
        ID = correct.getID()
        writer_object.writerow([title, ID])

        f_object.close()


#!/usr/bin/env python3
import sys
import os

import argparse
import json
import random
import shutil
import copy
import pickle
import torch
from torch import cuda
import numpy as np
import time
import logging
from tokenizer import Tokenizer
from utils import *
from torch.nn.utils.rnn import pad_sequence

parser = argparse.ArgumentParser()

parser.add_argument('--data_file', default='data/SCAN/tasks_test_addprim_jump.txt')
parser.add_argument('--model_path', default='model-scan-addjump.pt')
parser.add_argument('--gpu', default=0, type=int, help='which gpu to use')
parser.add_argument('--num_samples', default=10, type=int, help='num samples for decoding')
parser.add_argument('--seed', default=3435, type=int, help='random seed')

def get_data(data_file):
  data = []
  for d in open(data_file, "r"):
    src, tgt = d.split("IN: ")[1].split(" OUT: ")
    src = src.strip().split()
    tgt = tgt.strip().split()
    if len(src) == 1 or len(tgt) == 1:
      src = src + src
      tgt = tgt + tgt
    data.append({"src": src, "tgt": tgt})
  return data

def main(args):
  random.seed(args.seed)
  np.random.seed(args.seed)
  torch.manual_seed(args.seed)
  torch.cuda.manual_seed(args.seed)
  cuda.set_device(args.gpu)
  device = torch.device("cuda:"+str(args.gpu))
  data = get_data(args.data_file)
  model_checkpoint = torch.load(args.model_path)
  encoder = model_checkpoint["encoder"]
  decoder = model_checkpoint["decoder"]
  parser = model_checkpoint["parser"]
  x_tokenizer = model_checkpoint["x_tokenizer"]
  y_tokenizer = model_checkpoint["y_tokenizer"]
  model_args = model_checkpoint["args"]
  encoder.to(device)
  decoder.to(device)
  parser.to(device)
  eval(data, encoder, decoder, parser, device, x_tokenizer, y_tokenizer, model_args)

def eval(data, encoder, decoder, parser, device, x_tokenizer, y_tokenizer, model_args):
  num_sents = 0
  num_words = 0.
  num_words_pred = 0
  total_nll = 0.
  total_nll_pred = 0.
  total_correct = 0.
  num_examples = 0.
  for d in data:
    x = [d["src"]]
    y = [d["tgt"]]
    gold = " ".join(y[0])
    src = " ".join(x[0])
    x_tensor, _, _ = x_tokenizer.convert_batch(x)
    y_tensor, _, _ = y_tokenizer.convert_batch(y)
    x_tensor, y_tensor = x_tensor.to(device), y_tensor.to(device)
    x_lengths = torch.Tensor([len(d["src"])]).long().to(device)
    y_lengths = torch.Tensor([len(d["tgt"])]).long().to(device)
    _, x_spans, _, x_actions, _ = parser(x_tensor, x_lengths)
    with torch.no_grad():
      node_features, node_spans = encoder(x_tensor, x_lengths,
                                          spans = x_spans)
      num_sents += 1
      num_words += y_lengths.sum().item()
      nll = decoder(y_tensor, y_lengths,
                    node_features, node_spans, argmax=False)
      total_nll += nll.sum().item()
      y_preds = decoder.decode(node_features, node_spans, y_tokenizer,
                               num_samples = args.num_samples)
      best_pred = [""]
      best_nll = 1e5
      best_length = 0
      best_ppl = 1e5
      num_examples += 1
      for y_pred in y_preds[0]:
        if len(y_pred) < 2:
          continue
        y_pred = [y_pred]
        y_pred_tensor, _, _  = y_tokenizer.convert_batch(y_pred)
        y_pred_tensor = y_pred_tensor.to(device)
        y_pred_lengths = torch.Tensor([len(y_pred[0])]).long().to(device)
        with torch.no_grad():
          if len(y_pred[0]) > 60:
            continue
          pred_nll = decoder(y_pred_tensor, y_pred_lengths,
                             node_features, node_spans, argmax=False,
                             x_str = y_pred)
          ppl = np.exp(pred_nll.item() / y_pred_lengths.sum().item())
          # if pred_nll.item() < best_nll:
          if ppl < best_ppl:
            best_ppl = ppl
            best_pred = y_pred[0]
            best_nll = pred_nll.item()
            best_length = y_pred_lengths.sum().item()
            y_pred_tree, pred_all_spans, pred_all_spans_node = decoder(
              y_pred_tensor, y_pred_lengths, node_features, node_spans,
              x_str=y_pred, argmax=True)
      num_words_pred += best_length
      total_nll_pred += best_nll
      if " ".join(best_pred) == gold:
        total_correct += 1
      print(total_correct / num_examples, np.exp(total_nll / num_words), np.exp(total_nll_pred/num_words_pred))
    pred = " ".join(best_pred)
    x_parse = get_tree(x_actions[0], x[0])
    print("X: %s" % x_parse)
    print("SRC: %s\nPRED: %s\nGOLD: %s" % (" ".join(x[0]), pred, gold))
    print("")
  print("Accuracy: %.4f" % (total_correct / num_examples))
if __name__ == '__main__':
  args = parser.parse_args()
  main(args)


# -*- coding: utf-8 -*-
from django import template
from django.utils.safestring import SafeText
from glynt.apps.transact.models import Transaction

register = template.Library()

@register.inclusion_tag('transact/partials/transaction_choice.html', takes_context=True)
def transactions(context, transaction):
    if type(transaction) in [SafeText, str, unicode]:
        transaction = Transaction.objects.filter(slug=unicode(transaction))
    elif type(transaction) in [list, tuple]:
        transaction = Transaction.objects.filter(slug__in=transaction)
    else:
        transaction = Transaction.objects.all()

    context.update({
        'transactions': transaction
    })
    return context

@register.simple_tag(takes_context=True)
def transpose_company_data(context, value):
    user = context.get('user')
    if user:
        try:
            company = user.companies.all()[0]
        except IndexError:
            company = None
    t = template.Template(value)
    c = template.Context(company.__dict__)
    return t.render(c)


import os
import requests
from collections import Counter
from bs4 import BeautifulSoup

url = 'http://pokemondb.net/pokedex/all'
poke_folder = os.makedirs('poke_images', exist_ok = True)
soup = BeautifulSoup(requests.get(url).text)

poke_links = soup.select('.ent-name')
nicknames = {}
top_words = {}

prev_url = None
for link in poke_links[-10:]:
	poke_url = link['href']
	number = link['title'][18:21]
	if prev_url == poke_url: continue
	name = link.text
	poke_soup = BeautifulSoup(requests.get(url[:-12] + poke_url).text)
	nicknames[name] = poke_soup.select('q')[0].text
	descriptions_html = poke_soup.select('table.vitals-table')[-2]
	description_list = []
	for description in descriptions_html:
		description_list.extend(description.text.split())
	dl = []
	for poke, count in dict(Counter(description_list)).items():
		dl.append((count,poke))
	dl.sort(reverse = True)
	top_words[name] = dl[:5]
	img_urls = poke_soup.select('div > ul > li > div > div > img')
	for index, img_url in enumerate(img_urls):
		print('Downloading image of', name)
		res = requests.get(img_url['src'])
		img_file = open(os.path.join('poke_images', number+'_'+name+'_'+str(index)+'.jpg'), 'wb')
		for chunk in res.iter_content(100000):
			img_file.write(chunk)
		img_file.close()
	prev_url = poke_url


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

import logging
import unittest

import shlex
import subprocess

from .base import log_info

__title__ = 'tld.tests.test_commands'
__author__ = 'Artur Barseghyan'
__copyright__ = '2013-2019 Artur Barseghyan'
__license__ = 'GPL 2.0/LGPL 2.1'
__all__ = ('TestCommands',)

LOGGER = logging.getLogger(__name__)

class TestCommands(unittest.TestCase):
    """Tld commands tests."""

    def setUp(self):
        """Set up."""

    @log_info
    def test_1_update_tld_names_command(self):
        """Test updating the tld names (re-fetch mozilla source)."""
        res = subprocess.check_output(shlex.split('update-tld-names')).strip()
        self.assertEqual(res, b'True')
        return res

    @log_info
    def test_2_update_tld_names_module(self):
        """Test updating the tld names (re-fetch mozilla source)."""
        res = subprocess.check_output(
            shlex.split('python src/tld/commands/update_tld_names.py')
        ).strip()
        self.assertEqual(res, b'True')
        return res

if __name__ == '__main__':
    unittest.main()


import pandas as pd
import numpy as np
from scipy.stats import norm # Normal Distribution

# Variables
r = 0.01  # Risk-Free Rate
S = 30   # Underline asset price
K = 40   # Strike Price
T = 240/365 # Time to Expiration
sigma = 0.30 # Volatility aka Risk
Type = input("Type 'Call' or 'Put' for European Option Type: ")

# cdf is the cumulative distribution function
# pdf is the probability distribution function

def blackScholes(r, S, K, T, sigma, Type):
    "Calculate Black Scholes option price for a call or put european option"

    d1 = (np.log(S/K) + (r + sigma**2/2)*T)/ (sigma*np.sqrt(T))
    d2 = d1 - sigma*np.sqrt(T)
    try:
        if Type == "Call":
            price = S*norm.cdf(d1, 0, 1) - K*np.exp(-r*T)*norm.cdf(d2, 0, 1)
        elif Type == "Put":
            price = K*np.exp(-r*T)*norm.cdf(-d2, 0, 1) - S*norm.cdf(-d1, 0, 1)
        return price
    except:
        print("Make sure you type in 'Call' or 'Put' (Case Sensitive) ")

def delta(r, S, K, T, sigma, Type): # Rate of change of the option value with respect to the underline asset price.
    "Calculate Delta for a call or put european option"

    d1 = (np.log(S/K) + (r + sigma**2/2)*T)/ (sigma*np.sqrt(T))
    try:
        if Type == "Call":
            delta = norm.cdf(d1, 0, 1)
        elif Type == "Put":
            delta = -norm.cdf(-d1, 0, 1)
        return delta
    except:
        print("Make sure you type in 'Call' or 'Put' (Case Sensitive) ")

def gamma(r, S, K, T, sigma, Type): # Rate of change of Delta value with respect to the underline asset price.
    "Calculate Gamma for a call or put european option"

    d1 = (np.log(S/K) + (r + sigma**2/2)*T)/ (sigma*np.sqrt(T))
    d2 = d1 - sigma*np.sqrt(T)
    try:
        gamma = S*norm.pdf(d1, 0, 1)/(S*sigma*np.sqrt(T))
        return gamma
    except:
        print("Make sure you type in 'Call' or 'Put' (Case Sensitive) ")

def vegas(r, S, K, T, sigma, Type): # Vega measures the sensitivity to volatility. Derivative of the option value to derivative to option volatility
    "Calculate Gamma for a call or put european option"

    d1 = (np.log(S/K) + (r + sigma**2/2)*T)/ (sigma*np.sqrt(T))
    d2 = d1 - sigma*np.sqrt(T)
    try:
        vegas = S*norm.pdf(d1, 0, 1)*np.sqrt(T)
        return vegas*0.01
    except:
        print("Make sure you type in 'Call' or 'Put' (Case Sensitive) ")

def theta(r, S, K, T, sigma, Type): # Sensitivity of the value of the derivative to the passage of time per day
    "Calculate Delta for a call or put european option"
    d1 = (np.log(S/K) + (r + sigma**2/2)*T)/ (sigma*np.sqrt(T))
    d2 = d1 - sigma*np.sqrt(T)
    try:
        if Type == "Call":
            theta = -S*norm.pdf(d1, 0, 1)*sigma/(2*np.sqrt(T)) - r*K*np.exp(-r*T)*norm.cdf(d2, 0, 1)
        elif Type == "Put":
            theta = -S*norm.pdf(d1, 0, 1)*sigma/(2*np.sqrt(T)) + r*K*np.exp(-r*T)*norm.cdf(-d2, 0, 1)
        return theta/365
    except:
        print("Make sure you type in 'Call' or 'Put' (Case Sensitive)")

def rho(r, S, K, T, sigma, Type): # Sensitivity to the interest rate
    "Calculate Delta for a call or put european option"
    d1 = (np.log(S/K) + (r + sigma**2/2)*T)/ (sigma*np.sqrt(T))
    d2 = d1 - sigma*np.sqrt(T)
    try:
        if Type == "Call":
            rho = K*T*np.exp(-r*T)*norm.cdf(d2, 0, 1)
        elif Type == "Put":
            rho = -K*T*np.exp(-r*T)*norm.cdf(-d2, 0, 1)
        return rho*0.01
    except:
        print("Make sure you type in 'Call' or 'Put' (Case Sensitive)")

optionPrice = blackScholes(r, S, K, T, sigma, Type).round(2)
delta_calc = delta(r, S, K, T, sigma, Type).round(3)
gamma_calc = gamma(r, S, K, T, sigma, Type).round(3)
vega_calc = vegas(r, S, K, T, sigma, Type).round(3)
theta_calc = theta(r, S, K, T, sigma, Type).round(3)
rho_calc = rho(r, S, K, T, sigma, Type).round(3)
print(f"Option Price is: {optionPrice} ")
print(f"Delta: {delta_calc} ")
print(f"Gamma: {gamma_calc} ")
print(f"Vega: {vega_calc} ")
print(f"Theta: {theta_calc} ")
print(f"Rho: {rho_calc} ")


import pygame

pygame.init()
WIDTH = 1000
HEIGHT = 900
screen = pygame.display.set_mode([WIDTH, HEIGHT])
pygame.display.set_caption('Chess')
font = pygame.font.Font('freesansbold.ttf', 20)
medium_font = pygame.font.Font('freesansbold.ttf', 40)
big_font = pygame.font.Font('freesansbold.ttf', 50)
timer = pygame.time.Clock()
FPS = 60

white_pieces = ['rook', 'knight', 'bishop', 'king', 'queen', 'bishop', 'knight', 'rook',
                'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']
white_locations = [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0),
                   (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)]
black_pieces = ['rook', 'knight', 'bishop', 'king', 'queen', 'bishop', 'knight', 'rook',
                'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']
black_locations = [(0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7),
                   (0, 6), (1, 6), (2, 6), (3, 6), (4, 6), (5, 6), (6, 6), (7, 6)]
captured_pieces_white = []
captured_pieces_black = []
# 0 - ход белых, фигура не выбрана; 1 - ход белых, фигура выбрана;
# 2 - ход чёрных, фигура не выбрана; 3 - ход чёрных, фигура не выбрана
turn_step = 0
# 100 - никакая фигура не выбрана, для каждой фигуры своё число
selection = 100
valid_moves = []
# загрузка картиночек
black_queen = pygame.image.load('assets/images/black queen.svg')
black_queen = pygame.transform.scale(black_queen, (80, 80))
black_queen_small = pygame.transform.scale(black_queen, (45, 45))
black_king = pygame.image.load('assets/images/black king.svg')
black_king = pygame.transform.scale(black_king, (80, 80))
black_king_small = pygame.transform.scale(black_king, (45, 45))
black_rook = pygame.image.load('assets/images/black rook.svg')
black_rook = pygame.transform.scale(black_rook, (80, 80))
black_rook_small = pygame.transform.scale(black_rook, (45, 45))
black_bishop = pygame.image.load('assets/images/black bishop.svg')
black_bishop = pygame.transform.scale(black_bishop, (80, 80))
black_bishop_small = pygame.transform.scale(black_bishop, (45, 45))
black_knight = pygame.image.load('assets/images/black knight.svg')
black_knight = pygame.transform.scale(black_knight, (80, 80))
black_knight_small = pygame.transform.scale(black_knight, (45, 45))
black_pawn = pygame.image.load('assets/images/black pawn.svg')
black_pawn = pygame.transform.scale(black_pawn, (80, 80))
black_pawn_small = pygame.transform.scale(black_pawn, (45, 45))
white_queen = pygame.image.load('assets/images/white queen.svg')
white_queen = pygame.transform.scale(white_queen, (80, 80))
white_queen_small = pygame.transform.scale(white_queen, (45, 45))
white_king = pygame.image.load('assets/images/white king.svg')
white_king = pygame.transform.scale(white_king, (80, 80))
white_king_small = pygame.transform.scale(white_king, (45, 45))
white_rook = pygame.image.load('assets/images/white rook.svg')
white_rook = pygame.transform.scale(white_rook, (80, 80))
white_rook_small = pygame.transform.scale(white_rook, (45, 45))
white_bishop = pygame.image.load('assets/images/white bishop.svg')
white_bishop = pygame.transform.scale(white_bishop, (80, 80))
white_bishop_small = pygame.transform.scale(white_bishop, (45, 45))
white_knight = pygame.image.load('assets/images/white knight.svg')
white_knight = pygame.transform.scale(white_knight, (80, 80))
white_knight_small = pygame.transform.scale(white_knight, (45, 45))
white_pawn = pygame.image.load('assets/images/white pawn.svg')
white_pawn = pygame.transform.scale(white_pawn, (80, 80))
white_pawn_small = pygame.transform.scale(white_pawn, (45, 45))
white_images = [white_pawn, white_queen, white_king, white_knight, white_rook, white_bishop]
small_white_images = [white_pawn_small, white_queen_small, white_king_small, white_knight_small,
                      white_rook_small, white_bishop_small]
black_images = [black_pawn, black_queen, black_king, black_knight, black_rook, black_bishop]
small_black_images = [black_pawn_small, black_queen_small, black_king_small, black_knight_small,
                      black_rook_small, black_bishop_small]
piece_list = ['pawn', 'queen', 'king', 'knight', 'rook', 'bishop']

counter = 0
winner = ''
game_over = False
white_castling_short = True
white_castling_long = True
black_castling_short = True
black_castling_long = True
white_promotion = False
black_promotion = False

# рисует доску
def draw_board():
    for i in range(32):
        column = i % 4
        row = i // 4
        if row % 2 == 0:
            pygame.draw.rect(screen, 'light gray', [600 - (column * 200), row * 100, 100, 100])
        else:
            pygame.draw.rect(screen, 'light gray', [700 - (column * 200), row * 100, 100, 100])
        pygame.draw.rect(screen, 'gray', [0, 800, WIDTH, 100])
        pygame.draw.rect(screen, 'gold', [0, 800, WIDTH, 100], 5)
        pygame.draw.rect(screen, 'gold', [800, 0, 200, HEIGHT], 5)
        status_text = ['White: Select a Piece to Move!', 'White: Select a Destination!',
                       'Black: Select a Piece to Move!', 'Black: Select a Destination!']
        screen.blit(big_font.render(status_text[turn_step], True, 'black'), (20, 820))
        for j in range(9):
            pygame.draw.line(screen, 'black', (0, 100 * j), (800, 100 * j), 2)
            pygame.draw.line(screen, 'black', (100 * j, 0), (100 * j, 800), 2)
        screen.blit(medium_font.render('RESIGN', True, 'black'), (820, 830))

# рисует фигуры на доске
def draw_pieces():
    for i in range(len(white_pieces)):
        index = piece_list.index(white_pieces[i])
        screen.blit(white_images[index], (white_locations[i][0] * 100 + 10, white_locations[i][1] * 100 + 10))
        if turn_step < 2:
            if selection == i:
                pygame.draw.rect(screen, 'red', [white_locations[i][0] * 100 + 1, white_locations[i][1] * 100 + 1,
                                                 100, 100], 2)
    for i in range(len(black_pieces)):
        index = piece_list.index(black_pieces[i])
        screen.blit(black_images[index], (black_locations[i][0] * 100 + 10, black_locations[i][1] * 100 + 10))
        if turn_step >= 2:
            if selection == i:
                pygame.draw.rect(screen, 'blue', [black_locations[i][0] * 100 + 1, black_locations[i][1] * 100 + 1,
                                                 100, 100], 2)

# возвращает список с возможными ходами для каждой фигуры
def check_options(pieces, locations, turn):
    moves_list = []
    all_moves_list = []
    for i in range(len(pieces)):
        location = locations[i]
        piece = pieces[i]
        if piece == 'pawn':
            moves_list = check_pawn(location, turn)
        elif piece == 'rook':
            moves_list = check_rook(location, turn)
        elif piece == 'knight':
            moves_list = check_knight(location, turn)
        elif piece == 'bishop':
            moves_list = check_bishop(location, turn)
        elif piece == 'queen':
            moves_list = check_queen(location, turn)
        elif piece == 'king':
            moves_list = check_king(location, turn)
        all_moves_list.append(moves_list)
    return all_moves_list

# проверяет возможные ходы короля
def check_king(position, color):
    moves_list = []
    if color == 'white':
        friends_list = white_locations
    else:
        friends_list = black_locations
    targets = [(1, 0), (1, 1), (1, -1), (-1, 0), (-1, 1), (-1, -1), (0, 1), (0, -1)]
    for i in range(8):
        target = (position[0] + targets[i][0], position[1] + targets[i][1])
        if target not in friends_list and 0 <= target[0] <= 7 and 0 <= target[1] <= 7:
            moves_list.append(target)
    return moves_list

# проверяет возможные ходы ферзя
def check_queen(position, color):
    moves_list = check_bishop(position, color)
    second_list = check_rook(position, color)
    for i in range(len(second_list)):
        moves_list.append(second_list[i])
    return moves_list

# проверяет возможные ходы слона
def check_bishop(position, color):
    moves_list = []
    if color == 'white':
        enemies_list = black_locations
        friends_list = white_locations
    else:
        enemies_list = white_locations
        friends_list = black_locations
    for i in range(4):
        path = True
        chain = 1
        if i == 0:
            x = 1
            y = -1
        elif i == 1:
            x = -1
            y = -1
        elif i == 2:
            x = 1
            y = 1
        else:
            x = -1
            y = 1
        while path:
            if (position[0] + (chain * x), position[1] + (chain * y)) not in friends_list and \
                    0 <= position[0] + (chain * x) <= 7 and 0 <= position[1] + (chain * y) <= 7:
                moves_list.append((position[0] + (chain * x), position[1] + (chain * y)))
                if (position[0] + (chain * x), position[1] + (chain * y)) in enemies_list:
                    path = False
                chain += 1
            else:
                path = False
    return moves_list

# проверяет возможные ходы ладьи
def check_rook(position, color):
    moves_list = []
    if color == 'white':
        enemies_list = black_locations
        friends_list = white_locations
    else:
        enemies_list = white_locations
        friends_list = black_locations
    for i in range(4):
        path = True
        chain = 1
        if i == 0:
            x = 0
            y = 1
        elif i == 1:
            x = 0
            y = -1
        elif i == 2:
            x = 1
            y = 0
        else:
            x = -1
            y = 0
        while path:
            if (position[0] + (chain * x), position[1] + (chain * y)) not in friends_list and \
                    0 <= position[0] + (chain * x) <= 7 and 0 <= position[1] + (chain * y) <= 7:
                moves_list.append((position[0] + (chain * x), position[1] + (chain * y)))
                if (position[0] + (chain * x), position[1] + (chain * y)) in enemies_list:
                    path = False
                chain += 1
            else:
                path = False
    return moves_list

# проверяет возможные ходы коня
def check_knight(position, color):
    moves_list = []
    if color == 'white':
        friends_list = white_locations
    else:
        friends_list = black_locations
    targets = [(1, 2), (1, -2), (2, 1), (2, -1), (-1, 2), (-1, -2), (-2, 1), (-2, -1)]
    for i in range(8):
        target = (position[0] + targets[i][0], position[1] + targets[i][1])
        if target not in friends_list and 0 <= target[0] <= 7 and 0 <= target[1] <= 7:
            moves_list.append(target)
    return moves_list

# проверяет возможные ходы пешки
def check_pawn(position, color):
    moves_list = []
    if color == 'white':
        # ход на 1 клетку
        if (position[0], position[1] + 1) not in white_locations and \
                (position[0], position[1] + 1) not in black_locations and position[1] < 7:
            moves_list.append((position[0], position[1] + 1))
        # ход на 2 клетки
        if (position[0], position[1] + 2) not in white_locations and \
                (position[0], position[1] + 1) not in white_locations and \
                (position[0], position[1] + 2) not in black_locations and \
                (position[0], position[1] + 1) not in black_locations and position[1] == 1:
            moves_list.append((position[0], position[1] + 2))
        # взятие
        if (position[0] + 1, position[1] + 1) in black_locations:
            moves_list.append((position[0] + 1, position[1] + 1))
        if (position[0] - 1, position[1] + 1) in black_locations:
            moves_list.append((position[0] - 1, position[1] + 1))
    else:
        # ход на 1 клетку
        if (position[0], position[1] - 1) not in white_locations and \
                (position[0], position[1] - 1) not in black_locations and position[1] > 0:
            moves_list.append((position[0], position[1] - 1))
        # ход на 2 клетки
        if (position[0], position[1] - 2) not in white_locations and \
                (position[0], position[1] - 1) not in white_locations and \
                (position[0], position[1] - 1) not in black_locations and \
                (position[0], position[1] - 2) not in black_locations and position[1] == 6:
            moves_list.append((position[0], position[1] - 2))
        # взятие
        if (position[0] + 1, position[1] - 1) in white_locations:
            moves_list.append((position[0] + 1, position[1] - 1))
        if (position[0] - 1, position[1] - 1) in white_locations:
            moves_list.append((position[0] - 1, position[1] - 1))
    return moves_list

# проверяет вохможные ходы для выбранной фигуры
def check_valid_moves():
    if turn_step < 2:
        options_list = white_options
    else:
        options_list = black_options
    valid_options = options_list[selection]
    return valid_options

# рисует возможные ходы на доске
def draw_valid(moves):
    if turn_step < 2:
        color = 'red'
    else:
        color = 'blue'
    for i in range(len(moves)):
        pygame.draw.circle(screen, color, (moves[i][0] * 100 + 50, moves[i][1] * 100 + 50), 5)

# рисует съеденные фигуры с краю
def draw_captured():
    for i in range(len(captured_pieces_white)):
        captured_piece = captured_pieces_white[i]
        index = piece_list.index(captured_piece)
        screen.blit(small_black_images[index], (825, 5 + 50 * i))
    for i in range(len(captured_pieces_black)):
        captured_piece = captured_pieces_black[i]
        index = piece_list.index(captured_piece)
        screen.blit(small_white_images[index], (925, 5 + 50 * i))

# рисует окошко конца игры
def draw_game_over():
    pygame.draw.rect(screen, 'black', [200, 350, 400, 70])
    screen.blit(font.render(f'{winner} won the game!', True, 'white'), (302, 360))
    screen.blit(font.render('press ENTER to restart!', True, 'white'), (290, 390))

# рисует мигающую обводку вокруг короля, когда тот под шахом
def draw_check():
    if turn_step < 2:
        if 'king' in white_pieces:
            king_index = white_pieces.index('king')
            king_location = white_locations[king_index]
            for i in range(len(black_options)):
                if king_location in black_options[i]:
                    if counter < 15:
                        pygame.draw.rect(screen, 'dark red', [white_locations[king_index][0] * 100 + 1,
                                                              white_locations[king_index][1] * 100 + 1, 100, 100], 5)
    else:
        if 'king' in black_pieces:
            king_index = black_pieces.index('king')
            king_location = black_locations[king_index]
            for i in range(len(white_options)):
                if king_location in white_options[i]:
                    if counter < 15:
                        pygame.draw.rect(screen, 'dark blue', [black_locations[king_index][0] * 100 + 1,
                                                               black_locations[king_index][1] * 100 + 1, 100, 100], 5)

# проверяет возможные варианты для рокировки
def check_castling():
    castling_options = []
    white_options_1d = []
    black_options_1d = []
    all_locations = white_locations + black_locations
    for i in range(len(white_pieces)):
        for j in white_options[i]:
            white_options_1d.append(j)
    for i in range(len(black_pieces)):
        for j in black_options[i]:
            black_options_1d.append(j)

    if white_castling_short and (1, 0) not in black_options_1d and \
            (2, 0) not in black_options_1d and (3, 0) not in black_options_1d and \
            (1, 0) not in all_locations and (2, 0) not in all_locations:
        castling_options.append((1, 0))
    if white_castling_long and (5, 0) not in black_options_1d and \
            (4, 0) not in black_options_1d and (3, 0) not in black_options_1d and \
            (4, 0) not in all_locations and (5, 0) not in all_locations and (6, 0) not in all_locations:
        castling_options.append((5, 0))
    if black_castling_short and (1, 7) not in white_options_1d and \
            (2, 7) not in white_options_1d and (3, 7) not in white_options_1d and \
            (1, 7) not in all_locations and (2, 7) not in all_locations:
        castling_options.append((1, 7))
    if black_castling_long and (5, 7) not in white_options_1d and \
            (4, 7) not in white_options_1d and (3, 7) not in white_options_1d and \
            (4, 7) not in all_locations and (5, 7) not in all_locations and (6, 7) not in all_locations:
        castling_options.append((5, 7))
    return castling_options

black_options = check_options(black_pieces, black_locations, 'black')
white_options = check_options(white_pieces, white_locations, 'white')
run = True
while run:
    timer.tick(FPS)
    # штучка для мигания клетки
    if counter < 30:
        counter += 1
    else:
        counter = 0
    screen.fill('dark gray')
    draw_board()
    draw_pieces()
    draw_captured()
    draw_check()
    castling_squares = check_castling()
    # проверка на потерю прав для рокировки
    if (3, 0) in white_locations and (0, 0) in white_locations:
        if white_pieces[white_locations.index((3, 0))] != 'king' or white_pieces[white_locations.index((0, 0))] != 'rook':
            white_castling_short = False
    else:
        white_castling_short = False
    if (3, 0) in white_locations and (7, 0) in white_locations:
        if white_pieces[white_locations.index((3, 0))] != 'king' or white_pieces[white_locations.index((7, 0))] != 'rook':
            white_castling_long = False
    else:
        white_castling_long = False
    if (3, 7) in black_locations and (0, 7) in black_locations:
        if black_pieces[black_locations.index((3, 7))] != 'king' or black_pieces[black_locations.index((0, 7))] != 'rook':
            black_castling_short = False
    else:
        black_castling_short = False
    if (3, 7) in black_locations and (7, 7) in black_locations:
        if black_pieces[black_locations.index((3, 7))] != 'king' or black_pieces[black_locations.index((7, 7))] != 'rook':
            black_castling_long = False
    else:
        black_castling_long = False
    if selection != 100:
        valid_moves = check_valid_moves()
        draw_valid(valid_moves)
    # вывод окошка выбора фигуры при проведении пешки
    if white_promotion:
        pygame.draw.rect(screen, 'black', [200, 350, 400, 50])
        screen.blit(white_queen_small, (230, 350))
        screen.blit(white_rook_small, (330, 350))
        screen.blit(white_knight_small, (430, 350))
        screen.blit(white_bishop_small, (530, 350))
    if black_promotion:
        pygame.draw.rect(screen, 'black', [200, 350, 400, 50])
        screen.blit(black_queen_small, (230, 350))
        screen.blit(black_rook_small, (330, 350))
        screen.blit(black_knight_small, (430, 350))
        screen.blit(black_bishop_small, (530, 350))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 and not game_over:
            x_coord = event.pos[0] // 100
            y_coord = event.pos[1] // 100
            click_coords = (x_coord, y_coord)
            # выбор фигуры для превращения пешки
            if white_promotion:
                if click_coords == (2, 3):
                    white_pieces[promoted_pawn] = "queen"
                elif click_coords == (3, 3):
                    white_pieces[promoted_pawn] = "rook"
                elif click_coords == (4, 3):
                    white_pieces[promoted_pawn] = "knight"
                elif click_coords == (5, 3):
                    white_pieces[promoted_pawn] = "bishop"
                white_promotion = False
                black_options = check_options(black_pieces, black_locations, 'black')
                white_options = check_options(white_pieces, white_locations, 'white')
                turn_step = 2
                selection = 100
                valid_moves = []
                break
            if black_promotion:
                if click_coords == (2, 3):
                    black_pieces[promoted_pawn] = "queen"
                elif click_coords == (3, 3):
                    black_pieces[promoted_pawn] = "rook"
                elif click_coords == (4, 3):
                    black_pieces[promoted_pawn] = "knight"
                elif click_coords == (5, 3):
                    black_pieces[promoted_pawn] = "bishop"
                black_promotion = False
                black_options = check_options(black_pieces, black_locations, 'black')
                white_options = check_options(white_pieces, white_locations, 'white')
                turn_step = 0
                selection = 100
                valid_moves = []
                break
            if turn_step <= 1:
                # проверка на нажатие кнопки "сдаться"
                if click_coords == (8, 8) or click_coords == (9, 8):
                    winner = 'black'
                if click_coords in white_locations:
                    selection = white_locations.index(click_coords)
                    if turn_step == 0:
                        turn_step = 1
                if turn_step == 1:
                    # рокировка
                    if click_coords in castling_squares and white_pieces[selection] == 'king':
                        if click_coords == (1, 0):
                            white_locations[selection] = click_coords
                            white_locations[0] = (2, 0)
                        elif click_coords == (5, 0):
                            white_locations[selection] = click_coords
                            index = white_locations.index((7, 0))
                            white_locations[index] = (4, 0)
                        black_options = check_options(black_pieces, black_locations, 'black')
                        white_options = check_options(white_pieces, white_locations, 'white')
                        turn_step = 2
                        selection = 100
                        valid_moves = []
                if click_coords in valid_moves and selection != 100:
                    white_locations[selection] = click_coords
                    # достижение пешкой последней линии
                    if click_coords[1] == 7 and white_pieces[selection] == 'pawn':
                        white_promotion = True
                        promoted_pawn = selection
                        if click_coords in black_locations:
                            black_piece = black_locations.index(click_coords)
                            captured_pieces_white.append(black_pieces[black_piece])
                            if black_pieces[black_piece] == 'king':
                                winner = 'white'
                            black_pieces.pop(black_piece)
                            black_locations.pop(black_piece)
                        break
                    # взятие вражеской фигуры
                    if click_coords in black_locations:
                        black_piece = black_locations.index(click_coords)
                        captured_pieces_white.append(black_pieces[black_piece])
                        if black_pieces[black_piece] == 'king':
                            winner = 'white'
                        black_pieces.pop(black_piece)
                        black_locations.pop(black_piece)
                    black_options = check_options(black_pieces, black_locations, 'black')
                    white_options = check_options(white_pieces, white_locations, 'white')
                    turn_step = 2
                    selection = 100
                    valid_moves = []

            elif turn_step > 1:
                # роверка на нажатие кнопки "сдаться"
                if click_coords == (8, 8) or click_coords == (9, 8):
                    winner = 'white'
                if click_coords in black_locations:
                    selection = black_locations.index(click_coords)
                    if turn_step == 2:
                        turn_step = 3
                if turn_step == 3:
                    # рокировка
                    if click_coords in castling_squares and black_pieces[selection] == 'king':
                        if click_coords == (1, 7):
                            black_locations[selection] = click_coords
                            black_locations[0] = (2, 7)
                        elif click_coords == (5, 7):
                            black_locations[selection] = click_coords
                            index = black_locations.index((7, 7))
                            black_locations[index] = (4, 7)
                        black_options = check_options(black_pieces, black_locations, 'black')
                        white_options = check_options(white_pieces, white_locations, 'white')
                        turn_step = 0
                        selection = 100
                        valid_moves = []
                if click_coords in valid_moves and selection != 100:
                    black_locations[selection] = click_coords
                    # достижение пешкой последней линии
                    if click_coords[1] == 0 and black_pieces[selection] == 'pawn':
                        black_promotion = True
                        promoted_pawn = selection
                        if click_coords in white_locations:
                            white_piece = white_locations.index(click_coords)
                            captured_pieces_black.append(white_pieces[white_piece])
                            if white_pieces[white_piece] == 'king':
                                winner = 'black'
                            white_pieces.pop(white_piece)
                            white_locations.pop(white_piece)
                        break
                    # взятие вражеской фигуры
                    if click_coords in white_locations:
                        white_piece = white_locations.index(click_coords)
                        captured_pieces_black.append(white_pieces[white_piece])
                        if white_pieces[white_piece] == 'king':
                            winner = 'black'
                        white_pieces.pop(white_piece)
                        white_locations.pop(white_piece)
                    black_options = check_options(black_pieces, black_locations, 'black')
                    white_options = check_options(white_pieces, white_locations, 'white')
                    turn_step = 0
                    selection = 100
                    valid_moves = []
        # перезапуск игры
        if event.type == pygame.KEYDOWN and game_over:
            if event.key == pygame.K_RETURN:
                game_over = False
                winner = ''
                white_pieces = ['rook', 'knight', 'bishop', 'king', 'queen', 'bishop', 'knight', 'rook',
                                'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']
                white_locations = [(0, 0), (1, 0), (2, 0), (3, 0), (4, 0), (5, 0), (6, 0), (7, 0),
                                   (0, 1), (1, 1), (2, 1), (3, 1), (4, 1), (5, 1), (6, 1), (7, 1)]
                black_pieces = ['rook', 'knight', 'bishop', 'king', 'queen', 'bishop', 'knight', 'rook',
                                'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn', 'pawn']
                black_locations = [(0, 7), (1, 7), (2, 7), (3, 7), (4, 7), (5, 7), (6, 7), (7, 7),
                                   (0, 6), (1, 6), (2, 6), (3, 6), (4, 6), (5, 6), (6, 6), (7, 6)]
                captured_pieces_white = []
                captured_pieces_black = []
                turn_step = 0
                selection = 100
                valid_moves = []
                black_options = check_options(black_pieces, black_locations, 'black')
                white_options = check_options(white_pieces, white_locations, 'white')
                white_castling_short = True
                white_castling_long = True
                black_castling_short = True
                black_castling_long = True
                white_promotion = False
                black_promotion = False
    if winner != '':
        game_over = True
        draw_game_over()
    pygame.display.flip()
pygame.quit()


import pygame, json, pygame_gui, sys
import lib.button, lib.color, lib.save_manager, lib.options

#from lib.paint import Paint
#from name import *
#from menu import *
# from winlose import WinLose

# # Import DATA
# setting = json.load(open('data/setting.json'))
# game_data = json.load(open('data/game_data.json'))

# # LOAD DATA
# SCREEN_WIDTH  = setting['screen']['width']
# SCREEN_HEIGHT = setting['screen']['height']
# PLAYER_NAME = game_data["PlayerName"]

class SettingWindow(pygame_gui.elements.UIWindow):
    """class SettingWindow là class kế thừa (Inheritance) từ class pygame_gui.elements.UIWindow

    Args:
        pygame_gui (_type_): _description_
    """
    def __init__(self, rect, ui_manager,SCREEN_WIDTH, SCREEN_HEIGHT, ingame_sound, win_sound, click_sound, menu_sound):
        """Hàm khởi tạo (constructor)

        Args:
            rect (_type_): _description_
            ui_manager (_type_): _description_
            SCREEN_WIDTH (int): chiều dài (ngang) của cửa sổ
            SCREEN_HEIGHT (int): chiều cao (dọc) của cửa sổ
        """
        self.ingame_sound = ingame_sound
        self.win_sound = win_sound
        self.click_sound = click_sound
        self.menu_sound = menu_sound

        super().__init__(rect, ui_manager,
                         window_display_title='Setting',
                         object_id='#setting_window',
                         resizable=True)

        # Import DATA
        self.setting = json.load(open('data/setting.json'))
        self.game_data = json.load(open('data/game_data.json'))

        self.is_blocking = True  # blocks all clicking events from interacting beyond this window

        # LOAD DATA
        self.SCREEN_WIDTH  = self.setting['screen']['width']
        self.SCREEN_HEIGHT = self.setting['screen']['height']
        PLAYER_NAME = self.game_data["PlayerName"]

        # list chứa các giá trị hiện trong menu drop down
        self.pieces_mode = ['3', '4', '5', '6']
        self.pieces_mode_pos = -1
        self.board_size = [
            ['3x3'],
            ['10x10', '12x12'],
            ['16x16', '20x20'],
            ['20x20', '24x24']
        ]
        # self.resolution = ['640x480', '800x600', '1024x768', '1280x960']
        self.resolution = ['1280x960']

        self.options = lib.options.Options(SCREEN_WIDTH, SCREEN_HEIGHT)
        self.btn_size = ( int(self.rect.width *0.6), 30 )

        # Số quân liên tiếp cần để thắng
        self.pieces_mode_label = pygame_gui.elements.UILabel(pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 - 250)),
                                                            self.btn_size),
                                                            "Số quân liên tiếp để thắng: ",
                                                            self.ui_manager,
                                                            container=self)
        # Lấy giá trị của số quân liên tiếp để thắng
        self.current_pieces_mode = (str(self.setting["game"]["win_cnt"]))

        # Dòng này hiện ra menu xổ xuống của số quân liên tiếp cần để thắng
        self.pieces_mode_drop_down = pygame_gui.elements.UIDropDownMenu(self.pieces_mode,
                                                  self.current_pieces_mode,
                                                  pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 - 200)),
                                                            self.btn_size),
                                                  self.ui_manager,
                                                  container=self)

        # Kích cỡ bàn cờ
        self.pieces_mode_label = pygame_gui.elements.UILabel(pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 - 150)),
                                                            self.btn_size),
                                                            "Board size: ",
                                                            self.ui_manager,
                                                            container=self)
        # Lấy giá trị của kích cỡ bàn cờ hiện tại
        self.current_board_size = (str(self.setting["grid"]["size_x"])
                                   + 'x'
                                   + str(self.setting["grid"]["size_y"]))

        self.pieces_mode_pos = self.pieces_mode.index(self.pieces_mode_drop_down.selected_option)
        # self.update_pieces_mode_index()
        # Dòng này hiện ra menu xổ xuống của kích cỡ bàn cờ
        self.board_size_drop_down = pygame_gui.elements.UIDropDownMenu(self.board_size[self.pieces_mode_pos],
                                                  self.current_board_size,
                                                  pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 - 100)),
                                                            self.btn_size),
                                                  self.ui_manager,
                                                  container=self)

        # Độ phân giải
        self.resolution_label = pygame_gui.elements.UILabel(pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 - 50)),
                                                            self.btn_size),
                                                            "Resolution: ",
                                                            self.ui_manager,
                                                            container=self)
        # Lấy giá trị của độ phân giải màn hình hiện tại
        self.current_resolution_string = (str(self.options.resolution[0]) +
                                     'x' +
                                     str(self.options.resolution[1]))

        # Dòng này hiện ra menu xổ xuống
        self.resolution_drop_down = pygame_gui.elements.UIDropDownMenu(self.resolution,
                                                  self.current_resolution_string,
                                                  pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 + 0)),
                                                            self.btn_size),
                                                  self.ui_manager,
                                                  container=self)

        # Setting Volume
        # Dòng chữ "Volume"
        self.volume_label = pygame_gui.elements.UILabel(pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 + 50)),
                                                            self.btn_size),
                                                            "Volume: ",
                                                            self.ui_manager,
                                                            container=self)
        # Thanh trượt qua lại
        self.volume_settings = pygame_gui.elements.UIHorizontalSlider(pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2) + 100),
                                                            self.btn_size),
                                                            self.ingame_sound.get_volume() * 100.0,
                                                            (0.0, 100.0),
                                                            self.ui_manager,
                                                            container=self,
                                                            click_increment=5)
        #self.volume_settings.left_button.kill()
        #self.volume_settings.right_button.kill()
            # Âm thanh
        self.current_volume = pygame_gui.elements.UILabel(pygame.Rect((int(self.rect.width / 2 + self.btn_size[0] /2),
                                                int(self.rect.height / 2 + 100)),
                                                (50, 50)),
                                    str(int(self.volume_settings.get_current_value())),
                                    self.ui_manager,
                                    container=self)

    # def update_pieces_mode_index(self) -> None:
    #     self.pieces_mode_pos = self.pieces_mode.index(self.pieces_mode_drop_down.selected_option)

    def update_board_size_drop_down(self) -> None:
        self.pieces_mode_pos = self.pieces_mode.index(self.pieces_mode_drop_down.selected_option)

        # kill thanh cũ để tạo thanh mới
        self.board_size_drop_down.kill()

        self.board_size_drop_down = pygame_gui.elements.UIDropDownMenu(self.board_size[self.pieces_mode_pos],
                                                  self.board_size[self.pieces_mode_pos][0],
                                                  pygame.Rect((int(self.rect.width / 2 - self.btn_size[0] / 2),
                                                            int(self.rect.height / 2 - 100)),
                                                            self.btn_size),
                                                  self.ui_manager,
                                                  container=self)
        # print(self.board_size_drop_down.selected_option)
        self.board_size_drop_down.selected_option = self.board_size[self.pieces_mode_pos][0]

    def on_close_window_button_pressed(self):
        """
        Override this method to call 'hide()' instead if you want to hide a window when the
        close button is pressed.
        """
        # self.kill()
        self.hide()

        # self.health_bar = UIScreenSpaceHealthBar(pygame.Rect((int(self.rect.width / 9),
        #                                                       int(self.rect.height * 0.7)),
        #                                                      (200, 30)),
        #                                          self.ui_manager,
        #                                          container=self)

    def update(self, time_delta):
        super().update(time_delta)
        if self.alive() and self.volume_settings.has_moved_recently:
            cur_volume = int(self.volume_settings.get_current_value())
            self.current_volume.set_text(str(cur_volume))
            self.ingame_sound.set_volume(cur_volume / 100.0)
            self.win_sound.set_volume(cur_volume / 100.0)
            self.click_sound.set_volume(cur_volume / 100.0)
            self.menu_sound.set_volume(cur_volume / 100.0)


import tweepy
import tweepy.models
import time

class StreamingClient:
    def __init__(self, api: tweepy.API, interval=5):
        self.api = api
        self.interval = interval
        self.tweets = []
        self.api.wait_on_rate_limit = True

    def on_tweet(self, data: tweepy.models.Status):
        return data

    def filter(self, query):
        first = False
        while True:
            tweets = []
            # 最新のツイートを取得
            new_tweets = tweepy.Cursor(
                self.api.search_tweets, q=query, result_type="recent", count=5, tweet_mode="extended").items(5)

            # 初回のみツイートを取得
            if first == False:
                self.tweets = list((tweet for tweet in new_tweets))
                first = True
                time.sleep(self.interval)
                continue

            for tweet in new_tweets:
                if len(self.tweets) != 0:
                    # 既に取得済みのツイートは無視
                    if tweet in self.tweets:
                        break
                tweets.append(tweet)

            for tweet in tweets:
                self.on_tweet(tweet)
            # 更新があった場合はツイートを更新
            if len(tweets) > 0:
                self.tweets = tweets

            time.sleep(self.interval)


from plumbum import local

from benchbuild.project import Project
from benchbuild.environments import container
from benchbuild.source import HTTP
from benchbuild.utils.cmd import make, tar

class LibreSSL(Project):
    """ OpenSSL """

    NAME: str = 'libressl'
    DOMAIN: str = 'encryption'
    GROUP: str = 'benchbuild'
    BINARIES = [
        "aeadtest", "aes_wrap", "asn1test", "base64test", "bftest", "bntest",
        "bytestringtest", "casttest", "chachatest", "cipherstest",
        "cts128test", "destest", "dhtest", "dsatest", "ecdhtest", "ecdsatest",
        "ectest", "enginetest", "evptest", "exptest", "gcm128test",
        "gost2814789t", "hmactest", "ideatest", "igetest", "md4test",
        "md5test", "mdc2test", "mont", "pbkdf2", "pkcs7test", "poly1305test",
        "pq_test", "randtest", "rc2test", "rc4test", "rmdtest", "sha1test",
        "sha256test", "sha512test", "shatest", "ssltest", "timingsafe",
        "utf8test"
    ]
    SOURCE = [
        HTTP(remote={
            '2.1.6.':
            'http://ftp.openbsd.org/pub/OpenBSD/LibreSSL/libressl-2.1.6.tar.gz'
        },
             local='libressl.tar.gz')
    ]
    CONTAINER = container.Buildah().from_('debian:buster-slim')

    def compile(self):
        libressl_source = local.path(self.source_of('libressl.tar.gz'))
        libressl_version = self.version_of('libressl.tar.gz')

        self.cflags += ["-fPIC"]

        clang = compiler.cc(self)

        tar("xfz", libressl_source)
        unpack_dir = local.path(f'libressl-{libressl_version}')
        configure = local[unpack_dir / "configure"]
        configure = run.watch(configure)
        make_ = run.watch(make)

        with local.cwd(unpack_dir):
            with local.env(CC=str(clang)):
                configure("--disable-asm", "--disable-shared",
                          "--enable-static", "--disable-dependency-tracking",
                          "--with-pic=yes")

            make_("-j8")
            make_tests = make["-Ctests", "-j8"]
            make_tests = run.watch(make_tests)
            make_tests(LibreSSL.BINARIES)

    def run_tests(self):
        libressl_version = self.version_of('libressl.tar.gz')
        unpack_dir = local.path(f'libressl-{libressl_version}')
        with local.cwd(unpack_dir / "tests"):
            for binary in LibreSSL.BINARIES:
                wrapping.wrap(local.cwd / binary, self)

        with local.cwd(unpack_dir):
            make_ = run.watch(make)
            make_("V=1", "check", "-i")


from datetime import datetime
from typing import List, Optional
import sqlalchemy as sa
from sqlalchemy.engine import Row
from db.model_client import Client
from .baseRepo import BaseRepo, LOGGER

class ClientRepo(BaseRepo):
    """ `Row` filds: `id`, `work_id`, `status_id`, `api_id`, `api_hash`, `phone`, `created_at`"""

    async def get_all(self, limit: int = 100) -> List[Row]:
        try:
            query = sa.select(Client).limit(limit)
            return await self.database.fetch_all(query)
        except Exception as err:
            await self.database.disconnect()
            await self.database.connect()
            LOGGER.critical(err)

    async def get_by_id(self, id: str) -> Optional[Row]:
        query = sa.select(Client).where(Client.id == id)
        return await self.database.fetch_one(query)

    async def get_by_phone(self, phone: str) -> Optional[Row]:
        query = sa.select(Client).where(Client.phone == phone)
        return await self.database.fetch_one(query)

    async def get_by_work_id(self, work_id: int,
                             limit: int = 100,
                             skip: int = 0
                             ) -> List[Row]:
        query = sa.select(Client).limit(limit).offset(skip).where(Client.work_id == work_id)
        return await self.database.fetch_all(query)

    async def get_by_status_id(self, status_id: int,
                               limit: int = 100,
                               skip: int = 0
                               ) -> List[Row]:
        query = sa.select(Client).limit(limit).offset(skip).where(Client.status_id == status_id)
        return await self.database.fetch_all(query)

    async def get_by_user_id(self, user_id):
        query = sa.select(Client).where(Client.user_id == str(user_id))
        return await self.database.fetch_all(query)

    async def get_by_user_id_and_chat_id(self, user_id, chat_id):
        query = sa.select(Client).where(Client.proxy_status_id==1, Client.status_id==1, Client.user_id == str(user_id), Client.channel_id==int(chat_id))
        return await self.database.fetch_all(query)

    async def get_reserve(self, status_id: int = 5,
                               limit: int = 10, #TODO Лимит аккаунтов на 1го пользователя
                               skip: int = 0
                               ) -> List[Row]:
        query = sa.select(Client).limit(limit).offset(skip).where(Client.status_id == status_id)
        return await self.database.fetch_all(query)
    async def get_next_reserve(self,status_id: int = 5):
        query = sa.select(Client).where(Client.status_id == status_id)
        return await self.database.fetch_one(query)

    async def get_by_status_and_work_id(self, status_id: int, work_id: int,
                               limit: int = 100,
                               skip: int = 0
                               ) -> List[Row]:
        query = sa.select(Client).limit(limit).offset(skip).where(Client.status_id == status_id, Client.work_id == work_id)
        return await self.database.fetch_all(query)

    async def get_status_id(self, id:str):
        query = sa.select(Client).where(Client.id == id)
        res = await self.database.fetch_one(query)
        return res[2]

    async def set_user_and_channel_id(self, phone, user_id, channel_id):
        print(phone, type(phone))
        print(user_id, type(user_id))
        print(channel_id, type(channel_id))
        query = sa.update(Client).where(Client.phone==phone).values(user_id=str(user_id), channel_id=str(channel_id), status_id=1)
        return await self.database.execute(query)

    async def get_all_channel(self, user_id, channel_id):
        query = sa.select(Client).where(Client.user_id==user_id, Client.channel_id==channel_id)
        res = await self.database.fetch_all(query)
        return [i[11] for i in res]

    async def get_id_by_api_id(self, api_id):
        query = sa.select(Client).where(Client.api_id == api_id)
        res = await self.database.fetch_one(query)
        return res[0]

# Нужно будет изменить, если добавим к каждому пользователю ограниченное ко-во аккаунтов
    async def check_valid_all_acc(self):
        list_status = [status[2] for status in await self.get_all()]
        if not 1 in list_status:
            raise Exception('Все аккаунты неактивны!')

    async def check_valid_acc_client(self, mes, user_id):
            await mes.answer('Инвайтинг был завершен с ошибкой!')
            raise Exception('Все аккаунты клиента неактивны, а других нет!')

    async def create(self, work_id: int,
                     status_id: int,
                     proxy_status_id: int,
                     api_id: int,
                     api_hash: str,
                     phone: str,
                     ) -> int:
        """`return`  id: `int`"""
        client_acc = {
            'work_id': work_id,
            'status_id': status_id,
            'proxy_status_id': proxy_status_id,
            'api_id': api_id,
            'api_hash': api_hash,
            'phone': phone,
            'count_invite': 0,
            'created_at': datetime.now(),
        }

        query = sa.insert(Client).values(**client_acc)
        return await self.database.execute(query)

    async def update(self, id: str, **kwargs) -> int:
        """`return`  id: `int`"""
        query = sa.update(Client).where(Client.id == id).values(**kwargs)
        return await self.database.execute(query)

    async def delete(self, id: str):
        query = sa.delete(Client).where(Client.id == id)
        return await self.database.execute(query)

    async def checkBan(self, id:str):
        query = sa.select(Client).where(Client.id == id)
        res = await self.database.fetch_one(query)
        if res[2] == 3:
            return True
        else:
            return False

    async def banned(self, id: str):
        query = sa.update(Client).where(Client.id == id).values(status_id=3)
        return await self.database.execute(query)

    async def bannedByPhone(self, phone: str):
        query = sa.update(Client).where(Client.phone == phone).values(status_id=3)
        return await self.database.execute(query)

    async def bannedByApiId(self, api_id):
        query = sa.update(Client).where(Client.api_id == api_id).values(status_id=3)
        return await self.database.execute(query)

    async def get_count_invite(self, id: str):
        query = sa.select(Client).where(Client.id == id)
        res = await self.database.fetch_one(query)
        if res[8] == None:
            await self.set_count_invite(id, 0)
            return 0
        else:
            return res[8]

    async def set_count_invite(self, id: str, val: int):
        query = sa.update(Client).where(Client.id == id).values(count_invite=val)
        return await self.database.execute(query)

    async def plus_count_invite(self, id:str, val:int):
        count = await self.get_count_invite(id)
        query = sa.update(Client).where(Client.id == id).values(count_invite=count+1)
        return await self.database.execute(query)

    async def set_data_paused_invite(self, id:str):
        query = sa.update(Client).where(Client.id == id).values(data_paused=datetime.now())
        return await self.database.execute(query)

    async def get_data_paused_invite(self, id:str):
        query = sa.select(Client).where(Client.id == id)
        res = await self.database.fetch_one(query)
        return res[9]

    async def set_none_date_paused_invite(self, id: str):
        query = sa.update(Client).where(Client.id == id).values(data_paused=None)
        return await self.database.execute(query)

    async def set_unPaused_invite(self, id: str):
        query = sa.update(Client).where(Client.id == id).values(status_id=1)
        return await self.database.execute(query)

    async def check_end_pause(self, id:str):
        try:
            if (datetime.now() - datetime.strptime(str(await self.get_data_paused_invite(id)),
                                                   "%Y-%m-%d %H:%M:%S")).total_seconds() // 60 > 1439:
                await self.set_none_date_paused_invite(id)
                await self.set_count_invite(id, 0)
                await self.set_unPaused_invite(id)
                return True
            else:
                return False
        except:
            return False

    async def get_channel_id(self, id:int):
        query = sa.select(Client).where(Client.id == id)
        res = await self.database.fetch_one(query)
        if res[10]:
            return res[10]
        else:
            return None

# class Client(Base):
#     __tablename__ = 'client_accounts'
#     __table_args__ = {"comment": "Аккаунты парсеры"}

#     id = Column(Integer, primary_key=True, autoincrement=True)
#     work_id = Column(Integer, ForeignKey('client_workes.id'),nullable=False, default=CWorkes.UNWORKING.value['id'])
#     status_id = Column(Integer, ForeignKey('client_statuses.id'),nullable=False, default=CStatuses.WAITING_AUTHORIZATION.value['id'])
#     api_id = Column(Integer, nullable=False)
#     api_hash = Column(String(50), nullable=False)
#     phone = Column(String(16), nullable=False)
#     created_at = Column(DateTime, nullable=False, default=datetime.datetime.now)


# This script checks that distribution strategies work

# ##############################################################################################
# Importations
from datetime import datetime

from lib.DefaultNatures.DefaultNatures import *

from src.common.Agent import Agent
from src.common.Aggregator import Aggregator
from src.common.Strategy import *
from src.common.World import World

from src.tools.GraphAndTex import GraphOptions
from src.tools.SubclassesDictionary import get_subclasses

# ##############################################################################################
# Minimum
# the following objects are necessary for the simulation to be performed
# you need exactly one object of each type
# ##############################################################################################

# ##############################################################################################
# Importation of subclasses
# all the subclasses are imported in the following dictionary
subclasses_dictionary = get_subclasses()

# ##############################################################################################
# Creation of the world
# a world contains all the other elements of the model
# a world needs just a name
name_world = "validation"
world = World(name_world)  # creation

# ##############################################################################################
# Definition of the path to the files
world.set_directory("cases/ValidationCases/Results/DistributionStrategy")  # here, you have to put the path to your results directory

# ##############################################################################################
# Definition of the random seed
# The default seed is the current time (the value returned by datetime.now())
world.set_random_seed("seed")

# ##############################################################################################
# Time parameters
# it needs a start date, the value of an iteration in hours and the total number of iterations
start_date = datetime(year=1, month=1, day=1, hour=0, minute=0, second=0, microsecond=0)  # a start date in the datetime format
world.set_time(start_date,  # time management: start date
               1,  # value of a time step (in hours)
               24)  # number of time steps simulated

# ##############################################################################################
# Model
# ##############################################################################################

# ##############################################################################################
# Creation of nature
# low voltage electricity
LVE = load_low_voltage_electricity()

# ##############################################################################################
# Creation of daemons
price_manager_elec = subclasses_dictionary["Daemon"]["PriceManagerDaemon"]("prices", {"nature": LVE.name, "buying_price": 0, "selling_price": 0})  # sets prices for flat rate
price_manager_elec_expensive = subclasses_dictionary["Daemon"]["PriceManagerDaemon"]("expensive_prices", {"nature": LVE.name, "buying_price": 1, "selling_price": 0})  # sets prices for flat rate

subclasses_dictionary["Daemon"]["LimitPricesDaemon"]({"nature": LVE.name, "limit_buying_price": 1, "limit_selling_price": 1})  # sets prices for the system operator

# Water temperature
# this daemon is responsible for the value of the water temperature in the catalog
water_temperature_daemon = subclasses_dictionary["Daemon"]["ColdWaterTemperatureDaemon"]({"location": "Pau"}, "cases/ValidationCases/AdditionalData/Meteo/ColdWaterTemperatureProfiles.json")

# ##############################################################################################
# Creation of strategies
# the different distribution strategies
strategy_emergency = subclasses_dictionary["Strategy"]["AutarkyFullButFew"](get_emergency)
strategy_price = subclasses_dictionary["Strategy"]["AutarkyFullButFew"](get_price)
strategy_quantity = subclasses_dictionary["Strategy"]["AutarkyFullButFew"](get_quantity)
strategy_partial = subclasses_dictionary["Strategy"]["AutarkyPartialButAll"]()

# strategy grid, which always proposes an infinite quantity to sell and to buy
grid_strategy = subclasses_dictionary["Strategy"]["Grid"]()

# ##############################################################################################
# Manual creation of agents
early_emergency_owner = Agent("early_emergency_owner")
expensive_emergency_owner = Agent("expensive_emergency_owner")
consuming_emergency_owner = Agent("consuming_emergency_owner")

early_price_owner = Agent("early_price_owner")
expensive_price_owner = Agent("expensive_price_owner")
consuming_price_owner = Agent("consuming_price_owner")

early_quantity_owner = Agent("early_quantity_owner")
expensive_quantity_owner = Agent("expensive_quantity_owner")
consuming_quantity_owner = Agent("consuming_quantity_owner")

early_partial_owner = Agent("early_partial_owner")
expensive_partial_owner = Agent("expensive_partial_owner")
consuming_partial_owner = Agent("consuming_partial_owner")

aggregators_manager = Agent("aggregators_manager")

# ##############################################################################################
# Manual creation of contracts
elec_contract = subclasses_dictionary["Contract"]["CooperativeContract"]("elec_contract", LVE, price_manager_elec)

elec_expensive_contract = subclasses_dictionary["Contract"]["CooperativeContract"]("elec_expensive_contract", LVE, price_manager_elec_expensive)

producer_elec_contract = subclasses_dictionary["Contract"]["CurtailmentContract"]("producer_elec_contract", LVE, price_manager_elec)

# ##############################################################################################
# Creation of aggregators
aggregator_grid = Aggregator("national_grid", LVE, grid_strategy, aggregators_manager)
aggregator_elec_emergency = Aggregator("local_grid_emergency", LVE, strategy_emergency, aggregators_manager, aggregator_grid, elec_contract)
aggregator_elec_price = Aggregator("local_grid_price", LVE, strategy_price, aggregators_manager, aggregator_grid, elec_contract)
aggregator_elec_quantity = Aggregator("local_grid_quantity", LVE, strategy_quantity, aggregators_manager, aggregator_grid, elec_contract)
aggregator_elec_partial = Aggregator("local_grid_partial", LVE, strategy_partial, aggregators_manager, aggregator_grid, elec_contract)

# ##############################################################################################
# Manual creation of devices

# Each device is created 4 times
# emergency strategy
device_early_emergency = subclasses_dictionary["Device"]["HotWaterTank"]("device_early_emergency", elec_contract, early_emergency_owner, aggregator_elec_emergency, {"user": "dummy_user_early", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_expensive_emergency = subclasses_dictionary["Device"]["HotWaterTank"]("device_expensive_emergency", elec_expensive_contract, expensive_emergency_owner, aggregator_elec_emergency, {"user": "dummy_user", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_consuming_emergency = subclasses_dictionary["Device"]["HotWaterTank"]("device_consuming_emergency", elec_contract, consuming_emergency_owner, aggregator_elec_emergency, {"user": "dummy_user", "device": "dummy_usage_consuming"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")

production_emergency = subclasses_dictionary["Device"]["Background"]("production_emergency", producer_elec_contract, aggregators_manager, aggregator_elec_emergency, {"user": "dummy_user", "device": "dummy_producer_distribution_test"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, filename="cases/ValidationCases/AdditionalData/DevicesProfiles/Background.json")

# price strategy
device_early_price = subclasses_dictionary["Device"]["HotWaterTank"]("device_early_price", elec_contract, early_price_owner, aggregator_elec_price, {"user": "dummy_user_early", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_expensive_price = subclasses_dictionary["Device"]["HotWaterTank"]("device_expensive_price", elec_expensive_contract, expensive_price_owner, aggregator_elec_price, {"user": "dummy_user", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_consuming_price = subclasses_dictionary["Device"]["HotWaterTank"]("device_consuming_price", elec_contract, consuming_price_owner, aggregator_elec_price, {"user": "dummy_user", "device": "dummy_usage_consuming"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")

production_price = subclasses_dictionary["Device"]["Background"]("production_price", producer_elec_contract, aggregators_manager, aggregator_elec_price, {"user": "dummy_user", "device": "dummy_producer_distribution_test"}, filename="cases/ValidationCases/AdditionalData/DevicesProfiles/Background.json")

# quantity strategy
device_early_quantity = subclasses_dictionary["Device"]["HotWaterTank"]("device_early_quantity", elec_contract, early_quantity_owner, aggregator_elec_quantity, {"user": "dummy_user_early", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_expensive_quantity = subclasses_dictionary["Device"]["HotWaterTank"]("device_expensive_quantity", elec_expensive_contract, expensive_quantity_owner, aggregator_elec_quantity, {"user": "dummy_user", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_consuming_quantity = subclasses_dictionary["Device"]["HotWaterTank"]("device_consuming_quantity", elec_contract, consuming_quantity_owner, aggregator_elec_quantity, {"user": "dummy_user", "device": "dummy_usage_consuming"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")

production_quantity = subclasses_dictionary["Device"]["Background"]("production_quantity", producer_elec_contract, aggregators_manager, aggregator_elec_quantity, {"user": "dummy_user", "device": "dummy_producer_distribution_test"}, filename="cases/ValidationCases/AdditionalData/DevicesProfiles/Background.json")

# partial strategy
device_early_partial = subclasses_dictionary["Device"]["HotWaterTank"]("device_early_partial", elec_contract, early_partial_owner, aggregator_elec_partial, {"user": "dummy_user_early", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_expensive_partial = subclasses_dictionary["Device"]["HotWaterTank"]("device_expensive_partial", elec_expensive_contract, expensive_partial_owner, aggregator_elec_partial, {"user": "dummy_user", "device": "dummy_usage"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")
device_consuming_partial = subclasses_dictionary["Device"]["HotWaterTank"]("device_consuming_partial", elec_contract, consuming_partial_owner, aggregator_elec_partial, {"user": "dummy_user", "device": "dummy_usage_consuming"}, {"cold_water_temperature_daemon": water_temperature_daemon.name}, "cases/ValidationCases/AdditionalData/DevicesProfiles/HotWaterTank.json")

production_partial = subclasses_dictionary["Device"]["Background"]("production_partial", producer_elec_contract, aggregators_manager, aggregator_elec_partial, {"user": "dummy_user", "device": "dummy_producer_distribution_test"}, filename="cases/ValidationCases/AdditionalData/DevicesProfiles/Background.json")

# ##############################################################################################
# Creation of the validation daemon
description = "This script checks that distribution strategies work"

filename = "distribution_strategy_validation"

reference_values = {"early_emergency_owner.LVE.energy_bought": [418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "expensive_emergency_owner.LVE.energy_bought": [0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "consuming_emergency_owner.LVE.energy_bought": [0, 418/3.6/10000*2, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000*2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

                    "early_price_owner.LVE.energy_bought": [0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "expensive_price_owner.LVE.energy_bought": [418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "consuming_price_owner.LVE.energy_bought": [0, 418/3.6/10000*2, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000*2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

                    "early_quantity_owner.LVE.energy_bought": [0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "expensive_quantity_owner.LVE.energy_bought": [0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "consuming_quantity_owner.LVE.energy_bought": [418/3.6/10000, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 418/3.6/10000, 418/3.6/10000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],

                    "early_partial_owner.LVE.energy_bought": [418/3.6/10000/4, 418/3.6/10000*3/4, 0, 0, 0, 0, 0, 0, 418/3.6/10000/4, 418/3.6/10000*3/4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "expensive_partial_owner.LVE.energy_bought": [418/3.6/10000/4, 418/3.6/10000*3/4, 0, 0, 0, 0, 0, 0, 418/3.6/10000/4, 418/3.6/10000*3/4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
                    "consuming_partial_owner.LVE.energy_bought": [418/3.6/10000/2, 418/3.6/10000*3/2, 0, 0, 0, 0, 0, 0, 418/3.6/10000/2, 418/3.6/10000*3/2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
                    }

name = "LVE_emergency_energy_bought"
export_plot_emergency = {
    "name": name,
    "filename": "export_"+name,
    "options": GraphOptions(f"{name}_graph_options", ["csv", "LaTeX"], "multiple_series"),
    "X": {"catalog_name_entry": "iteration", "label": r"$t \, [\si{\hour}]$"},
    "Y": {"label": r"$\mathcal{C}_{ref.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_emergency_owner.LVE.energy_bought_reference", "style": "points", "legend": r"early"},
                      {"catalog_name_entry": "expensive_emergency_owner.LVE.energy_bought_reference", "style": "points", "legend": r"expens."},
                      {"catalog_name_entry": "consuming_emergency_owner.LVE.energy_bought_reference", "style": "points", "legend": r"consum."}
                    ]
          },
    "Y2": {"label": r"$\mathcal{C}_{num.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_emergency_owner.LVE.energy_bought_simulation", "style": "lines",  "legend": r""},
                      {"catalog_name_entry": "expensive_emergency_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""},
                      {"catalog_name_entry": "consuming_emergency_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""}
                      ]
          }
}

name = "LVE_price_energy_bought"
export_plot_price = {
    "name": name,
    "filename": "export_"+name,
    "options": GraphOptions(f"{name}_graph_options", ["csv", "LaTeX"], "multiple_series"),
    "X": {"catalog_name_entry": "iteration", "label": r"$t \, [\si{\hour}]$"},
    "Y": {"label": r"$\mathsf{P}_{ref.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_price_owner.LVE.energy_bought_reference", "style": "points", "legend": r"early"},
                      {"catalog_name_entry": "expensive_price_owner.LVE.energy_bought_reference", "style": "points", "legend": r"expens."},
                      {"catalog_name_entry": "consuming_price_owner.LVE.energy_bought_reference", "style": "points", "legend": r"consum."}
                    ]
          },
    "Y2": {"label": r"$\mathsf{P}_{num.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_price_owner.LVE.energy_bought_simulation", "style": "lines",  "legend": r""},
                      {"catalog_name_entry": "expensive_price_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""},
                      {"catalog_name_entry": "consuming_price_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""}
                      ]
          }
}

name = "LVE_quantity_energy_bought"
export_plot_quantity = {
    "name": name,
    "filename": "export_"+name,
    "options": GraphOptions(f"{name}_graph_options", ["csv", "LaTeX"], "multiple_series"),
    "X": {"catalog_name_entry": "iteration", "label": r"$t \, [\si{\hour}]$"},
    "Y": {"label": r"$\mathcal{C}_{ref.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_quantity_owner.LVE.energy_bought_reference", "style": "points",  "legend": r"early"},
                      {"catalog_name_entry": "expensive_quantity_owner.LVE.energy_bought_reference", "style": "points", "legend": r"expens."},
                      {"catalog_name_entry": "consuming_quantity_owner.LVE.energy_bought_reference", "style": "points", "legend": r"consum."}
                    ]
          },
    "Y2": {"label": r"$\mathcal{C}_{num.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_quantity_owner.LVE.energy_bought_simulation", "style": "lines",  "legend": r""},
                      {"catalog_name_entry": "expensive_quantity_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""},
                      {"catalog_name_entry": "consuming_quantity_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""}
                    ]
           }
}

name = "LVE_partial_energy_bought"
export_plot_partial = {
    "name": name,
    "filename": "export_"+name,
    "options": GraphOptions(f"{name}_graph_options", ["csv", "LaTeX"], "multiple_series"),
    "X": {"catalog_name_entry": "iteration", "label": r"$t \, [\si{\hour}]$"},
    "Y": {"label": r"$\mathcal{C}_{ref.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_partial_owner.LVE.energy_bought_reference", "style": "points",  "legend": r"early"},
                      {"catalog_name_entry": "expensive_partial_owner.LVE.energy_bought_reference", "style": "points", "legend": r"expens."},
                      {"catalog_name_entry": "consuming_partial_owner.LVE.energy_bought_reference", "style": "points", "legend": r"consum."}
                    ]
          },
    "Y2": {"label": r"$\mathcal{C}_{num.} \, [$\euro{}$]$",
          "graphs": [ {"catalog_name_entry": "early_partial_owner.LVE.energy_bought_simulation", "style": "lines",  "legend": r""},
                      {"catalog_name_entry": "expensive_partial_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""},
                      {"catalog_name_entry": "consuming_partial_owner.LVE.energy_bought_simulation", "style": "lines", "legend": r""}
                    ]
           }
}

parameters = {"description": description, "filename": filename, "reference_values": reference_values, "tolerance": 1E-6, "export_plots": [export_plot_emergency, export_plot_price, export_plot_quantity, export_plot_partial]}

validation_daemon = subclasses_dictionary["Daemon"]["ValidationDaemon"]("distribution_strategy_test", parameters)

# ##############################################################################################
# Simulation start
world.start()


# -*- coding: utf-8 -*-
#!/usr/bin/python
"""
Created on Thu Jan 17 10:06:03 2019

@author: pageot
"""

import pandas as pd
import numpy as np
import os
import datetime
import matplotlib.pyplot as plt

d={}
d["data_file"]="/datalocal/vboxshare/THESE/CLASSIFICATION/DONNES_SIG/DONNEES_METEO/SYNOP_MF"
list_synop=os.listdir(d['data_file'])
list_sta=pd.read_csv("/datalocal/vboxshare/THESE/CLASSIFICATION/DONNES_SIG/DONNEES_METEO/postesSynop.csv")
list_stat_supp=list(list_sta.iloc[42:,1])
list_stat_int=list(list_sta.iloc[[26,27,28,31,32,33,34],1])
list_stat_supp.append(78890)
list_stat_supp.append(61970)
list_sta=list_sta[:42]

#data=pd.DataFrame([])
#
now = datetime.datetime.now()

df=pd.DataFrame([])
for i in list_synop:
    reader=pd.read_csv(d['data_file']+"/"+i,sep=';')
    tab=reader.rename(index=str,columns={'numer_sta':'ID'})
    for j in list_stat_int:
        tabdata=tab[tab.ID == j]
        tab_sta=list_sta.append([list_sta]*(tabdata.shape[0]/42),ignore_index=True)
        Fusion=tab_sta.merge(tabdata, on='ID')
        df2=Fusion.drop_duplicates(keep="last")
        df=df.append(df2,ignore_index=True)
Data_climat=df.iloc[:,[1,2,3,4,5,6,12,-18]]
Data_climat['t']=Data_climat['t'].replace(to_replace=['mq'],value=-9999)
Data_climat['rr24']=Data_climat['rr24'].replace(to_replace=['mq'],value=-9999)
Data_climat[['t','rr24']]=Data_climat[['t','rr24']].astype(float)
Data_climat['t']=Data_climat['t']-273.15
Data_climat.drop_duplicates(keep="last", inplace=True)
a=[]

Data_climat['date']=Data_climat['date'].astype(str)
#Spliter les dates en AAAAMMJJ et
JJall=[]
for s in Data_climat.date:
    JJ=s[0:8]
    JJall.append(JJ)
Data_climat['JJ']=JJall
Data_climat['JJ']=Data_climat['JJ'].astype(int)
DF_Tmean=Data_climat.groupby(['Nom','JJ'])['t'].mean().reset_index()

now2= datetime.datetime.now()
print (now2-now)
DF_Tmean.to_csv("DATA_climat.csv",sep="\t")

#==============================================================================
# divers Test
#==============================================================================
#Tmean=[]
#rowa=[]
#stat=list(set(Data_climat.Nom))
#jj=list(set(Data_climat.JJ))
#jj=sorted(jj)

#for l in stat:
#    for t in jj:
#        a=Data_climat.t.loc[(Data_climat['Nom']==l) & (Data_climat['JJ']==t)].mean()
#        Tmean.append(a)
## ajoute condition de présence de la date sur le lieu.
#rowa=sorted(rowa)
#list_id=list(Data_climat.id)
#ju=[]
#for i in list_id:
#    g=list_id[i] in rowa
#    ju.append(g)
#
#
#Data_climat['drop']=ju
#Data_climat['drop']=Data_climat['drop'].replace(to_replace=False,value=pd.NaT)
#df_climat=Data_climat
#Data_climat=Data_climat.dropna()
#Data_climat['t_mean']=Tmean

#extraction des stations d'interets

#list_stat_int=list(list_sta.iloc[[26,27,28,31,32,33,34],1])
#dfs_cli=pd.DataFrame([])
#for k in list_stat_int:
#    df_climat=data.loc[data.ID==k]
#    dfs_cli=dfs_cli.append(df_climat,ignore_index=True)
#    data_climat=dfs_cli.iloc[:,[1,2,3,4,5,6,12,-18]]
#    data_climat['t']=data_climat['t'].replace(to_replace=['mq'],value=-9999)
#    data_climat['rr24']=data_climat['rr24'].replace(to_replace=['mq'],value=-9999)
#    data_climat[['t','rr24']]=data_climat[['t','rr24']].astype(float)
#    data_climat['t']=data_climat['t']-273.15
#    data_climat.drop_duplicates(keep="last", inplace=True)
#a=[]
#for r in data_climat.date:
#    if r%100000 == 0:
#        b=1
#    else:
#        b=pd.NaT
#    a.append(b)
#data_climat['drop']=a
#
#data_climat['date']=data_climat['date'].astype(str)
##Spliter les dates en AAAAMMJJ et
#JJall=[]
#for s in data_climat.date:
#    JJ=s[0:8]
#    JJall.append(JJ)
#data_climat['JJ']=JJall
#data_climat['JJ']=data_climat['JJ'].astype(int)
#
#Tmean=[]
#for t in data_climat.JJ:
#    a= data_climat.t.loc[data_climat['JJ']==t].mean()
#    Tmean.append(a)
#data_climat['t_mean']=Tmean
#data_climat=data_climat.dropna()
#now2= datetime.datetime.now()
#print (now2-now)
#Data_climat.to_csv("DATA_climat.csv",sep="\t")

##test extctraction deux colones + conversion T en T°c
#test=Data_climat.iloc[0:]
#test['date']=test['date'].astype(str)
#idr=[i for i in np.arange(0,test.shape[0],1)]
#test['id']=idr
##Spliter les dates en AAAAMMJJ et
#JJall=[]
#for s in test.date:
#    JJ=s[0:8]
#    JJall.append(JJ)
#test['JJ']=JJall
#test['JJ']=test['JJ'].astype(int)
#
#temean=[]
#rowa=[]
#stat=list(set(test.Nom))
#jj=list(set(test.JJ))
#
#for t in jj:
#    for l in stat:
#        a=test.t.loc[(test['Nom']==l) & (test['JJ']==t)].mean()
#        temean.append(a)
#        h=test.id.loc[(test['Nom']==l) & (test['JJ']==t)].iloc[0]
#        rowa.append(h)
#rowa=sorted(rowa)
#list_id=list(test.id)
##Moyenner les dates
#
#
#
##supp les lignes en trop afin d'ajoute la valeur journalière
#
#a=[]
#for i in list_id:
#    g=list_id[i] in rowa
#    a.append(g)
#
#
#test['drop']=a
#test['drop']=test['drop'].replace(to_replace=False,value=pd.NaT)
#test1['t_mean']=temean
#test1=test.dropna()
#depa= []
#fin = []
#for t in test.date:
#    if t%100000 == 10000:
#        print t
#        fin.append(t)
#    if t%100000 == 0:
#        print t
#        depa.append(t)
#
#redd=pd.DataFrame([])
#bluee=pd.DataFrame([])
#for i in depa:
#    qa=test.loc[test['date'] == i]
#    redd=redd.append(qa,ignore_index=False)
#for h in fin:
#    tr=test.loc[test['date'] ==h]
#    bluee=bluee.append(tr, ignore_index=False)
#redd.drop_duplicates(keep="last",inplace=True)
#bluee.drop_duplicates(keep="last", inplace=True)
##tré les ID par
#bluee.sort_index(axis = 0, ascending = True,inplace =True)
#redd.sort_index(axis = 0, ascending = True,inplace =True)
## 2 solution
#depar=pd.DataFrame(redd.iloc[:,-1])
#depar=depar.reset_index()
#fini=pd.DataFrame(bluee.iloc[:,-1])
#fini=fini.reset_index()
#tabs=[depar,fini]
#
#boucletab=pd.concat(tabs,axis=1,ignore_index=False)
#boucletab.replace(to_replace=['Nan'],value=-9999,inplace=True)
#boucletab.drop('index',axis=1,inplace=True)
##boucletab.columns = range(boucletab.shape[1])
#boucletab=boucletab.astype(int)
#date_moyenne=[]
#for index,row in boucletab.iterrows():
#    print row
#    a=test.t[row[0]:row[1]].mean()
#    print a
#    date_moyenne.append(a)

#
##==============================================================================
## creation plot dynamique rr + t
##==============================================================================
#plt.plot(DF_Tmean.Nom, DF_Tmean.t)