# https://towardsdatascience.com/a-detailed-guide-to-pytorchs-nn-transformer-module-c80afbc9ffb1

import math
from datetime import datetime
from os import path

import torch
import torch.nn as nn
from torch.utils.tensorboard import SummaryWriter
from tqdm import tqdm

from src.data_management.datasets.better_crnn_dataset import GOBetterCRNNDataset
from src.helper.utils import PATH_TO_LOG_FOLDER, PATH_TO_MODEL_FOLDER, print_blue, print_green, print_red, print_yellow

class PositionalEncoding(nn.Module):
    def __init__(self, dim_model, dropout_p, max_len):
        super().__init__()

        # Info
        self.dropout = nn.Dropout(dropout_p)

        # Encoding - From formula
        pos_encoding = torch.zeros(max_len, dim_model)
        positions_list = torch.arange(0, max_len, dtype=torch.float).view(-1, 1) # 0, 1, 2, 3, 4, 5
        division_term = torch.exp(torch.arange(0, dim_model, 2).float() * (-math.log(10000.0)) / dim_model) # 1000^(2i/dim_model)

        # PE(pos, 2i) = sin(pos/1000^(2i/dim_model))
        pos_encoding[:, 0::2] = torch.sin(positions_list * division_term)

        # PE(pos, 2i + 1) = cos(pos/1000^(2i/dim_model))
        pos_encoding[:, 1::2] = torch.cos(positions_list * division_term)

        # Saving buffer (same as parameter without gradients needed)
        pos_encoding = pos_encoding.unsqueeze(0).transpose(0, 1)
        self.register_buffer('pos_encoding',pos_encoding)

    def forward(self, token_embedding: torch.tensor) -> torch.tensor:
        # Residual connection + pos encoding
        return self.dropout(token_embedding + self.pos_encoding[:token_embedding.size(0), :])

class GOTransformer(nn.Module):
    """
    Model from "A detailed guide to Pytorch's nn.Transformer() module.", by
    Daniel Melchor: https://medium.com/p/c80afbc9ffb1/
    """
    # Constructor
    def __init__(
        self,
        num_tokens,
        dim_model,
        num_heads,
        num_encoder_layers,
        num_decoder_layers,
        dropout_p,
    ):
        super().__init__()

        # INFO
        self.model_type = 'Transformer'
        self.dim_model = dim_model

        # LAYERS
        self.embedding = nn.Embedding(num_tokens, dim_model)
        self.positional_encoder = PositionalEncoding(
            dim_model=dim_model, dropout_p=dropout_p, max_len=5000
        )
        self.transformer = nn.Transformer(
            d_model=dim_model,
            nhead=num_heads,
            num_encoder_layers=num_encoder_layers,
            num_decoder_layers=num_decoder_layers,
            dropout=dropout_p,
        )
        self.linear = nn.Linear(dim_model, num_tokens)

    def forward(self, src, tgt, tgt_mask=None, src_pad_mask=None, tgt_pad_mask=None):
        # Src size must be (batch_size, src sequence length)
        # Tgt size must be (batch_size, tgt sequence length)

        # Embedding + positional encoding - Out size = (batch_size, sequence length, dim_model)
        #src = self.embedding(src) * math.sqrt(self.dim_model)
        tgt = self.embed_token(tgt)
        src = self.positional_encoder(src)
        tgt = self.positional_encoder(tgt)

        # We could use the parameter batch_first=True, but our KDL version doesn't support it yet, so we permute
        # to obtain size (sequence length, batch_size, dim_model),
        src = src.permute(1,0,2)
        tgt = tgt.permute(1,0,2)

        # Transformer blocks - Out size = (sequence length, batch_size, num_tokens)
        transformer_out = self.transformer(src, tgt, tgt_mask=tgt_mask, src_key_padding_mask=src_pad_mask, tgt_key_padding_mask=tgt_pad_mask)
        linear_out = self.linear(transformer_out)

        return linear_out

    def get_tgt_mask(self, size) -> torch.tensor:
        # Generates a squeare matrix where the each row allows one word more to be seen
        mask = torch.tril(torch.ones(size, size) == 1) # Lower triangular matrix
        mask = mask.float()
        mask = mask.masked_fill(mask == 0, float('-inf')) # Convert zeros to -inf
        mask = mask.masked_fill(mask == 1, float(0.0)) # Convert ones to 0

        return mask

    def create_pad_mask(self, matrix: torch.tensor, pad_token: int) -> torch.tensor:
        # If matrix = [1,2,3,0,0,0] where pad_token=0, the result mask is
        # [False, False, False, True, True, True]
        return (matrix == pad_token)

    def embed_token(self, token):
        return self.embedding(token) * math.sqrt(self.dim_model)

class GOTransformerTrainer:

    def __init__(self,
                 sequence_length: int = 32,
                 batch_size: int = 8,
                 dim_model: int = 4096,
                 epochs: int = 100) -> None:
        # parameters
        self.sequence_length = sequence_length
        self.batch_size = batch_size
        self.dim_model = dim_model # (closest power of two to shape of data)
        self.epochs = epochs

        self.SOS_TOKEN = None
        self.EOS_TOKEN = None
        self.SOS_TOKEN_EMBEDDED = None
        self.EOS_TOKEN_EMBEDDED = None

        self.device = 'cuda' if torch.cuda.is_available() else 'cpu'

        self.writer = SummaryWriter(path.join(PATH_TO_LOG_FOLDER, 'runs', f'transformer_{str(datetime.now())}'))

    def train(self):
        torch.autograd.set_detect_anomaly(True)

        dataset = GOBetterCRNNDataset(sequence_length=self.sequence_length)
        train_set, val_set = torch.utils.data.random_split(dataset, [round(len(dataset) * 0.8), round(len(dataset) * 0.2)])

        train_loader = torch.utils.data.DataLoader(train_set, batch_size=self.batch_size, shuffle=True)
        val_loader = torch.utils.data.DataLoader(val_set, batch_size=1, shuffle=True)

        print(f'Using device {self.device}')

        model_params = {
            'num_tokens': 4,
            'dim_model': self.dim_model,
            'num_heads': 2,
            'num_encoder_layers': 3,
            'num_decoder_layers': 3,
            'dropout_p': 0.1
        }

        self.build(model_params)

        model = GOTransformer(**model_params).to(self.device)

        opt = torch.optim.SGD(model.parameters(), lr=0.01)
        loss_fn = nn.CrossEntropyLoss()

        self.writer.add_text('hyperparameters/batch_size', str(self.batch_size))
        self.writer.add_text('hyperparameters/sequence_length', str(self.sequence_length))
        self.writer.add_text('hyperparameters/dim_model', str(self.dim_model))
        self.writer.add_text('hyperparameters/epochs', str(self.epochs))

        time_before = datetime.now()
        self.fit(model, opt, loss_fn, train_loader, val_loader, self.epochs, self.writer)
        time_after = datetime.now()
        time_difference = time_after - time_before
        print(str(time_difference))
        self.writer.add_text('metrics/training_time', str(time_difference))

    def build(self, model_params):
        model = GOTransformer(**model_params).to(self.device)

        self.SOS_TOKEN = torch.tensor([2]).to(self.device)
        self.EOS_TOKEN = torch.tensor([3]).to(self.device)
        self.SOS_TOKEN_EMBEDDED = model.embed_token(self.SOS_TOKEN)
        self.EOS_TOKEN_EMBEDDED = model.embed_token(self.EOS_TOKEN)

    def add_sequence_tokens(self, batch):
        if isinstance(batch[0], (torch.LongTensor, torch.cuda.LongTensor)):
            return torch.stack([torch.concat((self.SOS_TOKEN, item, self.EOS_TOKEN)) for item in batch])
        elif isinstance(batch[0], (torch.FloatTensor, torch.cuda.FloatTensor)):
            return torch.stack([torch.concat((self.SOS_TOKEN_EMBEDDED, item, self.EOS_TOKEN_EMBEDDED)) for item in batch])
        else:
            return batch

    def features_to_embedding_vectors(self, features):
        # 192, 12, 115 -> 5, 52992
        split_and_flattened = torch.reshape(features, (self.sequence_length, -1))
        # 5, 52992 -> 5, 512
        embedded = split_and_flattened[:, :self.dim_model]
        return embedded * math.sqrt(self.dim_model)

    def train_loop(self, model, opt, loss_fn, dataloader):
        model.train()
        total_loss = 0

        for x, y in dataloader:
            # convert from a multi-dimensional feature vector to a simple embedding-vector
            x = torch.stack([self.features_to_embedding_vectors(item) for item in x])

            x = x.to(self.device)
            y = y.type(torch.long).to(self.device)

            # prepend and append the sequence tokens
            x = self.add_sequence_tokens(x)
            y = self.add_sequence_tokens(y)

            # Now we shift the tgt by one so with the <SOS> we predict the token at pos 1
            y_input = y[:,:-1]
            y_expected = y[:,1:]

            # Get mask to mask out the next words
            sequence_length = y_input.size(1)
            tgt_mask = model.get_tgt_mask(sequence_length).to(self.device)

            # Standard training except we pass in y_input and tgt_mask
            pred = model(x, y_input, tgt_mask)

            # Permute pred to have batch size first again
            pred = pred.permute(1, 2, 0)
            loss = loss_fn(pred, y_expected)

            opt.zero_grad()
            loss.backward(retain_graph=True)
            opt.step()

            total_loss += loss.detach().item()

        return total_loss / len(dataloader)

    def validation_loop(self, model, loss_fn, dataloader, epoch: int):
        model.eval()
        total_loss = 0
        total_accuracy_complete = 0
        total_accuracy_start = 0
        c_time = 0

        with torch.no_grad():
            for x, y in dataloader:
                # convert from a multi-dimensional feature vector to a simple embedding-vector
                x = torch.stack([self.features_to_embedding_vectors(item) for item in x])

                x = x.to(self.device)
                y = y.type(torch.long).to(self.device)

                # prepend and append the sequence tokens
                x = self.add_sequence_tokens(x)
                y = self.add_sequence_tokens(y)

                # Now we shift the tgt by one so with the <SOS> we predict the token at pos 1
                y_input = y[:,:-1]
                y_expected = y[:,1:]

                # Get mask to mask out the next words
                sequence_length = y_input.size(1)
                tgt_mask = model.get_tgt_mask(sequence_length).to(self.device)

                # Standard training except we pass in y_input and src_mask
                pred = model(x, y_input, tgt_mask)

                # Permute pred to have batch size first again
                pred = pred.permute(1, 2, 0)

                # get accuracy

                _, max_index = torch.max(pred, dim=1)
                for sequence in max_index:
                    correct_complete = 0
                    correct_start = 0
                    for j in range(sequence_length):

                        if not sequence[j] in (0, 1):
                            sequence[j] = 0.5

                _, max_index = torch.max(pred, dim=1)
                sequence_length_dec = sequence_length - 1
                for i in range(self.batch_size):
                    correct_complete = 0
                    correct_start = 0
                    for j in range(sequence_length_dec):
                        if max_index[i][j] == y_expected[i][j]:
                            correct_complete += 1
                            if correct_start == j:
                                correct_start += 1
                    total_accuracy_complete += correct_complete / sequence_length_dec
                    total_accuracy_start += correct_start / sequence_length_dec

                    self.writer.add_scalar(f'total_acc/epoch_{epoch}', correct_complete / sequence_length_dec, c_time)
                    self.writer.add_scalar(f'total_acc_start/epoch_{epoch}', correct_start / sequence_length_dec, c_time)

                    c_time += 1

                loss = loss_fn(pred, y_expected)
                total_loss += loss.detach().item()

        total_loss /= len(dataloader)
        total_accuracy_complete /= len(dataloader) * self.batch_size
        total_accuracy_start /= len(dataloader) * self.batch_size

        return total_loss, total_accuracy_complete, total_accuracy_start

    def fit(self, model, opt, loss_fn, train_dataloader, val_dataloader, epochs, writer):
        print_green('Training and validating model')
        max_accuracy_start = 0.0
        epoch_threshold = 20
        for epoch in tqdm(range(epochs), 'Epochs'):

            train_loss = self.train_loop(model, opt, loss_fn, train_dataloader)

            validation_loss, acc_complete, acc_start = self.validation_loop(model, loss_fn, val_dataloader, epoch)

            writer.add_scalar('loss/training', train_loss, epoch)
            writer.add_scalar('loss/validation', validation_loss, epoch)
            writer.add_scalar('accuracy/complete', acc_complete, epoch)
            writer.add_scalar('accuracy/start', acc_start, epoch)

            if epoch > epoch_threshold and acc_start > max_accuracy_start:
                torch.save(model, f'{PATH_TO_MODEL_FOLDER}/transformer_{epoch}_{acc_start}_{datetime.now().strftime("%Y-%m-%d_%H:%M")}.pt')
                max_accuracy_start = acc_start

    def predict(self, model, x : list, y : list):
        # convert from a multi-dimensional feature vector to a simple embedding-vector
        x = torch.stack([self.features_to_embedding_vectors(item) for item in x])

        x = x.to(self.device)
        y = y.type(torch.long).to(self.device)

        # prepend and append the sequence tokens
        x = self.add_sequence_tokens(x)
        y = self.add_sequence_tokens(y)

        # Now we shift the tgt by one so with the <SOS> we predict the token at pos 1
        y_input = y[:,:-1]
        y_expected = y[:,1:]

        # Get mask to mask out the next words
        sequence_length = y_input.size(1)
        tgt_mask = model.get_tgt_mask(sequence_length).to(self.device)

        # Standard training except we pass in y_input and src_mask
        pred = model(x, y_input, tgt_mask)

        # Permute pred to have batch size first again
        pred = pred.permute(1, 2, 0)

        # get accuracy
        _, max_index = torch.max(pred, dim=1)
        for sequence in max_index:
            for j in range(sequence_length):
                if not sequence[j] in (0, 1):
                    sequence[j] = 0.5

        return max_index

