import logging
import os
import random

import cv2
from numpy.core.records import ndarray

from ggly import img_utils

data_dir = os.path.dirname(os.path.realpath(__file__)) + '/data/'

class Rect(object):
    def __init__(self, dimensions):
        (self.x, self.y, self.width, self.height) = dimensions

    @property
    def center(self):
        return int(self.x + self.width / 2), int(self.y + self.height / 2)

class Ggly(object):
    img_max_size = (2048, 2048)
    eye_img = cv2.imread(data_dir + '/img/googly_eye.png', -1)
    face_cascade = cv2.CascadeClassifier(data_dir + '/haarcascades/haarcascade_frontalface_default.xml')
    right_eye_cascade = cv2.CascadeClassifier(data_dir + '/haarcascades/haarcascade_righteye_2splits.xml')
    left_eye_cascade = cv2.CascadeClassifier(data_dir + '/haarcascades/haarcascade_lefteye_2splits.xml')
    debug = False

    def __init__(self, debug: bool = False):
        super().__init__()
        self.debug = debug

    def go(self, img: ndarray):
        img = img_utils.resize_to_fit(img.copy(), self.img_max_size[0], self.img_max_size[1])
        img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        height, width, _ = img.shape

        faces = self.face_cascade.detectMultiScale(
            img_gray,
            scaleFactor=1.05,
            minNeighbors=2,
            minSize=(30, 30),
            flags=cv2.CASCADE_SCALE_IMAGE
        )

        face_count = 0
        for face in [Rect(x) for x in faces]:
            logging.debug("Found face at %s:%s" % (face.x, face.y))
            face_img_gray = img_gray[face.y:face.y + face.height, face.x:face.x + face.width]
            face_img = img[face.y:face.y + face.height, face.x:face.x + face.width]
            r_eye = self.__search_right_eye(face_img_gray, face)
            if r_eye:
                l_eye = self.__search_left_eye(face_img_gray, face)
                if not l_eye:
                    l_eye = self.__fake_left_eye(r_eye, face)
                self.__draw_eye(r_eye, face, face_img)
                self.__draw_eye(l_eye, face, face_img)
                face_count += 1
                if self.debug:
                    img_utils.draw_rect(face_img, l_eye, (0, 255, 0))
                    img_utils.draw_center_line(face_img, r_eye, l_eye, (0, 255, 0))
                    img_utils.draw_rect(face_img, r_eye, (255, 255, 0))
            if self.debug:
                img_utils.draw_rect(img, face, (255, 0, 255))
        return img, face_count

    def __search_right_eye(self, face_img_gray: ndarray, face: Rect):
        right_eyes = []
        for i in range(3, -1, -1):
            candidates = self.right_eye_cascade.detectMultiScale(face_img_gray, minNeighbors=i)
            right_eyes = [x for x in candidates if self.__is_right_eye_valid(Rect(x), face)]
            if len(right_eyes) > 0:
                logging.debug("Found right eye with accuracy %s" % i)
                break
        return Rect(right_eyes[0]) if right_eyes else None

    def __search_left_eye(self, face_img_gray: ndarray, face: Rect):
        left_eyes = []
        for i in range(3, -1, -1):
            candidates = self.left_eye_cascade.detectMultiScale(face_img_gray, minNeighbors=i)
            left_eyes = [x for x in candidates if self.__is_left_eye_valid(Rect(x), face)]
            if len(left_eyes) > 0:
                logging.debug("Found left eye with accuracy %s" % i)
                break
        return Rect(left_eyes[0]) if left_eyes else None

    @staticmethod
    def __fake_left_eye(r_eye: Rect, face: Rect):
        logging.debug("Made fake left eye")
        return Rect([r_eye.x + int(2 * (face.width / 2 - r_eye.center[0])), r_eye.y,
                     r_eye.width, r_eye.height])

    @staticmethod
    def __is_right_eye_valid(eye: Rect, face: Rect):
        if eye.center[0] > face.width / 2:  # left eye recognized as right eye
            return False
        if eye.center[1] > face.height / 2:  # nose recognized as right eye
            return False
        return True

    @staticmethod
    def __is_left_eye_valid(eye: Rect, face: Rect):
        if eye.center[0] < face.width / 2:  # right eye recognized as left eye
            return False
        if eye.center[1] > face.height / 2:  # noses recognized as left eye
            return False
        return True

    def __draw_eye(self, eye_rect: Rect, face: Rect, face_img: ndarray):
        scale_factor = 1.5
        eye_img = self.eye_img.copy()
        eye_img = img_utils.rotate(eye_img, random.randint(0, 360))
        eyes_width_scaled = int(eye_rect.width * scale_factor)
        eyes_height_scaled = int(eye_rect.height * scale_factor)
        x1 = max(eye_rect.center[0] - int(eyes_width_scaled / 2), 0)
        x2 = min(x1 + eyes_width_scaled, face.width)
        y1 = max(eye_rect.center[1] - int(eyes_height_scaled / 2), 0)
        y2 = min(y1 + eyes_height_scaled, face.height)
        eye_img = cv2.resize(eye_img, (x2 - x1, y2 - y1), interpolation=cv2.INTER_AREA)
        mask = eye_img[:, :, 3]
        mask_inv = cv2.bitwise_not(mask)
        eye_img = eye_img[:, :, 0:3]  # convert to BGR
        roi = face_img[y1:y2, x1:x2]
        roi_bg = cv2.bitwise_and(roi, roi, mask=mask_inv)
        roi_fg = cv2.bitwise_and(eye_img, eye_img, mask=mask)
        dst = cv2.add(roi_bg, roi_fg)
        face_img[y1:y2, x1:x2] = dst


import sqlite3

con = sqlite3.connect("database.db")
cur = con.cursor()

#  Create table
sql__inti_file = open("init.sql")
sql__init_as_string = sql__inti_file.read()
cur.executescript(sql__init_as_string)

# Execute queries
sql__query_file = open("query.sql")
sql__queries = sql__query_file.read()
sql_commands = sql__queries.split(';')

# Check queries
i: int = 0
for command in sql_commands:
    cur.execute(command)
    rows = cur.fetchall()
    if i == 0:
        try:
            if rows[0][0] == 'Mark' and rows[1][0] == 'David' and rows[2][0] == 'Kim':
                print('Первое заданиче выполнено успешно')
            else:
                print('Первое заданиче не выполнено ')
        except:
            print('Выборка не соответствует условию')
    elif i == 1:
        try:
            if rows[0][0] == 2:
                print('Второе заданиче выполнено успешно')
            else:
                print('Второе заданиче не выполнено ')
        except:
            print('Выборка не соответствует условию')
    elif i == 2:
        try:
            if rows[0][0] == 105000:
                print('Третье заданиче выполнено успешно')
            else:
                print('Третье заданиче не выполнено ')
        except:
            print('Выборка не соответствует условию')
    i += 1

con.close()


import random
import json

directions = [
    (-1, -1), (0, -1), (1, -1),
    (-1, 0), (1, 0),
    (-1, 1), (0, 1), (1, 1),
]

class Unit:
    def __init__(self, id, spawn_x, spawn_y, team):
        self.id = id
        self.team = team
        self.spawn_x = spawn_x
        self.spawn_y = spawn_y
        self.x = spawn_x
        self.y = spawn_y

    def update(self, x, y):
        self.x = x
        self.y = y

def on_map(x, y, map_width, map_height):
    return 0 <= x < map_width and 0 <= y < map_height

def random_move(unit, map_width, map_height):
    while True:
        dir_x, dir_y = random.choice(directions)
        new_x = unit.x + dir_x
        new_y = unit.y + dir_y

        if on_map(new_x, new_y, map_width, map_height):
            break

    return new_x, new_y

def main():
    config = json.loads(input())
    # there begins first turn

    my_team_id = config['my_team_id']
    map_width = config['map_width']
    map_height = config['map_height']

    units = {unit['id']: Unit(**unit) for unit in config['units']}

    while True:
        # get tick info
        tick = json.loads(input())

        # update local game state
        for unit in tick['units']:
            units[unit['id']].update(unit['x'], unit['y'])

        # make random moves for my units
        command = []
        for unit in units.values():
            if unit.team == my_team_id:
                move_x, move_y = random_move(unit, map_width, map_height)
                action = {
                    'action': 'move',
                    'properties': {'unit_id': unit.id, 'x': move_x, 'y': move_y}
                }
                command.append(action)

        command = json.dumps(command)

        print(command)

if __name__ == '__main__':
    main()


from django.http import HttpResponse
from django.shortcuts import render,get_object_or_404

from .models import PageView

def increment_page_view(request,page_name):
    page,created=PageView.objects.get_or_create(page_name=page_name)
    page.view_count+=1
    page.save()
    try:
        response=HttpResponse(f"page{{page_name}} viewed {{page.view_count}} times")
        response.set_cookie(f"page {{page.name}} views",page.view_count)
    except:
        print("deoesnt contain message")
    return response

def display_page_view(request,page_name):
    page=get_object_or_404(PageView,page_name=page_name)
    return render(request,"pagecount_app/page_view.html",{"page":page})


import datetime
import logging
import re
import time

from TwitterAPI import TwitterAPI, constants

from .config import TwitterConfig

logger = logging.getLogger(__name__)

class TwitterClientException(Exception):
    pass

class TwitterClientRetweetedException(Exception):
    pass

class RateLimiterExpired(Exception):
    pass

class RateLimiter(dict):

    def refresh_limits(self, new_limits):
        '''
        Refreshes the limits with the new limits info that was getted from the twitter api
        :param new_limits: a dictionary with the new limits
        '''

        # delete old values
        self.clear()

        # flatten dictionay
        for value in new_limits.values():
            for key, limits in value.items():
                # replace parameters in url like :id :slug to :PARAM
                key = re.sub(r'\/:[a-z_]+', '/:PARAM', key)
                self[key] = limits

        # create percent
        for key in self.keys():
            self._calculate_percent_remaining(key)

        logger.debug('Ratelimits was refreshed')

    def check_limit(self, endpoint):
        '''
        Check if we exceded the api calls for a particular endpoint. If we did it pauses until the nex
        reset
        :param endpoint: the endpoint (api url) to be checked
        '''

        # Only GET methods have ratelimits
        if constants.ENDPOINTS[endpoint][0] == 'POST':
            return

        logger.debug('Checking limits for {}'.format(endpoint))

        endpoint_limits = self[self._get_internal_endpoint_name(endpoint)]

        # if over threshold sleep untill reset
        if endpoint_limits['percent'] < TwitterConfig.get().min_ratelimit_percent:

            reset_time = endpoint_limits['reset']
            now = int(datetime.datetime.now().strftime('%s'))
            wait = reset_time - now

            if wait > 0:
                logger.warning('Rate limit {}. Waiting for {} seconds'.format(endpoint_limits['percent'], wait))
                time.sleep(wait)
                raise RateLimiterExpired()

    def decrease_remaining(self, endpoint):
        '''
        Decreases the remaining calls of an endpoint
        :param endpoint: the endpoint to decrease
        '''
        endpoint = self._get_internal_endpoint_name(endpoint)
        if endpoint in self:
            self[endpoint]['remaining'] -= 1
            logger.debug('Decreased remainin usages of {}. New value {}'.format(endpoint, self[endpoint]['remaining']))
            self._calculate_percent_remaining(endpoint)

    def _calculate_percent_remaining(self, endpoint):
        '''
        Calculate the percent of remaining calls for an endpoint
        :param endpoint: The target endpoint to calculate
        '''
        self[endpoint]['percent'] = self[endpoint]['remaining'] / self[endpoint]['limit'] * 100

    def _get_internal_endpoint_name(self, endpoint):
        '''
        Maps an TwitterApi endpoint to the internal endpoint. This is usefull because
        TwitterApi has the endpoints without the leading '/' but the twitter returns
        a dictionary starting with '/'
        :param endpoint: the endpoint to convert
        :return: the internal endpoint
        '''
        return '/' + endpoint

