from collections import OrderedDict

# from datetime import datetime
from django.conf import settings
from django.db import models
from django.utils import timezone

from jsonfield import JSONField

# Create your models here.

class fhir_Consent(models.Model):
    """ Store User:application consent in fhir format
    """
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    application = models.ForeignKey(settings.OAUTH2_PROVIDER_APPLICATION_MODEL)
    consent = JSONField(load_kwargs={'object_pairs_hook': OrderedDict})
    created = models.DateTimeField(blank=True, null=True)
    revoked = models.DateTimeField(blank=True, null=True)
    valid_until = models.DateTimeField(blank=True, null=True)
    key = models.TextField(max_length=250, blank=True, null=True)

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = timezone.now()
        # Update the key field
        self.key = self.user.username + ":" + self.application.name + "["
        self.key += self.created.strftime('%Y-%m-%dT%H:%M.%S') + "]"

        if self.valid_until:
            # print("\nChecking valid_until"
            #       " still valid:%s\nType:%s" % (self.valid_until,
            #                                   type(self.valid_until)))
            if self.valid_until <= timezone.now():
                if not self.revoked:
                    self.revoked = self.valid_until

        return super(fhir_Consent, self).save(*args, **kwargs)

    def revoke_consent(self, confirm=False, *args, **kwargs):
        if confirm is True:
            if not self.revoked:
                self.revoked = timezone.now()

        return super(fhir_Consent, self).save(*args, **kwargs)

    def status(self):
        consent_status = None
        if self.revoked:
            consent_status = "REVOKED"
        else:
            consent_status = "VALID"
        return consent_status

    def granted(self):
        if self.created and self.revoked:
            valid = False
        else:
            valid = True
        return valid

    def __str__(self):
        name = '%s %s (%s)' % (self.user.first_name,
                               self.user.last_name,
                               self.user.username)
        return ("%s:%s" % (name, self.application.name))

    def __unicode__(self):
        name = '%s %s (%s)' % (self.user.first_name,
                               self.user.last_name,
                               self.user.username)
        return ("%s:%s" % (name, self.application.name))


import time

def reverseTimSort(array):
    for i in range(len(array)):
        for j in range(i):
            if array[j] > array[i]:
                array[j], array[i] = array[i], array[j]
    return array

def getBiggerValue(array):
    biggerValue = 0
    for item in array:
        if item > biggerValue:
            biggerValue = item
    return biggerValue

def convertValueToCents(value):
    return int(float(value) * 100)

def openFile(filename):
    with open(filename, 'r') as f:
        value = convertValueToCents(f.readline())
        coins = []
        for line in f:
            coins = coins + line.split()
        coins = [int(coin) for coin in coins]

    return value, coins

def countCoins(coins):
    count = 0
    for coin in coins:
        count += coin * coins[coin]
    return count

def validate(coins, change, value):
    return change == countCoins(coins) and change >= value

def getTime(func, filename):
    value, coins = openFile(filename)
    start = time.time()
    change, changeCoins = func(value, coins)
    end = time.time()
    print("Value: ", value)
    print("Change: ", change)
    print("Coins: ", changeCoins)
    print("Is valid: ", validate(changeCoins, change, value))

    print("Tempo de execucao: ", end - start)


side=[]
for x in range(0,3):
    a=int(input(f"Enter side{x+1}: "))
    side.append(a)
if side[2]+side[1]>side[0] and side[0]+side[2]>side[1] and side[0]+side[1]>side[2]:
    print("This is a Prefect Triangle")
else:
    print("Thius is Not a triangle")


import logging
import os
import gzip
import filetype
import multiprocessing as mp
import pandas as pd
from moonstone.normalization.reads.read_downsize import DownsizePair

logger = logging.getLogger(__name__)

def pair_up(seq_files_info):
    paired_list = []
    query = None

    for key in seq_files_info:
        if key not in paired_list:  # Any one pairs should generate ONLY one loop.
            query = seq_files_info[key][0]  # set the query to the header of the sequence file
            file_counter = 0  # Confirm that we find two files
            fwd_reads_file = None  # reset the file results
            rev_reads_file = None

            for key_a in seq_files_info:  # Loop through again to find the matching header
                if query in seq_files_info[key_a][0]:  # If the headers match it is either forward or reverse reads.
                    if seq_files_info[key_a][1] == '1':
                        fwd_reads_file = key_a
                        file_counter += 1
                    if seq_files_info[key_a][1] == '2':
                        rev_reads_file = key_a
                        file_counter += 1
                    if fwd_reads_file and rev_reads_file:
                        logger.info('\nForward file = %s\nReverse file = %s' % (fwd_reads_file, rev_reads_file))
                        paired_list.append(fwd_reads_file)
                        paired_list.append(rev_reads_file)

    logger.info(f'List of Paired Reads Files:\n{paired_list}')
    return paired_list

def plot_reads(file_info_dict):
    logger.info('Generating plot of number of reads')
    # generate a dataframe from the file information dictionary
    # to include filename as the index
    files: list = []
    reads: list = []
    for key in file_info_dict:
        files.append(key)
        reads.append(file_info_dict[key][2])

    df = pd.DataFrame(index=files, data=reads, columns=['reads'])
    return df