if __name__ == '__main__':
    GOTransformerTrainer(
        sequence_length=64,
        dim_model=2048,
        epochs=100,
        batch_size=16
    ).train()


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

import csv

from config import ADDRESSES_FILE
from models import Birthday, get_this_week_list

def parse_data_file(in_file=ADDRESSES_FILE):
    """
    :return: [] of {}
        List of birthdays
    """

    reader = csv.DictReader(open(in_file, "r"))
    for row in reader:
        if row:
            yield row

def send_cake_remainder(birthdays):
    """Sends email remainder about cake to whoever turns

    :param birthdays: list of birthdays
    """

    this_week_birthdays = list(get_this_week_list(birthdays))
    for birthday in this_week_birthdays:
        birthday.send_msg()
        yield birthday

def send_birthday_remainder(birthdays):
    """Sends email remainder about people who turn to whoever does not turn

    :param birthdays: list of birthdays
    """

    this_week_birthdays = list(get_this_week_list(birthdays))
    if this_week_birthdays:  # just send emails if there is some birthday
        for b in birthdays:
            birthday = Birthday(b)  # parse raw csv data
            if not birthday.is_this_week():
                birthday.send_remainder_msg(this_week_birthdays)
                yield birthday

def send_emails(addresses):
    """
    :param addresses: str
        Path to file containing addresses
    :return: void
        Run bot
    """

    birthdays = list(parse_data_file(in_file=addresses))
    cakes_sent = list(send_cake_remainder(birthdays))
    reminders_sent = list(send_birthday_remainder(birthdays))

    # get summary
    cakes_sent = [
        {
            "reason": "cake",
            "message": cake.get_summary()
        } for cake in cakes_sent
    ]
    reminders_sent = [
        {
            "reason": "remind",
            "message": remind.get_summary()
        } for remind in reminders_sent
    ]

    return cakes_sent + reminders_sent


import requests
import json
import datetime,time
from kafka import KafkaProducer

# Liste des cryptos à récupérer

# Configuration du Kafka Producer
producer = KafkaProducer(bootstrap_servers=['broker:29092'], value_serializer=lambda x: json.dumps(x).encode('utf-8'))

crypto_list = ["bitcoin", "ethereum", "ripple"]
start_time = int(time.time())
# convert to timestamp

while int(time.time()) < start_time + 200:
    for crypto in crypto_list:
        url = f"https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&ids={crypto}"
        response = requests.get(url)
        data = response.json()[0]
        # print(data["current_price"])
        current_price = data["current_price"]
        date = datetime.datetime.now()
        message = {"crypto": crypto, "value": current_price, "date": date.strftime("%d-%m-%Y %H:%M:%S")}
        print(message)
        producer.send('crypto-values-f', value=message)
    # Récupération toutes les 5 minutes
    time.sleep(30)


#1065번
#수열 판별 먼저
def seq_dcm(num):
    discriminant = True
    n = set()
    for i in range(1, len(num)):
        temp = int(num[i]) - int(num[i-1])
        n.add(temp)
    if len(n) > 1:
        discriminant = False
    return discriminant

X = int(input())
count = 0
for i in range(1, X+1):
    if seq_dcm(str(i)):
        count += 1
print(count)


import threading
import time
import actions
from database import *

logInstance = log.logger('pinger')
plogger = logging.getLogger('pinger')
log.logger.init(logInstance, plogger)
plogger.info('Pinger started')

class Pinger(threading.Thread):
   """
   Pings all connected clients for activity.
   Drops them when they are not responding to pings.
   """

   def run(self):
      pinged = {}

      while 1:
         allclients = DB.get_all_connections()
         for c in allclients:
            #go through all connected clients and see if they need to be pinged for inactivity.
            if c['socket'] and c['last_action'] < (time.time() - 30):
               if pinged[c['name']]:
                  #You've already pinged this client, check if it has ponged in time.
                  if pinged[c['name']] < time.time() - 5:
                     #irresponsive client, drop it
                     plogger.info("Client %s (%s) didn't respond to ping, dropping it."\
                        % (c['name'], c['socket'].getaddress()[0]))
                     actions.drop_client_by_socket(c['socket'])

               else:
                  #Clients needs to be pinged: do it.
                  pinged[c['name']] = time.time()
                  plogger.info("Client %s (%s) inactive for over 30 s. Sending ping"\
                     % (c['name'], c['socket'].getaddress()[0]))
                  actions.unicast(140, 'letsping', c['socket'])

            else:
               #This client has recent activity, don't ping.
               pinged[c['name']] = None
         time.sleep(1)


from pydantic import BaseModel, EmailStr
from datetime import datetime
from typing import Optional

class User(BaseModel):
    user_id : int
    username : str
    forenames: str
    surname : str
    email : EmailStr
    bio : Optional[str]
    display_name : Optional[str]
    created_at:  datetime

class UserRegistrationRequest(BaseModel):
    username : str
    forenames: str
    surname: str
    email: EmailStr
    password: str

class UserUpdateRequest(BaseModel):
    forenames: str
    surname : str
    email : EmailStr
    bio : str
    display_name : str

class UserPartialUpdateRequest(BaseModel):
    forenames: Optional[str]
    surname : Optional[str]
    email : Optional[EmailStr]
    bio : Optional[str]
    display_name : Optional[str]

    class Config:
        extra = "forbid"


import math

class PriorityQueue:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return len(self.items) == 0
    def size(self): return len(self.items)
    def clear(self): self.items = []

    def enqueue(self, item):
        self.items.append(item)
    def findMaxIndex(self):
        if self.isEmpty(): return None
        else:
            highest = 0
            for i in range(1, self.size()):
                if self.items[i][2] > self.items[highest][2]:
                    highest = i
            return highest
    def dequeue(self):
        highest = self.findMaxIndex()
        if highest is not None:
            return self.items.pop(highest)
    def peek(self):
        highest = self.findMaxIndex()
        if highest is not None:
            return self.items[highest]

ox,oy = 5,4
dx = [0,0,1,-1]
dy = [1,-1,0,0]
def dist(x,y):
    dx, dy = ox-x, oy-y
    return math.sqrt(dx**2 + dy**2)

def mySmartSearch():
    global mapsize
    q = PriorityQueue()
    q.enqueue((0,1,-dist(0,1)))
    print('PQueue: ')

    while not q.isEmpty():
        here = q.dequeue()
        print(here, end='->')
        x,y,_ = here
        if (map_[y][x]=='x'):return True
        else:
            map_[y][x]='.'
            for i in range(4):
                if y+dy[i] < 0 or x+dx[i] < 0 or y+dy[i] > mapsize or x+dx[i] > mapsize:continue
                if map_[y+dy[i]][x+dx[i]] == '0' or map_[y+dy[i]][x+dx[i]] == 'x':
                    q.enqueue((x+dx[i],y+dy[i],-dist(x+dx[i],y+dy[i])))
        print('우선순위큐: ', q.items)
    return False

map_ = [['1','1','1','1','1','1'],
       ['e','0','1','0','0','1'],
       ['1','0','0','0','1','1'],
       ['1','0','1','0','1','1'],
       ['1','0','1','0','0','x'],
       ['1','1','1','1','1','1'],]
mapsize = len(map_)
mySmartSearch()


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

from PyQt5.QtWidgets import QWidget
from PyQt5.QtGui import QDoubleValidator
from PyQt5.QtCore import pyqtSignal, pyqtSlot
from selfdefineformat.views.editcheckbox import Ui_Form

class EditCheckBoxModule(QWidget, Ui_Form):
    edited = pyqtSignal()

    def __init__(self, element, parent=None):
        super(EditCheckBoxModule, self).__init__(parent)
        self.setupUi(self)
        self.element = element
        self.set_detail()
        self.set_validator()

    def set_validator(self):
        doubleValitor = QDoubleValidator()
        doubleValitor.setBottom(0)
        doubleValitor.setDecimals(2)
        doubleValitor.setNotation(QDoubleValidator.StandardNotation)
        self.lineEdit_width.setValidator(doubleValitor)
        self.lineEdit_height.setValidator(doubleValitor)
        self.lineEdit_fontsize.setValidator(doubleValitor)

    def set_detail(self):
        if self.element.tagName() != 'CheckBox':
            self.close()
            return
        self.lineEdit_text.setText(self.element.attribute("name"))
        self.lineEdit_fontsize.setText(self.element.attribute("size"))
        self.lineEdit_width.setText(self.element.attribute("width"))
        self.lineEdit_height.setText(self.element.attribute("height"))
        self.lineEdit_id.setText(self.element.attribute("ID"))

        try:
            self.style = int(self.element.attribute("style"))
        except ValueError:
            self.style = 0
        format = '{:03b}'.format(self.style)
        self.checkBox_bold.setCheckState(2 if format[0] != '0' else 0)
        self.checkBox_italic.setCheckState(2 if format[1] != '0' else 0)
        self.checkBox_underline.setCheckState(2 if format[2] != '0' else 0)

    @pyqtSlot(str)
    def on_lineEdit_id_textEdited(self, p_str):
        self.element.setAttribute("ID", p_str)
        self.edited.emit()

    @pyqtSlot(str)
    def on_lineEdit_fontsize_textEdited(self, p_str):
        self.element.setAttribute("size", p_str)
        self.edited.emit()

    @pyqtSlot(str)
    def on_lineEdit_width_textEdited(self, p_str):
        self.element.setAttribute("width", p_str)
        self.edited.emit()

    @pyqtSlot(str)
    def on_lineEdit_height_textEdited(self, p_str):
        self.element.setAttribute("height", p_str)
        self.edited.emit()

    @pyqtSlot(str)
    def on_lineEdit_text_textEdited(self, p_str):
        self.element.setAttribute("name", p_str)
        self.edited.emit()

    @pyqtSlot(bool)
    def on_checkBox_bold_toggled(self, p_bool):
        if p_bool:
            self.element.setAttribute("style", self.style + 4)
            self.style += 4
        else:
            self.element.setAttribute("style", self.style - 4)
            self.style -= 4
        self.edited.emit()

    @pyqtSlot(bool)
    def on_checkBox_italic_toggled(self, p_bool):
        if p_bool:
            self.element.setAttribute("style", self.style + 2)
            self.style += 2
        else:
            self.element.setAttribute("style", self.style - 2)
            self.style -= 2
        self.edited.emit()

    @pyqtSlot(bool)
    def on_checkBox_underline_toggled(self, p_bool):
        if p_bool:
            self.element.setAttribute("style", self.style + 1)
            self.style += 1
        else:
            self.element.setAttribute("style", self.style - 1)
            self.style -= 1
        self.edited.emit()

    @pyqtSlot(bool)
    def on_checkBox_default_toggled(self, p_bool):
        if p_bool:
            self.element.setAttribute("default", 2)
        else:
            self.element.setAttribute("style", 0)
        self.edited.emit()