class TwitterClient:

    def __init__(self, consumer_key, consumer_secret, access_token_key, access_token_secret):
        self.api = TwitterAPI(consumer_key, consumer_secret, access_token_key, access_token_secret)
        self.ratelimiter = RateLimiter()
        self.update_ratelimits(check_ratelimit=False)

    def search_tweets(self, query, limit, result_type='mixed', language=None):
        parameters = {'q': query, 'result_type': result_type, 'count': limit}
        if language is not None:
            parameters['lang'] = language
        r = self._api_call('search/tweets', parameters)
        return r['statuses']

    def get_tweet(self, post_id):
        return self._api_call('statuses/show/:{}'.format(post_id))

    def update(self, status, reply_id=None):
        data = dict()
        data['status'] = status
        if reply_id is not None:
            data['in_reply_to_status_id'] = reply_id
        return self._api_call('statuses/update', parameters=data)

    def retweet(self, post_id):
        return self._api_call('statuses/retweet/:{}'.format(post_id))

    def get_friends_ids(self):
        return self._api_call('friends/ids')['ids']

    def follow(self, username):
        return self._api_call('friendships/create', {'screen_name': username})

    def unfollow(self, user_id):
        return self._api_call('friendships/destroy', {'user_id': user_id})

    def favorite(self, post_id):
        return self._api_call('favorites/create', {'id': post_id})

    def get_blocks(self):
        return self._api_call('blocks/ids')['ids']

    def get_mentions_timeline(self, count=None, since_id=None):
        parameters = dict()
        if count is not None:
            parameters['count'] = count

        if since_id is not None:
            parameters['since_id'] = since_id

        return self._api_call('statuses/mentions_timeline', parameters)

    def update_ratelimits(self, check_ratelimit=True):

        # ratelimit_check controls if before the api_call we check the ratelimit. Usefull to be false the first update
        r = self._api_call('application/rate_limit_status', check_ratelimit=check_ratelimit)['resources']

        self.ratelimiter.refresh_limits(r)

        # log ratelimit status
        logger.debug("Ratelimit status: {}".format({key: item['percent'] for key, item in self.ratelimiter.items()
                                                    if item['percent'] < 100}))

    def _api_call(self, request, parameters=None, check_ratelimit=True):

        # !Fixme: TwitterApi doenst have all the endpoints. Some will raise exception
        _, endpoint = self.api._get_endpoint(request)

        if check_ratelimit:

            try:
                self.ratelimiter.check_limit(endpoint)
            except RateLimiterExpired:
                self.update_ratelimits(check_ratelimit=False)

        # Add support for extended tweets
        if parameters is not None:
            parameters['tweet_mode'] = 'extended'
        else:
            parameters = {'tweet_mode': 'extended'}

        response = self.api.request(request, parameters).json()

        try:
            self._check_for_errors(response)
        except Exception as e:
            logger.error('Error during twitter api call {} (parameters: {})'.format(request, parameters))
            raise

        self.ratelimiter.decrease_remaining(endpoint)

        return response

    def _check_for_errors(self, response):
        # check for errors
        if 'errors' in response:
            for error in response['errors']:
                message = error['message']
                code = error['code']
                if message == 'You have already retweeted this Tweet.':
                    raise TwitterClientRetweetedException()
                logger.error('Twitter api error code:{} error:{}'.format(code, message))
            raise TwitterClientException()


"""

Script for training and evaluating a model

"""
from cmath import nan
import os
import loss_fns
import croptype_models
import datetime
import torch
# import datasets
import metrics
import util
import numpy as np
import pickle

from torch import autograd

from constants import *
from tqdm import tqdm
from torch import autograd
import visualize

from sustainbench import get_dataset
from sustainbench.common.data_loaders import get_train_loader
import torchvision.transforms as transforms
import torch.nn.functional as F

def evaluate_split(model, model_name, split_loader, device, loss_weight, weight_scale, gamma, num_classes, country,
                   var_length):
    total_loss = 0
    total_pixels = 0
    total_cm = np.zeros((num_classes, num_classes)).astype(int)
    loss_fn = loss_fns.get_loss_fn(model_name)
    for inputs, targets, cloudmasks, hres_inputs in split_loader:
        with torch.set_grad_enabled(False):
            if not var_length:
                inputs.to(device)
            else:
                for sat in inputs:
                    if "length" not in sat:
                        inputs[sat].to(device)
            targets.to(device)
            hres_inputs.to(device)
            if hres_inputs is not None: hres_inputs.to(device)

            preds = model(inputs, hres_inputs) if model_name in MULTI_RES_MODELS else model(inputs)
            batch_loss, batch_cm, _, num_pixels, confidence = evaluate(model_name, preds, targets, country,
                                                                       loss_fn=loss_fn, reduction="sum",
                                                                       loss_weight=loss_weight,
                                                                       weight_scale=weight_scale, gamma=gamma)
            total_loss += batch_loss.item()
            total_pixels += num_pixels
            total_cm += batch_cm

    f1_avg = metrics.get_f1score(total_cm, avg=True)
    acc_avg = sum([total_cm[i][i] for i in range(num_classes)]) / np.sum(total_cm)
    return total_loss / total_pixels, f1_avg, acc_avg

def evaluate(model_name, preds, labels, country, loss_fn=None, reduction=None, loss_weight=None, weight_scale=None,
             gamma=None):
    """ Evalautes loss and metrics for predictions vs labels.

    Args:
        preds - (tensor) model predictions
        labels - (npy array / tensor) ground truth labels
        loss_fn - (function) function that takes preds and labels and outputs some loss metric
        reduction - (str) "avg" or "sum", where "avg" calculates the average accuracy for each batch
                                          where "sum" tracks total correct and total pixels separately
        loss_weight - (bool) whether we use weighted loss function or not

    Returns:
        loss - (float) the loss the model incurs
        cm - (nparray) confusion matrix given preds and labels
        accuracy - (float) given "avg" reduction, returns accuracy
        total_correct - (int) given "sum" reduction, gives total correct pixels
        num_pixels - (int) given "sum" reduction, gives total number of valid pixels
    """
    cm = metrics.get_cm(preds, labels, country, model_name)

    if model_name in NON_DL_MODELS:
        accuracy = metrics.get_accuracy(model_name, preds, labels, reduction=reduction)
        return None, cm, accuracy, None
    elif model_name in DL_MODELS:
        if reduction == "avg":
            loss, confidence = loss_fn(labels, preds, reduction, country, loss_weight, weight_scale)

            accuracy = metrics.get_accuracy(model_name, labels, model_name, reduction=reduction)
            return loss, cm, accuracy, confidence
        elif reduction == "sum":
            loss, confidence, _ = loss_fn(labels, preds, reduction, country, loss_weight, weight_scale)
            total_correct, num_pixels = metrics.get_accuracy(model_name, preds, labels, reduction=reduction)
            return loss, cm, total_correct, num_pixels, confidence
        else:
            raise ValueError(f"reduction: `{reduction}` not supported")

def predict_dl_model(model, model_name, dataloaders, args):
    splits = ['train', 'val'] if not args.eval_on_test else ['test']
    predictions = []

    if args.clip_val:
        clip_val = sum(p.numel() for p in model.parameters() if p.requires_grad) // 20000
        print('clip value: ', clip_val)

    # set up information lists for visdom
    vis_logger = visualize.VisdomLogger(args.env_name, model_name, args.country, splits)
    loss_fn = loss_fns.get_loss_fn(model_name)
    optimizer = loss_fns.get_optimizer(model.parameters(), args.optimizer, args.lr, args.momentum, args.weight_decay)
    best_val_f1 = 0

    for i in range(args.epochs if not args.eval_on_test else 1):
        print('Epoch: {}'.format(i))

        vis_logger.reset_epoch_data()

        for split in ['train', 'val'] if not args.eval_on_test else ['test']:
            train_data = dataloaders.get_subset(split)

            train_loader = get_train_loader('standard', train_data, args.batch_size)
            model.train() if split == ['train'] else model.eval()
            nclass = len(CM_LABELS[args.country]) + 1
            # for inputs, targets, cloudmasks, hres_inputs in tqdm(dl):
            for inputs, targets, cloudmasks in tqdm(train_loader):

                targets[targets > 4] = 0
                targets = F.one_hot(targets.to(torch.int64), num_classes=nclass)
                mask = torch.arange(1, 5)  # tensor([1, 2, 3, 4])

                targets = torch.index_select(targets, 3, mask)

                targets = targets.permute(0, 3, 1, 2)
                cloudmasks = None

                with torch.set_grad_enabled(True):
                    if not args.var_length:
                        # inputs.to(args.device)
                        for a in inputs:
                            inputs[a].to(args.device)

                        # if hres_inputs is not None: hres_inputs.to(args.device)
                    else:
                        for sat in inputs:
                            if "length" not in sat:
                                inputs[sat].to(args.device)
                    targets.to(args.device)

                    # ## For 2nd command(unet3d) uncommnet later commands
                    inputs=torch.cat( (inputs['s1'],inputs['s2'],inputs['planet']), dim=1)
                    inputs=inputs.permute(0,1,4,2,3)  #torch.Size([2, 17, 64, 64, 256]) After permute torch.Size([2, 17, 256, 64, 64])
                    inputs=inputs.float()
                    inputs=inputs.cuda()

                    # For 3rd command() uncommnet later commands
                    # for a in inputs:
                    #     inputs[a] = inputs[a].permute(0, 4, 1, 2, 3)  ##  batch, timestamps, bands, rows, columns
                    #     inputs[a] = inputs[a].float().cuda()

                    # # ## For 4th command() uncommnet later commands
                    # inputs=torch.cat( (inputs['s1'],inputs['s2'],inputs['planet']), dim=1)
                    # inputs=inputs.permute(0,4,1,2,3)
                    # inputs=inputs.float().cuda()

                    preds = model(inputs)
                    predictions.append(preds)
                    loss, cm_cur, total_correct, num_pixels, confidence = evaluate(model_name, preds, targets,
                                                                                args.country, loss_fn=loss_fn,
                                                                                reduction="sum",
                                                                                loss_weight=args.loss_weight,
                                                                                weight_scale=args.weight_scale,
                                                                                gamma=args.gamma)

                    if split == 'train' and loss is not None:  # TODO: not sure if we need this check?
                        # If there are valid pixels, update weights
                        optimizer.zero_grad()
                        # with autograd.detect_anomaly():
                        loss.backward()
                        if args.clip_val:
                            # `clip_grad_norm` helps prevent the exploding gradient problem in RNNs / LSTMs.
                            torch.nn.utils.clip_grad_norm_(model.parameters(), clip_val)
                        optimizer.step()
                        total_norm = 0
                        for p in model.parameters():
                            if p.grad is not None:
                                param_norm = p.grad.data.norm(2)
                                total_norm += param_norm.item() ** 2
                        gradnorm = total_norm ** (1. / 2)
                        # gradnorm = torch.norm(list(model.parameters())[0].grad).detach().cpu() / torch.prod(torch.tensor(list(model.parameters())[0].shape), dtype=torch.float32)

                        # vis_logger.update_progress('train', 'gradnorm', gradnorm)
                        loss = loss.cpu()
                        with torch.no_grad():
                            vis_logger.update_progress('train', 'gradnorm', gradnorm)

                    if cm_cur is not None:  # TODO: not sure if we need this check?
                        # If there are valid pixels, update metrics
                        with torch.no_grad():
                            vis_logger.update_epoch_all(split, cm_cur, loss, total_correct, num_pixels)
                        # vis_logger.update_epoch_all(split, cm_cur, loss, total_correct, num_pixels)

                # with torch.no_grad():
                #     vis_logger.record_batch(inputs, cloudmasks, targets.float(), preds, confidence,
                #                         NUM_CLASSES[args.country], split,
                #                         args.include_doy, args.use_s1, args.use_s2,
                #                         model_name, args.time_slice, var_length=args.var_length)

                # del loss  # adding this as the gpu usage was increasing with time
                # del preds

            if split in ['test']:
                vis_logger.record_epoch(split, i, args.country, save=False,
                                        save_dir=os.path.join(args.save_dir, args.name + "_best_dir"))
            else:
                vis_logger.record_epoch(split, i, args.country)

            if split == 'val':
                val_f1 = metrics.get_f1score(vis_logger.epoch_data['val_cm'], avg=True)
                print("val at epoch=", i, val_f1)

                if val_f1 > best_val_f1:
                    torch.save(model.state_dict(), os.path.join(args.save_dir, args.name + "_best"))
                    best_val_f1 = val_f1
                    print("best till now saved at epoch", i, args.name + "_best")

                    # """  # commenting the next lines to check now if it is working or not
                    if args.save_best:
                        # TODO: Ideally, this would save any batch except the last one so that the saved images
                        #  are not only the remainder from the last batch
                        vis_logger.record_batch(inputs, cloudmasks, targets.float(), preds, confidence,
                                                NUM_CLASSES[args.country], split,
                                                args.include_doy, args.use_s1, args.use_s2,
                                                model_name, args.time_slice, save=True, var_length=args.var_length,
                                                save_dir=os.path.join(args.save_dir, args.name + "_best_dir"))

                        vis_logger.record_epoch(split, i, args.country, save=True,
                                                save_dir=os.path.join(args.save_dir, args.name + "_best_dir"))

                        vis_logger.record_epoch('train', i, args.country, save=True,
                                                save_dir=os.path.join(args.save_dir, args.name + "_best_dir"))

    return predictions