class DownsizeDir:
    """Used to downsize all reads in a given directory to the same number of reads. Reads are downsized by
    random selection of raw reads generating a subset from which alpha diversity can be calculated.
    Note that removal of data, while useful for diversity assessment, is no longer considered good practice.
    https://doi.org/10.1371/journal.pcbi.1003531
    """
    def __init__(self, n=1000, processes=1, seed=62375, in_dir='./', out_dir=''):
        logger.info(f'Starting instance of {__class__.__name__} in {__name__}.')
        self.in_dir = in_dir
        self.downsize_to = n
        self.seed = seed

        if out_dir:
            self.out_dir = out_dir
        else:
            self.out_dir = in_dir + 'downsized/'
            logger.info('No output directory specified.\nCreating default: %s ' % self.out_dir)
        if not os.path.exists(self.out_dir):
            os.mkdir(self.out_dir)
        else:
            logger.info('Looks like %s exists.' % self.out_dir)

        if processes > mp.cpu_count():
            logger.warning('Number of requested processes [%i] is greater that the number of system CPUs [%i]' %
                           (processes, mp.cpu_count()))
            self.processes = mp.cpu_count()
            logger.info('Number of processes set to maximum number of detected CPUs [%i].' % self.processes)
        else:
            self.processes = processes
            logger.info('Number of processes set to %i ' % self.processes)

    def detect_seq_reads(self):
        """The provided directory might contain files that are not sequence reads.
        This module attempts to identify ONLY files with sequence data."""
        logger.info(f'Detecting sequence files in {self.in_dir}')
        seq_files = [f for f in os.listdir(self.in_dir) if os.path.isfile(self.in_dir + f)]
        logger.info(f'List of Sequencing Files Found:\n{seq_files}')
        return seq_files

    def read_info(self, seq_file):
        """Gather information on the number of reads for each of the sequence reads in the given directory.
        Number of reads can be plotted or reported. Files names and headers are used to match pairs.
        Both compressed and gzipped files are accepted.

        Function returns a dictionary where the filename is the key and the value is a list of information:
        {file: [header, F/R, Number of reads, format]}
        # e.g. {'forward.fastq': ['@A00709:44:HYG57DSXX:2:1101:10737:1266', '1', 100257, 'Uncompressed/FASTQ']"""

        seq_files_info = {}
        detect_type = filetype.guess(self.in_dir + seq_file)
        if detect_type:
            if detect_type.mime == 'application/gzip':
                logger.info('Detected gzipped file for %s' % seq_file)
                file = gzip.open(self.in_dir + seq_file, 'r')
                read_num = sum(1 for _ in gzip.open(self.in_dir + seq_file)) // 4
                header = file.readline().decode().split(' ')[0]
                file.seek(0, 0)
                pair = file.readline().decode().split(' ')[1][0]
                file.close()
                seq_files_info[seq_file] = [header, pair, read_num, detect_type.mime]
                return seq_files_info

        if not detect_type:
            logger.info('Assuming uncompressed fastq file for %s' % seq_file)
            file = open(self.in_dir + seq_file, 'r')
            read_num = sum(1 for _ in open(self.in_dir + seq_file)) // 4
            header = file.readline().split(' ')[0]
            file.seek(0, 0)
            pair = file.readline().split(' ')[1][0]
            file.close()
            seq_files_info[seq_file] = [header, pair, read_num, 'Uncompressed/FASTQ']
            return seq_files_info

    def down_dir_pair(self):
        files_to_downsize = self.detect_seq_reads()
        logging.info('Found %i files.' % len(files_to_downsize))

        '''This is a quick but efficient multiprocessing implementation to handle retrieving information from files
        in the target directory. The Pool is created, the number of workers = the class 'processes' attribute.
        Results are expected as a dictionary, so the resulting 'list of dictionaries' is converted with handy
        dict comprehension.
        '''
        with mp.Pool(processes=self.processes) as pool:
            results = pool.map(self.read_info, files_to_downsize, chunksize=1)
        file_info_dict = {k: v for result in results for k, v in result.items()}

        list_to_downsize = pair_up(file_info_dict)

        worker_parameters = []
        for k in range(len(list_to_downsize)//2):  # number of files divided by 2: one instance per pair
            worker_parameters.append({'raw_file_f': list_to_downsize[k * 2],
                                      'raw_file_r': list_to_downsize[k * 2 + 1],
                                      'read_info': file_info_dict[list_to_downsize[k * 2]],
                                      'in_dir': self.in_dir, 'out_dir': self.out_dir, 'n': self.downsize_to
                                      })

        with mp.Pool(processes=self.processes) as pool:
            check = pool.map(self.instantiate, worker_parameters, chunksize=1)  # noqa

        logger.info('Done!')

    def instantiate(self, wp):
        logger.info('Instantiating with parameters: %s' % wp)
        instance = DownsizePair(**wp)
        instance.downsize_pair()


import matplotlib.pyplot as plt
import numpy as np

with open('scores.txt', 'r') as f:
    scores = f.read().splitlines()
    scores = list(map(int, scores))

    mean = []
    max_list = []
    for i,j in enumerate(scores):
        if i % 1000 == 0:
            mean.append(np.average(scores[i:i+1000]))
            max_list.append(max(scores[i:i+1000]))

    episode = range(len(mean))
    plt.ylabel('episode scores')
    plt.xlabel('training episodes')
    plt.yticks(np.arange(min(mean), max(mean)+1, 5000))
    plt.title('mean scores')
    plt.plot(episode, mean)
    plt.show()

    plt.ylabel('episode scores')
    plt.xlabel('training episodes')
    plt.yticks(np.arange(min(max_list), max(max_list)+1, 10000))
    plt.title('max scores')
    plt.plot(episode, max_list)
    plt.show()


"""
 Problem Statement

 A zero-indexed array A of length N contains all integers from 0 to N-1.
 Find and return the longest length of set S,
 where S[i] = {A[i], A[A[i]], A[A[A[i]]], ... } subjected to the rule below.

 Suppose the first element in S starts with the selection of element A[i]
 of index = i, the next element in S should be A[A[i]], and then A[A[A[i]]]…
 By that analogy, we stop adding right before a duplicate element occurs in S.

 Example:
 Input: A = [5,4,0,3,1,6,2]
 Output: 4
 Explanation:
 A[0] = 5, A[1] = 4, A[2] = 0, A[3] = 3, A[4] = 1, A[5] = 6, A[6] = 2.

 One of the longest S[K]:
 S[0] = {A[0], A[5], A[6], A[2]} = {5, 6, 2, 0}

"""
from typing import List

def was_visited(value):
    return value < 0

def was_not_visited(value):
    return value >= 0

class Solution:
    @classmethod
    def array_nesting(cls, nums: List[int]) -> int:
        result = 0
        for index, _ in enumerate(nums):
            if was_visited(nums[index]):
                continue
            else:
                next_pos = nums[index]
                count = 0

                while was_not_visited(nums[next_pos]):
                    actual_pos = next_pos
                    next_pos = nums[next_pos]
                    count += 1
                    nums[actual_pos] = -1
                result = count if count > result else result

        return result


import sqlite3

class sqlcommands:

    def Open(self):
        if self.bOpen is False:
            self.conn = sqlite3.connect(self.db)
            self.curs = self.conn.cursor()
            self.bOpen = True
        return True

    def __init__(self, table):
        self.db = './~newsqlcommands.sqlt3'
        self.conn = None
        self.curs = None
        self.bOpen = False
        self.fields = None
        self.table_name = table

    def CreateTable(self):
        sqlCommand = f"""CREATE TABLE if not EXISTS {self.table_name} (
        EntryNumber INTEGER PRIMARY KEY,
        TimeIn TEXT,
        DateIn TEXT,
        TimeOut TEXT,
        DateOut TEXT);"""
        self.curs.execute(sqlCommand)

    def NewIn(self, field):
        if self.bOpen:
            self.curs.execute(f"INSERT INTO {self.table_name} (DateIn, TimeIn) VALUES (date('now', 'localtime'), '{field}');")
            self.conn.commit()
            self.fields = field
            return True
        return False

    def NewOut(self, field):
        if self.bOpen:
            self.curs.execute(f"UPDATE {self.table_name} SET DateOut = date('now', 'localtime'), TimeOut = '{field}' WHERE TimeIn = '{self.fields}';")
            self.conn.commit()
            return True
        return False

    def FillMissing(self, time_out, date_out, ifempty):
        if self.bOpen:
            self.curs.execute(f"UPDATE {self.table_name} SET DateOut = '{date_out}', TimeOut = '{time_out}' WHERE TimeIn = '{ifempty}';")
            self.conn.commit()
            return True
        return False

    def GetAll(self):
        self.curs.execute("SELECT TimeIn, TimeOut FROM " + self.table_name + ";")
        ans = self.curs.fetchall()
        return ans

    def GetLast(self):
        self.curs.execute(f"SELECT TimeIn FROM {self.table_name} WHERE ROWID IN ( SELECT max( ROWID ) FROM {self.table_name});")
        nochar = "!@,(){}[]' "
        naked = ""
        self.fields = self.curs.fetchone()
        for each in self.fields:
            for char in nochar:
                each = str(each).replace(char,"")
            naked = naked + each
        self.fields = naked
        return self.fields

    def GetSome(self, count):
        self.curs.execute("SELECT * FROM " + self.table_name + " ORDER BY DateIn LIMIT 5 OFFSET %s" % count + ";")
        ans = self.curs.fetchall()
        return ans

    def GetPrimary(self):
        self.curs.execute("SELECT TimeIn FROM " + self.table_name + ";")
        ans = self.curs.fetchall()
        return ans

    def CountDateIn(self):
        self.curs.execute("SELECT COUNT(DateIn) FROM " + self.table_name + ";")
        ans = self.curs.fetchone()
        return ans

    def DelTable(self):
        if self.bOpen:
            self.curs.execute("DROP TABLE IF EXISTS " + self.table_name + ";")
            return True
        return False

    def GetOne(self, TimeIn, inout):
        if self.bOpen:
            if inout == "TimeIn": self.curs.execute(f"Select DateIn from {self.table_name} where {inout} = '{TimeIn}';")
            else: self.curs.execute(f"Select DateOut from {self.table_name} where {inout} = '{TimeIn}';")
            Lalist = self.curs.fetchone()
            self.curs.execute(f"Select {inout} from {self.table_name} where {inout} = '{TimeIn}';")
            Lelist = self.curs.fetchone()
            self.curs.execute(f"SELECT TimeIn FROM {self.table_name} WHERE TimeOut is null;")
            saved = self.curs.fetchone()
            return Lelist, Lalist, saved
        return None

    def DelEm(self, TimeIns):
        if self.bOpen:
            if len(TimeIns) != 0:
                self.curs.execute("DELETE from " + self.table_name + " where " + " or ".join(("TimeIn = " + str(n) for n in TimeIns)))
                self.conn.commit()
                return True
        return False

    def UpdateOne(self, new, time, oldday, oldtime, inout):
        if self.bOpen:
            if inout == "TimeIn":
                self.curs.execute(f"UPDATE {self.table_name} SET DateIn = '{new} ', {inout} = '{time}' WHERE DateIn = '{oldday}' and {inout} = '{oldtime}';")
            else:
                self.curs.execute(f"UPDATE {self.table_name} SET DateOut = '{new} ', {inout} = '{time}' WHERE DateOut = '{oldday}' and {inout} = '{oldtime}';")
            self.conn.commit()
            return True
        return False

    def DelOne(self, TimeIn):
        if self.bOpen:
            self.curs.execute("DELETE from " + self.table_name + " where TimeIn = '" + TimeIn + "';")
            return True
        return False

    def End(self):
        if self.bOpen:
            self.conn.commit()
            self.bOpen = False
        return True


from Core import Core

class IN:
    def __init__(self):
        self.identifier = ""

    def parse(self, S): #should not output anything unless error case
        if S.currentToken() == Core.INPUT:
            S.nextToken()
        else:
            print("ERROR: Token should be 'input'")
            quit()
        if S.currentToken() == Core.ID:
            self.identifier = S.getID()
            S.nextToken()
        else:
            print("ERROR: Token should be an 'id'")
            quit()

        if S.currentToken() != Core.SEMICOLON:
            print("ERROR: Token should be ';'")
            quit()
        S.nextToken()

    def print(self, numIndents):
        print(("\t" * numIndents) + "input ", end = '')
        print(self.identifier + ";")


def reversedInt(num: int) -> int:
    result = 0
    while num:
        lastDigit = num % 10
        result = result * 10 + lastDigit
        if result < -2 ** 31 or result > 2 ** 31:
            return 0
        num //=10
    return result

print(reversedInt(1534236469))
print(reversedInt(2147483641))


import sys
import os
import subprocess

#### SETTINGS ####

CC = "gcc"

DEFAULT_INCLUDES = [
	"stdio.h",
	"stdbool.h",
	"stdlib.h",
	"unistd.h",
	"string.h",
]

TRY_USE_BAT = True

#### -------- ####

# This marker is used to remove any included code from the output,
# and only display the expanded macros given as the first argument to this program.
# Preproc seems to delete comments and defines, a global constant seems remain untouched.
# There should be no need to modify this.
MARKER = "const int PREPROC_CONTENT_MARKER = 69420;"

def error(message):
	print(f"\n{sys.argv[0]}: {message}")
	sys.exit(1)

def get_includes():
	if len(sys.argv) < 3:
		print(f"Using default includes: {DEFAULT_INCLUDES}")
		includes = DEFAULT_INCLUDES
	else:
		includes = []

	for i in range(2, len(sys.argv)):
		includes.append(sys.argv[i])

	result = []
	for include in includes:
		result.append("-include")
		result.append(include)
	return result

def run_preprocessor():
	arg_input = f"\n{MARKER}\n{sys.argv[1]}"
	arg_includes = get_includes()

	compiler_command = [CC, "-E", "-"]
	compiler_command.extend(arg_includes)
	try:
		return subprocess.check_output(
			compiler_command,
			input=str.encode(arg_input)
		).decode("UTF-8")
	except:
		error("Failed to run preprocessor.")

def clean_output(raw):
	stripped_marker = MARKER.strip()
	result = ""
	has_found_marker = False

	for line in iter(raw.splitlines()):
		if has_found_marker:
			result = result + line

		if line.strip() == stripped_marker:
			has_found_marker = True

	return result

def display_with_bat(cleaned):
	try:
		subprocess.run(
			["bat", "--language", "cpp"],
			input=str.encode(cleaned))
		return True
	except:
		return False

def main():
	if len(sys.argv) < 2:
		error("Invalid arguments. Expected:\n"
			+ "preproc <code to preprocess> (Uses a default set of includes)\n"
			+ "preproc <code to preprocess> <any number of headers to include>")

	preprocessor_output = run_preprocessor()
	cleaned = clean_output(preprocessor_output)
	if TRY_USE_BAT == False or display_with_bat(cleaned) == False:
		print(cleaned)
	sys.exit(0)

if __name__ == "__main__":
	main()


#!/usr/bin/env python3
"""
Main file for program
"""
import parser, sys, setup, functions
import time

FOLDERS = {
    "result": "Result",
    "finished": "Finished",
    "unfinished": "Unfinished",
    "video": "Video",
    "unsorted": "Unsorted"
}

def main():
    """
    Main function.
    """
    options = parser.parse_options()
    command = options["known_args"]["command"]

    if command == "setup":
        setup.setup_folders(FOLDERS)
    elif command == "clean":
        setup.remove_folder(FOLDERS["result"])
    elif command == "start":
        start_time = time.time()
        functions.start_sort(FOLDERS)
        print("--- %s seconds ---" % (time.time() - start_time))
    elif command == "scan":
        print("\n### Available folders ###\n")
        functions.present_folders(FOLDERS)
    sys.exit()

if __name__ == "__main__":
    main()


from hw2.datasets.train import TrainDataset
from hw2.models.base import Model
from hw2.models.catboost_model import CatBoostModel
from hw2.models.embeddings_model import EmbeddingModel
import numpy as np

class CombinedModel(Model):
    def __init__(self, loss_function: str, iterations: int, embedding_dim: int,
                 task_type: str, random_state: int, verbose: bool = True):
        super().__init__(random_state, verbose)
        self._catboost_model = CatBoostModel(loss_function, iterations, task_type, random_state, verbose)
        self._embedding_model = EmbeddingModel(embedding_dim, random_state, verbose)

    def _add_scores(self, dataset: TrainDataset):
        scores = self._embedding_model.predict(dataset)
        dataset.add_features("emb_score", scores)

    def _drop_scores(self, dataset: TrainDataset):
        dataset.drop_features("emb_score")

    def fit(self, dataset: TrainDataset) -> "CombinedModel":
        self._embedding_model.fit(dataset)
        self._add_scores(dataset)
        self._catboost_model.fit(dataset)
        self._drop_scores(dataset)
        return self

    def predict(self, dataset: TrainDataset) -> np.ndarray:
        self._add_scores(dataset)
        pred = self._catboost_model.predict(dataset)
        self._drop_scores(dataset)
        return pred


'''
Helps the user calculate the price that they should charge the customer
'''

def tax():
    #Checks if the user is from ontario or not
    location = input("Are you shopping from Ontario? Enter Y or N: ")

    #Makes the user input a tax rate if they are not from ontario
    if location == "n" or location == "N":
        taxRate = input("Enter the tax of your state or province as a percentage: ")

    #Gives the user the default rate of 13 percent if they are from ontario
    if location == "y" or location == "Y":
        taxRate = "13"

    #Gets some information from the user to help us calculate the final price
    price = float(input("Enter the price of the item: "))
    age = int(input("Enter your age: "))
    member = input("Are you a member of this store? Enter Y or N: ")

    #Gives the customer a discount if they fulfill all the proper conditions
    if (age < 18 or age >= 65) and (member == "y" or member == "Y"):
        price = price * 0.85

    return str(round((price * float("1." + taxRate)),2))

#prints out the final price that the user will need to pay
print("The total cost with tax for your order is " + tax())


import numpy as np
from .BaseNB import BaseNaiveBayes

# 高斯贝叶斯
class GaussianNaiveBayes(BaseNaiveBayes):

    # 训练
    def fit(self, X: np.ndarray, y: np.ndarray):
        """
        X: train dataset, shape = (n_samples, n_features)
        y: target, shape = (n_samples, )
        """
        # 计算 y 的先验概率
        y_prior_proba = []
        self.classes_ = np.unique(y)
        for c in self.classes_:
            c_count = (y == c).sum()
            y_prior_proba.append(c_count / np.size(y))
        self._y_prior_proba = np.array(y_prior_proba)
        # 计算连续变量 x 的高斯分布参数
        features = X.shape[1]
        self._theta = np.zeros((np.size(self.classes_), features))
        self._sigma = np.zeros((np.size(self.classes_), features))
        for i in range(np.size(self.classes_)):
            x_c = X[y == self.classes_[i]]
            self._theta[i, :] = np.mean(x_c, axis=0)
            self._sigma[i, :] = np.var(x_c, axis=0)
        return self

    def _joint_log_likelihood(self, X: np.ndarray):
        jll = []
        for i in range(np.size(self.classes_)):
            log_prior = np.log(self._y_prior_proba[i])
            # 高斯公式取对数
            x_given_y = - 0.5 * np.sum(np.log(2. * np.pi * self._sigma[i, :]))
            x_given_y -= 0.5 * np.sum(((X - self._theta[i, :]) ** 2) / (self._sigma[i, :]), axis=1)
            jll.append(log_prior + x_given_y)
        jll = np.array(jll).T
        return jll

    def __repr__(self):
        return "<GaussianNaiveBayes>"

if __name__ == "__main__":
    from sklearn.datasets import load_iris
    from sklearn.metrics import accuracy_score
    from sklearn.model_selection import train_test_split
    from sklearn.naive_bayes import GaussianNB

    test = np.array([[1, 'S'], [1, 'M'], [1, 'M'], [1, 'S'], [1, 'S'], [2, 'S'], [2, 'M'],
                    [2, 'M'], [2, 'L'], [2, 'L'], [3, 'L'], [3, 'M'], [3, 'M'], [3, 'L'], [3, 'L']])
    iris = load_iris()
    X = iris.data
    y = iris.target
    X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)
    gnb = GaussianNaiveBayes().fit(X_train, y_train)
    log_proba = gnb.predict_log_proba(X_test)
    proba = gnb.predict_proba(X_test)
    y_pred = gnb.predict(X_test)
    print(accuracy_score(y_test, y_pred))