with open(r'C:\Users\oush\Downloads\dataset_3380_5(1).txt') as file:
    lst_str = file.readlines()
d = {str(i): [] for i in range(1, 12)}
# print(lst_str)
for item in lst_str:
    item = item.split()
    print(item)
    d[item[0]].append(int(item[2]))
print(d)
with open(r'C:\Users\oush\Downloads\reply_3380_5.txt', 'w') as file:
    for i, item in d.items():
        if len(item) > 0:
            file.write('{} {}\n'.format(i, int(sum(item))/int(len(item))))
            # file.write('\n')
        else:
            file.write('{} -\n'.format(i))


# nums = [3,2,3]
# nums = [1,1,1,3,3,2,2,2]

cnt = {}
res = []

for i in nums:
    if i in cnt:
        cnt[i] += 1
    else:
        cnt[i] = 1

    if cnt[i] > len(nums)//3 and not i in res:
        res.append(i)

print(res)


import json, random, csv, sys

def check_input():
    out_file = ''

    if (len(sys.argv) == 3) & (sys.argv[1] == '-i'):
        coded_file = sys.argv[2]
        out_file = None

    elif (len(sys.argv) == 5) & (sys.argv[1] == '-i') & (sys.argv[3] == '-o'):
        coded_file = sys.argv[2]
        out_file = sys.argv[4]

    else:
        print("[Error] invalid parameters")
        exit()

    return coded_file, out_file

def write_data(data, file_name):

    if '.json' not in file_name:
        file_name = file_name + ".json"

    with open(file_name, 'w') as f_out:
            json.dump(data, f_out, indent=0)

    f_out.close()

def process(coded_file):

    data = {
        "course-related": 0,
        "food-related": 0,
        "residence-related": 0,
        "other": 0
    }

    if '.tsv' not in coded_file:
        coded_file = coded_file + ".tsv"

    with open(coded_file) as f:
        tsv_file = csv.reader(f, delimiter="\t")
        for line in tsv_file:
            anno = line[2]
            if len(anno) == 1:
                if anno == 'c': data["course-related"] = data["course-related"]+1
                elif anno == 'f': data["food-related"] = data["food-related"]+1
                elif anno == 'r': data["residence-related"] = data["residence-related"]+1
                elif anno == 'o': data["other"] = data["other"]+1

    f.close()

    return data

def main():
    coded_file, out_file = check_input()

    data = process(coded_file)

    if (out_file == None):
        print(json.dumps(data, indent=0))
    else:
        write_data(data, out_file)

if __name__ == '__main__':
    main()


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

# In[5]:

import numpy as np

# In[1]:

import plotly
import matplotlib.pyplot as plt

# In[3]:

#Equations of motion:
#y = vt + .5a(t**2)
#x = vt
#y = x + 0.5a(x**2)/(v**2)

# In[6]:

#Let intial velocity v = 10 m/s, acceleration a = -9.8 m/s^2, and initial height h = 100 m

# In[11]:

def y(x, a, v, h):
    return x + (1/2)*a*(x**2)/(v**2) + h

xlist = np.linspace(0, 100, num = 1000, endpoint=True, retstep=False)
ylist = y(xlist, -9.8, 10, 100)
plt.figure(num=0, dpi=120)
plt.plot(xlist, ylist, color='pink')
plt.xlabel('Distance x (m)')
plt.ylabel('Height y (m)')
plt.title("Projectile Motion")

# In[ ]:

# In[ ]:


from collections import OrderedDict
import fnmatch
import re

IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)