def predict(model, model_name, args=None, dataloaders=None, X=None, y=None):
    """ Trains the model on the inputs

    Args:
        model - trainable model
        model_name - (str) name of the model
        args - (argparse object) args parsed in from main; used only for DL models
        dataloaders - (dict of dataloaders) used only for DL models
        X - (npy arr) data for non-dl models
        y - (npy arr) labels for non-dl models
    """
    if dataloaders is None and model_name in DL_MODELS: raise ValueError("DATA GENERATOR IS NONE")
    if args is None and model_name in DL_MODELS: raise ValueError("Args is NONE")

    if model_name in NON_DL_MODELS:
        predictions = train_non_dl_model(model, model_name, dataloaders, args, X, y)
    elif model_name in DL_MODELS:
        predictions = predict_dl_model(model, model_name, dataloaders, args)
    else:
        raise ValueError(f"Unsupported model name: {model_name}")

    return predictions

def main(args):
    if args.seed is not None:
        if args.device == 'cuda':
            use_cuda = True
        elif args.device == 'cpu':
            use_cuda = False
        util.random_seed(seed_value=args.seed, use_cuda=use_cuda)

    # load in data generator

    dataset = get_dataset(dataset='africa_crop_type_mapping', split_scheme="cauvery", resize_planet=True,
                          normalize=True, calculate_bands=True, root_dir=args.path_to_cauvery_images)

    dataloaders = dataset

    # load in model
    model = croptype_models.get_model(**vars(args))
    if args.model_name in DL_MODELS:
        print('Total trainable model parameters: {}'.format(
            sum(p.numel() for p in model.parameters() if p.requires_grad)))

    if args.model_path is not None:
        model.load_state_dict(torch.load(args.model_path))
        # model.load_state_dict(torch.load("PATH/TO/MODEL"))

    if args.model_name in DL_MODELS and args.device == 'cuda' and torch.cuda.is_available():
        model.to(args.device)

    if args.name is None:
        args.name = str(datetime.datetime.now()) + "_" + args.model_name

    if not os.path.exists(args.save_dir):
        os.mkdir(args.save_dir)

    print("Starting to predict")
    return predict(model, args.model_name, args, dataloaders=dataloaders)

if __name__ == "__main__":
    # parse args
    parser = util.get_train_parser()

    main(parser.parse_args())


from typing import List

class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        m = len(nums1)
        n = len(nums2)
        end = (m+n)//2 + 1
        res = []
        p1, p2 = 0,0
        while p1+p2 != end:

            if p1<m and p2<n:
                if nums1[p1]<nums2[p2]:
                    res.append(nums1[p1])
                    p1+=1
                else:
                    res.append(nums2[p2])
                    p2+=1
            elif p1==m:
                res.append(nums2[p2])
                p2 += 1
            elif p2 ==n:
                res.append(nums1[p1])
                p1 += 1

        if (m+n)%2==0:
            return (res[-1]+res[-2])/2
        else:
            return res[-1]

if __name__ == '__main__':
    nums1 = [3]
    nums2 = [2,7]
    s = Solution()
    ans = s.findMedianSortedArrays(nums1,nums2)
    print(ans)


from django.shortcuts import render
from Testapp.models import StudentInfo
from .Form import StuInfo
# Create your views here.
def Temp(req):
    s=StudentInfo.objects.all()
    my_dick={'student':s}
    return render(req,'Hello.html',context=my_dick)
def RegForm(req):
    frm=StuInfo()
    if req.method=='POST':
        frm=StuInfo(req.POST)
        if frm.is_valid():
            print('name of the student is ',frm.cleaned_data['UserName'])
            print('Age of the student is ',frm.cleaned_data['Age'])
            print('Address of the student is ',frm.cleaned_data['Address'])
            print('E-mail of the student is ',frm.cleaned_data['Email'])
    return render(req,'Register.html',{'form':frm})


"""Non-official Python library for Pinata.cloud"""

import os
import typing as tp

import requests
import json

# Custom tpe hints
ResponsePayload = tp.Dict[str, tp.Any]
OptionsDict = tp.Dict[str, tp.Any]
Headers = tp.Dict[str, str]

# global constants
API_ENDPOINT: str = "https://api.pinata.cloud/"

class PinataPy:
    """A pinata api client session object"""

    def __init__(self, pinata_api_key: str, pinata_secret_api_key: str) -> None:
        self._auth_headers: Headers = {
            "pinata_api_key": pinata_api_key,
            "pinata_secret_api_key": pinata_secret_api_key,
        }

    @staticmethod
    def _error(response: requests.Response) -> ResponsePayload:
        """Construct dict from response if an error has occurred"""
        return {"status": response.status_code, "reason": response.reason, "text": response.text}

    @staticmethod
    def _validate_destination_folder_name(path: str) -> str:
        """
        Validates the IPFS destination folder name is valid by removing
        blankspaces and adding '/' to the end of the path
        """
        path = path.replace(" ", "")
        if not path.endswith("/"):
            path = path + "/"
        return path

    @staticmethod
    def _validate_path_to_file(path: str) -> str:
        """
        Validates the path to file is valid by removing '/' at the end
        of the path.
        """
        path = path.replace(" ", "")
        if path.endswith("/"):
            path = path[:-1]
        return path

    def pin_file_to_ipfs(
            self,
            path_to_file: str,
            ipfs_destination_path: str = "/",
            save_absolute_paths: bool = True,
            options: tp.Optional[OptionsDict] = None,
    ) -> ResponsePayload:
        """
        Pin any file, or directory, to Pinata's IPFS nodes

        Args:
            path_to_file: local path of file/directory to upload to IPFS node
            ipfs_destination_path: destination path of file(s) on the IPFS node.
                You can only set one destination path per call.
                Pathway can be viewed in the Pinata Cloud Pin Manager (https://app.pinata.cloud/pinmanager).
                Ex: input => destination path
                    '' => /
                    'animal-nfts/' => /animal-nfts/
                    'retro-nfts/animals' => /retro-nfts/animals/
            save_absolute_paths: parameter to control filepaths cutting.
                Ex: input => destination path
                    true: /dir1/dir2/dir3/filename => /dir1/dir2/dir3/filename
                    false: /dir1/dir2/dir3/filename => filename
            options: optional parameters (pinataMetadata, pinataOptions)

        Returns:
            JSON response

        More: https://docs.pinata.cloud/pinata-api/pinning/pin-file-or-directory
        """
        url: str = API_ENDPOINT + "pinning/pinFileToIPFS"
        headers: Headers = {k: self._auth_headers[k] for k in ["pinata_api_key", "pinata_secret_api_key"]}
        payload: OptionsDict = {}
        dest_folder_name = (
            ipfs_destination_path
            if ipfs_destination_path == "/"
            else self._validate_destination_folder_name(ipfs_destination_path)
        )

        def get_all_files(directory: str) -> tp.List[str]:
            """get a list of absolute paths to every file located in the directory"""
            paths: tp.List[str] = []
            for root, dirs, files_ in os.walk(os.path.abspath(directory)):
                for file in files_:
                    paths.append(os.path.join(root, file))
            return paths

        def get_mutated_filepath(filepath: str, dest_folder_name: str, save_absolute_paths: bool, path_to_file: str, is_directory: bool = False):
            """transform filepath with dest_folder_name and absolute path saving rules"""
            if save_absolute_paths:
                return dest_folder_name + (filepath[:1].replace("/", "") + filepath[1:])  # remove first '/' if exists
            else:
                # can't pin directory into root and save directory's hierarchy
                if is_directory and dest_folder_name == "/":
                    dest_folder_name =  self._validate_path_to_file(path_to_file).split("/")[-1]
                return dest_folder_name + filepath.split(dest_folder_name)[-1]

        files: tp.List[str, tp.Any]

        # If path_to_file is a directory
        if os.path.isdir(path_to_file):
            all_files: tp.List[str] = get_all_files(path_to_file)
            files = [("file", (get_mutated_filepath(file, dest_folder_name, save_absolute_paths, path_to_file, is_directory=True), open(file, "rb"))) for
                     file in all_files]  # type: ignore
        # If path_to_file is a single file
        else:
            files = [("file", (get_mutated_filepath(path_to_file, dest_folder_name, save_absolute_paths, path_to_file),
                               open(path_to_file, "rb")))]  # type: ignore

        if options is not None:
            if "pinataMetadata" in options:
                pinataMetadata = options["pinataMetadata"]
                payload["pinataMetadata"] = pinataMetadata if type(pinataMetadata) == str else json.dumps(pinataMetadata)
            if "pinataOptions" in options:
                pinataOptions = options["pinataOptions"]
                payload["pinataOptions"] = pinataOptions if type(pinataOptions) == str else json.dumps(pinataOptions)

        response: requests.Response = requests.post(url=url, files=files, headers=headers, data=payload)
        return response.json() if response.ok else self._error(response)  # type: ignore

    def pin_hash_to_ipfs(self, hash_to_pin: str, options: tp.Optional[OptionsDict] = None) -> ResponsePayload:
        """WARNING: This Pinata API method is deprecated. Use 'pin_hash_to_ipfs' instead"""
        url: str = API_ENDPOINT + "pinning/addHashToPinQueue"
        headers: Headers = self._auth_headers
        headers["Content-Type"] = "application/json"
        body = {"hashToPin": hash_to_pin}
        if options is not None:
            if "host_nodes" in options:
                body["host_nodes"] = options["host_nodes"]
            if "pinataMetadata" in options:
                body["pinataMetadata"] = options["pinataMetadata"]
        response: requests.Response = requests.post(url=url, json=body, headers=headers)
        return response.json() if response.ok else self._error(response)  # type: ignore

    def pin_to_pinata_using_ipfs_hash(self, ipfs_hash: str, filename: str) -> ResponsePayload:
        """ Pin file to Pinata using its IPFS hash

        https://docs.pinata.cloud/pinata-api/pinning/pin-by-cid
        """
        payload: OptionsDict = {"pinataMetadata": {"name": filename}, "hashToPin": ipfs_hash}
        url: str = API_ENDPOINT + "/pinning/pinByHash"
        response: requests.Response = requests.post(url=url, json=payload, headers=self._auth_headers)
        return self._error(response) if not response.ok else response.json()  # type: ignore

    def pin_jobs(self, options: tp.Optional[OptionsDict] = None) -> ResponsePayload:
        """ Retrieves a list of all the pins that are currently in the pin queue for your user.

        More: https://docs.pinata.cloud/pinata-api/pinning/list-pin-by-cid-jobs
        """
        url: str = API_ENDPOINT + "pinning/pinJobs"
        payload: OptionsDict = options if options else {}
        response: requests.Response = requests.get(url=url, params=payload, headers=self._auth_headers)
        return response.json() if response.ok else self._error(response)  # type: ignore

    def pin_json_to_ipfs(self, json_to_pin: tp.Any, options: tp.Optional[OptionsDict] = None) -> ResponsePayload:
        """ pin provided JSON

        More: https://docs.pinata.cloud/pinata-api/pinning/pin-json
        """
        url: str = API_ENDPOINT + "pinning/pinJSONToIPFS"
        headers: Headers = self._auth_headers
        headers["Content-Type"] = "application/json"
        payload: ResponsePayload = {"pinataContent": json_to_pin}
        if options is not None:
            if "pinataMetadata" in options:
                payload["pinataMetadata"] = options["pinataMetadata"]
            if "pinataOptions" in options:
                payload["pinataOptions"] = options["pinataOptions"]
        response: requests.Response = requests.post(url=url, json=payload, headers=headers)
        return response.json() if response.ok else self._error(response)  # type: ignore

    def remove_pin_from_ipfs(self, hash_to_remove: str) -> ResponsePayload:
        """ Removes specified hash pin

        More: https://docs.pinata.cloud/pinata-api/pinning/remove-files-unpin
        """
        url: str = API_ENDPOINT + f"pinning/unpin/{hash_to_remove}"
        headers: Headers = self._auth_headers
        headers["Content-Type"] = "application/json"
        response: requests.Response = requests.delete(url=url, data={}, headers=headers)
        return self._error(response) if not response.ok else {"message": "Removed"}

    def pin_list(self, options: tp.Optional[OptionsDict] = None) -> ResponsePayload:
        """ Returns list of your IPFS files based on certain filters.

        Ex: Filter by only 'pinned' files
            options = ({"status": "pinned"})
        Ex: Filter by 'pinned' files and files that contain a metadata 'name' of 'dogs-nfts'
            options = ({"status": "pinned", "metadata[name]": "dogs-nfts"})

        More: https://docs.pinata.cloud/pinata-api/data/query-files
        """
        url: str = API_ENDPOINT + "data/pinList"
        payload: OptionsDict = options if options else {}
        response: requests.Response = requests.get(url=url, params=payload, headers=self._auth_headers)
        return response.json() if response.ok else self._error(response)  # type: ignore

    def user_pinned_data_total(self) -> ResponsePayload:
        url: str = API_ENDPOINT + "data/userPinnedDataTotal"
        response: requests.Response = requests.get(url=url, headers=self._auth_headers)
        return response.json() if response.ok else self._error(response)  # type: ignore