"""Calculate the expected detection rates for apertif."""
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
from frbpoppy import CosmicPopulation, Survey, SurveyPopulation, hist

from tests.convenience import plot_aa_style, rel_path
from alpha_real import EXPECTED, poisson_interval

N_DAYS = 1  # Not used in eventual result
SCALE_TO = 'parkes-htru'

pop = CosmicPopulation.complex(n_srcs=1e5, n_days=N_DAYS)
pop.generate()

apertif = Survey('wsrt-apertif', n_days=N_DAYS)
apertif.set_beam(model='apertif_real')

if SCALE_TO == 'parkes-htru':
    htru = Survey('parkes-htru', n_days=N_DAYS)
    htru.set_beam(model='parkes')
if SCALE_TO == 'askap':
    askap = Survey('askap-fly', n_days=N_DAYS)
    askap.set_beam(model='gaussian', n_sidelobes=0.5)

days_per_frbs = []
for i in tqdm(range(2000), desc='Survey Run'):

    apertif_pop = SurveyPopulation(pop, apertif, mute=True)

    if SCALE_TO == 'parkes-htru':
        htru_pop = SurveyPopulation(pop, htru, mute=True)
        n_frbs_htru = EXPECTED['parkes-htru'][0]
        n_days_htru = EXPECTED['parkes-htru'][1]
        scaled_n_days = n_days_htru*(htru_pop.source_rate.det / n_frbs_htru)

    if SCALE_TO == 'askap':
        askap_pop = SurveyPopulation(pop, askap, mute=True)
        n_frbs_askap = EXPECTED['askap-fly'][0]
        n_days_askap = EXPECTED['askap-fly'][1]
        scaled_n_days = n_days_askap*(askap_pop.source_rate.det / n_frbs_askap)

    days_per_frb = scaled_n_days / apertif_pop.source_rate.det
    # print(f'{days_per_frb} days per frb')
    days_per_frbs.append(days_per_frb)

days_per_frbs = np.array(days_per_frbs)
mean = np.mean(days_per_frbs)
std = np.std(days_per_frbs)
poisson_std = poisson_interval(mean)
print(f'Mean rate for apertif is {mean}')
print(f'Standard deviation of {std}')

# Plot
rates, values = hist(days_per_frbs, bin_type='lin')
plot_aa_style()
plt.step(rates, values, where='mid')
plt.xlabel(f'Apertif days per burst scaled to {SCALE_TO}')
plt.savefig(rel_path('./plots/rate_apertif_dist.pdf'))


import matplotlib.pyplot as plt

class Drawer():

    def __init__(self,y_pred, y_test, target_names,X_test,eigenfaces):
        self.y_pred=y_pred
        self.y_test=y_test
        self.target_names=target_names
        self.X_test=X_test
        self.eigenfaces=eigenfaces

    def plot_gallery(self,images, titles, h, w, n_row=3, n_col=4):
        """Helper function to plot a gallery of portraits"""
        plt.figure(figsize=(1.8 * n_col, 2.4 * n_row))
        plt.subplots_adjust(bottom=0, left=.01, right=.99, top=.90, hspace=.35)
        for i in range(n_row * n_col):
            plt.subplot(n_row, n_col, i + 1)
            plt.imshow(images[i].reshape((h, w)), cmap=plt.cm.gray)
            plt.title(titles[i], size=12)
            plt.xticks(())
            plt.yticks(())

    # plot the result of the prediction on a portion of the test set

    # def title(self):
    #     pred_name = self.target_names[self.y_pred[self.i]].rsplit(' ', 1)[-1]
    #     true_name = self.target_names[self.y_test[self.i]].rsplit(' ', 1)[-1]
    #     return 'predicted: %s\ntrue:      %s' % (pred_name, true_name)

    def show(self,h,w):
        prediction_titles = []

        for i in range(self.y_pred.shape[0]):
            pred_name = self.target_names[self.y_pred[i]].rsplit(' ', 1)[-1]
            true_name = self.target_names[self.y_test[i]].rsplit(' ', 1)[-1]
            prediction_titles.append('predicted: %s\ntrue:      %s' % (pred_name, true_name))

        self.plot_gallery(self.X_test, prediction_titles, h, w)

        # plot the gallery of the most significative eigenfaces

        eigenface_titles = ["eigenface %d" % i for i in range(self.eigenfaces.shape[0])]
        self.plot_gallery(self.eigenfaces, eigenface_titles, h, w)
        plt.show()


print("\n Bem-vindo ao menu de gerenciamento!\n")
esc = int(input('Digite 1 para criar um ônibus: '))

class Onibus:

    def __init__(self, nome, parada, motorista, fiscal):
        self.nome = nome
        self.parada = parada
        self.motorista = motorista
        self.fiscal = fiscal

    def __str__(self):
        return f" Nome do ônibus: {self.nome} \
            \n Rota: {self.parada} \
            \n Motorista: {self.motorista} \
            \n Fiscal: {self.fiscal}"

class Motorista:
    def __init__(self, nomeMot, idade, cpf):
        self.nomeMot = nomeMot
        self.idade = idade
        self.cpf = cpf

    def __str__(self):
            return f" Nome do motorista: {self.nomeMot} \
                \n Idade: {self.idade} \
                \n CPF: {self.cpf} "

class Fiscal:
    def __init__(self, nomeFis, idade, cpf):
        self.nomeFis = nomeFis
        self.idade = idade
        self.cpf = cpf

    def __str__(self):
            return f" Nome do fiscal: {self.nomeFis} \
                \n Idade: {self.idade} \
                \n CPF: {self.cpf} "

loop1 = True
loop2 = False
ListaOnibus = []
ListaMotoristas = []
ListaFiscais = []

while loop1 == True:

    while loop2 == True:
        print('\n O que deseja fazer agora?\
        \n 1 - Criar um ônibus \
        \n 2 - Mostrar ônibus \
        \n 3 - Alterar dados do motorista\
        \n 4 - Alterar dados do fiscal\
        \n 5 - Alterar rota do ônibus\
        \n 6 - Deletar ônibus \n')

        esc = int(input('Escolha uma das opções para continuar: '))

        loop2 = False

    if (esc == 1):
        #Criar um ônibus com ponto de parada, motorista e fiscal,
        #assigna motorista e fiscal ao ônibus e adicona ponto de parada.

        nome = str(input('Nome do ônibus: '))
        parada = str(input('Parada do ônibus:'))
        motorista = str(input('Nome do motorista: '))
        fiscal = str(input('Nome do fiscal: '))

        onb = Onibus(nome, parada, motorista, fiscal)

        ListaOnibus.append(onb)

        print('\n Ônibus criado!')

        loop2 = True

    if (esc == 2):
    #Mostra o ônibus, sua rota, seu motorista e seu fiscal

        print('\n Informações do ônibus', onb.nome, ':\n')

        for item in ListaOnibus:
            print(item)

        tamanho = len(ListaOnibus)

        if tamanho == 0:
            print('Não há nenhum ônibus cadastrado.')

        loop2 = True

    if (esc == 3):
        #Altera dados do Motorista

        onb = Onibus(nome, parada, motorista, fiscal)

        print('\n O motirsta do ônibus', onb.nome, 'é o: ', onb.motorista)

        print('\n')
        nomeMot = onb.motorista
        idade = str(input('Idade do motorista:'))
        cpf = str(input('CPF: '))
        print('\n')

        mot = Motorista(nomeMot, idade, cpf)

        ListaMotoristas.append(mot)

        for item in ListaMotoristas:
            print(item)

        print('\n Os dados do motorista', onb.motorista, 'foram alterados!')

        loop2 = True

    if (esc == 4):
        #Altera dados do Fiscal

        onb = Onibus(nome, parada, motorista, fiscal)

        print('O fiscal do ônibus:', onb.nome, 'é o: ', onb.fiscal)

        print('\n')
        nomeFis = onb.fiscal
        idade = str(input('Idade do fiscal:'))
        cpf = str(input('CPF: '))
        print('\n')

        fis = Fiscal(nomeFis, idade, cpf)

        ListaFiscais.append(fis)

        for item in ListaFiscais:
            print(item)

        print('\n Os dados do fiscal foram alterados!')

        loop2 = True

    if (esc == 5):
    #Altera rota do ônibus
        onb = Onibus(nome, parada, motorista, fiscal)

        print('\n O ponto de parada do ônibus', onb.nome, 'é: ', onb.parada)

        print('\n')
        NovaParada = str(input('Nova parada:'))
        print('\n')

        onb.parada = NovaParada

        print('Local de parada atualizado para: ', onb.parada, '.')

        loop2 = True

    if (esc == 6):
        #Deleta ônibus

        ListaOnibus.clear()

        print('O ônibus foi deletado')

        loop2 = True


from typing import List