DEFAULT_CONFIGS = OrderedDict({
    'ckdn': {
        'metric_opts': {
            'type': 'CKDN',
        },
        'metric_mode': 'FR',
    },
    'lpips': {
        'metric_opts': {
            'type': 'LPIPS',
            'net': 'alex',
            'version': '0.1',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'lpips-vgg': {
        'metric_opts': {
            'type': 'LPIPS',
            'net': 'vgg',
            'version': '0.1',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'dists': {
        'metric_opts': {
            'type': 'DISTS',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'ssim': {
        'metric_opts': {
            'type': 'SSIM',
            'downsample': False,
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
    },
    'psnr': {
        'metric_opts': {
            'type': 'PSNR',
            'test_y_channel': False,
        },
        'metric_mode': 'FR',
    },
    'fsim': {
        'metric_opts': {
            'type': 'FSIM',
            'chromatic': True,
        },
        'metric_mode': 'FR',
    },
    'ms_ssim': {
        'metric_opts': {
            'type': 'MS_SSIM',
            'downsample': False,
            'test_y_channel': True,
            'is_prod': True,
        },
        'metric_mode': 'FR',
    },
    'vif': {
        'metric_opts': {
            'type': 'VIF',
        },
        'metric_mode': 'FR',
    },
    'gmsd': {
        'metric_opts': {
            'type': 'GMSD',
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'nlpd': {
        'metric_opts': {
            'type': 'NLPD',
            'channels': 1,
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'vsi': {
        'metric_opts': {
            'type': 'VSI',
        },
        'metric_mode': 'FR',
    },
    'cw_ssim': {
        'metric_opts': {
            'type': 'CW_SSIM',
            'channels': 1,
            'level': 4,
            'ori': 8,
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
    },
    'mad': {
        'metric_opts': {
            'type': 'MAD',
            'test_y_channel': True,
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'niqe': {
        'metric_opts': {
            'type': 'NIQE',
            'test_y_channel': True,
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'ilniqe': {
        'metric_opts': {
            'type': 'ILNIQE',
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'brisque': {
        'metric_opts': {
            'type': 'BRISQUE',
            'test_y_channel': True,
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'nrqm': {
        'metric_opts': {
            'type': 'NRQM',
        },
        'metric_mode': 'NR',
    },
    'pi': {
        'metric_opts': {
            'type': 'PI',
        },
        'metric_mode': 'NR',
        'lower_better': True,
    },
    'musiq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'koniq10k'
        },
        'metric_mode': 'NR',
    },
    'musiq-ava': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'ava'
        },
        'metric_mode': 'NR',
    },
    'musiq-koniq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'koniq10k'
        },
        'metric_mode': 'NR',
    },
    'musiq-paq2piq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'paq2piq'
        },
        'metric_mode': 'NR',
    },
    'musiq-spaq': {
        'metric_opts': {
            'type': 'MUSIQ',
            'pretrained': 'spaq'
        },
        'metric_mode': 'NR',
    },
    'nima': {
        'metric_opts': {
            'type': 'NIMA',
            'pretrained': 'ava'
        },
        'metric_mode': 'NR',
    },
    'pieapp': {
        'metric_opts': {
            'type': 'PieAPP',
        },
        'metric_mode': 'FR',
        'lower_better': True,
    },
    'paq2piq': {
        'metric_opts': {
            'type': 'PAQ2PIQ',
        },
        'metric_mode': 'NR',
    },
    'dbcnn': {
        'metric_opts': {
            'type': 'DBCNN',
            'pretrained': 'koniq'
        },
        'metric_mode': 'NR',
    },
})

def _natural_key(string_):
    return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_.lower())]

def list_models(filter='', exclude_filters=''):
    """ Return list of available model names, sorted alphabetically
    Args:
        filter (str) - Wildcard filter string that works with fnmatch
        exclude_filters (str or list[str]) - Wildcard filters to exclude models after including them with filter
    Example:
        model_list('*ssim*') -- returns all models including 'ssim'
    """
    all_models = DEFAULT_CONFIGS.keys()
    if filter:
        models = []
        include_filters = filter if isinstance(filter, (tuple, list)) else [filter]
        for f in include_filters:
            include_models = fnmatch.filter(all_models, f)  # include these models
            if len(include_models):
                models = set(models).union(include_models)
    else:
        models = all_models
    if exclude_filters:
        if not isinstance(exclude_filters, (tuple, list)):
            exclude_filters = [exclude_filters]
        for xf in exclude_filters:
            exclude_models = fnmatch.filter(models, xf)  # exclude these models
            if len(exclude_models):
                models = set(models).difference(exclude_models)
    return list(sorted(models, key=_natural_key))


import os
import subprocess
from src.manager.manager.launcher.launcher_interface import ILauncher, LauncherException
from src.manager.manager.docker_thread.docker_thread import DockerThread
from src.manager.libs.process_utils import wait_for_xserver
from typing import List, Any
import time

class LauncherDronesRos2(ILauncher):
    exercise_id: str
    type: str
    module: str
    resource_folders: List[str]
    model_folders: List[str]
    plugin_folders: List[str]
    world_file: str
    running = False
    threads: List[Any] = []

    def run(self, callback):
        # Start X server in display
        xserver_cmd = f"/usr/bin/Xorg -quiet -noreset +extension GLX +extension RANDR +extension RENDER -logfile ./xdummy.log -config ./xorg.conf :0"
        xserver_thread = DockerThread(xserver_cmd)
        xserver_thread.start()
        wait_for_xserver(":0")
        self.threads.append(xserver_thread)

        # expand variables in configuration paths
        self._set_environment()
        world_file = os.path.expandvars(self.world_file)

        # Launching MicroXRCE and Aerostack2 nodes
        as2_launch_cmd = f"ros2 launch jderobot_drones as2_default_classic_gazebo.launch.py world_file:={world_file}"

        as2_launch_thread = DockerThread(as2_launch_cmd)
        as2_launch_thread.start()
        self.threads.append(as2_launch_thread)

        # Launching gzserver and PX4
        px4_launch_cmd = f"$AS2_GZ_ASSETS_SCRIPT_PATH/default_run.sh {world_file}"

        px4_launch_thread = DockerThread(px4_launch_cmd)
        px4_launch_thread.start()
        self.threads.append(px4_launch_thread)

        self.running = True

    def is_running(self):
        return True

    def terminate(self):
        if self.is_running():
            for thread in self.threads:
                thread.terminate()
                thread.join()
            self.running = False

    def _set_environment(self):
        resource_folders = [os.path.expandvars(path) for path in self.resource_folders]
        model_folders = [os.path.expandvars(path) for path in self.model_folders]
        plugin_folders = [os.path.expandvars(path) for path in self.plugin_folders]

        os.environ["GAZEBO_RESOURCE_PATH"] = f"{os.environ.get('GAZEBO_RESOURCE_PATH', '')}:{':'.join(resource_folders)}"
        os.environ["GAZEBO_MODEL_PATH"] = f"{os.environ.get('GAZEBO_MODEL_PATH', '')}:{':'.join(model_folders)}"
        os.environ["GAZEBO_PLUGIN_PATH"] = f"{os.environ.get('GAZEBO_PLUGIN_PATH', '')}:{':'.join(plugin_folders)}"


"""empty message

Revision ID: b7c0cfa43719
Revises: 25279a0b5c75
Create Date: 2016-11-02 00:02:18.768539

"""

# revision identifiers, used by Alembic.
revision = 'b7c0cfa43719'
down_revision = '25279a0b5c75'

from alembic import op
import sqlalchemy as sa

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.add_column('twilio', sa.Column('state_number', sa.String(length=255), nullable=True))
    op.add_column('user', sa.Column('state_number', sa.String(length=255), nullable=True))
    ### end Alembic commands ###

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('user', 'state_number')
    op.drop_column('twilio', 'state_number')
    ### end Alembic commands ###


from resizer import *
import argparse

if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "--src",
        type=str,
        required=True,
        help="The directory of the folder with the image to be resized.",
    )
    parser.add_argument(
        "--width", type=int, required=True, help="Width of a resized image"
    )
    parser.add_argument(
        "--height", type=int, required=True, help="Height of a resized image"
    )
    parser.add_argument(
        "--save_dir",
        type=str,
        required=False,
        default=None,
        help="A directory to store images.",
    )
    parser.add_argument(
        "--inplace",
        type=bool,
        required=False,
        default=False,
        help="Whether to save the images inplace or not.",
    )
    args = parser.parse_args()
    images, image_names, folder_name, file_list = open_images(args.src)
    images = resize_images(images, args.width, args.height)

    if args.inplace:
        inplace_save_images(images, file_list)
    elif args.save_dir is not None:
        save_images(images, image_names, folder_name, args.save_dir)
    else:
        save_images(images, image_names, folder_name)

    print("Done")


"""dividing a given corpus 'test' or 'dev' set into arbitrary sentence lengths"""

### input: .iob file ###
### output: .iob files ###

with open("../test.iob", "r", encoding="utf-8") as f:
    test_split = f.readlines()

very_low = list()
very_very_low = list()
low = list()
med = list()
high = list()
current = ""
counter = 0
counter_len = ""

for i in range(len(test_split)):
    if test_split[i] != "\n":
        current += test_split[i]
        counter += 1
    else:
        current += "\n"
        if counter <= 5:
            with open("test/test_very_very_low.iob", "a", encoding="utf-8") as f:
                f.write(current)

            current = current.split("\n")
            current = current[:-2]
            for j in range(len(current)):
                counter_len += current[j].split("\t")[0] + " "

            very_very_low.append(counter_len)
            current = ""
            counter_len = ""
            counter = 0

            continue
        if 5 < counter and counter <= 10:
            with open("test/test_very_low.iob", "a", encoding="utf-8") as f:
                f.write(current)

            current = current.split("\n")
            current = current[:-2]
            for j in range(len(current)):
                counter_len += current[j].split("\t")[0] + " "

            very_low.append(counter_len)
            current = ""
            counter_len = ""
            counter = 0

            continue
        if 10 < counter and counter <= 25:
            with open("test/test_low.iob", "a", encoding="utf-8") as f:
                f.write(current)

            current = current.split("\n")
            current = current[:-2]
            for j in range(len(current)):
                counter_len += current[j].split("\t")[0] + " "

            low.append(counter_len)
            current = ""
            counter_len = ""
            counter = 0

            continue
        if 25 < counter and counter <= 50:
            with open("test/test_med.iob", "a", encoding="utf-8") as f:
                f.write(current)

            current = current.split("\n")
            current = current[:-2]
            for j in range(len(current)):
                counter_len += current[j].split("\t")[0] + " "

            med.append(counter_len)
            current = ""
            counter_len = ""
            counter = 0

            continue
        if 50 < counter:
            with open("test/test_high.iob", "a", encoding="utf-8") as f:
                f.write(current)

            current = current.split("\n")
            current = current[:-2]
            for j in range(len(current)):
                counter_len += current[j].split("\t")[0] + " "

            high.append(counter_len)
            current = ""
            counter_len = ""
            counter = 0

            continue

print("very_very_low =>5", len(very_low))
print("5 < very_low <= 10", len(very_low))
print("10 < low <= 25 ", len(low))
print("25 < med <= 50 ", len(med))
print("high: 50< ", len(high))


#######################################################################
# Necessaria a instalacao do biopython (pip install biopython)
from Bio import pairwise2
from Bio.pairwise2 import format_alignment
from Bio.Seq import Seq

def alinhamento(seqt, numseq):
    nome1 = "guilherme"
    nome2 = "costa"
    nome3 = "oliveira"

    dicionario = {"q":1, "w":2, "e":3, "r":4, "t":5, "y":6, "u":7, "i":8, "o":9, "p":10, "á":11, "ã":12,
                "a":11, "s":9, "d":7, "f":5, "g":3, "h":1, "j":11, "k":9, "l":7, "ç":5, "é":3, "í":1,
                "z":2,  "x":4, "c":6, "v":8, "b":10, "n":12, "m":2, "ó":4, "õ":6, "ô":8, "ẫ":10, "ê":12}

    #Funcao para transformar o primeiro nome em numeros
    def converte(x):
        for l in dicionario:
            x = x.replace(l, str(dicionario[l]))
        return x

    nome1 = converte(nome1)     #O primeiro nome
    nome1 = int(nome1)
    resto1 = nome1 % 3

    if resto1 == 0:
        alpha = 1
        beta = 0
        delta = -1

    elif resto1 == 1:
        alpha = 2
        beta = 0
        delta = -1

    elif resto1 == 2:
        alpha = 1
        beta = 0
        delta = -2

    nome2 = converte(nome2)
    nome2 = int(nome2)              #O último nome
    pref_gap = nome2 % 3

    nome3 = converte(nome3)
    nome3 = int(nome3)             #O nome do meio
    gap_js = nome3 % 2

    score = 0
    scoreaux = 0
    count1 = 0
    count2 = 0

    n = numseq     # numero de sequencias
    k = 0
    scoretotal = 0

    while n > 0:
        if n == numseq:# eh reduzido 0.5 do score a cada gap consecutivo, ou seja, as sequencias com gaps separados podem ter maior score, assim cumprindo a condicao de que os gaps sejam separados
            alignments = pairwise2.align.globalms(seqt[k], seqt[k + 1], alpha, beta, delta, -0.5)
            for alignment in alignments:
                if count1 == 0:
                    seqt[k] = alignment.seqA
                    seqt[k + 1] = alignment.seqB
                    score = alignment.score
                    count1 = count1 + 1
                else:
                    if alignment.score >= score:
                        seqt[k] = alignment.seqA
                        seqt[k + 1] = alignment.seqB
                        score = alignment.score
            n = n - 2
            k = k + 1
            scoretotal = scoretotal + alignment.score
        else:
            alignments = pairwise2.align.globalms(seqt[k], seqt[k + 1], alpha, beta, delta, -0.5)
            for alignment in alignments:
                if count2 == 0:
                    seqt[k] = alignment.seqA
                    seqt[k + 1] = alignment.seqB
                    scoreaux = alignment.score
                    count2 = count2 + 1
                else:
                    if alignment.score >= scoreaux:
                        seqt[k] = alignment.seqA
                        seqt[k + 1] = alignment.seqB
                        scoreaux = alignment.score
            n = n - 2
            k = k + 1
            scoretotal = scoretotal + alignment.score
    scoretotal = "Score Total: " + str(scoretotal)
    seqt.append(scoretotal)
    return seqt


# -*- coding: utf-8 -*-
from django.template.loader import render_to_string
from django.contrib.admin.utils import quote

def get_mptt_admin_node_template(instance):
    '''
    Get MPTT admin node template name by model instance
    :param instance: instance of mptt model
    :return: template name
    '''
    return 'edw/admin/mptt/_%s_node.html' % instance.__class__.__name__.lower()

def mptt_admin_node_info_update_with_template(admin_instance, template, instance, node_info, context={}):
    '''
    Update MPTT admin node with rendered by html template node label.
    :param admin_instance: mptt admin instance
    :param template: template name for renfer
    :param instance: instance of mptt model
    :param node_info: jstree node info
    :param context: additional context for render
    :return: none
    '''

    pk_attname = admin_instance.model._meta.pk.attname
    pk = quote(getattr(instance, pk_attname))

    context.update({
        'instance': instance,
        'node_info': node_info,
        'app_label': instance._meta.app_label.lower()
    })

    label = render_to_string(template, context)

    node_info.update(
        url=admin_instance.get_admin_url('change', (quote(pk),)),
        move_url=admin_instance.get_admin_url('move', (quote(pk),)),
        label=label,
    )


import socket
import struct
import subprocess
import logging
from datetime import datetime

# Configuração do cliente
MULTICAST_IP = '224.0.0.1'
MULTICAST_PORT = 5004
CHUNK_SIZE = 1472  # Tamanho do pacote incluindo 4 bytes para o contador
CLIENT_INTERFACE_IP = '0.0.0.0'  # Use o IP de interface apropriado se necessário
PACKETS_RECEIVED = 0

# Configuração do logging
log_filename = datetime.now().strftime("cliente_%H%M%S.txt")
logging.basicConfig(filename=log_filename,
                    filemode='w',
                    level=logging.DEBUG,
                    format='CLIENTE - %(asctime)s - %(levelname)s - %(message)s')

# Criar um socket UDP
client_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
logging.info("Socket criado.")

# Permitir múltiplos clientes na mesma máquina (para fins de teste)
client_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
logging.info("Socket configurado para permitir múltiplos clientes.")

# Vincular ao endereço do servidor
client_sock.bind((CLIENT_INTERFACE_IP, MULTICAST_PORT))
logging.info(f"Socket vinculado a {CLIENT_INTERFACE_IP}:{MULTICAST_PORT}.")

# Dizer ao sistema operacional para adicionar o socket ao grupo multicast
group = socket.inet_aton(MULTICAST_IP) + socket.inet_aton(CLIENT_INTERFACE_IP)
client_sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, group)
logging.info(f"Socket adicionado ao grupo multicast {MULTICAST_IP}.")

# Inicializar contadores
expected_packet_counter = None
lost_packets = 0
out_of_order_packets = 0

# Preparar comando subprocess para VLC
vlc_command = "vlc -"  # O traço '-' diz ao VLC para aceitar entrada do stdin

# Iniciar VLC como um subprocesso
vlc_process = subprocess.Popen(["vlc", "fd://0"], stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
logging.info("Processo VLC iniciado.")
logging.info("Iniciando loop de recebimento de pacotes.")

try:
    while True:
        # Receber pacote
        data, address = client_sock.recvfrom(CHUNK_SIZE)

        # Verificar pacote "fim-de-stream"
        if data[4:] == b'END_OF_STREAM':
            PACKETS_RECEIVED += 1
            logging.info("Fim do stream detectado, redefinindo contador.")
            expected_packet_counter = None
            continue

        # Extrair contador de pacotes
        packet_counter, = struct.unpack('>I', data[:4])
        video_data = data[4:]

        # Se for o primeiro pacote ou se for o pacote esperado
        if expected_packet_counter is None or packet_counter == expected_packet_counter:
            PACKETS_RECEIVED += 1
            # Atualiza o contador esperado para o próximo pacote
            if expected_packet_counter is None:
                logging.info(f"Primeiro pacote recebido com contador {packet_counter}")
            expected_packet_counter = (packet_counter + 1) % (2 ** 32)
        else:
            if packet_counter < expected_packet_counter:
                PACKETS_RECEIVED += 1
                # Pacote fora de ordem
                out_of_order_packets += 1
                logging.warning(f"Pacote fora de ordem. Esperado: {expected_packet_counter}, Recebido: {packet_counter}")
            else:
                # Pacotes perdidos
                lost_packets += packet_counter - expected_packet_counter
                expected_packet_counter = (packet_counter + 1) % (2 ** 32)
                if lost_packets > 0:  # Registra apenas se houver pacotes perdidos
                    logging.warning(f"Pacotes perdidos. Esperado: {expected_packet_counter-1}, Recebido: {packet_counter}")

            # Definir o próximo contador de pacote esperado
            expected_packet_counter = (packet_counter + 1) % (2 ** 32)

        # Escrever os dados do vídeo no stdin do VLC
        vlc_process.stdin.write(video_data)

except KeyboardInterrupt:
    logging.info("Cliente encerrando por KeyboardInterrupt.")
    logging.info(f"Pacotes recebidos: {PACKETS_RECEIVED}")

finally:
    # Fechar processo VLC
    if vlc_process:
        vlc_process.terminate()
        logging.info("Processo VLC terminado.")

    # Fechar o socket
    client_sock.close()
    logging.info("Socket fechado.")

    # Logar estatísticas finais
    logging.info(f"Total de pacotes perdidos: {lost_packets}. Total de pacotes fora de ordem: {out_of_order_packets}.")


from fbchat import *
from fbchat.models import *
from Credentials import *
import json
import requests
import re
import os
import time
from threading import Thread
import socket

def finalVerification(url):
    if re.search("homework-help", url):
        return True
    return False

def question_id(url):
    try:
        ID = ""
        i = len(url) - 1
        while i > 0:
            if url[i] != "q":
                ID = url[i] + ID
            else:
                return "q" + ID
            i -= 1
    except Exception:
        return "QUESTION ID ERROR"

def verifyURL(url):
    try:
        response = requests.head(url)
        print(response.status_code)
        if response.status_code == 404:
            print("Bad website.")
            return False
        return True
    except Exception:
        print("Bad website")
        return False

def isAnswered(url):
    id = question_id(url)
    for root, dirs, files in os.walk("./screenshots"):
        for name in files:
            if name == id + ".png":
                return True
        return False

class CustomClient(Client):

    def onMessage(self, mid, author_id, message, message_object, thread_id, thread_type, ts, metadata, msg):
        global daily_limit, start_time

        def respond(text, msgType=None):
            if thread_type == thread_type.GROUP:
                if msgType is None:
                    self.send(Message(text=text), thread_id=thread_id, thread_type=thread_type)
                elif msgType == "IMAGE":
                    self.sendLocalImage(text, thread_id=thread_id, thread_type=thread_type)
            elif thread_type == thread_type.USER:
                if msgType is None:
                    self.send(Message(text=text), thread_id=author_id, thread_type=thread_type)
                elif msgType == "IMAGE":
                    self.sendLocalImage(text, thread_id=author_id, thread_type=thread_type)

        def collectPNG():
            global que_position, socket, recent_call
            que_position += 1
            print("Started a thread to collect {}".format(question_id(message)))
            respond("You have {} new questions left. Approximate retrieval time: {:.0F} seconds".format(daily_limit[author_id], que_position*10 + 1*max(0, 25-(time.time()-recent_call)) + (que_position-1)*25))

            while que_position-1 != 0 or time.time() - recent_call < 25:
                time.sleep(0.1)

            socket.sendto(message.encode(), ("127.0.0.1", 5000))
            recent_call = time.time()
            print("Request sent to AnswerMe")
            started = time.time()
            while time.time() - started < 15:
                if os.path.exists("./screenshots/" + question_id(message) + ".png"):
                    respond("./screenshots/" + question_id(message) + ".png", "IMAGE")
                    que_position -= 1
                    return
            respond("Error: Timed out.")

        if time.time() - start_time > 86400:
            start_time = time.time()
            daily_limit = {}
        print(message_object)
        if author_id != self.uid:
            if re.search("CHEGG", message):
                message = message.replace("CHEGG", "").strip()
                if verifyURL(message) and finalVerification(message):
                    respond("Your question {} is being processed.".format(question_id(message)))
                    if isAnswered(message):
                        respond("The question has been identified in Steve's data base.")
                        respond("./screenshots/" + question_id(message) + ".png", "IMAGE")
                    elif author_id in daily_limit and daily_limit[author_id] > 0 or author_id not in daily_limit:
                        if author_id not in daily_limit:
                            daily_limit[author_id] = 4
                        daily_limit[author_id] -= 1
                        Thread(target=collectPNG).start()
                    else:
                        respond(
                            "You have asked too many questions today. Please wait {:.2f} minute(s) to ask more questions!".format(
                                (86400 - (time.time() - start_time)) / 60))
                else:
                    respond("Invalid URL. Please type in a correct link.")

class MessengerBot:
    def __init__(self):
        self.client = None

    def login(self, username, password):
        if self.client is None:
            cookies = None
            try:
                with open("session.json") as file:
                    cookies = json.load(file)
                    print("Loading session cookies...")

            except FileNotFoundError:
                print("First time logging in...")

            self.client = CustomClient(username, password, session_cookies=cookies)
            print("Is logged in? {}".format(self.client.isLoggedIn()))

            if cookies is None:
                with open("session.json", "w") as file:
                    json.dump(self.client.getSession(), file)

    def listen(self):
        print("Listening")
        self.client.listen()

if __name__ == "__main__":
    while True:
        try:
            socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            que_position = 0
            start_time = time.time()
            recent_call = 0
            daily_limit = {}
            bot = MessengerBot()
            bot.login(username, passwd)
            bot.listen()
        except Exception:
            continue


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Mar 16 19:35:10 2020

@author: isaacparker
"""

#Load libraries
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd
from scipy.stats import lognorm, gaussian_kde

# Specify font used in plots
font = 'Adobe Myungjo Std'
math_font = 'cm'

import matplotlib as mpl
mpl.style.use('seaborn-white')
mpl.rcParams['font.family'] = font
mpl.rcParams['font.size'] = 18
mpl.rcParams['mathtext.fontset'] = 'cm'

#LOAD DATA
JV_exp = np.loadtxt('perov_JV_exp.txt',delimiter=',')
JV_exp = JV_exp

v_sweep = np.linspace (0,1.2,100)
power_exp= JV_exp[:,100*2:100*3]*v_sweep
eff_exp = np.max(power_exp, axis=1)/0.98

exp_condition = pd.read_excel('prcess_label.xlsx',index_col=0)
exp_condition = exp_condition.values

#Stack data and order
X_data = np.concatenate([eff_exp.reshape(-1,1), exp_condition],axis= 1)

p_index = []
X_data_re=[]
for i in [70,90,110,130]:
    for j in [2,4,8]:
        idx = np.intersect1d(np.where(X_data[:,1]==i) ,np.where(X_data[:,2]==j))
        X_data_re.append(X_data[idx,:])

X_data_re = np.vstack(X_data_re)

#Remove data to have same # of samples:
X_data_re = np.delete(X_data_re, [0,15,21,13,14,10,12,17,12,9,7,4], 0)
X_data_re = np.insert(X_data_re, 36, [3.88, 90, 2], axis=0)
X_data_re = np.delete(X_data_re, [106,107,108,96,110,112], 0)
X_data_re = np.insert(X_data_re, 143, [5.77, 130, 8], axis=0)

# Compute efficiency and normalize
df_X1 = pd.DataFrame(X_data_re, columns=['Efficiency','Temperature','Ratio'])

df_X = df_X1.copy()

max_eff = df_X['Efficiency'].max()

# Normalize
df_X['Efficiency'] = df_X['Efficiency'] / max_eff

# Get mean and variance for empirical distribution
X_mean = df_X['Efficiency'].mean()
eff_data = df_X['Efficiency']

log_norm_var = eff_data.std()

# Lognormal distribution histogram
np.random.seed(6)
logn = lognorm(s=1*log_norm_var, scale = 0.7*(1-X_mean))
sample = logn.rvs (size=500)
sample[sample>1]= 1
plt.figure()
plt.hist((1-sample)*20,50,
         density=True,
         edgecolor='white',
         linewidth=1.2,
         # color='mediumseagreen',
         # alpha=0.5)
         # color=(60/255, 110/255, 135/255, 0.8))
         color='k',
         alpha=0.5)
plt.xlabel(r'Solar Cell Efficiency $\eta$ [%]', size=18, fontname=font)
plt.ylabel(r'Probability $p(\eta)$', size=18, fontname=font)
plt.xlim(left=0, right=20)
plt.yticks(np.arange(0, 0.25, step=0.1))

density = gaussian_kde((1-sample)*20)
xs = np.linspace(0,20,50)
density.covariance_factor = lambda : 1*log_norm_var
density._compute_covariance()
plt.plot(xs,density(xs),
         # color=(60/255, 110/255, 135/255))
         # color='mediumseagreen')
         color='k')
plt.tight_layout()
plt.savefig('Fig1.png',dpi=300)
plt.show()


import news_parser as Util
import datetime
import time
import DBHandler
from tensorflow.keras.models import load_model
import predict
CompanyList=[]
Headless = True # False : 창띄움, True : 창없음
MakeCompanyList = False # 회사 리스트 갱신
host = '데이터베이스 주소'
ID= '계정명'
PW='비밀번호'
DB_name='DB이름'

def GetNewsInfo(driver):
    headlines, news_info, Text,NewsUrl = Util.GetNews(driver) # 헤드라인, 신문사 정보 및 게시 시간, 본문, 기사링크 파싱.
    CompanyFromNews = Util.GetCompanyFromNews(headlines, CompanyList)
    #Util.save_headlines(headlines, news_info, Text,CompanyFromNews,NewsUrl)
    #Util.PrintNews(headlines, news_info, Text, CompanyFromNews)
    return headlines, news_info, Text, NewsUrl,CompanyFromNews

def GetPriceInfo(driver):
    NameList, PriceInfo, Fluctuation = Util.get_prices(driver) #KTOP 30, KOSPI, KOSPI200, KOSDAQ, KOSDAQ150, KRX300 순
    Util.PrintPrice(NameList, PriceInfo, Fluctuation)
    return NameList, PriceInfo, Fluctuation

def MakeCompanyFile(MakeCompanyList):
    #Company CSV파일 생성
    Util.MakeCompanyCSV()

if __name__ == '__main__':
    print("Setting Interface...")
    CompanyList = Util.GetCompanyList() # 코스피 상장 기업 업로드
    try: #네이버 증권
        NewsDriver = Util.News_get_driver(Headless)
    except Exception as ex:
        print("News Driver Err")
        print('에러가 발생 했습니다', ex)
    try : #한국거래소
         PriceDriver = Util.NowPriceDriver(Headless)
    except Exception as ex:
         print("Price Driver Err")
         print('에러가 발생 했습니다', ex)
    try: # 다음 증권
        KospiImageDriver = Util.Get_KospiGraphDriver(Headless)
    except Exception as ex:
        print("KospiImage Driver Err")
        print('에러가 발생 했습니다', ex)
    MakeCompanyFile(MakeCompanyList) #기업 리스트 갱신
    DBController = DBHandler.MySqlController(host, ID, PW, DB_name)

    label=[]
    while(True):
            now = datetime.datetime.now()
            nowDatetime = now.strftime('%Y_%m_%d_%H시%M분%S초'.encode('unicode-escape').decode()).encode().decode('unicode-escape')
            nowDatehour = now.strftime('%Y_%m_%d_%H시%M분'.encode('unicode-escape').decode()).encode().decode('unicode-escape')
            try:
                NameList, PriceInfo, Fluctuation = Util.get_prices(PriceDriver)
                Util.PrintPrice(NameList,PriceInfo,Fluctuation)
                DBController.update_totalprice(PriceInfo,Fluctuation)
            except Exception as ex:
                print("Price Info Err")
                print('에러가 발생 했습니다', ex)
                PriceDriver.quit()
                PriceDriver = Util.NowPriceDriver(Headless)
                NameList, PriceInfo, Fluctuation = Util.get_prices(PriceDriver)
            # print("========================================")
            try:
                headlines, news_info, Text,NewsUrl,CompanyFromNews = GetNewsInfo(NewsDriver) #뉴스에서 기업 추출
                print("News Updated...")
            except Exception as ex:
                print("News Update Err")
                NewsDriver.quit()
                NewsDriver = Util.News_get_driver(Headless)
                print('에러가 발생 했습니다', ex)
            try:
                Util.Write_News(headlines, CompanyFromNews, nowDatehour)  # 기업별 뉴스 자료 Writing
            except Exception as ex:
                print("News Write Err")
                CompanyList = Util.GetCompanyList()  # 코스피 상장 기업 업로드
            try:
                Util.GetKospiGraph(KospiImageDriver, PriceInfo, Fluctuation) # Kospi, Kosdaq 그래프 이미지 저장
                print("Get Kospi Graph")
            except Exception as ex:
                KospiImageDriver.quit()
                KospiImageDriver = Util.Get_KospiGraphDriver(Headless)
                print("Graph Err")
                print('에러가 발생 했습니다', ex)
            try:
                label = predict.classification(headlines, model)
                print("Get labels")
                DBController.UpdateNews(CompanyFromNews, headlines, Text, NewsUrl, news_info, label)  # 최신 20개 기사 DB저장
                DBController.InsertNewsHistory(CompanyFromNews, headlines, Text, NewsUrl, news_info, nowDatehour)
                print("DB Commit : News Updated, News History Inserted")
            except Exception as ex:
                print("Label Err")
                MakeCompanyFile(MakeCompanyList)  # 기업 리스트 갱신
                DBController = DBHandler.MySqlController(host, ID, PW, DB_name)
                print('에러가 발생 했습니다', ex)
            time.sleep(30)
            NewsDriver.refresh()
            PriceDriver.refresh()
            KospiImageDriver.refresh()
            print("DONE")


import numpy as np
import pytest

from gym.spaces import Box, Discrete
from gym.wrappers import AtariPreprocessing, StepAPICompatibility
from tests.testing_env import GenericTestEnv, old_step_fn

class AleTesting:
    """A testing implementation for the ALE object in atari games."""

    grayscale_obs_space = Box(low=0, high=255, shape=(210, 160), dtype=np.uint8, seed=1)
    rgb_obs_space = Box(low=0, high=255, shape=(210, 160, 3), dtype=np.uint8, seed=1)

    def lives(self) -> int:
        """Returns the number of lives in the atari game."""
        return 1

    def getScreenGrayscale(self, buffer: np.ndarray):
        """Updates the buffer with a random grayscale observation."""
        buffer[...] = self.grayscale_obs_space.sample()

    def getScreenRGB(self, buffer: np.ndarray):
        """Updates the buffer with a random rgb observation."""
        buffer[...] = self.rgb_obs_space.sample()

class AtariTestingEnv(GenericTestEnv):
    """A testing environment to replicate the atari (ale-py) environments."""

    def __init__(self):
        super().__init__(
            observation_space=Box(
                low=0, high=255, shape=(210, 160, 3), dtype=np.uint8, seed=1
            ),
            action_space=Discrete(3, seed=1),
            step_fn=old_step_fn,
        )
        self.ale = AleTesting()

    def get_action_meanings(self):
        """Returns the meanings of each of the actions available to the agent. First index must be 'NOOP'."""
        return ["NOOP", "UP", "DOWN"]

@pytest.mark.parametrize(
    "env, obs_shape",
    [
        (AtariTestingEnv(), (210, 160, 3)),
        (
            AtariPreprocessing(
                StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
                screen_size=84,
                grayscale_obs=True,
                frame_skip=1,
                noop_max=0,
            ),
            (84, 84),
        ),
        (
            AtariPreprocessing(
                StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
                screen_size=84,
                grayscale_obs=False,
                frame_skip=1,
                noop_max=0,
            ),
            (84, 84, 3),
        ),
        (
            AtariPreprocessing(
                StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
                screen_size=84,
                grayscale_obs=True,
                frame_skip=1,
                noop_max=0,
                grayscale_newaxis=True,
            ),
            (84, 84, 1),
        ),
    ],
)
def test_atari_preprocessing_grayscale(env, obs_shape):
    assert env.observation_space.shape == obs_shape

    # It is not possible to test the outputs as we are not using actual observations.
    # todo: update when ale-py is compatible with the ci

    env = StepAPICompatibility(
        env, output_truncation_bool=True
    )  # using compatibility wrapper since ale-py uses old step API

    obs, _ = env.reset(seed=0)
    assert obs in env.observation_space

    obs, _, _, _, _ = env.step(env.action_space.sample())
    assert obs in env.observation_space

    env.close()

@pytest.mark.parametrize("grayscale", [True, False])
@pytest.mark.parametrize("scaled", [True, False])
def test_atari_preprocessing_scale(grayscale, scaled, max_test_steps=10):
    # arbitrarily chosen number for stepping into env. and ensuring all observations are in the required range
    env = AtariPreprocessing(
        StepAPICompatibility(AtariTestingEnv(), output_truncation_bool=True),
        screen_size=84,
        grayscale_obs=grayscale,
        scale_obs=scaled,
        frame_skip=1,
        noop_max=0,
    )

    obs, _ = env.reset()

    max_obs = 1 if scaled else 255
    assert np.all(0 <= obs) and np.all(obs <= max_obs)

    terminated, truncated, step_i = False, False, 0
    while not (terminated or truncated) and step_i <= max_test_steps:
        obs, _, terminated, truncated, _ = env.step(env.action_space.sample())
        assert np.all(0 <= obs) and np.all(obs <= max_obs)

        step_i += 1
    env.close()


def osm_vs_imd(osmxlsx, osmxml, imd, outfishnet, outshp):

    #Create a fishnet use raster file
    while imd:

        osm_ref_tags = {

            "TABLE"     : osmxlsx,
            "SHEET"     : 'osm_features',
            "LULC_COL"  : 'L4',
            "KEY_COL"   : "key",
            "VALUE_COL" : "value",
            "GEOM_COL"  : "geom"
            }

        osmdata = {
            "FILE"  : osmxml,
            "DB"    : 'dgt_cmb',
            "TABLE" : "multipolygons",
            "DBSET" : "local"
            }

        ref_edificado = [
            '1151', '1221',
            '1222', '1223', '1231', '1241',
            '1251', '1252', '1254', '1255',
            '1257', '1253', '1612',
            '1631', '1632', '1633', '1651',
            '16', '143', '1431', '1432'
            ]

        lulccls = 'lulc_cls'

        epsg = 3763

        import os

        from glass.it.osm import osm_to_psql

        from glass.prop.sql import cols_name
        from glass.rd import tbl_to_obj
        from glass.sql.db import create_pgdb
        from glass.pys.oss import mkdir

        # Prepare workspace
        ws = mkdir(os.path.join(
            os.path.dirname(outshp), 'grswork'
        ), overwrite=True)

    #when have data in the workspace, for don't run all code again

    #ws = os.path.join(os.path.dirname(outshp), 'grswork')

    # Import data into a database
        create_pgdb(osmdata["DB"], overwrite=True, dbset=osmdata["DBSET"])

        osm_to_psql(osmdata["FILE"], osmdata["DB"])

        osm_tags = tbl_to_obj(osm_ref_tags["TABLE"], sheet=osm_ref_tags["SHEET"])

        osm_tags = osm_tags[osm_tags[osm_ref_tags["GEOM_COL"]] == 'Polygon']

        osm_tags['sevtags'] = osm_tags[osm_ref_tags["LULC_COL"]].str.contains(';')

        osm_tags = osm_tags[osm_tags.sevtags != True]

    # Create key/value column
        osm_tags.loc[:, osm_ref_tags["VALUE_COL"]] = osmdata["TABLE"] + "." + \
            osm_tags[osm_ref_tags["KEY_COL"]] + \
            "='" + osm_tags[osm_ref_tags["VALUE_COL"]] + "'"

    # Add new column to multipolygons table
    # Update it adding an LULC class

        cols = cols_name(osmdata["DB"], osmdata['TABLE'], dbset=osmdata["DBSET"])

        qs = [] if "lulc_cls" in cols else [(
            f"ALTER TABLE {osmdata['TABLE']} ADD COLUMN "
            "lulc_cls integer"
        )]

        for cls in osm_tags[osm_ref_tags["LULC_COL"]].unique():
    # Se uma feature estiver associada a duas TAGS que dizem respeito a classes
    # diferentes, a classe da feature será a última classe considerada
    # Abordagem multitag vai resolver este problema.
            __osmtags = osm_tags[osm_tags[osm_ref_tags["LULC_COL"]] == cls]

            qs.append((
                f"UPDATE {osmdata['TABLE']} SET lulc_cls={str(cls)} "
                f"WHERE {str(__osmtags[osm_ref_tags['VALUE_COL']].str.cat(sep=' OR '))}"
            ))

        cols = cols_name(osmdata["DB"], osmdata['TABLE'], dbset=osmdata["DBSET"])
        print(cols)


import cv2
import numpy as np
import glob
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import numpy as np
from time import sleep

dis_test_label = np.load("D:/PythonFile/NestProject/Nest_Model/pos_process/test_data/dis_test_data_complex_exp_shuffle_3.npy")
dis_test_predict = np.load('D:/PythonFile/NestProject/Nest_Model/pos_process/prediction_data/predict_data_complex_exp_shuffle_3.npy')

dis_train_label = np.load("D:/NestData/3tx-32chirp-jaco-55times_all/data_usage/radar_pos_label_deleted.npy")
dis_train_predict = np.load('D:/PythonFile/NestProject/Nest_Model/pos_process/prediction_data/predict_data_complex_exp_shuffle_4(train).npy')

# dis_label = np.concatenate((label1, label2))
print(dis_train_label.shape, dis_test_predict.shape)

app = QtGui.QApplication([])
w = gl.GLViewWidget()
w.show()
g = gl.GLGridItem()
w.addItem(g)

colors_1 = [1.0,0,0,0.5]
colors_2 = [0,1.0,0,0.5]

# dis_test_predict = dis_test_predict[:,0,:]

dis_test_label = dis_test_label/100
dis_test_predict = dis_test_predict/100
dis_train_label = dis_train_label/100
dis_train_predict = dis_train_predict/100
dis_train_label = dis_train_label[:500]

# dis_test_label = dis_test_label[:,1:3]
# dis_predict = dis_predict[:,1:3]
# print(dis_test_label.shape)

# sp0 = gl.GLScatterPlotItem(pos=dis_test_label[:], color=colors_1)
# w.addItem(sp0)

# sp1 = gl.GLScatterPlotItem(pos=dis_test_predict[:])
# w.addItem(sp1)

sp2 = gl.GLScatterPlotItem(pos=dis_train_label[:], color=colors_2)
w.addItem(sp2)

# sp3 = gl.GLScatterPlotItem(pos=dis_train_predict[:])
# w.addItem(sp3)

# i = 0
# def update():

#     global i

#     sp2 = gl.GLScatterPlotItem(pos=dis_train_label[i], color=colors_1)
#     w.addItem(sp2)

#     # sp3 = gl.GLScatterPlotItem(pos=dis_test_predict[i])
#     # w.addItem(sp3)
#     print(i)
#     i += 1

# time = QtCore.QTimer()
# time.timeout.connect(update)
# time.start(5)

if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()


# This is a sample Python script.

#########################################: Please Don't Change :#######################################
import logging
import os
import sys
from datetime import datetime

sys.path.append(
    "/home/sonu/workspace/pro/component/"
)
sys.path.append(
    "/home/sonu/workspace/pro/utils/"
)
sys.path.append(
    "/home/sonu/workspace/pro/db_conn/"
)
from common import get_logger
from db_conn import DatabaseConnection

def log_setup():
    """This funtion is require for log_confi.yaml file."""
    path = os.path.dirname(os.path.realpath(__file__))
    log_dir = os.path.join(path, "log")
    os.makedirs(log_dir, exist_ok=True)
    log_path = os.path.join(path, log_dir, "running_log.log")
    filelog = logging.handlers.TimedRotatingFileHandler(
        log_path, when="midnight", backupCount=5
    )
    return filelog

#########################################: Please Code write Below :#######################################

STAGE_01 = "Connection Establish"
STAGE_02 = ""
STAGE_03 = ""
STAGE_04 = ""

def main():
    logger = get_logger(logger_name="sample")
    logger.info("main logging initialized")
    try:
        start_time = datetime.now()
        logger.info(f"<<<<<<< The start of {STAGE_01} has begun. >>>>>>>")
        database_connection = DatabaseConnection()
        snowflake_connection = database_connection.get_snowflake_connection()
        logger.info(f"<<<<<<< {STAGE_01} has been completed. >>>>>>>")

        cux = snowflake_connection.cursor()
        cux.execute("select current_timestamp();")
        result = cux.fetchone()
        logger.info(f"test connection succeed at {str(result)}")

        end_time = datetime.now()
        logger.info(
            "The project has been successfully executed, with a runtime of {0}.".format(
                end_time - start_time
            )
        )

    except Exception as e:
        logger.exception(f"getting error message {str(e)}")

if __name__ == "__main__":
    main()


#!/usr/bin/env python3
from sys import stderr, stdout
from os import environ
from random import randrange, randint

from tc import TC

from triangolo_lib import Triangolo

############## TESTCASES' PARAMETERS ############################
TL = 1   # the time limit for each testcase

MAPPER = {"tiny": 1, "small": 2, "medium": 3, "big": 4}
DATA = ((10, (5, 7)), (10, (8, 10)), (10, (25, 28)), (70, (30, 40)))
# that is, 10 instances of size "tiny", i.e., with 5 <= n <= 6
#################################################################

def gen_tc(min_n, max_n):
    n = randint(min_n, max_n)
    Tr = Triangolo([[randint(0, 9) for j in range(i+1)] for i in range(n)])
    Tr.display(stdout)
    rnk = randrange(Tr.num_opt_sols_ric_memo())
    print(rnk)
    return (Tr, rnk)

def check_tc(Tr, rnk):
    risp_val = int(input())
    risp_sol = input().strip()
    ok, rank_of_risp = Tr.rank_unsafe(risp_sol, risp_val)
    if not ok:
        return False, rank_of_risp
    if rank_of_risp != rnk:
        return False, f"On input:\n{Tr.n} {rnk}\n{Tr.as_str(with_n = False)}\nyou were right in stating that the optimum value of a solution is {risp_val}. However, you then returned the optimal solution:\n{risp_sol}\nwhich is of rank {rank_of_risp}. Instead, the optimal solution of rank {rnk}, as required, was:\n{Tr.unrank_safe(rnk)}"
    return True

if __name__ == "__main__":
    size = MAPPER[environ["TAL_size"]]
    tc = TC(DATA[:size], TL)
    tc.run(gen_tc, check_tc)


import pygame, sys #기본세팅
import random, time #내가 추가한 것
from pygame.locals import *

#Set up pygame.
pygame.init()

#상수 정의
SCREEN =8

BLACK = (0,0,0)
GREEN = (0, 128, 0)
WHITE = (255, 255, 255)
BLUE = (0,0,255)
RED = (255,0,0)
YELLOW = (255,204,51)

screen = pygame.display.set_mode((600,400), 0,32)
pygame.display.set_caption("Othello")

#화면 세팅
screen.fill(GREEN)

#가로 줄 긋기
for x in range(0, 8):
    if x==0:
        continue
    else:
        pygame.draw.line(screen, BLACK, [0,x*50],[400,x*50],5)

#세로 줄 긋기
for y in range(0,9):
    if y==0:
        continue
    else:
        pygame.draw.line(screen, BLACK, [y*50,0],[y*50,400],5)

#오른쪽에 상태창 만들기
pygame.draw.rect(screen, WHITE, [403,0,200,400])

#각 위치에서의 블럭값들 초기화
screenArr = [] #리스트 안에 리스트. 열을 나누기 위함.

for y in range(0,SCREEN):
    colList =[]
    for x in range(0,SCREEN):
        colList.append(0)

    screenArr.append(colList)

screenArr[3][3]=2
screenArr[3][4]=1
screenArr[4][3]=1
screenArr[4][4]=2

#변수
currentTurn =1 #현재 턴- 플레이어 :1 컴퓨터 :2

diagnoalScreenArr =[] #대각선 검사를 위한 변수, 3차원 배열

for i in range(0,4):
    rowList =[]
    for y in range(0,SCREEN):
        colList =[]
        for x in range(0,SCREEN):
            colList.append(0)

        rowList.append(colList)

    diagnoalScreenArr.append(rowList)

#함수
def changeTurn(pTurn):
    if pTurn ==1: #플레이어의 턴을 컴퓨터의 턴으로 전환
        return 2
    elif pTurn ==2:
        return 1
    else:
        return -1 #오류인 경우

def changeArrxToX(arrx): #x, y를 arrx, arry로 바꿔서 리턴.
    for x in range(0,SCREEN):
        if arrx==x:
            return 25*(arrx*2+1)

def changeArryToY(arry):
    for y in range(0,SCREEN):
        if arry ==y:
            return 25*(arry*2+1)

def viewGameScreen(): #screen이 해당 값들을 가지면 해당 블럭 출력
    for arry in range(0,SCREEN):
        for arrx in range(0,SCREEN):
            if screenArr[arry][arrx] ==1: #플레이어
                pygame.draw.circle(screen, BLACK, [changeArrxToX(arrx),changeArryToY(arry)], 20)
            elif screenArr[arry][arrx] ==2: #컴퓨터
                pygame.draw.circle(screen, WHITE, [changeArrxToX(arrx),changeArryToY(arry)], 20)
            elif screenArr[arry][arrx] ==3: #컴퓨터의 블럭 랜덤위치
                pygame.draw.circle(screen, BLUE, [changeArrxToX(arrx),changeArryToY(arry)], 20)
            elif screenArr[arry][arrx] ==4: #게임이 끝난후 빈 공간이 있을 때 사용
                pygame.draw.circle(screen, GREEN, [changeArrxToX(arrx),changeArryToY(arry)], 20)

def changeMousePosXToArrx(mousePosX):
    for i in range(0,SCREEN):
        if mousePosX < 50 * (i+1) -5 and mousePosX > 50*i +5:
            return i
    else:
        return -1 #오류일 경우

def changeMousePosYToArry(mousePosY):
    for i in range(0,SCREEN):
        if mousePosY < 50 * (i+1) -5 and mousePosY > 50*i +5: #경계 안쪽
            return i
    else: #화면의 검은색 경계 부분
        return -1 #오류일 경우

def checkIfTherisBlock(pScreenArr): #해당 자리에 블럭이 현재 있는지 없는지
    #iScreenArr : screenArr을 매개변수로 받아야하는데 헷갈릴까봐
    #parameter에서 p를 따옴
    if pScreenArr == 1 or pScreenArr ==2: #플레이어 또는 컴퓨터의 블럭
        return 1 #블럭이 이미 있음을 리턴
    else:
        return 0 #블럭이 해당자리에 없음을 리턴

def setDiagonalCnt(): #대각선 검사를 위해 미리 대각선 개수 설정

    #왼쪽 위 방향 대각선
    diagonalDir =0

    for row in range(0,SCREEN):
        for col in range(7, row-1,-1):
            diagnoalScreenArr[diagonalDir][row][col]=row

        remainingCol = row
        num =0

        for col in range(0, remainingCol):
            diagnoalScreenArr[diagonalDir][row][col] = num
            num=num+1

    #오른쪽 위 방향 대각선
    diagonalDir =1

    for row in range(0,SCREEN):
        for col in range(0, SCREEN-row):
            diagnoalScreenArr[diagonalDir][row][col]=row

        remainingCol = 7 -row
        num =row

        for col in range(remainingCol, SCREEN):
            diagnoalScreenArr[diagonalDir][row][col] = num
            num = num-1

    #왼쪽 아래 방향 대각선
    diagonalDir =2

    for row in range(7, -1, -1):
        for col in range(7, 6-row, -1):
            diagnoalScreenArr[diagonalDir][row][col] = 7-row

        remainingCol = 7-row
        num =0

        for col in range(0, remainingCol):
            diagnoalScreenArr[diagonalDir][row][col] = num
            num = num+1

    #오른쪽 아래 대각선 개수
    diagonalDir =3

    for row in range(7, -1, -1):
        for col in range(0, 1+row):
            diagnoalScreenArr[diagonalDir][row][col] =7-row

        remainingCol = row+1
        num = 6-row

        for col in range(remainingCol, SCREEN):
            diagnoalScreenArr[diagonalDir][row][col] = num
            num = num-1

#setDiagonalCnt()함수 시각적 확인
##setDiagonalCnt()
##for x in range(0,8):
##    print(diagnoalScreenArr[0][x])

def InspectIfItCanBePlacedInPlace(pArrx, pArry, changeValue, pCurrentTurn): #해당 위치에 블럭을 놓을 수 있는 자리인지 검사
    returnValue=0

    if 1==checkIfTherisBlock(screenArr[pArry][pArrx]):
        return 0

    #대각선 검사
    for diagonalValue in range(0,4):
        if diagnoalScreenArr[diagonalValue][pArry][pArrx] != 0:

            if diagonalValue==0: #왼쪽 위방향
                if screenArr[pArry-1][pArrx-1] == changeTurn(pCurrentTurn):
                    for a in range(1, diagnoalScreenArr[diagonalValue][pArry][pArrx]+1):
                        if screenArr[pArry-a][pArrx-a]==0:
                            break
                        elif screenArr[pArry-a][pArrx-a] ==pCurrentTurn:
                            for b in range(1, a):
                                if changeValue ==True:
                                    screenArr[pArry-b][pArrx-b] =pCurrentTurn
                            returnValue =1
                            break

            if diagonalValue ==1: #오른쪽 위 방향
                if screenArr[pArry-1][pArrx+1] == changeTurn(pCurrentTurn):
                    for a in range(1, diagnoalScreenArr[diagonalValue][pArry][pArrx]+1):
                        if screenArr[pArry-a][pArrx+a]==0:
                            break
                        elif screenArr[pArry-a][pArrx+a]==pCurrentTurn:
                            for b in range(1, a):
                                if changeValue ==True:
                                    screenArr[pArry-b][pArrx+b]=pCurrentTurn
                            returnValue =1
                            break

            if diagonalValue ==2: #왼쪽 아래 방향
                if screenArr[pArry+1][pArrx-1] == changeTurn(pCurrentTurn):
                    for a in range(1, diagnoalScreenArr[diagonalValue][pArry][pArrx]+1):
                        if screenArr[pArry+a][pArrx-a]==0:
                            break
                        elif screenArr[pArry+a][pArrx-a]==pCurrentTurn:
                            for b in range(1, a):
                                if changeValue ==True:
                                    screenArr[pArry+b][pArrx-b]=pCurrentTurn
                            returnValue =1
                            break

            if diagonalValue ==3: #오른쪽 아래 방향
                if screenArr[pArry+1][pArrx+1] == changeTurn(pCurrentTurn):
                    for a in range(1, diagnoalScreenArr[diagonalValue][pArry][pArrx]+1):
                        if screenArr[pArry+a][pArrx+a]==0:
                            break
                        elif screenArr[pArry+a][pArrx+a]==pCurrentTurn:
                            for b in range(1, a):
                                if changeValue ==True:
                                    screenArr[pArry+b][pArrx+b]=pCurrentTurn
                            returnValue =1
                            break

    #행 검사 - 위 방향으로 검사
    if pArry != 0: #pArry가 0이면 검사할 때 리스트 인덱스 넘어감
        if screenArr[pArry-1][pArrx] == changeTurn(pCurrentTurn):
            for a in range(pArry-1, -1, -1):
                if screenArr[a][pArrx] ==0:
                    break
                elif screenArr[a][pArrx] ==pCurrentTurn:
                    for b in range(pArry-1, a,-1):
                        if changeValue ==True:
                            screenArr[b][pArrx] =pCurrentTurn
                    returnValue =1
                    break

    #행 검사 - 아래  방향으로 검사
    if pArry != SCREEN-1:
        if screenArr[pArry+1][pArrx] == changeTurn(pCurrentTurn):
            for a in range(pArry+1, SCREEN):
                if screenArr[a][pArrx] ==0:
                    break
                elif screenArr[a][pArrx]==pCurrentTurn:
                    for b in range(pArry+1, a):
                        if changeValue ==True:
                            screenArr[b][pArrx]=pCurrentTurn
                    returnValue =1
                    break

    #열 검사 - 왼쪽 방향으로 검사
    if pArrx !=0:
        if screenArr[pArry][pArrx-1] == changeTurn(pCurrentTurn):
            for a in range(pArrx-1, -1,-1):
                if screenArr[pArry][a] ==0:
                    break
                elif screenArr[pArry][a] ==pCurrentTurn:
                    for b in range(pArrx-1, a, -1):
                        if changeValue ==True:
                            screenArr[pArry][b] =pCurrentTurn
                    returnValue =1
                    break

    #열 검사 - 오른쪽 방향으로 검사
    if pArrx != SCREEN-1:
        if screenArr[pArry][pArrx+1] == changeTurn(pCurrentTurn):
            for a in range(pArrx+1, SCREEN):
                if screenArr[pArry][a] ==0:
                    break
                elif screenArr[pArry][a] ==pCurrentTurn:
                    for b in range(pArrx+1, a):
                        if changeValue ==True:
                            screenArr[pArry][b] =pCurrentTurn
                    returnValue =1
                    break

    return returnValue #놓을 수 있는 곳이  없을 경우:0   있을 경우 :1

def calculateComputerRandomPlace(randomComputerNum): #컴퓨터가 놓는 위치 랜덤으로 계산
    randNum=0
    randNum = random.randrange(1, randomComputerNum+1)
    return randNum

def setWhereComputerCanPutBlock():
    randomComputerNum =1
    tmpRow=-1
    tmpCol=-1
    noMeaningStorage=0
    computerRandomPlace =[]

    #computerRandomPlace 모두 0으로 초기화(8x8 2차원 배열)
    for y in range(0,SCREEN):
        colList =[]
        for x in range(0,SCREEN):
            colList.append(0)

        computerRandomPlace.append(colList)

    for row in range(0, SCREEN):
        for col in range(0,SCREEN):
            if InspectIfItCanBePlacedInPlace(col, row, False, currentTurn) ==1:
                computerRandomPlace[row][col] = randomComputerNum
                randomComputerNum = randomComputerNum +1

    randomComputerNum = calculateComputerRandomPlace(randomComputerNum-1) #-1하는 이유 맨 마지막에 +1돼서 끝나기 때문

    for row in range(0,SCREEN):
        for col in range(0,SCREEN):
            if computerRandomPlace[row][col] == randomComputerNum:
                screenArr[row][col] =3 #컴퓨터가 랜덤으로 놓을위치 파랑색으로 설정
                tmpRow = row
                tmpCol = col

    #컴퓨터가 랜덤으로 놓을 위치 미리 보여주기
    viewGameScreen()
    pygame.display.update()

    #해당 위치 원래 컴퓨터 블럭색으로 변경
    time.sleep(2)
    noMeaningStorage = InspectIfItCanBePlacedInPlace(tmpCol, tmpRow, True, currentTurn)
    screenArr[tmpRow][tmpCol] = 2 #컴퓨터가 랜덤으로 놓을위치 원래색인 하얀색으로 변경

    viewGameScreen()
    pygame.display.update()

def moveNextTurnWhenBlockCanNotPutPlace(): #둘 곳이 없을 경우 다음턴으로 넘어간다.
    global currentTurn
    global isClick
    cannotPutPlaceCnt =0

    for row in range(0,SCREEN):
        for col in range(0,SCREEN):
            if screenArr[row][col] == 0:
                if InspectIfItCanBePlacedInPlace(col,row,False, currentTurn)==1:
                    cannotPutPlaceCnt = cannotPutPlaceCnt+1

    if cannotPutPlaceCnt ==0 :
        currentTurn = changeTurn(currentTurn)
        print(currentTurn,"의 유저가 놓을 곳이 없습니다. ")
        clearStateScreen(False)
        printTurnInformation() #플레이어 -> 컴퓨터 턴 : 컴퓨터 턴 출력
        time.sleep(1)

def viewGameResult():
    font = pygame.font.SysFont("arial",20,True)
    playerBlockCnt =0
    computerBlockCnt =0

    for row in range(0,SCREEN):
        for col in range(0,SCREEN):
            if screenArr[row][col] ==1:
                playerBlockCnt = playerBlockCnt+1
            elif screenArr[row][col] ==2:
                computerBlockCnt = computerBlockCnt+1
            screenArr[row][col] = 4

    tmpBlockCnt =0
    isFirstCheck = False

    for row in range(0,SCREEN):
        for col in range(0,SCREEN):
            if (tmpBlockCnt < playerBlockCnt) and isFirstCheck == False:
                screenArr[row][col] =1
                tmpBlockCnt = tmpBlockCnt+1
            else:
                if isFirstCheck == False:
                    isFirstCheck = True
                    tmpBlockCnt =0
                if tmpBlockCnt < computerBlockCnt:
                    screenArr[row][col] =2
                    tmpBlockCnt = tmpBlockCnt+1

    print("컴퓨터 블럭 개수 : ", computerBlockCnt)
    print("플레이어 블럭 개수 : ", playerBlockCnt)
    print("tmpBlockCnt : ", tmpBlockCnt)

    clearStateScreen(True)

    if computerBlockCnt < playerBlockCnt:
        printWinner("Player")
    elif computerBlockCnt > playerBlockCnt:
        printWinner("Computer")
    else: #동점
        printWinner("Draw")

    viewGameScreen()
    printBlockCnt(playerBlockCnt, computerBlockCnt)
    pygame.display.update()
    print("개수 출력화면까지 끝")
    time.sleep(3)
    #이후 다시 게임을 다시할지 시작화면으로갈지 끌지 선택.
    sys.exit()

def ifNoOneDoNotPutBlock():
    enablePutBlock= [True,True]

    for row in range(0,SCREEN):
        for col in range(0,SCREEN):
            #플레이어 검사와 검퓨터 모두 블럭을 둘 곳이 없을 경우
            if 1==InspectIfItCanBePlacedInPlace(col,row,False,1):
                #print("플레이어 : (",row,col,") : 0")
                enablePutBlock[0] = False
            if 1==InspectIfItCanBePlacedInPlace(col,row,False,2):
                #print("컴퓨터   : (",row,col,") : 0")
                enablePutBlock[1] = False

    if enablePutBlock[0] ==True and enablePutBlock[1] ==True:
        return True
    else:
        return False

def checkGameOver():
    spaceFilledCnt =0

    for row in range(0,SCREEN):
        for col in range(0,SCREEN):
            if screenArr[row][col] ==1 or screenArr[row][col] ==2:
                spaceFilledCnt= spaceFilledCnt+1

    if spaceFilledCnt == SCREEN * SCREEN or ifNoOneDoNotPutBlock() == True:
        clearStateScreen(True)
        printGameOverText()
        printCalculateGameResult()
        time.sleep(5) #결과 집계중 5초동안 띄운 뒤 결과 보여주기
        viewGameResult()

def printTurn(pTurn):
    if pTurn ==1:
        return "Player"
    elif pTurn ==2:
        return "Computer"
    else:
        return "Error"

def clearStateScreen(isGameOver):
    clearScreenScaleY =145

    if isGameOver == True:
        clearScreenScaleY = 400

    pygame.draw.rect(screen, WHITE, [403,0,200,clearScreenScaleY])
    pygame.display.update()

def printTurnInformation():
    userTextFont = pygame.font.SysFont("arial",20, True)
    userTextContentFont = pygame.font.SysFont("arial",20)

    userText = userTextFont.render("Current Turn : ", True, BLACK)
    userTextContent = userTextContentFont.render(printTurn(currentTurn), True, BLACK)

    screen.blit(userText, (410,100))
    screen.blit(userTextContent, (525,100))
    pygame.display.update()

def printUserColorInformation():
    font = pygame.font.SysFont("arial",20,True)
    playerColor = font.render("Player Color : ", True, BLACK)
    computerColor = font.render("Computer Color : ", True, BLACK)

    screen.blit(playerColor, (410,150))
    screen.blit(computerColor, (410,200))

    pygame.draw.rect(screen, GREEN, (548, 148, 30, 30))
    pygame.draw.circle(screen, BLACK, [563, 163], 10)
    pygame.draw.rect(screen, GREEN, (548, 198, 30, 30))
    pygame.draw.circle(screen, WHITE, [563, 213], 10)

    pygame.display.update()

def printGameOverText():
    font = pygame.font.SysFont("arial",30,True)
    text = font.render("-Game Over-", True, RED)

    screen.blit(text, (425,50))
    pygame.display.update()

def printCalculateGameResult(): #게임 결과 계산중 이라고 출력
    font = pygame.font.SysFont("arial",15)
    text = font.render("~Calculating Game Result~", True, BLACK)

    screen.blit(text, (425,100))
    pygame.display.update()

def printWinner(winner):

    winnerFont = pygame.font.SysFont("arial",40)
    winnerContentFont = pygame.font.SysFont("arial",30)

    if winner != "Draw":
        winnerText = winnerFont.render("Winner", True, RED)
    else:
        winnerText = winnerFont.render("Result", True, RED)
    winnerContentText = winnerContentFont.render("-"+winner+"-", True, YELLOW)

    screen.blit(winnerText, (450,50))
    if winner == "Computer":
        screen.blit(winnerContentText, (440,100))
    elif winner == "Plyaer":
        screen.blit(winnerContentText, (460,100))
    else:
        screen.blit(winnerContentText, (460,100))
    pygame.display.update()

def printBlockCnt(playerBlockCnt, computerBlockCnt):
    font = pygame.font.SysFont("arial",20)

    playerBlockCntText = font.render("Player Block : "+ str(playerBlockCnt), True, BLACK)
    computerBlockCntText = font.render("Computer Block : " + str(computerBlockCnt), True, BLACK)

    screen.blit(playerBlockCntText, (440,200))
    screen.blit(computerBlockCntText, (430,225))
    pygame.display.update()

def printReplayButton():
    font = pygame.font.SysFont("arial",40)
    replayBtnText = font.render("Replay", True, WHITE,2)
    screen.blit(replayBtnText, (100,200))

def printGoStartScreenButton():
    font = pygame.font.SysFont("arial",40)
    goStartScreenBtnText = font.render("Go StartScreen", True, WHITE,2)
    screen.blit(goStartScreenBtnText, (300,200))

#둘다 블럭을  놓을 수 없는 경우
##for row in range(0,SCREEN):
##        for col in range(0,SCREEN):
##            screenArr[row][col] =2
##screenArr[2][6] =1
##screenArr[2][2] =1
##screenArr[3][3] =1
##screenArr[4][4] =1
##screenArr[4][6] =1
##screenArr[5][5] =1
##screenArr[7][7] =1
##screenArr[6][7] =0

##
##for row in range(0,SCREEN):
##    for col in range(0,SCREEN):
##        screenArr[row][col] =2
##
##screenArr[2][2]=1
##screenArr[1][0]=0
##screenArr[2][0]=0
##screenArr[3][0]=0

setDiagonalCnt()
viewGameScreen()
printTurnInformation()
printUserColorInformation()

printReplayButton()
printGoStartScreenButton()

#Game Loop
while True:
    checkGameOver()

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        if event.type == pygame.MOUSEBUTTONDOWN:
            mousePosToArr = []
            mousePosToArr.append(changeMousePosXToArrx(pygame.mouse.get_pos()[0]))
            mousePosToArr.append(changeMousePosYToArry(pygame.mouse.get_pos()[1]))

            if not(mousePosToArr[0] ==-1 or mousePosToArr[1] ==-1):
                if InspectIfItCanBePlacedInPlace(mousePosToArr[0],mousePosToArr[1], True, currentTurn) ==1:
                    mousePos = pygame.mouse.get_pos() #자료형 : tuple
                    screenArr[changeMousePosYToArry(mousePos[1])][changeMousePosXToArrx(mousePos[0])] =1 #클릭한 곳 색깔 바꾸기
                    currentTurn = changeTurn(currentTurn) #턴 바꾸기
                    clearStateScreen(False)
                    printTurnInformation() #플레이어 -> 컴퓨터 턴 : 컴퓨터 턴 출력

    viewGameScreen()
    pygame.display.update()

    moveNextTurnWhenBlockCanNotPutPlace()

    if currentTurn ==2 :
        time.sleep(2)
        setWhereComputerCanPutBlock()
        currentTurn = changeTurn(currentTurn)
        clearStateScreen(False)
        printTurnInformation() #컴퓨터 -> 플레이어 턴 : 컴퓨터 턴 출력