import glob
import os
import sys
from functools import partial
from multiprocessing import Pool

import pandas as pd

from .detect import detect_adapter_in_read
from .extract import extract_adapter_from_read
from .io import (
    copy_and_process_fast5_file,
    process_fast5_file,
    write_results_to_csv,
    write_signals_to_tsv,
)
from .parser import parser
from .trim import trim_adapter_from_read

def main(args=None):
    if args is None:
        args = sys.argv[1:]

    args = parser.parse_args(args)

    os.makedirs(args.save_path, exist_ok=True)

    # parse files to process
    if args.fast5_subset_txt is not None:
        files_df = pd.read_csv(args.fast5_subset_txt, header=None, names=["filename"])
        files_df["src"] = files_df.filename.apply(
            lambda fname: os.path.join(args.input_path, fname)
        )

    elif args.fast5_subset is not None:
        files_df = pd.DataFrame(args.fast5_subset, columns=["filename"])
        files_df["src"] = files_df.filename.apply(
            lambda fname: os.path.join(args.input_path, fname)
        )
    else:
        flist_src = glob.glob(os.path.join(args.input_path, "*.fast5"))
        fnames_src = [os.path.basename(x) for x in flist_src]
        files_df = pd.DataFrame(dict(filename=fnames_src, src=flist_src))

    process_args = []
    process_call = lambda x: None

    # execute different modes
    if args.mode == "trim":
        trim_kwargs = {"buffer": args.trimming_buffer}

        files_df["dst"] = files_df.src.apply(
            lambda x: x.replace(args.input_path, args.save_path)
        )

        process_args = files_df[["src", "dst"]].values.tolist()
        process_call = partial(
            copy_and_process_fast5_file,
            process_fn=trim_adapter_from_read,
            process_kwargs=trim_kwargs,
        )
        mp_map_fn = lambda pool_obj: pool_obj.starmap

    elif args.mode == "detect":
        detect_kwargs = {
            "max_obs": args.max_obs,
            "min_obs_adapter": args.min_obs_adapter,
            "border_trim": args.border_trim,
        }

        process_args = files_df["src"].values.tolist()
        process_call = partial(
            process_fast5_file,
            mode="r",
            process_fn=detect_adapter_in_read,
            process_kwargs=detect_kwargs,
        )
        mp_map_fn = lambda pool_obj: pool_obj.map

    else:  # "extract" or "extract_OpenDBA"
        # TODO: flag partial adapter in some way!

        extract_kwargs = {
            "extract_buffer": args.extraction_buffer,
        }

        process_args = files_df["src"].values.tolist()
        process_call = partial(
            process_fast5_file,
            mode="r",
            process_fn=extract_adapter_from_read,
            process_kwargs=extract_kwargs,
        )
        mp_map_fn = lambda pool_obj: pool_obj.map

    if len(process_args) > 1:
        with Pool(args.j) as p:
            res = mp_map_fn(p)(
                process_call, process_args
            )  # list (files) of lists (processResults)

    elif len(process_args) == 1:
        if type(process_args[0]) == list:
            res = [process_call(*process_args[0])]
        else:
            res = [process_call(process_args[0])]
    else:
        raise ValueError(
            f"Provided `--input_path`={args.input_path} contains no fast5 files."
        )

    # save results
    write_results_to_csv(
        res,
        args.save_path,
        "detect",
        [args.save_path, args.input_path],
        args.global_output_csv,
    )

    if args.mode == "extract":
        write_results_to_csv(
            res,
            args.save_path,
            "extract",
            [args.save_path, args.input_path],
            args.global_output_csv,
        )

    if args.mode == "extract_OpenDBA":
        write_signals_to_tsv(
            res,
            args.save_path,
            reverse_signal=True,
        )

if __name__ == "__main__":
    main()


import requests
from pathlib import Path

from download_image import download_image

def fetch_spacex_last_launch(url, name_folder):
  response = requests.get(url)
  response.raise_for_status()
  images = response.json()
  for image in images:
    if image["links"]["flickr_images"]:
        flickr_images = image["links"]["flickr_images"]
  for images_number, link_image in enumerate(flickr_images):
    filename = f"spacex{images_number}.jpg"
    file_path = f"{name_folder}/{filename}"
    download_image(link_image, file_path)

def main():
    name_folder = "images"
    Path(name_folder).mkdir(parents=True, exist_ok=True)
    url = "https://api.spacexdata.com/v3/launches"
    fetch_spacex_last_launch(url, name_folder)

if __name__ == "__main__":
  main()


from typing import Optional, Sequence, Tuple, Union, Hashable, Dict, Any
from fuse.eval.metrics.libs.thresholding import Thresholding
from fuse.eval.metrics.utils import PerSampleData

import numpy as np

from .metrics_classification_common import MetricMultiClassDefault

class MetricApplyThresholds(MetricMultiClassDefault):
    def __init__(
        self,
        pred: str,
        class_names: Optional[Sequence[str]] = None,
        operation_point: Union[float, Sequence[Tuple[int, float]], str, None] = None,
        **kwargs: dict
    ):
        """
        :param pred: key name for the model prediction scores
        :param class_names: class names. required for multi-class classifiers
        :param operation_point: Optional. If specified will be used to convert probabilities to class prediction.
                                          Options:
                                          * None - argmax(probability) - default mode
                                          * float - used as a threshold for the positive class in binary classification
                                          * [(<class_index_first>, <threshold_first>), ...,(<class_index_last>, <threshold_last>)] -
                                            the class prediction will be the first class in which the probability cross the threshold.
                                            If no class probability crossed the threshold the predicated class will be set to -1
        """
        super().__init__(
            pred=pred,
            target=None,
            extract_ids=True,
            metric_func=self._apply_thresholds,
            class_names=class_names,
            operation_point=operation_point,
            **kwargs
        )

    def _apply_thresholds(
        self,
        pred: Sequence[np.ndarray],
        ids: Sequence[Hashable],
        operation_point: Union[float, Sequence[Tuple[int, float]], str, None] = None,
    ) -> Dict[str, Any]:
        pred_thresholded = Thresholding.apply_thresholds(
            pred=pred, operation_point=operation_point
        )
        # make sure to return the per-sample metric result for the relevant sample ids:
        per_sample_data = PerSampleData(data=pred_thresholded, ids=ids)

        return {"cls_pred": per_sample_data}


#!/usr/bin/env python3
import lib.stitch
from lib.canvas import Image, Rectangle, Vector
import numpy as np
import cv2
import os

imshow = lambda im: Image(None, im).show()

dir = "./var/stitch/tile9c/m/%s.jpg"
read = lambda f:cv2.imread(dir % f, cv2.IMREAD_COLOR)
ims = [read(f) for f in range(7)]

ctx = lib.stitch2.StitchContext()
ctx.features.grey().histeq()
ctx.post.histeq_clr()
stitcher = lib.stitch2.ReferenceStitcher(ctx, ims[2], (1000,1000))

for im in ims[1:4]:
    (x,y), im_ = stitcher.align(im)
    h, w = im_.shape[:2]
    print(x,y,w,h)

im = stitcher.assemble()
#os._exit(0)

h, w = im.shape[:2]
im2 = cv2.resize(im, (int(400*w/h), 400))
imshow(im2)
save = lambda fn: cv2.imwrite(fn, im)
os._exit(0)


import keras as K
import numpy as np
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Dense, Dropout, Flatten
from keras.models import Sequential
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer

from data.process_data import process

BATCH_SIZE = 128
NUM_CLASSES = 10
EPOCHS = 12
img_rows, img_cols = 128, 128
input_shape = (img_rows, img_cols, 3)

DATA_DIR = "data/"
IMAGE_ARRAYS = DATA_DIR + "image_arrays.npy"
LABEL_ARRAYS = DATA_DIR + "label_arrays.npy"

def make_model(bs=BATCH_SIZE, e=EPOCHS, ts=0.2):
    try:
        X = np.load(IMAGE_ARRAYS, allow_pickle=True)
        y = np.load(LABEL_ARRAYS, allow_pickle=True)
    except FileNotFoundError:
        print(f"Processed data not found! Creating files at {IMAGE_ARRAYS} and {LABEL_ARRAYS}.")
        process()
        X = np.load(IMAGE_ARRAYS, allow_pickle=True)
        y = np.load(LABEL_ARRAYS, allow_pickle=True)

    encoder = LabelBinarizer()
    y = encoder.fit_transform(y)

    x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=ts)

    X_train = np.stack(x_train)
    X_test = np.stack(x_test)

    model = Sequential()
    model.add(Conv2D(32, kernel_size=(3, 3),
                     activation='relu',
                     input_shape=input_shape))
    model.add(Conv2D(64, (3, 3), activation='relu'))
    model.add(MaxPooling2D(pool_size=(2, 2)))
    model.add(Dropout(0.25))
    model.add(Flatten())
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(NUM_CLASSES, activation='softmax'))

    model.compile(loss=K.losses.categorical_crossentropy,
                  optimizer=K.optimizers.Adadelta(),
                  metrics=['accuracy'])

    model.fit(X_train, y_train,
              batch_size=bs,
              epochs=e,
              verbose=2,
              validation_data=(X_test, y_test))

    # score = model.evaluate(X_test, y_test, verbose=0)
    # print('Test loss:', score[0])
    # print('Test accuracy:', score[1])

    model.save("models/butterfly_classifier.h5")
    return model


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

__author__ = "Marlon"
__dataset__ = "https://www.statmt.org/europarl/"

import numpy as np
import pandas as pd
import math
import re
import time
import zipfile
import random
from google.colab import drive
import tensorflow as tf
from tensorflow.keras import layers
import tensorflow_datasets as tfds