class Solution:
    def optimalArray(self, n : int, ar : List[int]) -> List[int]:
        # code here
        res = []
        half, full = 0, 0
        for i in range(n):
            full += ar[i]
            if i&1:
                res.append(full - 2*half)
            else:
                half += ar[i//2]
                res.append(full - 2*half + ar[i//2])
        return res;

#{
 # Driver Code Starts
class IntArray:
    def __init__(self) -> None:
        pass
    def Input(self,n):
        arr=[int(i) for i in input().strip().split()]#array input
        return arr
    def Print(self,arr):
        for i in arr:
            print(i,end=" ")
        print()

if __name__=="__main__":
    t = int(input())
    for _ in range(t):

        n = int(input())

        a=IntArray().Input(n)

        obj = Solution()
        res = obj.optimalArray(n, a)

        IntArray().Print(res)

# } Driver Code Ends


# Usage
# python scripts/collect_pickle_states.py -i PICKLE_DATA_PATH

import argparse
import numpy as np
import tqdm

import structs

def collect_stats(args):
    data = structs.load(args.input_path)

    sample_count = []
    for key in tqdm.tqdm(data):
        sample_count.append(data[key]['rst'].shape[0])

    values, counts = np.unique(sample_count, return_counts=True)

    value_counts_pairs = list(zip(values, counts))
    for (value, count) in value_counts_pairs:
        print('{} has {} predictions with counts {}'.format(args.input_path, value, count))

def main():
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument('-i', '--input-path', help='Input pickle file to read')
    args = parser.parse_args()

    collect_stats(args)

if __name__ == '__main__':
    main()


import matplotlib.pyplot as plt
import numpy as np
import scipy.optimize as spy

from . import AstroLib_Basic as AL_BF

################################################################################
# CREATE BODY WITH ITS CHARACTERISTICS
################################################################################
class Spacecraft:
    """
    Spacecraft class: create spacecraft with its mass and propulsion parameters
    """
    def __init__(self, *args, **kwargs):
        """
        Constructor: input the main characteristics
        INPUTS:
        ADDITIONAL INPUTS:
            Isp: specific impulse
            m_dry: dry mass of the spacecraft
            T: thrust of the spacecraft
            g0: acceleration of gravity
        """
        # Propulsive parameters
        self.Isp = kwargs.get('Isp', 3100)
        self.m_dry = kwargs.get('m_dry', 747)
        self.T = kwargs.get('T', 90e-3)
        self.g0 = kwargs.get('g0', AL_BF.g0)

    def MassChange(self, m, deltav):
        """
        MassChange: change (decrease) mass of the spacecraft when an impulse is
        applied
        INPUTS:
            m: current mass of the spacecraft (fuel+drymass)
            deltav: magnitude of the impulse applied
        OUTPUTS:
            mf: final mass
        """
        mf = m * np.exp( -deltav/(self.g0 * self.Isp) )
        return mf

    def MassChangeInverse(self, m, deltav):
        """
        MassChangeInverse: change (increase) the mass to obtain the mass of the
            spacecraft before an impulse was applied
        IMPUTS:
            m: current mass of the spacecraft (fuel+drymass)
            deltav: magnitude of the impulse applied
        OUTPUTS:
            mi: final mass
        """
        mi = m/np.exp( -deltav /(self.g0 * self.Isp) )
        return mi

class Body:
    """
    Body: contains the main characteristics of a celestial body.
    """
    def __init__(self, name, color = 'black', Mass = 0, radius = 0, *args, **kwargs):
        """
        Constructor:
        INPUTS:
            name: name of the body.
        ADDITIONAL INPUTS:
            Mass: mass of the body
            radius: radius of the body
            color: color to plot the body
            mu = gravitational parameter of the body. If it is not given, it
            is calculated as G*Mass
            orb: orbit of the body. Orbit is an object.
        """
        self.name = name
        self.R = radius
        self.M = Mass
        self.color = color
        #if mu it is not given, it is calculated with the mass:
        self.mu = kwargs.get('mu', self.M * AL_BF.ConstantsBook().G)
        # Orbit of the body:
        self.orb = kwargs.get('orbit', 'No information of the orbit')

    def addOrbit(self, orbit):
        """
        addOrbit: include an orbit to the body
        INPUTS:
            orbit: orbit object
        """
        self.orb = orbit

################################################################################
# CREATE ORBIT AND ITS CHARACTERISTICS
# Valid for an elliptical orbit. Application of the 2 Body Problem.
################################################################################
class CircularOrbit:
    """
    CircularOrbit: creation of a circular object around a central body.
    """
    def __init__(self, a, CentralBody, *args, **kwargs):
        """
        Constructor:
        INPUTS:
            a: semi-major axis of the orbit. Same as the radius of the orbit.
            CentralBody: central body about which the orbit is performed.
        ADDITIONAL INPUTS:
            Body: body object that is orbitting.
        """
        self.a = a
        self.CentralBody = CentralBody
        self.Body = kwargs.get('Body', 'Unknown')

        # Mean motion, period of the orbit
        self.n = np.sqrt(self.CentralBody.mu / self.a**3)
        self.T = 2*np.pi / self.n

#Review Kepler 2000: not working
class BodyOrbit:
    """
    BodyOrbit: creation of an orbit object around a central body. Contains the
    main characteristics of an ELLIPTICAL orbit. Application of the 2 Body problem.
    """
    def __init__(self, x, typeParam, Body, *args, **kwargs):
        """
        Constructor:
        INPUTS:
            x: Two main cases are possible:
                Keplerian elements as inputs:
                    a: semi-major axis (m)
                    e: eccentricity of the orbit
                    i: inclination of the orbit
                    RAAN: right ascension of the ascending node
                    omega: argument of the periapsis
                    M: mean anomaly
                    units: 'deg' indicates that the angles have to be
                    transformed to radians
                Cartesian elements:
                    x,y,z,xdot,ydot,zdot: position and velocity at a given time
            typeParam:
                'Keplerian_J2000': x is a matrix with:
                    row 0: Keplerian elements at J2000
                    row 1: centennial rates of change of those elements
                    row 2: date in Julian centuries
                'Keplerian': to use Keplerian parameters as inputs
                'Cartesian': to use Cartesian parameters as inputs
            Body: central Body of the orbit
        ADDITIONAL INPUTS:
            unitsI: units of the angles of x: 'rad' or 'deg'
    """
        self.CentralBody = Body

        ######################################
        #### Case 1: Keplerian Elements J2000 + centennial rates
        ######################################
        # Obtain Keplerian elements at a given date (in Julian Centuries)

        units_input = kwargs.get('unitsI', 'rad')

        if typeParam == 'Keplerian_J2000':
            a,e,i,L,varpi,RAAN = x[0,:] + x[1,:]*x[2,0]
            omega = varpi - RAAN
            M = L - varpi

        ######################################
        #### Case 1: Keplerian Elements given
        ######################################
        elif typeParam == 'Keplerian':
            self.a,self.e,self.i,self.RAAN,self.omega,self.M = x

        if typeParam == 'Keplerian' or typeParam == 'Keplerian_J2000':

            if units_input == 'deg': #Operations are done in radians
                [self.i,self.RAAN,self.omega,self.M] = [AL_BF.deg2rad(angle) \
                for angle in [self.i,self.RAAN,self.omega,self.M]]

            #Obtain the eccentric and true anomaly
            self.theta, self.E, self.M = Kepler(self.M, self.e,'Mean')

            #Obtain the cartesian coordinates
            x = self.Kepl2Cart()
            self.r = x[0:3]
            self.v = x[3:]
            self.h = np.cross(self.r, self.v)

        ######################################
        #### Case 3: Cartesian Elements given"
        ######################################
        elif typeParam == 'Cartesian':
            state = x #in m and m/s

            self.r = state[0:3] # position vector
            self.v = state[3:] # velocity vector
            self.r_mag = np.linalg.norm(self.r) # magnitude of the position vector
            self.v_mag = np.linalg.norm(self.v) # magnitude of the velocity vector

            self.h = np.cross(self.r, self.v)
            self.h_mag = np.linalg.norm(self.h)
            self.N = np.cross(np.array([0,0,1]),self.h)
            self.N_mag = np.linalg.norm(self.N)

            #Keplerian elements
            #semi-major axis. Negative if e>1:
            self.a = 1 / (2/self.r_mag-self.v_mag**2/Body.mu)
            #eccentricity vector:
            self.e_vec = np.cross(self.v,self.h)/Body.mu - self.r/self.r_mag
            self.e = np.linalg.norm(self.e_vec) #eccentricity of the orbit

            self.i = np.arccos(self.h[2]/self.h_mag) #inclination of the orbit

            N_xy = np.sqrt(self.N[0]**2 + self.N[1]**2)
            if N_xy == 0.:
                self.RAAN = 0
            else:
                #right ascension of the ascending node:
                self.RAAN = np.arctan2(self.N[1]/N_xy , self.N[0]/N_xy)

            if self.e == 0.0 or self.N_mag == 0.0:
                self.omega = 0.0
            else:
                #argument of the perihelium:
                self.omega = np.arccos(np.dot(self.e_vec/self.e , self.N/self.N_mag))
                if (np.dot(np.cross(self.N/self.N_mag , self.e_vec),self.h)) <= 0:
                    self.omega = -self.omega

            if self.r_mag == 0.0 or self.e == 0.0:
                self.theta = 0.0
            else:
                 #true anomaly:
                self.theta = np.arccos(np.dot(self.r/self.r_mag , self.e_vec/self.e))
                if (np.dot(np.cross(self.e_vec,self.r),self.h)) <= 0:
                    self.theta = -self.theta

            if self.e < 1:
                #Mean anomaly:
                self.theta, self.E, self.M = Kepler(self.theta,self.e,'True')
            else:
                #Mean anomaly:
                self.theta, self.E, self.M = Keplerh(self.theta,self.e,'True')

        else:
            print('Warning: Specify the type of elements')

        ######################################
        ## More parameters of the orbit
        ######################################
        #Create a vector with all the keplerian elements

        self.KeplerElem = np.array([self.a,self.e,self.i,self.RAAN,self.omega,self.M])
        self.KeplerElem_deg = np.zeros(6)
        self.KeplerElem_deg[0:2] = [self.a,self.e]
        for item, angle in enumerate([self.i,self.RAAN,self.omega,self.M]):
            self.KeplerElem_deg[2+item] = AL_BF.rad2deg(angle)

        #Mean motion, period of the orbit
        self.n = np.sqrt(Body.mu/self.a**3)
        self.T = 2*np.pi * np.sqrt(self.a**3/Body.mu)

        #Geometry of the elliptic trajectory
        self.p = self.a * (1-self.e**2)
        self.rp = self.a * (1-self.e)
        self.ra = self.a * (1+self.e)
        self.b = self.a * np.sqrt(1-self.e**2)

    def Kepl2Cart(self, *args, **kwargs):
        """
        Kepl2Cart: transform from Keplerian elements to cartesian coordinates.
        INPUTS:
        ADDITIONAL INPUTS:
            givenElements: option to input a vector to be transformed. If false,
            the elements from the class are used.

        OUTPUTS:
            [x,y,z,xdot,ydot,zdot]: state of the body given by its position and
            velocity vectors.
        """
        givenElements = kwargs.get('givenElements', 'False')
        if type(givenElements) != str:
            [a,e,i,RAAN,omega,M,theta] = givenElements
        else:
            [a,e,i,RAAN,omega,M,theta] = np.array([self.a,self.e,self.i, \
                self.RAAN,self.omega,self.M,self.theta])

        l1 = np.cos(RAAN)*np.cos(omega) - np.sin(RAAN)*np.sin(omega)*np.cos(i)
        l2 = -np.cos(RAAN)*np.sin(omega) - np.sin(RAAN)*np.cos(omega)*np.cos(i)
        m1 = np.sin(RAAN)*np.cos(omega) + np.cos(RAAN)*np.sin(omega)*np.cos(i)
        m2 = -np.sin(RAAN)*np.sin(omega) + np.cos(RAAN)*np.cos(omega)*np.cos(i)
        n1 = np.sin(omega)*np.sin(i)
        n2 = np.cos(omega)*np.sin(i)

        #magnitude of the angular momentum:
        H = np.sqrt(self.CentralBody.mu*a*(1-e**2))
        #magnitude of the position vector at a given moment:
        r = a*(1-e*np.cos(self.E))

        #Position vector
        x = l1*r*np.cos(theta) + l2*r*np.sin(theta)
        y = m1*r*np.cos(theta) + m2*r*np.sin(theta)
        z = n1*r*np.cos(theta) + n2*r*np.sin(theta)

        #Velocity vector
        xdot = self.CentralBody.mu/H * (-l1*np.sin(theta) + l2*(e+np.cos(theta)))
        ydot = self.CentralBody.mu/H * (-m1*np.sin(theta) + m2*(e+np.cos(theta)))
        zdot = self.CentralBody.mu/H * (-n1*np.sin(theta) + n2*(e+np.cos(theta)))

        return [x,y,z,xdot,ydot,zdot]

    def Propagation(self, t, typeParam, *args, **kwargs):
        """
        Propagation: propagate the mean anomaly M in time.
        INPUTS:
            t: time in seconds at which the position wants to be known with
                respect to the given state in the init
            typeParam: type fo the elements: "Keplerian", "Cartesian".
        OUTPUTS:
            M: new mean anomaly
        """
        self.M += self.n*t # Propagate in time
        self.M = AL_BF.correctAngle(self.M, 'rad') # Correct for more than 306deg

        if self.e < 1:
            self.theta, self.E, self.M = Kepler(self.M, self.e,'Mean')
        else:
            self.theta, self.E, self.M = Keplerh(self.M, self.e,'Mean')
        # self.theta = Kepler(self.M, self.e,'Mean')[0]

        x = np.array([self.a,self.e,self.i,self.RAAN,self.omega,self.M,self.theta])
        if typeParam == 'Keplerian':
            return x
        else:
            #Obtain the cartesian coordinates
            x = self.Kepl2Cart(givenElements = x)
            return x

    def atPeriapsis(self):
        """
        atPeriapsis: find the radius of the periapsis, velocity at periapsis and
        time since passage through periapsis
        """
        self.rp, self.vp = VisVivaEq(self.CentralBody, self.a, r = self.rp)
        self.tp = self.M / self.n # time since passage through periapsis

    # def solveKeplerUniversal(self, Xi, x_add):
    #     [t, alpha] = x_add
    #     self.atPeriapsis()
    #     r0 = self.rp
    #     vr0 = self.vp
    #     t0 = self.tp
    #     f = - np.sqrt(self.CentralBody.mu) * (t + t0) + \
    #         r0*vr0 / np.sqrt(self.CentralBody.mu) * Xi**2 * Stumpff_C(alpha* Xi**2) +\
    #         (1 - alpha* r0) * Xi**3 * Stumpff_S( alpha* Xi**2) +\
    #         r0 * Xi
    #     return f

    # def PropagationUniversal(self, t, typeParam, *args, **kwargs):
    #     """
    #     Propagation: propagate the mean anomaly M in time. Valid for ellipses,
    #     hyperbola, parabola
    #     Inputs:
    #         t: time in seconds at which the position wants to be known with
    #             respect to the given state in the init
    #     Outputs:
    #         M: new mean anomaly
    #     """
    #     # Find value of XI: universal anomaly
    #     alpha = 1/self.a
    #     Xi_0 = np.sqrt(self.CentralBody.mu) * abs(alpha) * t
    #     Xi = spy.fsolve(self.solveKeplerUniversal, Xi_0, args = [t, alpha, ])

    def PlotOrbit(self):
        """
        PlotOrbit: plot the relative position of the planets at a given date for
         each one
        INPUTS:
            Body: central Body
        OUTPUTS:
            xEl_E: x coordinate of the ellipse that represents the orbit
            yEl_E: y coordinate of the ellipse that represents the orbit
        """
        # Plot ellipse
        xEllipse = np.linspace(-self.a,self.a, num = 2500)
        yPos = np.sqrt(self.b**2*(1-xEllipse**2/self.a**2))
        yNeg = -np.sqrt(self.b**2*(1-xEllipse**2/self.a**2))
        xEl_E = np.append(xEllipse,xEllipse[::-1])
        xEl_E -= self.a*self.e*np.ones(len(xEl_E))
        yEl_E = np.append(yPos,yNeg)

    #     # Rotate ellipse
    #     ELL0=np.zeros((len(xEl_E0),3)) #Ellipse coordinates
    #     ELL0[:,0] = xEl_E0
    #     ELL0[:,1] = yEl_E0
    #     Q, nan,nan = transforMatrix(x,(x[4]-x[3])*np.pi/180,[0,0,0],[0,0,0])

    #     ELL = np.dot(ELL0,np.transpose(Q))
    #     xEl_E = ELL[:,0]
    #     yEl_E = ELL[:,1]

        fig, ax = plt.subplots(1,1, figsize = (9,8))
        # Plot orbit
        plt.plot(xEl_E,yEl_E,color = 'black',linestyle = '--') # Plot ellipse
        # Plot line from planet to the Sun:
        plt.plot([self.r[0],0],[self.r[1],0],color = 'black')
        plt.plot(self.r[0],self.r[1], marker = "o",markersize = 20, \
             color = 'black', alpha = 0.5,label = 'Position') # Plot planet

        plt.plot(0, 0, Markersize = 695508/15000, color= self.CentralBody.color,\
             marker="o")

        plt.title('2D Trajectory',size = 22)

        plt.axis("equal")
#         plt.xticks(np.arange(-3e11, 3e11, 1.0e11))
#         plt.yticks(np.arange(-3e11, 3e11, 1.0e11))
        plt.xlabel('(m)',size = 25)
        plt.ylabel('(m)',size = 25)

        plt.tick_params(axis ='both', which='major', labelsize = 15)
        plt.tick_params(axis ='both', which='minor', labelsize = 15)
        text = ax.xaxis.get_offset_text()
        text.set_size(15) #
        text = ax.yaxis.get_offset_text()
        text.set_size(15) #

#         lgnd = plt.legend(bbox_to_anchor=(0.5, 0), loc='lower left',ncol=2, \
#               mode="expand", borderaxespad=0.,fontsize=16)
#         lgnd.legendHandles[0]._legmarker.set_markersize(20)

    #     plt.savefig("_%i.png"%i,dpi=200,bbox_inches='tight')
        plt.show()

################################################################################
# STUMPFF FUNCTIONS
################################################################################
def Stumpff_C(z):
    """
    Stumpff_C: Stumpff function C for the propagation with universal variables
    INPUTS:
        z: Stumpff variable
    OUTPUTS:
        f: value of the function
    """
    if z > 0:
        f = ( 1 - np.cos(np.sqrt(z)) ) / z
    elif z == 0:
        f = 1/2
    else:
        f = ( np.cosh(np.sqrt(-z)) - 1 ) / (-z)
    return f

def Stumpff_S(z):
    """
    Stumpff_S: Stumpff function S for the propagation with universal variables
    INPUTS:
        z: Stumpff variable
    OUTPUTS:
        f: value of the function
    """
    if z > 0:
        f = ( np.sqrt(z) - np.sin(np.sqrt(z)) ) / z**(3/2)
    elif z == 0:
        f = 1/6
    else:
        f = ( np.sinh(np.sqrt(-z)) - np.sqrt(-z)  ) / (-z)**(3/2)
    return f

################################################################################
# PROPAGATE ALONG ORBIT FG PARAMS
################################################################################
def fgSolveE(E,x):
    """
    fgSolveE: solve Kepler's equation to obtain the Eccentric anomaly
    INPUTS:
        E: initial guess of the eccentric anomaly
        x: arguments to put in the equation
            x[0]: E0. Initial eccentric anomaly of the spacecraft
            x[1]: M0. Initial mean nomaly of the spacecraft
            x[2]: M. Current mean anomaly of the spacecraft
            x[3]: e. Eccentricity of the orbit
            x[4]: a. Semi-major axis of the propagation orbit
            x[5]: SV. State vector of the planet. [x,y,z,vx,vy,vz,m0,ind]
                x: position in the x axis
                y: position in the y axis
                z: position in the z ais
                vx : velocity in the x axis
                vy : velocity in the y axis
                vz : velocity in the z axis
                m0: mass at that point
                ind: indicator to know if there is an impulse
    OUTPUTS:
        f: function to solve
    """
    [E0,M0,M,e,a,SV,mu] = x
    r = np.linalg.norm(SV[0:3])

    sigma0 = np.dot(SV[0:3],SV[3:6])/np.sqrt(mu) # Value to put in next equation
    # Modified Kepler's equation:
    f = E-E0-(1-r/a)*np.sin(E-E0)+sigma0/np.sqrt(a)*(1-np.cos(E-E0))-(M-M0)
    # for the case in which we are not in perigee
    return f

def fgPropagate(orbit,SV,t):
    """
    fgPropagate: propagate the mean anomaly M in time.
    INPUTS:
        param: list of parameters. [a,e,E0,nu0,M0,n]
            E0: previous eccentric anomaly
            nu0: previous true anomaly
            M0: previous mean anomaly
            n: proper motion
        SV: state vector at the previous point [x,y,z,vx,vy,vz,m0,ind]
                x: position in the x axis
                y: position in the y axis
                z: position in the z ais
                vx : velocity in the x axis
                vy : velocity in the y axis
                vz : velocity in the z axis
        t: difference in time from the previous point
    OUTPUTS:
            E: new eccentric anomaly
            M: new mean anomaly
    """

    M = orbit.M + orbit.n * t
    E = spy.fsolve(fgSolveE, orbit.E, [orbit.E, orbit.M, M, orbit.e, orbit.a, \
        SV, orbit.Body.mu]) # Obtain new E
    E = float(E)

    return [E,M]

def fgSV(orbit,param,t):
    """
    fgSV: obtain new state vector from the previous one and the parameters of
    the orbit.
    INPUTS:
        SV0: state vector at the previous point [x,y,z,vx,vy,vz,m,ind]
            x: position in the x axis
            y: position in the y axis
            z: position in the z ais
            vx: velocity in the x axis
            vy: velocity in the y axis
            vz: velocity in the z axis
            m: mass at that point
            ind: indicator to know if there is an impulse
        param: parameters of the point of the propagation
        paramF: parametrs of the next point of the propagation
            a: semi-major axis of the propagation orbit
            e: eccentricity of the propagation orbit
            E: new eccentric anomaly
            nu: new true anomaly
            M: new mean anomaly
            n: proper motion
        t: difference in time from the previous time
    OUTPUTS:
        SV: new state vector
    """
    E0 = orbit.E
    E = param[0]

    r0 = np.linalg.norm(orbit.r)

    # f and g coefficients
    sigma0 = np.dot(orbit.r,orbit.v)/np.sqrt(orbit.Body.mu)
    f = 1 - orbit.a / r0*(1-np.cos(E-E0))
    g = (orbit.a * sigma0 * (1-np.cos(E-E0)) + r0 * np.sqrt(orbit.a) * \
        np.sin(E-E0)) / np.sqrt(orbit.Body.mu)

    #New position
    SV = np.zeros(6)
    SV[0:3] = f*orbit.r + g*orbit.v
    r = np.linalg.norm(SV[0:3])

    #f',g'
    ff = -np.sqrt(orbit.Body.mu * orbit.a) / (r*r0)*(np.sin(E-E0))
    gg = 1 - orbit.a / r *(1-np.cos(E-E0))

    #New velocity
    SV[3:6] = ff*orbit.r + gg*orbit.v

    return SV

################################################################################
# MORE
################################################################################
def VisVivaEq(Body,a,*args,**kwargs):
    """
    VisVivaEq: obtain position from velocity or vice versa with the vis viva or
    energy equation.
    INPUTS:
        Body: body around which the orbit is performed
        a: semi-major axis of the orbit
        **kwargs:
            r: magnitude of the position vector
            v: magnitude of the velocity vector
    OUTPUTS:
        r: magnitude of the position vector
        v: magnitude of the velocity vector
    """
    r = kwargs.get('r', None)
    v = kwargs.get('v', None)

    if r == None and v != None: #v is given
        r = Body.mu / (Body.mu/(2*a)+v**2/2)
    elif  r != None and v == None: #r is given
        v = 2*np.sqrt(-Body.mu/(2*a) + Body.mu/r)
    else:
        print('Warning: Not enough arguments or too many arguments given')
    return r,v

def KeplerSolve(E0, x):
    """
    Kepler: function to solve Kepler's equation knowing the mean anomaly. To
    obtain the eccentric anomaly.
    INPUTS:
        E0: initial guess of the solution
        x: vector containing other parameters of the equation:
            x[0]: Mean anomaly (rad)
            x[1]: Eccentricity
    OUTPUTS:
        F: function to solve (rad)
    """
    #Parametrs of the equation
    M = x[0]
    e = x[1]

    #Equation to solve
    F = E0-e*np.sin(E0)-M
    F = AL_BF.correctAngle(F, 'rad')

    return F

def Kepler(angle,e,name):
    """
    Kepler: function to calculate true, eccentric and mean anomaly given one of
    them and the eccentricity of the orbit.
    INPUTS:
        angle: initial angle known. It can be any of the three mentioned
        e: eccentricity of the orbit (magnitude)
        name: specify which the initial angle given is:
            'Mean': mean anomaly
            'True': true anomaly
            'Eccentric': eccentric anomaly
    OUTPUTS:
        theta: true anomaly
        E: eccentric anomaly
        M: mean anomaly
    """
    if name == 'Mean':
        M = angle
        E = spy.fsolve(KeplerSolve,M,[M,e]) #Solve Kepler's equation
        E = E[0]
        theta = 2*np.arctan(np.sqrt((1+e)/(1-e))*np.tan(E/2)) #Calculate true anomaly
#         if abs(theta) >= 2*np.pi: #Correction in case is higher than 360
#             a = theta//(2*np.pi)
#             theta = theta-2*np.pi*a
        return(theta,E,M)

    elif name == 'Eccentric':
        E = angle
        # Calculate true anomaly
        theta = 2*np.arctan(np.sqrt((1+e)/(1-e))*np.tan(E/2))
        M = E-e*np.sin(E) #Kepler's equation
        return(theta,E,M)

    elif name == 'True':
        theta = angle
        # Calculate eccentric anomaly:
        E = 2*np.arctan(np.sqrt((1-e)/(1+e))*np.tan(theta/2))
        M = E-e*np.sin(E) #Kepler's equation
        return(theta,E,M)

    else:
        print('Warning: Include a valid name for the angle given')

def KeplerhSolve(E0, x):
    """
    Kepler: function to solve Kepler's equation knowing the mean anomaly. To
    obtain the eccentric anomaly.
    INPUTS:
        E0: initial guess of the solution
        x: vector containing other parameters of the equation:
            x[0]: Mean anomaly (rad)
            x[1]: Eccentricity
    OUTPUTS:
        F: function to solve (rad)
    """
    #Parametrs of the equation
    M = x[0]
    e = x[1]

    #Equation to solve
    F = e*np.sinh(E0) - E0- M
    F = AL_BF.correctAngle(F, 'rad')
    return F

def Keplerh(angle, e, name):
    """
    Keplerh: function to calculate true, eccentric and mean anomaly given one of
    them and the eccentricity of the orbit. For an orbit of e >= 1
    INPUTS:
        angle: initial angle known. It can be any of the three mentioned
        e: eccentricity of the orbit (magnitude)
        name: specify which the initial angle given is:
            'Mean': mean anomaly
            'True': true anomaly
            'Eccentric': eccentric anomaly
    OUTPUTS:
        theta: true anomaly
        E: eccentric anomaly
        M: mean anomaly
    """
    print("Hyperbola")

    if name == 'Mean':
        M = angle
        E = spy.fsolve(KeplerhSolve, M, [M,e]) #Solve Kepler's equation
        E = E[0]
        theta = 2*np.arctan( np.sqrt( (e+1) / (e-1) ) * np.tan(E/2) )
        return(theta, E, M)

    elif name == 'Eccentric':
        E = angle
        # Calculate true anomaly:
        theta = 2 * np.arctan( np.sqrt( (e+1) / (e-1) ) * np.tan(E/2) )
        M = e * np.sinh(E) - E #Kepler's equation
        return(theta, E, M)

    elif name == 'True':
        theta = angle
        # Calculate eccentric anomaly:
        E = 2 * np.arctanh( np.sqrt( (e-1) / (e+1) ) * np.tan(theta/2) )
        M = e * np.sinh(E) - E #Kepler's equation
        return(theta, E, M)

    else:
        print('Warning: Include a valid name for the angle given')


#
#
# Font Lato https://fonts.google.com/specimen/Lato
# https://opengameart.org/content/4-chiptunes-adventure
#
# scanlines less mem
## https://www.reddit.com/r/pygame/comments/6yk6zk/least_memory_intensive_way_to_implement_scanlines/
# Not used:
# Audio Voices by MadamVicious (https://freesound.org/people/MadamVicious/sounds/238641)
#
# @todo turn this into "kawaii clock" game for github?
# @todo refactor 'em all ...
# @todo spritesheet
# @todo create the wordle game -> no words, winning/losing
# @todo scope of the game -> intro/menu/options/languages?
#
#
#   OMG refactor me
#   Particles List-> got better :)
#   ✔   Lock -> Class
#   Typing sounds?
#   easingFunc
#   naming conventions
#   moving in update, for exp. "scrollX"
#   ✔   handleInput
#   ✔   fix assets colors -> indicator
#   ✔   Window Icon
#   ✔   Delete/Replace Letters
#   init methode
#   ✔   gameOver -> Transition back to the startscreen
#   check "glitch" performance on raspi
#   intro with "fake" loading screen or fade in effect for the main menu
#   compare diff screens to find design errors - like missing shadows
#   create a short docu
#       - show the "drawn" hierarchy
#   clean up the assets and upload them
#   escape key back to menu and on the second press exit the game
#   turn debug on/off -> log printing
#   create /utils/ folder for texture atlas and effect editor
#   juicify the effects/animations -> intro? "special effects" on the first start?
#
#
#   'BUGS'
#   ✔   word to short -> index out of bounds
#   ✔   Lock on the title screen is not bouncing after winning
#   ✔   overlapping background
#   multiple letters are displayed wrong -> "lllll" four orange and one green -> correct -> one green
#
#
#   Unclear:
#   Easings -why "wrong" values
#
#
#
#
import itertools
import random

import pygame
from easing_functions import easing

from background import Background
from gamestate_manager import GamestateManager
from letter import Letter
from lock import Lock
from part_confetti import create_confetti
from particle import Particle
from phrase import Phrase
from screen_game import ScreenGame
from screen_menu import ScreenMenu
from screen_over import ScreenOver
from screen_transition import ScreenTransitions
from settings import Settings
from sky import Sky
from scanline import Scanline
from glitch import Glitch
from dataclasses import dataclass

@dataclass
class WordleGame:
    # init
    # Setup Pygame / Display
    pygame.init()
    manager = GamestateManager()
    settings = Settings()
    pygame.display.set_caption(settings.str_title)

    particles_new = []
    particles_confetti = []

    # surfaceOrg = pygame.display.set_mode((927, 750), pygame.HWSURFACE)
    surfaceOrg = pygame.display.set_mode((settings.screen_width, settings.screen_height), pygame.HWSURFACE)
    lock = Lock()
    pygame_icon = pygame.image.load('tex/icon.png')
    pygame.display.set_icon(pygame_icon)

    # surfaceOrg = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
    surfaceOrg.fill(color=(255, 66, 112))
    surface = surfaceOrg.copy()
    surface.fill(color=(255, 66, 112))

    TexBg = pygame.image.load('tex/tiles/bg_fields.png').convert_alpha()
    TexBgSky = pygame.image.load('tex/bg_sky.png').convert_alpha()
    TexBgScroll = pygame.image.load('tex/bg2.png').convert_alpha()
    TexLock2 = pygame.image.load('tex/lock/lock2.png').convert_alpha()
    TexLockShine = pygame.image.load('tex/tiles/lock_shine.png').convert_alpha()
    TexLockShine2 = pygame.image.load('tex/tiles/lock_shine_2.png').convert_alpha()
    TexScanline = pygame.image.load('tex/scanline.png').convert_alpha()
    TexScanline2 = pygame.image.load('tex/scanline2.png').convert_alpha()
    TexScanlineOverlaySkull = pygame.image.load('tex/scanline_overlay_skull.png').convert_alpha()
    TexStartscreen = pygame.image.load('tex/startscreen.png').convert_alpha()
    TexStartscreenLock = pygame.image.load('tex/lock/startscreen_lock.png').convert_alpha()

    TexWordTileYellow = pygame.image.load('tex/tiles/tile_yellow.png').convert_alpha()
    TexWordTileGreen = pygame.image.load('tex/tiles/tile_green.png').convert_alpha()
    TexWordTileGrey = pygame.image.load('tex/tiles/tile_grey.png').convert_alpha()
    TexWordTileGrey2 = pygame.image.load('tex/tiles/tile_grey2.png').convert_alpha()
    TexWordTileDefault = pygame.image.load('tex/tiles/tile_default.png').convert_alpha()

    TexTileIndicatorGreen = pygame.image.load('tex/tiles/indicator_green.png').convert_alpha()
    TexTileIndicatorGrey = pygame.image.load('tex/tiles/indicator_grey.png').convert_alpha()
    TexTileIndicatorYellow = pygame.image.load('tex/tiles/indicator_yellow.png').convert_alpha()
    TexTileIndicatorDefault = pygame.image.load('tex/tiles/indicator_default.png').convert_alpha()

    TexTileFlash1 = pygame.image.load('tex/tiles/tile_flash_1.png').convert_alpha()

    background = Background(TexBgScroll)
    skies = Sky(TexBgSky)
    phrase = Phrase(settings.str_title_waving)
    screen_menu = ScreenMenu(TexStartscreen, TexStartscreenLock)
    # screen_game = ScreenGame()
    screen_over = ScreenOver()
    screen_transition = ScreenTransitions()
    dt=0

    # SOUNDS
    sound_enabled = False
    if sound_enabled:
        snd_hit_1 = pygame.mixer.Sound('../snd/1.mp3')
        snd_hit_2 = pygame.mixer.Sound('../snd/2.mp3')
        snd_hit_3 = pygame.mixer.Sound('../snd/3.mp3')
        snd_hit_4 = pygame.mixer.Sound('../snd/4.mp3')
        snd_hit_5 = pygame.mixer.Sound('../snd/5.mp3')
        hit_sounds = [snd_hit_1, snd_hit_2, snd_hit_3, snd_hit_4, snd_hit_5]

    def gen_smoke(self, x, y):
        self.particles_new.extend(Particle.generate_smoke_list_white(
            x, y, 60, color="#fafafa"))

    def show_hit_screen(self):
        self.settings.offsetShake = self.shake()

        self.settings.showScanlines = not self.settings.showScanlines
        self.settings.scanlineTimer = 10
        self.settings.scanlineEffectTimer = 450
        self.settings.glitch_enabled = True

    def shoot_confetti(self):
        self.particles_confetti.extend(create_confetti())

    def show_lose_screen(self):
        print("show lose")
        self.settings.init_over_screen()
        self.screen_over = ScreenOver(4)
        self.manager.set_gamestate(4)

    def show_win_screen(self):
        self.settings.hero_replacement_showIntro = True
        self.lock.bar_popup = True
        self.settings.won = True
        self.settings.win_timer = 1900

        # confetti
        # shoot_confetti()

        # self.settings.show_blend_screen = True
        if self.lock.bar_popup:
            self.lock.eyes_flash_timer = 150

    #
    # Seperate the gameLogic into its own class
    #
    def checkGuess(self, current_guess):
        print(f"guesses_count: {self.settings.guesses_count}")
        print(f"currentPosition: {self.settings.currentPosition}")
        tmpLen = len(self.settings.guesses)
        print(f"tmpLen: {tmpLen}")
        self.settings.checkedGuess = True
        GOAL = self.settings.goal_word  # useless variable :)

        if self.sound_enabled:
            self.snd_hit_2.play()
        check_won = True
        for i in range(5):
            # lock the letter
            current_guess[i].locked = True

            # gen smoke
            self.gen_smoke(current_guess[i].x, current_guess[i].y)

            lower = current_guess[i].key
            if current_guess[i].key in GOAL:
                if lower == GOAL[i]:
                    current_guess[i].flash = i * -1
                    current_guess[i].flash_timer = 0
                    current_guess[i].tile = self.TexWordTileGreen
                    self.settings.indicator[lower] = self.TexTileIndicatorGreen
                else:
                    current_guess[i].tile = self.TexWordTileYellow
                    self.settings.indicator[lower] = self.TexTileIndicatorYellow
                    check_won = False
            else:
                current_guess[i].fontcolor = "#ebe8da"
                current_guess[i].tile = self.TexWordTileGrey
                self.settings.indicator[lower] = self.TexTileIndicatorGrey
                check_won = False

        if check_won:
            self.show_win_screen()
        else:
            if self.settings.guesses_count >= 3:
                self.show_lose_screen()
            self.show_hit_screen()

        self.settings.glitch_flip = not self.settings.glitch_flip
        self.settings.currentPosition = 0
        self.settings.guesses_count += 1

    # LINE += 1

    # https://stackoverflow.com/questions/23633339/pygame-shaking-window-when-loosing-lifes
    # slightly modified
    #
    def shake(self, hori=False, times=5, power=10):
        s = -1
        for _ in range(0, times):
            for x in range(power, 0, 2):
                if hori:
                    yield x * s, x * s
                else:
                    yield 0, x * s
            for x in range(0, power, 2):
                if hori:
                    yield x * s, x * s
                else:
                    yield 0, x * s
            s *= -1
        while True:
            yield 0, 0

    def change_indicators(self, guess):
        self.settings.usedLetters.append(guess)

    def init_indicators(self, settings):
        for i in range(3):
            for let in settings.alphabet[i]:
                settings.indicator.update({let: self.TexTileIndicatorDefault})

    scanline = Scanline(settings.screen_width, settings.screen_height)
    glitch = Glitch(settings.screen_width, settings.screen_height, TexScanlineOverlaySkull)

    def add_new_letter(self, key_pressed):
        x = 465 + (self.settings.currentPosition * 67)
        y = 47 + (self.settings.guesses_count * 79)
        letter = Letter(key_pressed, (x, y), self.TexWordTileDefault)
        self.settings.guesses[self.settings.guesses_count].append(letter)
        self.settings.currentPosition += 1

    def add_new_letter_effects(self):
        self.settings.offsetShake = self.shake()
        self.lock.eyes_blink_timer = 60
        self.lock.flash = True
        self.lock.eyes_flash_timer = 20

        x = 455 + (self.settings.currentPosition * 67)
        y = 100 + (self.settings.guesses_count * 80)
        self.particles_new.extend(Particle.generate_smoke_list(
            x, y, 80,
        ))

    def handle_input(self, events):
        for event in events:
            if event.type == pygame.KEYDOWN:
                if self.manager.gamestate == 1:
                    if self.sound_enabled:
                        # snd_typing.play()
                        pass
                    key_pressed = event.unicode.upper()
                    if key_pressed in self.settings.alphabet_sorted:
                        if len(self.settings.guesses[self.settings.guesses_count]) <= 4:
                            self.add_new_letter(key_pressed)
                            self.add_new_letter_effects()

                    elif event.key == pygame.K_BACKSPACE:
                        print("Please dont crash")
                        if len(self.settings.guesses[self.settings.guesses_count]) >= 1:
                            print(len(self.settings.guesses[self.settings.guesses_count]))
                            self.settings.guesses[self.settings.guesses_count].pop()
                            self.settings.currentPosition -= 1
                    elif event.key == pygame.K_RETURN:
                        self.settings.offsetShake = self.shake(power=8, times=5)
                        if len(self.settings.guesses[self.settings.guesses_count]) == 5:
                            print("over 5!")
                        if len(self.settings.guesses[self.settings.guesses_count]) == 5:
                            self.checkGuess(self.settings.guesses[self.settings.guesses_count])
                    elif event.key == pygame.K_ESCAPE:
                        # running = False
                        self.manager.set_gamestate(0)
                        self.screen_menu = ScreenMenu(self.TexStartscreen, self.TexStartscreenLock)
                else:
                    if event.key == pygame.K_SPACE:
                        print("Space")
                        # shoot_confetti()

                        self.manager.set_gamestate(2)
                        screen_game = ScreenGame()
                        # if sound_enabled:
                        #    pygame.mixer.music.load('music/stage.mp3')
                        #    pygame.mixer.music.play(-1, 0.0)

                    elif event.key == pygame.K_ESCAPE:
                        self.settings.game_is_running = False
                        # gamestate_mgr.gamestate = 0

            if event.type == pygame.QUIT:
                self.settings.game_is_running = False

            if event.type == pygame.MOUSEBUTTONDOWN:
                x, y = event.pos
                print(f"Mouse   x: {x}  y:{y}")

    def draw_letters(self):
        for guess in self.settings.guesses:
            for letter in guess:
                letter.update(self.dt, self.settings.easing_frame)
                letter.draw(self.surface, self.settings, self.TexTileFlash1)

    def draw_indicators(self):  # own class !
        y_offset = 0
        if self.settings.hero_replacement_showIntro:
            self.settings.hero_replacement_y_offset_indicator += self.dt * 2
            y_offset = self.settings.hero_replacement_y_offset_indicator

        offset = 0

        self.settings.indication_easing_amount = self.settings.easingFunction(self.settings.easing_frame * 0.01)
        self.settings.indication_easing_amount = min(1, self.settings.indication_easing_amount)
        self.settings.indication_y_bounce = (
                                                    self.settings.indication_easing_end_pos - self.settings.indication_easing_start_pos) * self.settings.indication_easing_amount

        for i in range(3):
            spacer = 0

            y_offset += 5
            if i == 1:
                offset = 23
            elif i == 2:
                offset = 73
            for letter in self.settings.alphabet[i]:
                x = 222 + offset + (spacer * 49)
                y = 1000 + y_offset + (i * 50)  # + 545
                spacer += 1
                tempRect = (x, y + self.settings.indication_y_bounce, 42, 42)

                if not self.settings.indicator[letter] == self.TexTileIndicatorDefault:
                    text_surface = self.settings.font_small.render(letter, True, "#ebe8da")
                else:
                    text_surface = self.settings.font_small.render(letter, True, "#304059")
                textRect = text_surface.get_rect(center=(x + 21, self.settings.indication_y_bounce + y + 18))

                self.surface.blit(self.settings.indicator[letter], tempRect)
                self.surface.blit(text_surface, textRect)

    def update_particles(self, dt):
        for part in itertools.chain(self.particles_new, self.particles_confetti):
            if part.isActive:
                part.update(dt)

        self.remove_particles()

    # how to refactor me? itertools chain?
    def remove_particles(self):
        for part in self.particles_new:
            if not part.isActive:
                self.particles_new.remove(part)

        for part in self.particles_confetti:
            if not part.isActive:
                self.particles_confetti.remove(part)

    # move me into screen_game
    def update_scanlines(self, dt):
        if self.settings.showScanlines:
            self.settings.scanlineTimer -= dt / 2
            self.settings.scanlineEffectTimer -= dt / 2
            if self.settings.scanlineEffectTimer < 0:
                self.settings.showScanlines = False
                self.settings.glitch_enabled = False
            if self.settings.scanlineTimer < 0:
                self.settings.scanlinesFlash = not self.settings.scanlinesFlash
                self.settings.scanlineTimer = 10

    def update_movement(self, dt):

        self.background.update(dt)
        self.skies.update(dt)
        self.update_particles(dt)
        self.update_scanlines(dt)
        self.screen_transition.update(dt, self.settings, self.manager.gamestate)
        self.screen_menu.update(dt, self.manager.gamestate)

        if self.settings.won:  # rename me -> wait for screen_to_end ?
            self.settings.win_timer -= dt
            self.settings.show_blend_screen = True
            if self.screen_transition.radius > 1050:
                self.settings.won = False
                # reset 'em all
                self.lock = Lock()
                self.phrase.x_pos = 150
                self.screen_menu = ScreenMenu(self.TexStartscreen, self.TexStartscreenLock)
                self.manager.set_gamestate(3)
                self.screen_over = ScreenOver(3)
                self.particles_confetti.extend(create_confetti())

        if self.settings.currentPosition <= 4:
            self.lock.update_lock_shine_pos(self.settings.currentPosition * 67,
                                            self.settings.guesses_count * 80)

    def draw_background(self):
        self.background.draw(self.surface)
        self.skies.draw(self.surface)
        self.surface.blit(self.scanline.surface, (0, 0))

    def draw_gamefield(self):
        self.surface.blit(self.TexBg, (self.settings.gamefield_pos_x, 0))

    def draw_particles(self):
        for part in itertools.chain(self.particles_new, self.particles_confetti):
            if part.isActive:
                part.draw(self.surface)

    def draw_scanlines(self):
        if self.settings.showScanlines:
            if self.settings.scanlinesFlash:
                self.surface.blit(self.TexScanline, (0, 0))
            else:
                self.surface.blit(self.TexScanline2, (0, 0))

    def update_easing_game_screen(self):
        # mixture of lock & gamefield easing :(
        easing_amount = self.settings.easingFunction(self.settings.easing_frame * 0.01)
        easing_amount = min(1, easing_amount)
        self.settings.easing_frame += 1

        # end - start pos
        gamefield_easing_x = (930 - 0) * easing_amount
        self.settings.gamefield_pos_x = 930 - gamefield_easing_x

    def show_highlight_current_field(self):
        if self.settings.currentPosition <= 4:
            if self.lock.shineTime and self.settings.gamefield_pos_x == 0:
                self.surface.blit(self.TexLockShine, (self.lock.TexLockShine_x, self.lock.TexLockShine_y))

    def load_sounds(self):
        if self.sound_enabled:
            snd_hit_1 = pygame.mixer.Sound('sounds/hit_1.mp3')
            snd_hit_2 = pygame.mixer.Sound('sounds/hit_2.mp3')
            snd_typing = pygame.mixer.Sound('sounds/typing.mp3')

            pygame.mixer.music.load('music/menu.mp3')
            pygame.mixer.music.play(-1, 0.0)

    def draw_screen_game(self):
        self.draw_gamefield()
        # confetti behind the hero banner
        for con in self.particles_confetti:
            con.draw(self.surface)
        self.lock.draw(self.surface, self.lock.bar_popup_offset)

        self.draw_indicators()  # optimize me
        self.draw_letters()

    def draw_screen_win_lose(self, dt):
        self.screen_over.update(dt)
        self.settings.flip_update(dt)
        self.screen_over.draw(self.surface, self.settings.blink, self.settings.flip)
        if self.manager.gamestate == 4:
            # don't like the way the offsetting is handled
            self.surface.blit(self.settings.lose_surface, (540, 554 + (self.screen_over.y * -1)))

        for con in self.particles_confetti:
            con.draw(self.surface)

    def create_new_game(self):
        self.init_indicators(self.settings)

        self.manager.new_game(self.settings)

    # refactor me!
    def reset_game(self):
        # called when ever menu is loaded, resets all objects

        self.manager.set_gamestate(0)

        self.lock = Lock()
        self.settings.hero_replacement_showIntro = False
        self.settings.hero_replacement_y_offset_indicator = 0
        self.settings.gamefield_pos_x = 930  # gamefield reset to spawn outside of the viewport
        self.settings.easing_frame = 0

        self.screen_menu = ScreenMenu(self.TexStartscreen, self.TexStartscreenLock)

    def start_game(self):
        self.init_indicators(self.settings)

        print("starting game")
        while self.settings.game_is_running:
            dt = self.settings.clock.tick(60)
            # print(clock.get_fps())

            # START UPDATE
            self.update_movement(dt)

            if self.manager.gamestate == 1:
                self.update_easing_game_screen()
                self.lock.update(dt)

            elif self.manager.gamestate == 2:
                if self.screen_menu.startscreen_y_lock < -1000:
                    self.create_new_game()

            # START DRAWING
            self.draw_background()

            if self.manager.gamestate == 1:
                self.draw_screen_game()
                self.show_highlight_current_field()
            elif self.manager.gamestate == 3 or self.manager.gamestate == 4:
                self.draw_screen_win_lose(dt)

                if not self.screen_over.change_to_next_screen:
                    self.reset_game()

            else:
                # if gamestate is menu or transition
                self.screen_menu.draw(self.surface)
                self.phrase.draw(self.surface, self.screen_menu.startscreen_y, self.settings)

            self.draw_particles()
            self.draw_scanlines()

            self.surfaceOrg.blit(self.surface, next(self.settings.offsetShake))

            self.glitch.draw(self.surfaceOrg, self.settings.glitch_enabled, self.settings.glitch_flip)

            self.screen_transition.draw(self.surfaceOrg, self.settings)

            pygame.display.update()
            self.handle_input(pygame.event.get())

        pygame.quit()
        print("DONE")

# easy todo
# the colors - correct names -> put them in inkscape on the color scheme

# next try
# global are killing it
if __name__ == '__main__':
    wordle = WordleGame()
    wordle.start_game()


# ---------------------------------J.A.R.V.I.S.----------------------------------
import datetime

import pyttsx3
import speech_recognition as sr
import __name__
import comtypes.client

# -----------------------------------------------------------------------------
engine = pyttsx3.init("sapi5")
voices = engine.getProperty("voices")
engine.setProperty('voice', voices[0].id)

def speak(audio):
    """This function is used to speak the text"""
    engine.say(audio)
    engine.runAndWait()

def wishMe():
    """This function is used to wish me     """
    hour = int(datetime.datetime.now().hour)
    if hour >= 0 and hour < 12:
        speak('Good Morning!')
    elif hour >= 12 and hour < 18:
        speak('Good Afternoon!')
    else:
        speak('Good Evening!')
    speak("I am JARVIS Sir. Please tell me how may I help you")

def takeCommand():
    """This function in used to take microphone input fron the user and return string"""
    r = sr.Recognizer()
    with sr.Microphone() as source:
        print("Listening...")
        r.pause_threshold = 1
        audio = r.listen(source)
    try:
        print("Recognizing...")
        query = r.recognize_google(audio, language='en-in')
        print(f"User said: {query}\n")
    except Exception:
        # print(e)
        print("Say that again please...")
        return "None"
    return query

if __name__ != '__main__':
    pass
else:
    wishMe()
    query = takeCommand().lower()


from DataInit import *
from AuxiliaryFunctions import *

# Initialize the map of game.
listOfCountries, NACountries, SACountries, CACountries, EUCountries, AFRCountries, ASIACountries, OCECountries = initCountryStruct()

# Initialize the list of possible colors.
listOfColors = ["Green", "Yellow", "Blue", "White", "Black", "Red"]

# Initialize an empty list for the players
listOfPlayers = []

# Initiliaze the modifiers
snow = False
tailwind = False
crisis = False
extra_reinforcements = False
open_borders = False
closed_borders = False
rest = False
globalSituations = [snow, tailwind, crisis, extra_reinforcements, open_borders, closed_borders, rest]

# Let's ask how many players are going to play
while True:
    numberOfPlayers = int(input("How many players are going to play? "))
    if numberOfPlayers > 6:
        print("Too many players")
    else:
        break

# Let's ask how many BOTS are going to play
while True:
    numberOfBots = int(input("How many BOTS do you want to add to the game? "))
    if numberOfBots > 6 - numberOfPlayers:
        print("Too many BOTS")
    else:
        break

# Calculate how many countries each player start with
amountOfInitialCountries = int(len(listOfCountries) / (numberOfPlayers + numberOfBots))
amountOfExtraCountries = len(listOfCountries) % (numberOfPlayers + numberOfBots)
print("Each player will start with {} countries".format(amountOfInitialCountries))

for i in range(numberOfPlayers):
    name = input("What is the name of player {}? ".format(i + 1))
    while True:
        color = input("What color do you want to use? ")
        if color not in listOfColors:
            print("Wrong color")
        else:
            break
    listOfColors.remove(color)

    player = Player(name, color)

    print("Which countries are you starting with? ")
    initPlayerCountries(player, amountOfInitialCountries, listOfCountries)

# Now, let's setup the bots
for i in range(numberOfBots):
    name = "BOT_{}".format(i)
    color = listOfColors[0]
    listOfColors.remove(listOfColors[0])

    bot = Player(name, color)

    print("Which countries is BOT_{} starting with?".format(i))
    initPlayerCountries(bot, amountOfInitialCountries, listOfCountries)

    bot.convertToBOT()
    listOfPlayers.append(bot)

# Raffle the extra countries.
if amountOfExtraCountries != 0:
    raffleExtraCountries(listOfCountries, amountOfExtraCountries, listOfPlayers)

# Now  we define each player mission
selectMission(listOfPlayers)

# Establish the first turn order of players
firstTurn(listOfPlayers)
sorted(listOfPlayers, key=lambda player_turn: player.turn)

# First turn of reinforcements
for p in listOfPlayers:
    reinforceCountries(p, 8)
for p in listOfPlayers:
    reinforceCountries(p, 4)

# Begin the game
while True:
    pickSituationCard(globalSituations)
    for p in listOfPlayers:
        if not p.human:
            i = 0
            # TODO: Develop BOT Intelligence
        else:
            conquered = attackPhase(p, listOfCountries)
            regroupPhase(p, listOfCountries)
            if conquered:
                withdrawCard(p, listOfCountries)
    nextTurn(listOfPlayers)


from clustering_algorithms.spectral_clustering import *
from clustering_algorithms.louvain import *
from clustering_algorithms.paris import *
from dendrogram_manager.homogeneous_cut_slicer import *
from dendrogram_manager.heterogeneous_cut_slicer import *
from dendrogram_manager.distance_slicer import *
from experiments.flat_clustering_experiments_manager import *

SAVE_PLOTS = True
LOAD_RESULTS = True
SAVE_RESULTS = True
directory_results = "/home/sharp/Documents/Graphs/Graph_Clustering/Results/"
results_file_name = "ppm"
n_samples = 10

# List of tested algorihtms:
# - Spectral clustering
# - Louvain
# - Paris + homogenegeous cut
# - Paris + heterogeneous cut
# - Paris + distance cut + Louvain
# - Paris + distance cut + Louvain + spectral

def paris_homogeneous(G):
    D = paris(G)
    best_cut, best_score = best_homogeneous_cut(D)
    clusters = clustering_from_homogeneous_cut(D, best_cut)
    return clusters

def paris_heterogeneous(G):
    D = paris(G)
    best_cut, best_score = best_heterogeneous_cut(D)
    clusters = clustering_from_heterogeneous_cut(D, best_cut)
    return clusters

def paris_louvain(G):
    D = paris(G)
    best_dist, best_score = best_distance(D)
    clusters = louvain(G, 1/float(best_dist))
    return clusters

def paris_louvain_spectral_clustering(G):
    n_clusters = len(paris_louvain(G))
    clusters = spectral_clustering(G, n_clusters=n_clusters)
    return clusters

algorithms = [('Spectral Clustering - (25)', lambda G: spectral_clustering(G, n_clusters=25)),
              ('Spectral Clustering - (50)', lambda G: spectral_clustering(G, n_clusters=50)),
              ('Spectral Clustering - (75)', lambda G: spectral_clustering(G, n_clusters=75)),
              ('Louvain', louvain),
              ('Paris+homogeneous cut', paris_homogeneous),
              ('Paris+heterogeneous cut', paris_heterogeneous),
              ('Paris+Louvain', paris_louvain),
              ('Paris+Louvain+Spectral', paris_louvain_spectral_clustering)]

# print('Experiment: number of blocks')
# make_n_blocks_experiment(algorithms, range_n_blocks=range(10, 101, 10), block_size=10, d_in=5., d_out=1., n_samples=10, score=lambda true, pred: AMI(true, pred),
#                          SAVE_PLOTS=SAVE_PLOTS, LOAD_RESULTS=LOAD_RESULTS, SAVE_RESULTS=SAVE_RESULTS, directory_results=directory_results, results_file_name=results_file_name)
#
#
# print('Experiment: internal/external degree')
# make_degree_in_out_experiment(algorithms, d_in=5., range_d_out=np.linspace(1, 20, num=10), n_blocks=50, block_size=10, n_samples=10, score=lambda true, pred: AMI(true, pred),
#                               SAVE_PLOTS=SAVE_PLOTS, LOAD_RESULTS=LOAD_RESULTS, SAVE_RESULTS=SAVE_RESULTS, directory_results=directory_results, results_file_name=results_file_name)
#
# print('Experiment: block size heterogeneity')
# make_block_size_het_experiment(algorithms, range_param=np.linspace(1., 3., num=10), range_block_size=range(10, 100), n_blocks=50, p_in=.5, p_out=.01, n_samples=10, score=lambda true, pred: AMI(true, pred),
#                                SAVE_PLOTS=SAVE_PLOTS, LOAD_RESULTS=LOAD_RESULTS, SAVE_RESULTS=SAVE_RESULTS, directory_results=directory_results, results_file_name=results_file_name)
#
# print('Experiment: block size ratio')
# make_block_size_ratio_experiment(algorithms, range_ratio=range(1, 11), big_block_size=100, graph_size=600, p_in=.5, p_out=.01, n_samples=10, score=lambda true, pred: AMI(true, pred),
#                                    SAVE_PLOTS=SAVE_PLOTS, LOAD_RESULTS=LOAD_RESULTS, SAVE_RESULTS=SAVE_RESULTS, directory_results=directory_results, results_file_name=results_file_name)

print('Experiment: size of blocks')
make_block_size_experiment(algorithms, range_block_size=range(10, 101, 10), n_blocks=50, d_in=5., d_out=1., n_samples=10, score=lambda true, pred: AMI(true, pred),
                           SAVE_PLOTS=SAVE_PLOTS, LOAD_RESULTS=LOAD_RESULTS, SAVE_RESULTS=SAVE_RESULTS, directory_results=directory_results, results_file_name=results_file_name)


def carga_numeros(n):
    total=int(0)
    lista=list()
    porcentaje=int(0)
    ultimo_digito=int(0)
    n_menor=int(0)
    menores_7=str("Si")

    while n!=0:
        total+=1
        if n%2==0: porcentaje+=1 # a) Determinar el porcentaje que cantidad de números pares representa en la cantidad total de números ingresados.
        if n%10==4 or n%10==5: ultimo_digito+=1 # b) Determinar cuántos de los números ingresados tenían su último dígito igual a 4 o igual a 5.
        if n%3==0:
            if total==1 or n<n_menor: n_menor=n # c) Determinar el menor de los números ingresados que sean divisibles por 3.

        lista.append(int(n))

        n=int(input("Introduzca otro numero: "))

    for num in lista: #Determinar si la secuencia estaba formada sólo por números menores de 7
        if num>7:
            menores_7="No"

    porcentaje= (porcentaje*100)/total #determino el procentaje
    #muetro resultados por pantalla
    print(f"El porcentaje de numeros pares sobre los {total} numeros ingresados es de {round(porcentaje, 2)}%.")
    print(f"La cantidad de números ingresados que tenían su último dígito igual a 4 o igual a 5 es de {ultimo_digito}.")
    print(f"El menor numero divisible por 3 ingresado es {n_menor}")
    print(f"La secuencia estaba formada solo por numeros menores de 7? {menores_7}")

carga_numeros(int(input("Introduzca un numero (si introduce 0, se cancela la carga de numeros): ")))


# -*- coding: utf-8 -*-
"""
Created on Sat Oct 17 20:55:15 2020

@author: Emmanuel
"""
def unique(list1):

    # intilize a null list
    unique_list = []

    # traverse for all elements
    for x in list1:
        # check if exists in unique_list or not
        if x not in unique_list:
            unique_list.append(x)
    # print list
    for x in unique_list:
        print (x)

nombrearchivo = r'C:\Temp\dtsxsql\total.sql'
contenido=[]

with open(nombrearchivo) as fin:
    contenido = [ linea.strip().split(' ') for linea in fin ]

Local = []
for r in contenido:
    for x in r :
        Local.append(x)

unique(Local)


# declare dictionary
banner = {}

# fill dictionary
banner['os'] = 'Ubuntu Server 13.04'
banner['server'] = 'ProFTPd 1.3.4'
banner['up'] = 315.5
banner[200] = 'OK'

print(banner)

# iterate through dictionary
for key, value in banner.items():
    print(key, value)

# delete item based on key
del banner['up']
print(banner)