with open("/content/pt-en/europarl-v7.pt-en.en", "r", encoding="utf-8") as f:
  europarl_en = f.read()
with open("/content/pt-en/europarl-v7.pt-en.pt", "r", encoding="utf-8") as f:
  europarl_pt = f.read()

europarl_en[0:100]

en = europarl_en.split("\n")

pt = europarl_pt.split("\n")

for _ in range(5):
  print("-"*10)
  i = random.randint(0, len(en) -1 )
  print(en[i])
  print(pt[i])

len(pt)

len(en)

"""# Limpeza dos Dados"""

corpus_en = europarl_en
corpus_en = re.sub(r"\.(?=[0-9]|[a-z]|[A-Z])", ".$$$", corpus_en)
corpus_en = re.sub(r".\$\$\$", "", corpus_en)
corpus_en = re.sub(r" +", " ", corpus_en)
corpus_en = corpus_en.split("\n")

corpus_pt = europarl_pt
corpus_pt = re.sub(r"\.(?=[0-9]|[a-z]|[A-Z])", ".$$$", corpus_pt)
corpus_pt = re.sub(r".\$\$\$", "", corpus_pt)
corpus_pt = re.sub(r" +", " ", corpus_pt)
corpus_pt = corpus_pt.split("\n")

len(corpus_en), len(corpus_pt)

tokenizer_en = tfds.deprecated.text.SubwordTextEncoder.build_from_corpus(corpus_en, target_vocab_size=2**13)

tokenizer_en.vocab_size

tokenizer_pt = tfds.deprecated.text.SubwordTextEncoder.build_from_corpus(corpus_pt, target_vocab_size=2**13)

tokenizer_pt.vocab_size

vocab_size_en = tokenizer_en.vocab_size + 2
vocab_size_pt = tokenizer_pt.vocab_size + 2

inputs = [[vocab_size_en - 2] + tokenizer_en.encode(setence) + [vocab_size_en -1] for setence in corpus_en]

for _ in range(5):
  print(inputs[random.randint(0, len(inputs) - 1)])

outputs = [[vocab_size_en - 2] + tokenizer_pt.encode(setence) + [vocab_size_pt -1] for setence in corpus_pt]

for _ in range(5):
  print(outputs[random.randint(0, len(outputs) - 1)])

"""# Remoção de Sentenças Longas"""

max_len = 15
idx_remove = [count for count, sent in enumerate(inputs) if len(sent) > max_len]

len(idx_remove)

for idx in reversed(idx_remove):
  del inputs[idx]
  del outputs[idx]

idx_remove = [count for count, sent in enumerate(outputs) if len(sent) > max_len]

for idx in reversed(idx_remove):
  del inputs[idx]
  del outputs[idx]

len(inputs), len(outputs)

"""# Padding e Batches"""

inputs = tf.keras.preprocessing.sequence.pad_sequences(inputs, value=0, padding="post", maxlen=max_len)
outputs = tf.keras.preprocessing.sequence.pad_sequences(outputs, value=0, padding="post", maxlen=max_len)

for _ in range(5):
  print(outputs[random.randint(0, len(outputs) - 1)])

batch_size = 64
buffer_size = 20000

dataset = tf.data.Dataset.from_tensor_slices((inputs, outputs)) # Transformar no formato do tensorflow
dataset = dataset.cache()
dataset = dataset.shuffle(buffer_size).batch(batch_size)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

"""# Construção do Modelo

## Embedding
"""

class PositionalEncoding(layers.Layer):

  def __init__(self):
    super(PositionalEncoding, self).__init__()

  def get_angles(self, pos, i, d_model):
    angles = 1/np.power(10000., (2*(i // 2)) / np.float32(d_model))
    return pos * angles # (seq_len, d_model)

  def call(self, inputs):
    seq_len = inputs.shape.as_list()[-2]
    d_model = inputs.shape.as_list()[-1]
    angles = self.get_angles(np.arange(seq_len)[:, np.newaxis],
                             np.arange(d_model)[np.newaxis, :], d_model)

    angles[:, 0::2] = np.sin(angles[:, 0::2])
    angles[:, 1::2] = np.cos(angles[:, 1::2])
    pos_encoding = angles[np.newaxis, ...]
    return inputs + tf.cast(pos_encoding, tf.float32)

"""## Mecanismo de Atenção"""

def scaled_dot_product_attention(queries, keys, values, mask):
  product = tf.matmul(queries, keys, transpose_b=True)
  keys_dim = tf.cast(tf.shape(keys)[-1], tf.float32)
  scaled_product = product / tf.math.sqrt(keys_dim)

  if mask is not None:
    scaled_product += (mask * -1e9)

  attention = tf.matmul(tf.nn.softmax(scaled_product, axis=-1), values)

  return attention

class MultiHeadAttention(layers.Layer):

    def __init__(self, nb_proj):
      super(MultiHeadAttention, self).__init__()
      self.nb_proj = nb_proj

    def build(self, input_shape):
      self.d_model = input_shape[-1]
      assert self.d_model % self.nb_proj == 0

      self.d_proj = self.d_model // self.nb_proj

      self.query_lin = layers.Dense(units = self.d_model)
      self.key_lin = layers.Dense(units = self.d_model)
      self.value_lin = layers.Dense(units = self.d_model)

      self.final_lin = layers.Dense(units = self.d_model)

    def split_proj(self, inputs, batch_size): # inputs: (batch_size, seq_lenght, d_model)
      shape = (batch_size, -1, self.nb_proj, self.d_proj)
      splited_inputs = tf.reshape(inputs, shape = shape) # (batch_size, seq_lenght, nb_proj, d_proj)
      return tf.transpose(splited_inputs, perm=[0, 2, 1, 3]) # (batch_size, nb_proj, seq_lenght, d_proj)

    def call(self, queries, keys, values, mask):
      batch_size = tf.shape(queries)[0]

      queries = self.query_lin(queries)
      keys = self.key_lin(keys)
      values = self.value_lin(values)

      queries = self.split_proj(queries, batch_size)
      keys = self.split_proj(keys, batch_size)
      values = self.split_proj(values, batch_size)

      attention = scaled_dot_product_attention(queries, keys, values, mask)

      attention = tf.transpose(attention, perm=[0, 2, 1, 3])

      concat_attention = tf.reshape(attention, shape=(batch_size, -1, self.d_model))

      outputs = self.final_lin(concat_attention)

      return outputs

"""## Encoder"""

class EncoderLayer(layers.Layer):

    def __init__(self, FFN_units, nb_proj, dropout_rate):
      super(EncoderLayer, self).__init__()
      self.FFN_units = FFN_units
      self.nb_proj = nb_proj
      self.dropout_rate = dropout_rate

    def build(self, input_shape):
      self.d_model = input_shape[-1]

      self.multi_head_attention = MultiHeadAttention(self.nb_proj)
      self.dropout_1 = layers.Dropout(rate=self.dropout_rate)
      self.norm_1 = layers.LayerNormalization(epsilon=1e-6) # 0.0000001

      self.dense_1 = layers.Dense(units=self.FFN_units, activation='relu')
      self.dense_2 = layers.Dense(units=self.d_model, activation='relu')
      self.dropout_2 = layers.Dropout(rate=self.dropout_rate)

      self.norm_2 = layers.LayerNormalization(epsilon=1e-6)

    def call(self, inputs, mask, training):
      attention = self.multi_head_attention(inputs, inputs, inputs, mask)
      attention = self.dropout_1(attention, training = training)
      attention = self.norm_1(attention + inputs)

      outputs = self.dense_1(attention)
      outputs = self.dense_2(outputs)
      outputs = self.dropout_2(outputs, training=training)
      outputs = self.norm_2(outputs + attention)

      return outputs

class Encoder(layers.Layer):

    def __init__(self,
                 nb_layers,
                 FFN_units,
                 nb_proj,
                 dropout_rate,
                 vocab_size,
                 d_model,
                 name="encoder"):
      super(Encoder, self).__init__(name=name)
      self.nb_layers = nb_layers
      self.d_model = d_model

      self.embedding = layers.Embedding(vocab_size, d_model)
      self.pos_encoding = PositionalEncoding()
      self.dropout = layers.Dropout(rate=dropout_rate)
      self.enc_layers = [EncoderLayer(FFN_units, nb_proj, dropout_rate) for _ in range(nb_layers)]

    def call(self, inputs, mask, training):
      outputs = self.embedding(inputs)
      outputs *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))
      outputs = self.pos_encoding(outputs)
      outputs = self.dropout(outputs, training)

      for i in range(self.nb_layers):
        outputs = self.enc_layers[i](outputs, mask, training)

      return outputs

"""## Decoder"""

class DecoderLayer(layers.Layer):

    def __init__(self, FFN_units, nb_proj, dropout_rate):
      super(DecoderLayer, self).__init__()
      self.FFN_units = FFN_units
      self.nb_proj = nb_proj
      self.dropout_rate = dropout_rate

    def build(self, input_shape):
      self.d_model = input_shape[-1]

      self.multi_head_attention_1 = MultiHeadAttention(self.nb_proj)
      self.dropout_1 = layers.Dropout(rate=self.dropout_rate)
      self.norm_1 = layers.LayerNormalization(epsilon=1e-6)

      self.multi_head_attention_2 = MultiHeadAttention(self.nb_proj)
      self.dropout_2 = layers.Dropout(rate=self.dropout_rate)
      self.norm_2 = layers.LayerNormalization(epsilon=1e-6)

      self.dense_1 = layers.Dense(units = self.FFN_units, activation='relu')
      self.dense_2 = layers.Dense(units = self.d_model, activation='relu')
      self.dropout_3 = layers.Dropout(rate=self.dropout_rate)
      self.norm_3 = layers.LayerNormalization(epsilon=1e-6)

    def call(self, inputs, enc_outputs, mask_1, mask_2, training):
      attention = self.multi_head_attention_1(inputs, inputs, inputs, mask_1)
      attention = self.dropout_1(attention, training)
      attention = self.norm_1(attention + inputs)

      attention_2 = self.multi_head_attention_2(attention, enc_outputs, enc_outputs, mask_2)
      attention_2 = self.dropout_2(attention_2, training)
      attention_2 = self.norm_2(attention_2 + attention)

      outputs = self.dense_1(attention_2)
      outputs = self.dense_2(outputs)
      outputs = self.dropout_3(outputs, training)
      outputs = self.norm_3(outputs + attention_2)

      return outputs

class Decoder(layers.Layer):

    def __init__(self,
                 nb_layers,
                 FFN_units,
                 nb_proj,
                 dropout_rate,
                 vocab_size,
                 d_model,
                 name="decoder"):
      super(Decoder, self).__init__(name=name)
      self.d_model = d_model
      self.nb_layers = nb_layers

      self.embedding = layers.Embedding(vocab_size, d_model)
      self.pos_encoding = PositionalEncoding()
      self.dropout = layers.Dropout(rate=dropout_rate)

      self.dec_layers = [DecoderLayer(FFN_units, nb_proj, dropout_rate) for i in range(nb_layers)]

    def call(self, inputs, enc_outputs, mask_1, mask_2, training):
      outputs = self.embedding(inputs)
      outputs *= tf.math.sqrt(tf.cast(self.d_model, tf.float32))
      outputs = self.pos_encoding(outputs)
      outputs = self.dropout(outputs, training)

      for i in range(self.nb_layers):
        outputs = self.dec_layers[i](outputs, enc_outputs, mask_1, mask_2, training)

      return outputs

"""## Transformer"""

class Transformer(tf.keras.Model):

    def __init__(self,
                 vocab_size_enc,
                 vocab_size_dec,
                 d_model,
                 nb_layers,
                 FFN_units,
                 nb_proj,
                 dropout_rate,
                 name="transformer"):
        super(Transformer, self).__init__(name=name)

        self.encoder = Encoder(nb_layers, FFN_units, nb_proj, dropout_rate,
                               vocab_size_enc, d_model)
        self.decoder = Decoder(nb_layers, FFN_units, nb_proj, dropout_rate,
                               vocab_size_dec, d_model)
        self.last_linear = layers.Dense(units=vocab_size_dec, name='lin_output')

    def create_padding_mask(self, seq): # (batch_size, seq_length) -> (batch_size, nb_proj, seq_lenght, d_proj)
      mask = tf.cast(tf.math.equal(seq, 0), tf.float32)
      return mask[:, tf.newaxis, tf.newaxis, :]

    def create_look_ahead_mask(self, seq):
      seq_len = tf.shape(seq)[1]
      look_ahed_mask = 1 - tf.linalg.band_part(tf.ones((seq_len, seq_len)), -1, 0)
      return look_ahed_mask

    def call(self, enc_inputs, dec_inputs, training):
      enc_mask = self.create_padding_mask(enc_inputs)
      dec_mask_1 = tf.maximum(self.create_padding_mask(dec_inputs), self.create_look_ahead_mask(dec_inputs))
      dec_mask_2 = self.create_padding_mask(enc_inputs)

      enc_outputs = self.encoder(enc_inputs, enc_mask, training)
      dec_outputs = self.decoder(dec_inputs, enc_outputs, dec_mask_1, dec_mask_2, training)

      outputs = self.last_linear(dec_outputs)

      return outputs

"""# Treinamento"""

tf.keras.backend.clear_session()

d_model = 128
nb_layers = 4
ffn_units = 512
nb_proj = 8
dropout_rate = 0.1

transformer = Transformer(vocab_size_enc=vocab_size_en, vocab_size_dec=vocab_size_pt, d_model=d_model,
                          nb_layers=nb_layers, FFN_units=ffn_units, nb_proj=nb_proj, dropout_rate=dropout_rate)

loss_object = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True, reduction='none')

def loss_function(target, pred):
  mask = tf.math.logical_not(tf.math.equal(target, 0))
  loss_ = loss_object(target, pred)

  mask = tf.cast(mask, dtype=loss_.dtype)
  loss_ *= mask

  return tf.reduce_mean(loss_)

train_loss = tf.keras.metrics.Mean(name="train_loss")
train_accuracy = tf.keras.metrics.SparseCategoricalAccuracy(name="train_accuracy")

class CustomSchedule(tf.keras.optimizers.schedules.LearningRateSchedule):

  def __init__(self, d_model, warmup_steps=4000):
    super(CustomSchedule, self).__init__()

    self.d_model = tf.cast(d_model, tf.float32)
    self.warmup_steps = warmup_steps

  def __call__(self, step):
    arg1 = tf.math.rsqrt(step)
    arg2 = step * (self.warmup_steps ** -1.5)

    return tf.math.rsqrt(self.d_model) * tf.math.minimum(arg1, arg2)

learning_rate = CustomSchedule(d_model)

optimizer = tf.keras.optimizers.Adam(learning_rate, beta_1=0.9, beta_2=0.98, epsilon=1e-9)

checkpoint_path = "/content/drive/MyDrive/"
ckpt = tf.train.Checkpoint(transformer=transformer, optimizer=optimizer)
ckpt_manager = tf.train.CheckpointManager(ckpt, checkpoint_path, max_to_keep=5)
if ckpt_manager.latest_checkpoint:
  ckpt.restore(ckpt_manager.latest_checkpoint)
  print("Último Checkpoint Restaurado")

epochs = 10
for epoch in range(epochs):
  print('Start or epoch {}'.format(epoch + 1))
  start = time.time()

  train_loss.reset_states()
  train_accuracy.reset_states()

  for (batch, (enc_inputs, targets)) in enumerate(dataset):
    dec_inputs = targets[:, :-1]
    dec_outputs_real = targets[:, 1:]
    with tf.GradientTape() as tape:
      predictions = transformer(enc_inputs, dec_inputs, True)
      loss = loss_function(dec_outputs_real, predictions)

    gradients = tape.gradient(loss, transformer.trainable_variables)
    optimizer.apply_gradients(zip(gradients, transformer.trainable_variables))

    train_loss(loss)
    train_accuracy(dec_outputs_real, predictions)

    if batch % 50 == 0:
      print('Epoch {} Batch {} Loss {:.4f} Accuracy {:.4f}'.format(epoch+1, batch, train_loss.result(), train_accuracy.result()))

  ckpt_save_path = ckpt_manager.save()
  print('Saving checkpoint for epoch {} at {}'.format(epoch + 1, ckpt_save_path))
  print('Time taken for 1 epoch {} secs\n'.format(time.time() - start))


#!/usr/bin/env python

#This script gets raw UBX messages from the receivers through serial communication and parses them
#then it translates the longitude and lattitude to local X and Y of the parking deck, translates the
#heading angle to quaternion angles and publishes on a ROS node

import utm
import math
import rospy
from serial import Serial
from pyubx2 import UBXReader
from transformations import quaternion_from_euler
from std_msgs.msg import Header
from geometry_msgs.msg import PoseWithCovarianceStamped

heading = 0
lon = 0
lat = 0

def ToLocalXY(lat, lon): #This function translates the longitude and lattitude to local x and y of the parking deck
    global x, y

    utm_coordinates = utm.from_latlon(lat, lon)  #Input the lat and lon coordinates
    angle = math.radians(221.8)     #Input the angle of rotation of the coordinates in degrees according to north

    x = (utm_coordinates[0] - 702486.199827401)*math.cos(angle) + \
        (utm_coordinates[1] - 5764080.1172225075)*math.sin(angle)
    y = (utm_coordinates[1] - 5764080.1172225075)*math.cos(angle) - \
        (utm_coordinates[0] - 702486.199827401)*math.sin(angle)

    return {'x': x, 'y': y}

def ToQuaternion(heading): #This function translates the heading angle into quaternion angles
    global w, z

    heading_angle = -math.radians(heading - 230.8) #rotate the angle so that positive x of the parking deck is 0 degrees
    quaternion_angle = quaternion_from_euler(0, 0, heading_angle)
    w = quaternion_angle[0]
    z = quaternion_angle[3]

    return {'z': z, 'w': w}

def main():
    stream = Serial('/dev/ttyACM0', 448000, timeout=3)
    ubr = UBXReader(stream)
    (raw_data, parsed_data) = ubr.read()
    initial_goal_publisher = rospy.Publisher('localization', PoseWithCovarianceStamped, queue_size=10)
    rospy.init_node('location_publisher', anonymous=True)
    rate = rospy.Rate(10) # 10hz
    while not rospy.is_shutdown():
        for (raw_data, parsed_data) in ubr:
            if parsed_data.identity == "NAV-RELPOSNED":
                global heading
                heading = parsed_data.relPosHeading
                print("Heading: {} degrees".format(heading))
            if parsed_data.identity == "NAV-HPPOSLLH":
                global lon, lat
                lon = (parsed_data.lon)
                lat = (parsed_data.lat)
                ToQuaternion(heading)
                ToLocalXY(lat, lon)
                print(x, y)
            localization_msg = PoseWithCovarianceStamped()
            localization_msg.header = Header()
            localization_msg.header.stamp = rospy.Time.now()
            localization_msg.header.frame_id = "map"
            localization_msg.pose.pose.position.x = x
            localization_msg.pose.pose.position.y = y
            localization_msg.pose.pose.orientation.z = z
            localization_msg.pose.pose.orientation.w = w
            localization_msg.pose.covariance = [0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
                                                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06853892326654787]
            initial_goal_publisher.publish(localization_msg)
            rate.sleep()

if __name__ == '__main__':
    main()


import pathlib
import numpy
import heapq
from time import perf_counter

# define data-file
ROOT_DIR = pathlib.Path(__file__).parent.parent
input_file = ROOT_DIR / '2021/input/15.txt'

t1_start = perf_counter()

# create numpy array from file, remove 1 from each risklevel
matrix = numpy.genfromtxt(input_file, dtype=int, delimiter=1) - 1

def calc_risk_level(data):
    max_row, max_col = numpy.shape(data)  # size of grid
    risk_levels = [(0, (0, 0))]  # risk, starting point
    while risk_levels:
        # remove smallest item, i.e lowest risk
        risk, (col, row) = heapq.heappop(risk_levels)
        # when we reach end of matrix return risk
        if (col, row) == (max_col - 1, max_row - 1):
            return risk
        for col, row in [
            (col, row + 1), (col + 1, row), (col, row - 1), (col - 1, row)
        ]:
            if (col >= 0 and col < max_col and row >= 0 and row < max_row
                    and data[row][col] >= 0):
                heapq.heappush(
                        risk_levels,
                        (risk + (data[row][col] % 9) + 1, (col, row))
                )
                data[row][col] = -1    # mark as seen

matrix_b = matrix.copy()  # store copy of original matrix before solving a
print(f'Answer B: {calc_risk_level(matrix)}')

# expand numpy array
matrix_b = numpy.concatenate([matrix_b + i for i in range(5)], axis=0)
matrix_b = numpy.concatenate([matrix_b + i for i in range(5)], axis=1)
print(f'Answer B: {calc_risk_level(matrix_b)}')

t1_stop = perf_counter()
print(f'Elapsed time during the whole program in seconds: {t1_stop-t1_start}')


'''
Made by NEELANGSHU ROY
Student of B.Tech in Computer Science and Engineering at NIT Allahabad
Batch of 2021-25
'''
import sys
import random
import pygame
from pygame.locals import *

BACKGROUND = 'Game sprites/game background.png'
BASE = 'Game sprites/game_base.png'
PIPE = 'Game sprites/game_pillar.jpg'
SCREEN = pygame.display.set_mode((960,686))
BIRD = 'Game sprites/flappy_bird.png'
GAME_SPRITES,GAME_SOUNDS={},{}
FPS=30
def welcome():
    GAME_SOUNDS['welcomeMusic'].play()
    kk=GAME_SPRITES['play']
    mm=GAME_SPRITES['instruct']
    nn=GAME_SPRITES['exit']
    inst=GAME_SPRITES['instructions']
    bb=GAME_SPRITES['back']
    exi=GAME_SPRITES['exitpanel']
    yes=GAME_SPRITES['yes']
    no=GAME_SPRITES['no']
    k,n=0,0
    while True:
        SCREEN.blit(GAME_SPRITES['background'],(0,0))
        SCREEN.blit(GAME_SPRITES['gamename'],(272,15))
        SCREEN.blit(GAME_SPRITES['myname'],(225,114))

        SCREEN.blit(GAME_SPRITES['base'],(0,541))
        SCREEN.blit(GAME_SPRITES['bird'],(80,300))

        if k==0 and n==0:
            SCREEN.blit(kk,(332,205))
            SCREEN.blit(mm,(332,283))
            SCREEN.blit(nn,(332,361))
        elif k==1:
            SCREEN.blit(inst,(180,205))
            SCREEN.blit(bb,(484,535))
        elif n==1:
            SCREEN.blit(exi,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))

        for event in pygame.event.get():
            change=0
            if event.type==QUIT:
                    pygame.quit()
                    sys.exit()
                    return False
            x,y=pygame.mouse.get_pos()
            clic=pygame.mouse.get_pressed()
            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 205<=y<=268) and k==0 and n==0):
                GAME_SOUNDS['click'].play()
                return True
            elif (332<=x<=628 and 205<=y<=268 and k==0 and n==0):
                kk=GAME_SPRITES['play_click']
            elif k==0 and n==0:
                kk=GAME_SPRITES['play']

            if event.type==MOUSEBUTTONDOWN and event.button==1 and (484<=x<=780 and 535<=y<=598) and k==1 and n==0:
                GAME_SOUNDS['click'].play()
                k=0
            elif (484<=x<=780 and 535<=y<=598) and k==1:
                bb=GAME_SPRITES['back_click']
            elif k==1:
                bb=GAME_SPRITES['back']

            if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 283<=y<=346) and k==0 and n==0:
                GAME_SOUNDS['click'].play()
                k=1
            elif (332<=x<=628 and 283<=y<=346 and k==0 and n==0):
                mm=GAME_SPRITES['instruct_click']
            elif k==0 and n==0:
                mm=GAME_SPRITES['instruct']

            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 325<=y<=388) and n==1 and k==0):
                n=0
                GAME_SOUNDS['click'].play()
                pygame.quit()
                sys.exit()
                return False
            elif (332<=x<=628 and 325<=y<=388) and n==1 and k==0:
                yes=GAME_SPRITES['yes_click']
            elif n==1 and k==0:
                yes=GAME_SPRITES['yes']

            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 408<=y<=471) and n==1 and k==0):
                GAME_SOUNDS['click'].play()
                change=1
                n=0
            elif (332<=x<=628 and 408<=y<=471) and n==1 and k==0:
                no=GAME_SPRITES['no_click']
            elif n==1 and k==0:
                no=GAME_SPRITES['no']

            if change==1:
                continue

            if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=626 and 361<=y<=424) and k==0 and n==0):
                GAME_SOUNDS['click'].play()
                n=1
            elif (332<=x<=626 and 361<=y<=424 and k==0 and n==0):
                nn=GAME_SPRITES['exit_click']
            elif k==0 and n==0:
                nn=GAME_SPRITES['exit']

        pygame.display.update()
        FPSCLOCK.tick(FPS)

def gameover():
    GAME_SOUNDS['die'].play()
    new=0
    nn=''
    with open('hs.txt') as f:
        nn=f.read()
    if nn[len(nn)-1]==' ':
        new=1
        nn=nn[:len(nn)-1]
        with open('hs.txt','w') as f:
            f.write(nn)
    ss=[int(x) for x in list(nn)]

    try_ag = GAME_SPRITES['retry']
    exi = GAME_SPRITES['exit']
    exit_p = GAME_SPRITES['exitpanel']
    yes=GAME_SPRITES['yes']
    no=GAME_SPRITES['no']
    k=0

    while True:
        SCREEN.blit(GAME_SPRITES['gameover'],(0,0))
        SCREEN.blit(GAME_SPRITES['base'],(0,541))
        if k==0:
            SCREEN.blit(try_ag,(154,440))
            SCREEN.blit(exi,(510,440))
            width=435
            for item in ss:
                SCREEN.blit(GAME_SPRITES['digits'][item],(width,330))
                width+=45
            if new==1:
                SCREEN.blit(GAME_SPRITES['new'],(width+90,300))
        elif k==1:
            SCREEN.blit(exit_p,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))

        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                sys.exit()
                return False
            x,y=pygame.mouse.get_pos()
            clic=pygame.mouse.get_pressed()

            if clic[0] and (332<=x<=628 and 325<=y<=388) and k==1:
                k=0
                GAME_SOUNDS['click'].play()
                pygame.quit()
                sys.exit()
                return 0
            elif (332<=x<=628 and 325<=y<=388) and k==1:
                yes=GAME_SPRITES['yes_click']
            elif k==1:
                yes=GAME_SPRITES['yes']

            if clic[0] and (332<=x<=629 and 408<=y<=471) and k==1:
                GAME_SOUNDS['click'].play()
                k=0
            elif (332<=x<=629 and 408<=y<=471) and k==1:
                no=GAME_SPRITES['no_click']
            elif k==1:
                no=GAME_SPRITES['no']

            if clic[0] and (154<=x<=450 and 440<=y<=503) and k==0:
                GAME_SOUNDS['click'].play()
                return True
            elif (154<=x<=450 and 440<=y<=503) and k==0:
                try_ag=GAME_SPRITES['retry_click']
            elif k==0:
                try_ag=GAME_SPRITES['retry']

            if clic[0] and (510<=x<=806 and 440<=y<=503) and k==0:
                k=1
                GAME_SOUNDS['click'].play()
            elif (510<=x<=806 and 440<=y<=503) and k==0:
                exi=GAME_SPRITES['exit_click']
            elif k==0:
                exi = GAME_SPRITES['exit']

        pygame.display.update()
        FPSCLOCK.tick(FPS)

def roll():
    w=[960, 960+310, 960+620, 960+930]
    t=[
        random.randint(250,400),
        random.randint(250,400),
        random.randint(250,400),
        random.randint(250,400)
    ]
    # pattern of pipes will remain the same as values of t[0], t[1],
    # t[2] and t[3] remain fixed outside the loop

    t_coin=[
        random.randint(0,1),
        random.randint(0,1),
        random.randint(0,1),
        random.randint(0,1)
    ]

    pipeVel = [4,5,7,9,11,13,16]
    sp=[0, 26, 50]
    sc=[0, 10, 20, 30, 40, 50, 75]

    p=300
    score = 0

    playerPosX=80

    PAUSE=0

    kk=GAME_SPRITES['resume']
    mm=GAME_SPRITES['restart']
    nn=GAME_SPRITES['instruct']
    pp=GAME_SPRITES['exit']
    inst=GAME_SPRITES['instructions']
    bb=GAME_SPRITES['back']
    rest=GAME_SPRITES['restartpanel']
    exi=GAME_SPRITES['exitpanel']
    yes=GAME_SPRITES['yes']
    no=GAME_SPRITES['no']
    k1,k2,n=0,0,0

    while True:
        s=[int(x) for x in list(str(score))]
        s.reverse()
        width=GAME_SPRITES['digits'][4].get_width()

        SCREEN.blit(GAME_SPRITES['background'],(0,0))

        for i in range(4):
            SCREEN.blit(GAME_SPRITES['pipe'][0],(w[i],t[i]))
            i2=2
            for i1 in range(3):
                if 0==score:
                    SCREEN.blit(GAME_SPRITES['pipe'][1],(w[i],t[i]-750+sp[0]))
                    break
                if sc[i2-2]<score<=sc[i2]:
                    SCREEN.blit(GAME_SPRITES['pipe'][1],(w[i],t[i]-750+sp[i1]))
                    break
                elif sc[6]<score:
                    SCREEN.blit(GAME_SPRITES['pipe'][1],(w[i],t[i]-750+sp[2]))
                    break
                i2 += 2
            if t_coin[i]==1:
                k=2
                for j in range(3):
                    if score==0:
                        SCREEN.blit(GAME_SPRITES['coin'],(w[i]+50,t[i] - 13 - int( (150-sp[0])/2 )) )
                    elif sc[k-2]<score<=sc[k]:
                        SCREEN.blit(GAME_SPRITES['coin'],(w[i]+50,t[i] - 13 - int( (150-sp[j])/2 )) )
                        break
                    elif sc[6]<score:
                        SCREEN.blit(GAME_SPRITES['coin'],(w[i]+50,t[i] - 13 - int( (150-sp[2])/2 )) )
                        break
                    k+=2

        # t[i] - 163 + int( (150-sp[j])/2) )

        SCREEN.blit(GAME_SPRITES['base'],(0,541))
        SCREEN.blit(GAME_SPRITES['bird'],(playerPosX,p))

        for i in range(len(s)):
            SCREEN.blit(GAME_SPRITES['digits'][s[i]],(GAME_SPRITES['background'].get_width()-width,0))
            width+=GAME_SPRITES['digits'][4].get_width()
        SCREEN.blit(GAME_SPRITES['level'],(0,0))
        if 0<=score<=10:
            SCREEN.blit(GAME_SPRITES['digits'][1],(195,0))
        elif 10<score<=20:
            SCREEN.blit(GAME_SPRITES['digits'][2],(195,0))
        elif 20<score<=30:
            SCREEN.blit(GAME_SPRITES['digits'][3],(195,0))
        elif 30<score<=40:
            SCREEN.blit(GAME_SPRITES['digits'][4],(195,0))
        elif 40<score<=50:
            SCREEN.blit(GAME_SPRITES['digits'][5],(195,0))
        elif 50<score<=75:
            SCREEN.blit(GAME_SPRITES['digits'][6],(195,0))
        elif 75<score:
            SCREEN.blit(GAME_SPRITES['digits'][7],(195,0))

        if k1==0 and k2==0 and n==0 and PAUSE==1:
            SCREEN.blit(kk,(332,205))
            SCREEN.blit(mm,(332,283))
            SCREEN.blit(nn,(332,361))
            SCREEN.blit(pp,(332,439))
        elif k1==1 and k2==0 and n==0 and PAUSE==1:
            SCREEN.blit(rest,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))
        elif k2==1 and k1==0 and n==0 and PAUSE==1:
            SCREEN.blit(inst,(180,205))
            SCREEN.blit(bb,(484,535))
        elif n==1 and k1==0 and k2==0 and PAUSE==1:
            SCREEN.blit(exi,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))

        pygame.display.update()
        FPSCLOCK.tick(FPS)

        prev_score=score

        for i in range(4):
            a0=0

            k=2
            for j in range(3):
                if sc[k-2]<=score<sc[k]:
                    a0=t[i] - 13 - int( (150-sp[j])/2 )
                    break
                elif sc[6]<=score:
                    a0=t[i] - 13 - int( (150-sp[j])/2 )
                    break
                k+=2

            a1=a0+GAME_SPRITES['coin'].get_height()
            a2=p+GAME_SPRITES['bird'].get_height()
            a3=p+int(GAME_SPRITES['bird'].get_height()/2)
            a4=w[i]+50
            a5=playerPosX+GAME_SPRITES['bird'].get_width()
            a6=a4+GAME_SPRITES['coin'].get_width()+GAME_SPRITES['bird'].get_width()
            if (a4<=a5<a6 and (a0<=p<=a1 or a0<=a2<=a1 or a0<=a3<=a1) and t_coin[i]==1):
                score+=1
                GAME_SOUNDS['point'].play()
                t_coin[i]=0

        if prev_score<=10 and score>10:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=20 and score>20:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=30 and score>30:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=40 and score>40:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=50 and score>50:
            GAME_SOUNDS['level_up'].play()
        if prev_score<=75 and score>75:
            GAME_SOUNDS['level_up'].play()

        for i in range(4):
            go=0
            b1=playerPosX+GAME_SPRITES['bird'].get_width()
            b2=p+6
            b3=w[i]+GAME_SPRITES['pipe'][0].get_width()
            b4=p+GAME_SPRITES['bird'].get_height()
            if ((b1-12<=w[i]<=b1 and b2<=t[i]-150)or(playerPosX<=w[i]<b1-12 and p<=t[i]-150)or(playerPosX<w[i]<=b1 and b4>t[i])):
                go=1
            elif (w[i]<b1<=b3 and (p<=t[i]-150 or b4>t[i]) ):
                go=1
            elif ( (playerPosX<b3<=playerPosX+6 and b4-13>=t[i])or(playerPosX<b3<=playerPosX+14 and p+12<=t[i]-150)or(playerPosX+14<b3<=b1 and p<=t[i]-150)or(playerPosX+6<b3<=b1 and b4>t[i]) ):
                go=1
            if go==1:
                numb=0
                with open('hs.txt') as f:
                    numb=int(f.read())
                if score>numb:
                    with open('hs.txt','w') as f:
                        f.write(str(score)+' ')
                return 1
            '''if ( 80<=w[i]<=80+GAME_SPRITES['bird'].get_width() or w[i]<=(80+GAME_SPRITES['bird'].get_width())<=(w[i]+GAME_SPRITES['pipe'][0].get_width()) or 80<=(w[i]+GAME_SPRITES['pipe'][0].get_width())<=(80+GAME_SPRITES['bird'].get_width()) ) and (p+GAME_SPRITES['bird'].get_height())>=t[i]:
                return True
            elif ( 80<=w[i]<=80+GAME_SPRITES['bird'].get_width() or w[i]<=(80+GAME_SPRITES['bird'].get_width())<=(w[i]+GAME_SPRITES['pipe'][0].get_width()) or 80<=(w[i]+GAME_SPRITES['pipe'][0].get_width())<=(80+GAME_SPRITES['bird'].get_width()) ) and (t[i]-500+GAME_SPRITES['pipe'][0].get_height())>=p:
                return True '''

        keys=pygame.key.get_pressed() # a list storing keys pressed in 1 iteration
        if ((keys[K_UP] or keys[K_w]) and p>=0) and PAUSE==0:     # This syntax is correct, although there are no
            p-=3                      # loops involved, but if UP key is pressed 5 times
        elif ((keys[K_DOWN] or keys[K_s]) and p<=545-GAME_SPRITES['bird'].get_height()) and PAUSE==0:
            p+=3                      # in 1 iteration, then this if condition is executed
        elif ((keys[K_LEFT] or keys[K_a]) and playerPosX>=0) and PAUSE==0:
            playerPosX-=3             # 5 times, how I don't know !
        elif ((keys[K_RIGHT] or keys[K_d]) and playerPosX+GAME_SPRITES['bird'].get_width()<=960) and PAUSE==0:
            playerPosX+=3

        # for key in keys:
        #     if key==K_UP:
        #         p-=3              This syntax is wrong, though it seems
        #     elif key==K_DOWN:     correct, but it is not
        #         p+=3

        for i in range(4):
            if w[i]>-130 and score<=10 and PAUSE==0:
                w[i]-=pipeVel[0]
            elif w[i]>-130 and 10<score<=20 and PAUSE==0:
                w[i]-=pipeVel[1]
            elif w[i]>-130 and 20<score<=30 and PAUSE==0:
                w[i]-=pipeVel[2]
            elif w[i]>-130 and 30<score<=40 and PAUSE==0:
                w[i]-=pipeVel[3]
            elif w[i]>-130 and 40<score<=50 and PAUSE==0:
                w[i]-=pipeVel[4]
            elif w[i]>-130 and 50<score<=75 and PAUSE==0:
                w[i]-=pipeVel[5]
            elif w[i]>-130 and 75<score and PAUSE==0:
                w[i]-=pipeVel[6]
            elif 1<=i<=3 and PAUSE==0:
                w[i]=w[i-1]+GAME_SPRITES['pipe'][0].get_width()+180
                t[i]=random.randint(250,400)
                t_coin[i]=random.randint(0,1)
            elif i==0 and PAUSE==0:
                w[0]=w[3]+GAME_SPRITES['pipe'][0].get_width()+180
                t[0]=random.randint(250,400)
                t_coin[0]=random.randint(0,1)
        # now this will bring some volatility to the pipe pattern

        '''if k1==0 and k2==0 and n==0 and PAUSE==1:
            SCREEN.blit(kk,(332,205))
            SCREEN.blit(mm,(332,283))
            SCREEN.blit(nn,(332,361))
        elif k1==1 and PAUSE==1:
            SCREEN.blit(rest,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))
        elif k2==1 and PAUSE==1:
            SCREEN.blit(inst,(180,205))
            SCREEN.blit(bb,(484,535))
        elif n==1 and PAUSE==1:
            SCREEN.blit(exi,(180,205))
            SCREEN.blit(yes,(332,325))
            SCREEN.blit(no,(332,408))'''

        for event in pygame.event.get():

            change = 0

            if event.type==QUIT:
                pygame.quit()
                sys.exit()
                return 0
            elif event.type==KEYDOWN and event.key==K_ESCAPE:
                PAUSE=1
                change=1
            x,y=pygame.mouse.get_pos()
            # clic=pygame.mouse.get_pressed()

            if (n==1 or k1==1 or k2==1) and PAUSE==1:
                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 325<=y<=388) and k1==1 and PAUSE==1:
                    k1=0
                    GAME_SOUNDS['click'].play()
                    return 2
                elif (332<=x<=628 and 325<=y<=388) and k1==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes_click']
                elif k1==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=629 and 408<=y<=471) and k1==1 and PAUSE==1:
                    k1=0
                    change=1
                    GAME_SOUNDS['click'].play()
                elif (332<=x<=629 and 408<=y<=471) and k1==1 and PAUSE==1:
                    no=GAME_SPRITES['no_click']
                elif k1==1 and PAUSE==1:
                    no=GAME_SPRITES['no']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (484<=x<=780 and 535<=y<=598) and k2==1 and PAUSE==1:
                    k2=0
                    # change=1
                    GAME_SOUNDS['click'].play()
                elif (484<=x<=780 and 535<=y<=598) and k2==1 and PAUSE==1:
                    bb=GAME_SPRITES['back_click']
                elif k2==1 and PAUSE==1:
                    bb=GAME_SPRITES['back']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 325<=y<=388) and n==1 and PAUSE==1:
                    n=0
                    GAME_SOUNDS['click'].play()
                    pygame.quit()
                    sys.exit()
                    return 0
                elif (332<=x<=628 and 325<=y<=388) and n==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes_click']
                elif n==1 and PAUSE==1:
                    yes=GAME_SPRITES['yes']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=629 and 408<=y<=471) and n==1 and PAUSE==1:
                    n=0
                    change=1
                    GAME_SOUNDS['click'].play()
                elif (332<=x<=629 and 408<=y<=471) and n==1 and PAUSE==1:
                    no=GAME_SPRITES['no_click']
                elif n==1 and PAUSE==1:
                    no=GAME_SPRITES['no'] ##

            if change==1:
                continue

            if k1==0 and k2==0 and n==0 and PAUSE==1:
                if (event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 205<=y<=268) and k1==0 and k2==0 and n==0) and PAUSE==1:
                    '''or (event.type==KEYDOWN and event.key==K_ESCAPE)'''
                    '''or (event.type==KEYDOWN and event.key==K_ESCAPE and k1==0 and k2==0 and n==0)'''
                    PAUSE=0
                    GAME_SOUNDS['click'].play()
                elif (332<=x<=628 and 205<=y<=268) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    kk=GAME_SPRITES['resume_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    kk=GAME_SPRITES['resume']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 283<=y<=346) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    GAME_SOUNDS['click'].play()
                    k1,k2,n=1,0,0
                elif (332<=x<=628 and 283<=y<=346) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    mm=GAME_SPRITES['restart_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    mm=GAME_SPRITES['restart']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 361<=y<=424) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    GAME_SOUNDS['click'].play()
                    k2,k1,n=1,0,0
                elif (332<=x<=628 and 361<=y<=424) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    nn=GAME_SPRITES['instruct_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    nn=GAME_SPRITES['instruct']

                if event.type==MOUSEBUTTONDOWN and event.button==1 and (332<=x<=628 and 439<=y<=502) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    GAME_SOUNDS['click'].play()
                    n,k1,k2=1,0,0
                elif (332<=x<=628 and 439<=y<=502) and k1==0 and k2==0 and n==0 and PAUSE==1:
                    pp=GAME_SPRITES['exit_click']
                elif k1==0 and k2==0 and n==0 and PAUSE==1:
                    pp=GAME_SPRITES['exit'] ##

if __name__=='__main__':
    pygame.init()
    FPSCLOCK=pygame.time.Clock()
    pygame.display.set_caption('FLAPPY BIRD by Neelangshu Roy')
    pygame.display.set_icon(pygame.image.load('Game sprites/flappybird_windowicon.png'))
    GAME_SPRITES['background']=pygame.image.load(BACKGROUND).convert()
    GAME_SPRITES['base']=pygame.image.load(BASE).convert_alpha()
    GAME_SPRITES['pipe']=(
        pygame.image.load(PIPE).convert_alpha(),
        pygame.transform.rotate(pygame.image.load(PIPE).convert_alpha(),180)
    )
    GAME_SPRITES['bird']=pygame.image.load(BIRD).convert_alpha()
    GAME_SPRITES['myname']=pygame.image.load('Game sprites/my_name.png').convert_alpha()
    GAME_SPRITES['gamename']=pygame.image.load('Game sprites/game_name.png').convert_alpha()
    GAME_SPRITES['gameover']=pygame.image.load('Game sprites/game_over.png').convert_alpha()
    GAME_SPRITES['coin']=pygame.image.load('Game sprites/coin.png').convert_alpha()
    GAME_SPRITES['level']=pygame.image.load('Game sprites/level.png').convert_alpha()

    GAME_SPRITES['play']=pygame.image.load('Game sprites/play.png').convert_alpha()
    GAME_SPRITES['play_click']=pygame.image.load('Game sprites/play_clicked.png').convert_alpha()
    GAME_SPRITES['exit']=pygame.image.load('Game sprites/exit.png').convert_alpha()
    GAME_SPRITES['exit_click']=pygame.image.load('Game sprites/exit_clicked.png').convert_alpha()
    GAME_SPRITES['resume']=pygame.image.load('Game sprites/resume.png').convert_alpha()
    GAME_SPRITES['resume_click']=pygame.image.load('Game sprites/resume_clicked.png').convert_alpha()
    GAME_SPRITES['restart']=pygame.image.load('Game sprites/restart.png').convert_alpha()
    GAME_SPRITES['restart_click']=pygame.image.load('Game sprites/restart_clicked.png').convert_alpha()
    GAME_SPRITES['instruct']=pygame.image.load('Game sprites/instructions.png').convert_alpha()
    GAME_SPRITES['instruct_click']=pygame.image.load('Game sprites/instructions_clicked.png').convert_alpha()
    GAME_SPRITES['instructions']=pygame.image.load('Game sprites/instruction.png').convert_alpha()
    GAME_SPRITES['back']=pygame.image.load('Game sprites/back.png').convert_alpha()
    GAME_SPRITES['back_click']=pygame.image.load('Game sprites/back_clicked.png').convert_alpha()
    GAME_SPRITES['exitpanel']=pygame.image.load('Game sprites/exit_panel.png').convert_alpha()
    GAME_SPRITES['restartpanel']=pygame.image.load('Game sprites/restart_panel.png').convert_alpha()
    GAME_SPRITES['yes']=pygame.image.load('Game sprites/yes.png').convert_alpha()
    GAME_SPRITES['yes_click']=pygame.image.load('Game sprites/yes_clicked.png').convert_alpha()
    GAME_SPRITES['no']=pygame.image.load('Game sprites/no.png').convert_alpha()
    GAME_SPRITES['no_click']=pygame.image.load('Game sprites/no_clicked.png').convert_alpha()
    GAME_SPRITES['new']=pygame.image.load('Game sprites/new.png').convert_alpha()
    GAME_SPRITES['retry']=pygame.image.load('Game sprites/retry.png').convert_alpha()
    GAME_SPRITES['retry_click']=pygame.image.load('Game sprites/retry_clicked.png').convert_alpha()

    GAME_SPRITES['digits']=(
        pygame.image.load('Game sprites/0_number.png').convert_alpha(),
        pygame.image.load('Game sprites/1_number.png').convert_alpha(),
        pygame.image.load('Game sprites/2_number.png').convert_alpha(),
        pygame.image.load('Game sprites/3_number.png').convert_alpha(),
        pygame.image.load('Game sprites/4_number.png').convert_alpha(),
        pygame.image.load('Game sprites/5_number.png').convert_alpha(),
        pygame.image.load('Game sprites/6_number.png').convert_alpha(),
        pygame.image.load('Game sprites/7_number.png').convert_alpha(),
        pygame.image.load('Game sprites/8_number.png').convert_alpha(),
        pygame.image.load('Game sprites/9_number.png').convert_alpha(),
    )
    GAME_SOUNDS['die']=pygame.mixer.Sound('Game sounds/die.wav')
    GAME_SOUNDS['hit']=pygame.mixer.Sound('Game sounds/hit.wav')
    GAME_SOUNDS['point']=pygame.mixer.Sound('Game sounds/point.wav')
    GAME_SOUNDS['wing']=pygame.mixer.Sound('Game sounds/wing.wav')
    GAME_SOUNDS['welcomeMusic']=pygame.mixer.Sound('Game sounds/game_openingSound.mp3')
    GAME_SOUNDS['click']=pygame.mixer.Sound('Game sounds/click.wav')
    GAME_SOUNDS['level_up']=pygame.mixer.Sound('Game sounds/level_complete.wav')
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['welcomeMusic'],0.80)
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['click'],0.20)
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['point'],0.30)
    pygame.mixer.Sound.set_volume(GAME_SOUNDS['level_up'],8.0)

    bool = welcome()
    while bool:
        check=0
        check = roll()
        if check==0:
            bool=False
            break
        elif check==1:
            bool=True
        elif check==2:
            continue
        bool = gameover()
        if bool==False:
            break