from collections import defaultdict
from collections.abc import Iterable
from typing import Optional, Generator, Union, Hashable, List, Dict
import sys

import dataset

from pymemdb import Column, ColumnDoesNotExist

version = sys.version_info
if version.major < 3:  # pragma: no cover
    raise Exception("Python version must be 3.6 or higher")
if version.major >= 3 and version.minor < 8:  # pragma: no cover
    ORDER_TYPE = Union[str, bool]
else:  # pragma: no cover
    from typing import Literal  # type: ignore
    ORDER_TYPE = Literal["ascending", "descending", False]  # type:ignore

ROW_GEN = Generator[dict, None, None]

class Table:
    """Object that represents a Table in the Database.
       Can also used standalone"""

    def __init__(self, name: Optional[str] = None,
                 primary_id: str = "id") -> None:
        self.name = name
        self.idx_name = primary_id
        self._columns: defaultdict = defaultdict(Column)
        self.idx = 1
        self.keys: set = set()
        self.create_column(name=self.idx_name, unique=True)

    @classmethod
    def from_dataset(cls, table: dataset.table.Table, name=None) -> None:
        if name is None:
            name = table.name

        pk = None
        for col in table.table.columns:
            if col.primary_key is True:
                pk = col.name
                break

        pymemdb_table = cls(name, primary_id=pk)
        for row in table:
            pymemdb_table.insert(row)

        return pymemdb_table

    def to_dataset(self, db: dataset.Database, drop=False):
        if self.name in db.tables and drop:
            db[self.name].drop()
        if self.name not in db.tables:
            db.create_table(self.name, primary_id=self.idx_name)

        with db as tx:
            for row in self.all():
                tx[self.name].insert(row)

    def all(self, ordered: ORDER_TYPE = False) -> ROW_GEN:
        """returns a generator of all rows of the table.

        Keyword Arguments:
            ordered {["ascending", "descending", False]} -- Can be set to
                ascending or descending to sort by the primary id column
                (default: {False})
        Raises:
            ValueError: [if 'ordered' is not in {"ascending', 'descending',
                                                 False}]

        Returns:
            Generator -- [A Generator over all the rows in the table]

        Yields:
            dict -- [Dictionary that contains all elements of a row in the
                     table]
        """
        if ordered is False:
            for i in self.keys:
                yield self._get_row(i)
        elif ordered == "ascending":
            for i in sorted(self.keys):
                yield self._get_row(i)
        elif ordered == "descending":
            for i in sorted(self.keys, reverse=True):
                yield self._get_row(i)
        else:
            raise ValueError("Value for kwarg 'ordered' not in [False, "
                             "ascending, descending] !")

    def create_column(self, name: str, default: Hashable = None,
                      unique: bool = False) -> None:
        """Create a Column in the table.

        Arguments:
            name {str} -- Name of the column

        Keyword Arguments:
            default {Hashable} -- Default value for the column
                                    (default: {None})
            unique {bool} -- If values are enforced to be unique for this
                             column. If True, trying to insert a value more
                             than once will raise UniqueConstraintError
                             (default: {False})
        """
        self._columns[name] = Column(default=default, unique=unique)

    @property
    def columns(self) -> List[str]:
        """Returns a list of all column names of the table.

        Returns:
            List[str] -- [List of column names]

        """
        return list(self._columns)

    def drop(self) -> None:
        """Delete table."""
        del self

    def insert(self, row: Dict) -> int:
        """Inserts a row in the table. If a column is not present,
           it will be created with default value None

        Arguments:
            row {Dict} -- dictionary that represents a row in the table.

        Raises:
            UniqueConstraintError: [if constraint of a column is violated]

        Returns:
            int -- [primary key for the row inserted]
        """
        if self.idx_name in row:
            idx = row[self.idx_name]
        else:
            while self.idx in self.keys:
                self.idx += 1
            idx = self.idx
        self.keys.add(idx)
        for key, val in row.items():
            self._columns[key].insert(idx, val)
        if self.idx_name not in row:
            self._columns[self.idx_name].insert(idx, idx)
        return idx

    def insert_ignore(self, row: Dict, keys: List[str], ignore_errors: bool = True) -> Optional[int]:
        """Inserts rows into the table. If another row is already present
           where all the values are identical for the fields in 'keys', the
           insert will be skipped

        Arguments:
            row {Dict} -- [row to be inserted]
            keys {List[str]} -- [List of columns to check for ignore]

        Raises:
            UniqueConstraintError: [if constraint of a column is violated]

        Returns:
            Optional[int] -- [primary key for the row inserted or None if
                              the insert was skipped]

        """
        results = self.find(**{key: row[key] for key in keys}, ignore_errors=ignore_errors)
        try:
            next(results)
        except StopIteration:
            return self.insert(row)
        return None

    def find(self, ignore_errors: bool = True,
             **kwargs) -> Generator[dict, None, None]:
        """finds rows in the table.

        Keyword Arguments:
            **kwargs -- keyword is the column name and value represents the
                        value to search.
                        if value is in iterable, it matches a
                        SELECT * WHERE keyword IN val
                        search.
            ignore_errors {bool} -- if True, it raises an error if a column
                                    does not exist in the table
                                    (default: {False})

        Returns:
            Generator[dict] -- [Generator over all rows that match the search]
        """
        results = self._find_rows(ignore_errors=ignore_errors, **kwargs)

        for idx in results:
            yield {self.idx_name: idx, **self._get_row(idx)}

    def find_one(self, ignore_errors: bool = False, **kwargs) -> Optional[dict]:
        """finds a single row from the table, if there is one.
        Keyword Arguments:
            ignore_errors {bool} -- if True, it raises an error if a column
                                    does not exist in the table
                                    (default: {False})

        Returns:
            Optional[dict] -- single row from the table or None if there is
                              none that matches the query.
        """

        try:
            row = next(self.find(ignore_errors=ignore_errors, **kwargs))
        except StopIteration:
            return None
        return row

    def delete(self, ignore_errors: bool = False, **kwargs) -> int:
        pks = {row[self.idx_name] for row in self.find(**kwargs)}
        if len(pks) == 0 and not ignore_errors:
            raise KeyError(f"No matching rows found for {kwargs}")
        for pk in pks:
            self.keys.remove(pk)
        for col in self._columns.values():
            for pk in pks:
                col.drop(pk)
        return len(pks)

    def update(self, where: dict, **kwargs) -> int:
        pks = self._find_rows(**where)
        if not pks:
            return 0

        for col, val in kwargs.items():
            cell_dict = self._columns[col].cells
            val_dict = self._columns[col].values
            for pk in pks:
                cell_dict[pk] = val
                val_dict[val].add(pk)
        return len(pks)

    def update_replace(self, where: dict, **kwargs):
        n_rows = self.update(where=where, **kwargs)
        if n_rows == 0:
            return 0

        new_where = {**where, **kwargs}
        rows = self.find(**new_where)
        result_counter = defaultdict(frozenset)
        for row in rows:
            pk = row[self.idx_name]
            del row[self.idx_name]
            r = result_counter[tuple(row.items())]
            result_counter[tuple(row.items())] = r.union({pk})

        rowcount = 0
        for pks in result_counter.values():
            if len(pks) < 2:
                continue
            keep = min(pks)
            pks = pks.difference({keep})
            n = self.delete(**{self.idx_name: pks})
            rowcount += n

        return rowcount

    def _get_row(self, idx: int) -> dict:
        row = {col: self._columns[col].find_value(idx) for col in self.columns}
        row = {self.idx_name: idx, **row}
        return row

    def _find(self, col: str, val: Hashable) -> set:
        if isinstance(val, Iterable) and not isinstance(val, str):
            results: set = set()
            for v in val:
                results.update(self._columns[col].find(v))
            return results
        return self._columns[col].find(val)

    def _find_rows(self, ignore_errors: bool = True, **kwargs) -> set:
        results: set = set()
        for col, val in kwargs.items():
            if col not in self._columns:
                if ignore_errors:
                    continue
                else:
                    raise KeyError(f"Column {col} not in Table!")
            if len(results) == 0:
                results = self._find(col, val)
            else:
                pk = self._find(col, val)
                results = results.intersection(pk)
            if val == self._columns[col].default:
                column_cells = set(self._columns[col].cells)
                mis_def_keys = self.keys.symmetric_difference(column_cells)
                results.update(mis_def_keys)
            if not results:
                return set()
        return results

    def __eq__(self, other):
        return self.name == other.name

    def __getitem__(self, col):
        if col not in self._columns:
            raise ColumnDoesNotExist("Column {col} does not exist!")
        return self._columns[col]

    def __delitem__(self, col):
        if col not in self._columns:
            raise ColumnDoesNotExist(f"Column {col} does not exist!")
        del self._columns[col]

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


import matplotlib.pyplot as plt
import numpy as np

def t_chart(patient, lwst, bgst, keylwst, keybgst, constant):
    x_min = lwst - constant
    x_max = bgst + constant

    x = np.linspace(x_min, x_max, 1000)
    y = np.ones(1000)

    range_values = np.where(x <= lwst, 0, np.where(x > bgst, 1, (x - lwst) / (bgst - lwst)))
    range_values = range_values.reshape(1, -1)

    fig, ax = plt.subplots(figsize=(6, 0.5))

    ax.imshow(range_values, cmap='RdYlGn_r', aspect='auto', extent=[x_min, x_max, 0, 1], alpha=0.7)

    ax.plot(x, y, color='black')

    ax.get_yaxis().set_visible(False)
    ax.get_xaxis().set_visible(False)

    for limit, label in zip([lwst, bgst], [keylwst, keybgst]):
        ax.axvline(x=limit, color='black', linestyle='-', linewidth=1.5)
        ax.annotate(str(limit), xy =(limit, 0),
             xytext =(limit, -0.50), ha='center', va='center', fontsize = 14,
             arrowprops = dict(facecolor ='black',headwidth=7, headlength=6))

    # Patient
    custom_value = max(x_min, min(patient, x_max))
    linewidth = 2 if x_min < patient < x_max else 5
    ax.axvline(x=custom_value, color='red', linestyle='-', linewidth=linewidth)

    if patient < x_max and patient > x_min:
        ax.annotate(str(patient), xy =(patient, 1),
            xytext =(patient, 1.45), ha='center', va='center', fontsize = 14,
            arrowprops = dict(facecolor ='red',headwidth=7, headlength=6))
    elif patient <= x_min:
        ax.annotate(str(patient), xy =(x_min + constant/25, 1), fontsize = 14,
            xytext =(x_min + constant/25, 1.45), ha='center', va='center',
            arrowprops = dict(facecolor ='red',headwidth=7, headlength=6))
    else:
        ax.annotate(str(patient), xy =(x_max - constant/25, 1), fontsize = 14,
                xytext =(x_max - constant/25, 1.45), ha='center', va='center',
                arrowprops = dict(facecolor ='red',headwidth=7, headlength=6))

    #plt.show()
    return plt

def trial():
    constant = 2 * (abs(27 - 20)) / 3
    t_chart(7, 20, 27, "<", ">", constant)

#trial()


from collections import Counter

MyList = [1, 2, 3, 4, 1, 2, 3, 1, 2, 1, 5]
ListCount = Counter(MyList)

print(ListCount)

for ThisItem in ListCount.items():
   print("L'élément : ", ThisItem[0],
         " apparait : ", ThisItem[1], " fois")

print("La valeur 1 apparait {0} fois."
      .format(ListCount.get(1)))


# 84. Prime Number Checker
# Coded on 08.10.2022

# Prime number: Number only divisible by 1 and itself

#Write your code below this line ðŸ‘‡
import math

def prime_checker(number):
    is_prime = True
    for n in range (2, number):
        # print(f"{number} % {n} = {number % n}")
        if number % n == 0:
            # Not a prime number
            is_prime = False
    # If number is a prime
    if is_prime:
        print("It's a prime number.")
    else:
        print("It's not a prime number.")

#Write your code above this line ðŸ‘†

#Do NOT change any of the code belowðŸ‘‡
n = int(input("Check this number: "))
prime_checker(number=n)


import pandas as pd

def read_data(path):
    return pd.read_csv(path, sep=",", index_col=['index'])

def treat_input(bag_of_plugins):
    """
    Consider only pedalboards with more then 3 distinct plugins
    """
    # Convert only zero and one
    bag_of_plugins = ((bag_of_plugins > 0) * 1)

    # Remove guitar_patches.id column
    del bag_of_plugins['id']
    # Remove never unused plugin
    # > bag_of_plugins.T[bag_of_plugins.sum() == 0]
    # 9
    #del bag_of_plugins['9']

    # Zero all that will disconsider
    # BOMB(9) and None(107)
    bag_of_plugins['9'] = 0
    bag_of_plugins['107'] = 0

    # Consider only pedalboards with more then 3 distinct plugins
    bag_of_plugins = bag_of_plugins[bag_of_plugins.T.sum() > 3]
    return bag_of_plugins

def train(dataset, batch_size=10, epochs=100, persist=False):
    """
    # Batch_size = 10 or 100
    # https://www.cs.toronto.edu/~hinton/absps/guideTR.pdf
    """
    import time

    import tensorflow as tf

    from rbm.learning.constant_learning_rate import ConstantLearningRate
    from rbm.rbm import RBM
    from rbm.regularization.regularization import L1Regularization, L2Regularization
    from rbm.train.task.beholder_task import BeholderTask
    from rbm.train.task.persistent_task import PersistentTask
    from rbm.train.task.rbm_mensurate_task import RBMMeasureTask
    from rbm.train.task.summary_task import SummaryTask
    from rbm.train.trainer import Trainer

    tf.set_random_seed(42)

    total_elements, size_element = dataset.shape

    rbm = RBM(
        visible_size=size_element,
        #hidden_size=10,
        hidden_size=6,
        #regularization=L1Regularization(0.01),
        #regularization=L2Regularization(0.01),
        learning_rate=ConstantLearningRate(0.05)
    )

    trainer = Trainer(rbm, dataset, batch_size=batch_size)
    trainer.stopping_criteria.append(lambda current_epoch: current_epoch > epochs)

    log = "experiments/logs/{}/{}".format(batch_size, time.time())

    trainer.tasks.append(RBMMeasureTask())
    trainer.tasks.append(SummaryTask(log=log))
    trainer.tasks.append(BeholderTask(log='experiments/logs'))

    if persist:
        trainer.tasks.append(PersistentTask(path="experiments/model/{}/rbm.ckpt".format(batch_size)))

    trainer.train()

# Treinar
bag_of_plugins = read_data('data/pedalboard-plugin-bag-of-words.csv')
bag_of_plugins = treat_input(bag_of_plugins)
train(bag_of_plugins, persist=True, batch_size=1, epochs=100)

# Isso aqui vai ser usado para verificar se as probabilidades batem
#Counselor(bag_of_plugins).suggest(['1', '3'])

# Gerar amostras
# Verificar se a probabilidade que deu bate com a do dataset


#!/usr/bin/python3
#ProSlimer
#Vsauce2 - A Game You Can Always Win - https://youtu.be/dUXW3Kh_kxo

#computer vs human: winner is the first to get to 100 without going over.
#level 1: computer makes random guesses
#level 2: computer makes random guess until 50 and then moves to optimal strategy.
#level 3: the computer always plays optimal strategy.

#To Do:
#Clean up the code a bit. It is kinda hard to follow at this point. I jsut got shit everywhere

import random

# Initiate all used variables to 0
number = 0
useradd = 0
cpuadd = 0
turn = 0
difficulty = 0
scores = [0, 0]
max_score = max(scores)
width = len(str(max_score)) + 1  # Add 1 for padding

# Read scores from the file
file_path = "D:/Documents/PyProjects/Vsauce-100-Game/scores.txt"  # Replace with the actual file path
try:
    with open(file_path, "r") as score_file:
        player_score, computer_score = map(int, score_file.readline().strip().split(","))
        scores = [computer_score, player_score]  # Update scores based on the file data
except FileNotFoundError:
    # Handle the case where the file doesn't exist
    scores = [0, 0]  # Initialize scores with default values

def start(difficulty):
    while True:
        try:
            print(
                f'''
    ============================
    |                          |
    | Welcome to The 100 Game! |
    |                          |
    ============================
            SCOREBOARD
    ============================
    Player:                 {scores[1]:0{width}}
    Computer:               {scores[0]:0{width}}
    ''')

            input_difficulty = input("What difficulty would you like to play? (1-3)\n")
            difficulty = int(input_difficulty)
            if difficulty not in {1, 2, 3}:
                raise ValueError("Invalid difficulty selection")
            break  # Exit the loop if a valid difficulty is selected
        except ValueError:
            print("That is not a valid difficulty option, please try again.\n")

    return difficulty

def userturn(number):
    while True:
        useradd = input("Please enter your number. (1-10)\n")
        try:
            useradd = int(useradd)
            if 1 <= useradd <= 10:
                if useradd + number > 100:
                    print("That number is too high, please enter a smaller number so you don't pass 100")
                else:
                    number += useradd
                    print(f"The new number is {number}.\n")
                return useradd, number
            else:
                print("That number isn't between 1 and 10, please enter a number between 1 and 10")
        except ValueError:
            print("Invalid input. Please enter a valid number between 1 and 10.")

def computerrandom(number):
    cpuadd = random.randint(1, 10)
    if cpuadd + number > 100:
        return computerrandom(number)
    else:
        number += cpuadd
        print(f"The computer chose {cpuadd}, the new number is {number}.")
    return number

def computerturn(useradd, difficulty, number):
    if difficulty == 1:
        number = computerrandom(number)
    elif difficulty == 2:
        if number < 50:
            number = computerrandom(number)
        else:
            cpuadd = min(11 - useradd, 100 - number)  # Ensure the total doesn't go over 100
            number += cpuadd
            print(f"The computer chose {cpuadd} the new number is {number}.")
    elif difficulty == 3:
        if useradd == 0:
            number = computerrandom(number)  # Computer chooses a random number if it's turn is first
        else:
            cpuadd = min(11 - useradd, 100 - number)  # Ensure the total doesn't go over 100
            number += cpuadd
            print(f"The computer chose {cpuadd} the new number is {number}.")
    else:
        print(f"Difficulty variable is invalid? The current difficulty variable is:{difficulty}. Fix something.")
        quit()
    return number

difficulty = start(difficulty)
turn = random.randint(0, 1)
if turn == 0:
    print("You get to go first!")
else:
    print("The computer will go first.")

while number < 100:
    if turn == 0:
        useradd, number = userturn(number)
        turn = 1
    else:
        number = computerturn(useradd, difficulty, number)
        turn = 0

if turn == 0:
    print("The computer wins, better luck next time!")
    scores[0] += 1  # Increment the computer's score
elif turn == 1:
    print("You win! Great job!")
    scores[1] += 1  # Increment the player's score
else:
    print("The turn variable is invalid. How did you do that? Turn:", turn)

# Save the scores list to a file with the specified path
file_path = "D:/Documents/PyProjects/Vsauce-100-Game/scores.txt"
with open(file_path, "w") as score_file:
    score_file.write(f"{scores[1]:0{width}},{scores[0]}:0{width}\n")


import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE','first_project.settings')

import django
django.setup()

import random
from firstapp.models import AccessRecord,Webpage,Topic
from faker import Faker

fakegen = Faker()

topics = ['Search', 'social', 'Sports','Politics']

def add_topic():
    t= Topic.objects.get_or_create(top_name=random.choice(topics))[0]
    t.save()
    return t

def populate(N=5):
    for i in range(N):

        fake_url = fakegen.url()
        fake_date = fakegen.date()
        fake_name = fakegen.company()

        wepg = Webpage.objects.get_or_create(Topic=random.choice(topics),name=fake_name,url=fake_url)[0]
        acred = AccessRecord.objects.get_or_create(name=fake_name,date=fake_date)[0]

if __name__=='__main__':
    print("start")
    populate(N=10)
    print("done")


from collections import deque

g_mango = {
    "i": ["alice", "bob", "claire"],
    "alice": ["peggy"],
    "bob": ["anuj", "peggy"],
    "claire": ["thom", "jonny"],
    "anuj": [],
    "peggy": [],
    "thom": [],
    "jonny": []
}
sells_mango = {"peggy": True}

def sell_mango(person):
    if sells_mango.get(person):
        return sells_mango[person]

def search(name):
    search_queue = deque()
    search_queue += g_mango[name]
    verified = []
    while search_queue:
        person = search_queue.popleft()
        if person not in verified:
            if sell_mango(person):
                print(person + " sells mango!")
                return True
            else:
                search_queue += g_mango[person]
                verified.append(person)
    return False

search("i")


# encoding:utf-8
import copy
import random
import bisect #bisect_left　これで二部探索の大小検索が行える
import fractions #最小公倍数などはこっち
import math
import sys

mod = 10**9+7
sys.setrecursionlimit(mod) # 再帰回数上限はでdefault1000

def LI(): return list(map(int, sys.stdin.readline().split()))

N,K = LI()

if K > (N-1)*(N-2)//2 :
    print("-1")
    exit()
nodes = []
for i in range(1,N):
    nodes.append([1,i+1])
add = (N-1)*(N-2) // 2 - K
for i in range(N-2):
    for j in range(i,N-2):
        add -= 1
        if add < 0:
            break
        nodes.append([i+2,j+3])
    else:
        continue
    break

print(len(nodes))
for node in nodes:
    x,y = node
    print(x,y)


import os

import eventlet
from oslo.config import cfg

from nova import exception
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
from nova.servicegroup import api
from nova import utils

evzookeeper = importutils.try_import('evzookeeper')
membership = importutils.try_import('evzookeeper.membersip')
zookeeper = importutils.try_import('zookeeper')

zk_driver_opts = [
    cfg.StrOpt('address',
               default=None,
               help='The ZooKeeper addresses for servicegroup service in the '
                    'format of host1:port,host2:port,host3:port'),
    cfg.IntOpt('recv_timeout',
               default=4000,
               help='recv_timeout parameter for the zk session'),
    cfg.StrOpt('sg_prefix',
               default="/servicegroups",
               help='The prefix used in ZooKeeper to store ephemeral nodes'),
    cfg.IntOpt('sg_retry_interval',
               default=5,
               help='Number of seconds to wait until retrying to join the '
                    'session'),
    ]

CONF = cfg.CONF
CONF.register_opts(zk_driver_opts, group="zookeeper")

LOG = logging.getLogger(__name__)

class ZooKeeperDriver(api.ServiceGroupDriver):
    """ZooKeeper driver for the service group API."""

    def __init__(self, *args, **kwargs):
        """Create the zk session object."""
        if not all([evzookeeper, membership, zookeeper]):
            raise ImportError('zookeeper module not found')
        null = open(os.devnull, "w")
        self._session = evzookeeper.ZKSession(CONF.zookeeper.address,
                                              recv_timeout=
                                                CONF.zookeeper.recv_timeout,
                                              zklog_fd=null)
        self._memberships = {}
        self._monitors = {}
        # Make sure the prefix exists
        try:
            self._session.create(CONF.zookeeper.sg_prefix, "",
                                 acl=[evzookeeper.ZOO_OPEN_ACL_UNSAFE])
        except zookeeper.NodeExistsException:
            pass

        super(ZooKeeperDriver, self).__init__()

    def join(self, member_id, group, service=None):
        """Join the given service with its group."""
        LOG.debug(_('ZooKeeperDriver: join new member %(id)s to the '
                    '%(gr)s group, service=%(sr)s'),
                    {'id': member_id, 'gr': group, 'sr': service})
        member = self._memberships.get((group, member_id), None)
        if member is None:
            # the first time to join. Generate a new object
            path = "%s/%s" % (CONF.zookeeper.sg_prefix, group)
            try:
                member = membership.Membership(self._session, path, member_id)
            except RuntimeError:
                LOG.exception(_("Unable to join. It is possible that either "
                                "another node exists with the same name, or "
                                "this node just restarted. We will try "
                                "again in a short while to make sure."))
                eventlet.sleep(CONF.zookeeper.sg_retry_interval)
                member = membership.Membership(self._session, path, member_id)
            self._memberships[(group, member_id)] = member
        return FakeLoopingCall(self, member_id, group)

    def leave(self, member_id, group):
        """Remove the given member from the service group."""
        LOG.debug(_('ZooKeeperDriver.leave: %(member)s from group %(group)s'),
                  {'member': member_id, 'group': group})
        try:
            key = (group, member_id)
            member = self._memberships[key]
            member.leave()
            del self._memberships[key]
        except KeyError:
            LOG.error(_('ZooKeeperDriver.leave: %(id)s has not joined to the '
                        '%(gr)s group'), {'id': member_id, 'gr': group})

    def is_up(self, service_ref):
        group_id = service_ref['topic']
        member_id = service_ref['host']
        all_members = self.get_all(group_id)
        return member_id in all_members

    def get_all(self, group_id):
        """Return all members in a list, or a ServiceGroupUnavailable
        exception.
        """
        monitor = self._monitors.get(group_id, None)
        if monitor is None:
            path = "%s/%s" % (CONF.zookeeper.sg_prefix, group_id)
            monitor = membership.MembershipMonitor(self._session, path)
            self._monitors[group_id] = monitor
            # Note(maoy): When initialized for the first time, it takes a
            # while to retrieve all members from zookeeper. To prevent
            # None to be returned, we sleep 5 sec max to wait for data to
            # be ready.
            for _retry in range(50):
                eventlet.sleep(0.1)
                all_members = monitor.get_all()
                if all_members is not None:
                    return all_members
        all_members = monitor.get_all()
        if all_members is None:
            raise exception.ServiceGroupUnavailable(driver="ZooKeeperDriver")
        return all_members

class FakeLoopingCall(utils.LoopingCallBase):
    """The fake Looping Call implementation, created for backward
    compatibility with a membership based on DB.
    """
    def __init__(self, driver, host, group):
        self._driver = driver
        self._group = group
        self._host = host

    def stop(self):
        self._driver.leave(self._host, self._group)

    def start(self, interval, initial_delay=None):
        pass

    def wait(self):
        pass


import random

#Begining Code
input_file = open('dictionary.txt', 'r')
input_read = input_file.read()
word_bank = input_read.split()
break1 = 62 * '*'
print(break1)
rules_ask = int(input('Hello and welcome to Hangman! This is a game of guessing\na random word will be selected and you will be given how many\nletters the word contains from the amount of dashes.\nYour job is to guess letter by letter what the word is.\nWhen you wrongly guess a letter you will be given a strike.\nYou have a total of 8 guesses before you lose the game.\nIf you would like to play type 1, if you do not then type 0: '))
#counters
game_counter = 0
win_counter = 0
loss_counter = 0
word_guess = ('')
#while loop to play
while rules_ask == 1:
    word = random.choice(word_bank)
    turns = 0
    game_counter +=1
    correct = 0
    #while hangman loop
    while turns < 8:
        for character in word:
            #prints the guessed character or a underscore
            if character in word_guess:
                print(character)
                correct += 1
            else:
                print(str(('i'.strip('\n'))))
                incorrect = 0
                incorrect += 1

        if incorrect < 1:
            print('Congrats, you won the game!')
            win_counter += 1
        #keeps guessing the character
        guessing = input('guess one of the character of the random word: ')
        word_guess += guessing
        #increase turn
        if guessing  not in word:
            turns += 1 #when not guessed it increases the turn
        print('You still have', (8 - turns), 'more guesses in total')
        #Lose
        if turns == 8:
            print('You lost, the word was', word)
            loss_counter += 1
    rules_ask = int(input('Type 1 to play again. Type 2 to end the game: ')) #loop stopper

print('\nYou played a total of',game_counter, 'games')
print('You won', win_counter, 'amount of games and lost', loss_counter, 'amount of games')
print('Goodbye')


import argparse
import os
import torch
import numpy as np
import utils
import helps_pre as pre
import optuna
from optuna.samplers import TPESampler
from optuna.pruners import MedianPruner
import yaml
from easydict import EasyDict as edict

parser = argparse.ArgumentParser()
parser.add_argument(
    '--edl', type=int, default=0,
    help='0: no edl; 1: edl without kl; 2: edl with kl (annealing); \
        3: edl with kl (trade-off)')
parser.add_argument('--tcn', action='store_true', default=False,
                    help='to use tcn if it activates, cnn otherwise')

args = parser.parse_args()

EDL_USED = args.edl
TCN_USED = args.tcn
DEVICE = pre.try_gpu()
GLOBAL_BEST_LOSS = np.inf

def run_training(fold, cfg):
    train_trial_list = list(set(range(1,cfg.DATA_CONFIG.trial_n+1))-set(cfg.CV.valid_trial_list[fold]))

    # load_data
    train_loader = pre.load_data(cfg.DATA_PATH, cfg.DATA_CONFIG.sb_n, cfg.DATA_CONFIG.day_list, cfg.DATA_CONFIG.time_list, train_trial_list, tcn_used=TCN_USED, batch_size=cfg.HP.batch_size, shuffle=cfg.DATA_LOADER.shuffle, drop_last=cfg.DATA_LOADER.drop_last, num_workers=cfg.DATA_LOADER.num_workers, pin_memory=cfg.DATA_LOADER.pin_memory)

    valid_loader = pre.load_data(cfg.DATA_PATH, cfg.DATA_CONFIG.sb_n, cfg.DATA_CONFIG.day_list, cfg.DATA_CONFIG.time_list, cfg.CV.valid_trial_list[fold], tcn_used=TCN_USED, batch_size=cfg.HP.batch_size, shuffle=cfg.DATA_LOADER.shuffle, drop_last=cfg.DATA_LOADER.drop_last, num_workers=cfg.DATA_LOADER.num_workers, pin_memory=cfg.DATA_LOADER.pin_memory)

    trainloaders = {
        "train": train_loader,
        "val": valid_loader,
    }

    n_class = len(cfg.CLASS_NAMES)
    # Load Model
    if TCN_USED:
        #model = utils.TCN(input_size=cfg.DATA_CONFIG.channel_n, output_size=n_class, num_channels=cfg.HP.tcn_channels, kernel_size=cfg.HP.kernel_size, dropout=cfg.HP.dropout_rate)
        model = utils.TCN(input_size=cfg.DATA_CONFIG.channel_n, output_size=n_class, num_channels=cfg.HP.layer_n*[cfg.DATA_CONFIG.channel_n], kernel_size=cfg.HP.kernel_size, dropout=cfg.HP.dropout_rate)
    else:
        model = utils.Model(number_of_class=n_class, dropout=cfg.HP.dropout_rate)
    model.to(DEVICE)
    optimizer = getattr(
        torch.optim,cfg.HP.optimizer)(model.parameters(), lr=cfg.HP.lr)

    eng = utils.EngineTrain(model, optimizer, device=DEVICE)

    loss_params = {'edl_used': EDL_USED, 'device': DEVICE}
    if EDL_USED != 0:
        loss_params['class_n'] = n_class
        for item in cfg.HP_SEARCH[f'EDL{EDL_USED}']:
            loss_params[item]=cfg.HP[item]

    best_loss = np.inf
    early_stopping_iter = cfg.TRAINING.early_stopping_iter

    for epoch in range(1, cfg.TRAINING.epochs + 1):
        # if 'annealing_step' in loss_params:
        if EDL_USED == 2:
            loss_params['epoch_num'] = epoch
        train_losses, acc = eng.train(trainloaders, loss_params)
        train_loss = train_losses['train']
        valid_loss = train_losses['val']
        train_acc = acc['train']
        valid_acc = acc['val']
        '''
        print(
            f"epoch:{epoch}, "
            f"train_loss: {train_loss}, "
            f"valid_loss: {valid_loss}. "
            f"train_acc: {train_acc}, "
            f"valid_acc: {valid_acc}. "
        )
        '''
        if valid_loss < best_loss:
            best_loss = valid_loss
            early_stopping_counter = 0
            '''
            torch.save({
                'epoch': epoch,
                'model_state_dict': model.state_dict(),
                'optimizer': params['optimizer'],
                'optimizer_state_dict': optimizer.state_dict(),
                'train_loss': train_loss,
                'valid_loss': valid_loss # best_loss
                }, params['saved_model'])
            '''
        else:
            early_stopping_counter += 1
            early_stopping_counter += 1
        if early_stopping_counter > early_stopping_iter:
            break

    global GLOBAL_BEST_LOSS
    if best_loss < GLOBAL_BEST_LOSS:
        GLOBAL_BEST_LOSS = best_loss
        torch.save({
            'model_state_dict': model.state_dict(),
            'train_loss': train_loss,
            'valid_loss': valid_loss, # best_loss
            'train_acc:': train_acc,
            'valid_acc': valid_acc
            }, cfg.model_path+f'/{cfg.TRAINING.model_name}_sb{cfg.DATA_CONFIG.sb_n}.pt') # modify it later
    return best_loss

def objective(trial, cfg):
    # cfg.HP={} # hyperparams
    # Update the params for tuning with cross validation
    #with open("hpo_search.yaml", 'r') as f:
    #    hyo_search = yaml.load(f, Loader=yaml.SafeLoader)
    #trial.set_user_attr("batch_size", 256)
    #if TCN_USED:
    #    trial.set_user_attr("kernel_size", 5)
    for key, item in cfg.HP_SEARCH[f'EDL{EDL_USED}'].items():
        cfg.HP[key] =  eval(item) # Example of an item: trial.suggest_int("kernel_size", 2, 6)
    if TCN_USED:
        cfg.HP['layer_n'] = eval(cfg.HP_SEARCH['TCN'].layer_n)
        cfg.HP['kernel_size'] = cfg.HP_SEARCH['TCN'].kernel_list[cfg.HP['layer_n']-3]
        #for key, item in cfg.HP_SEARCH['TCN'].items():
        #    if key == 'tcn_channels':
        #        cfg.HP[key] = item
        #    else:
        #        cfg.HP[key] =  eval(item)

        #tcn_channels = [int(cfg.HP['init_channel'])]
        #for i in range(cfg.HP['tcn_layer_n']-1):
        #    tcn_channels.append(tcn_channels[-1]*2)
        #cfg.HP['TCN_CHANNELS'] = [32, 64, 128, 256, 512]
    #print(cfg.HP)
    #cfg.HP['batch_size'] = 256
    #if TCN_USED:
    #    cfg.HP['kernel_size'] = 5

    if cfg.CV.valid_trial_select is None:
        all_losses = []
        for fold_n in range(len(cfg.CV.valid_trial_list)):
            temp_loss = run_training(fold_n, cfg)
            intermediate_value = temp_loss
            trial.report(intermediate_value, fold_n)
            if trial.should_prune():
                raise optuna.TrialPruned()

            all_losses.append(temp_loss)
        return np.mean(all_losses)
    else:
        temp_loss = run_training(cfg.CV.valid_trial_select, cfg)
        return temp_loss

def cv_hyperparam_study():

    # Load config file
    with open("hpo_search.yaml", 'r') as f:
        cfg = edict(yaml.load(f, Loader=yaml.SafeLoader))

    sb_n=cfg.DATA_CONFIG.sb_n
    # Check study path
    study_dir = f'etcn{EDL_USED}' if TCN_USED else f'ecnn{EDL_USED}'
    study_path = os.getcwd() + cfg.STUDY_PATH + study_dir
    if not os.path.exists(study_path):
        os.makedirs(study_path)

    # Check model saved path
    cfg.model_path = os.getcwd() + cfg.MODEL_PATH + study_dir
    if not os.path.exists(cfg.model_path):
        os.makedirs(cfg.model_path)

    # Create Optuna Study
    sampler = eval(cfg.HPO_STUDY.sampler)
    study = optuna.create_study(
        direction=cfg.HPO_STUDY.direction,  # maximaze or minimaze our objective
        sampler=sampler,  # parametrs sampling strategy
        pruner=eval(cfg.HPO_STUDY.pruner),
        study_name=study_dir+f'_sb{sb_n}',
        storage=f"sqlite:///study/{study_dir}/sb{sb_n}.db",
        load_if_exists=True
    )
    study.optimize(lambda trial: objective(trial, cfg), n_trials=cfg.HPO_STUDY.trial_n)

    print("Number of finished trials: ", len(study.trials))
    print("Best trial:")
    trial = study.best_trial
    print("  Value: ", trial.value)
    study_results = [{'best_loss': trial.value}, trial.params]
    #if TCN_USED:
    #    study_results[1]['tcn_channels'] = cfg.HP_SEARCH.TCN.tcn_channels

    # Write (Save) HP to a yaml file
    with open(f'{study_path}/sb_{cfg.DATA_CONFIG.sb_n}', 'w') as f:
        yaml.dump(study_results, f)

        for key, value in trial.params.items():
            print("    {}: {}".format(key, value))
    return

if __name__ == "__main__":

    cv_hyperparam_study()

    os.system('shutdown')


import network
import time

print("Init WiFi network")
sta_if = network.WLAN(network.STA_IF)
ap_if = network.WLAN(network.AP_IF)

def init_wifi():
    print("Setting AP to false")
    ap_if.active(False)
    time.sleep(1)
    print("Setting IF to true")
    sta_if.active(True)
    time.sleep(1)
    print("Connecting to WiFi...")
    # Put WiFi details in here
    sta_if.connect('Access Point Name', 'Access Point Password')

    while not sta_if.isconnected():
        print("Connecting...")
        time.sleep_ms(2000)

    print("Connected")

def disable_wifi():
    sta_if.active(False)


from collections import Counter

ll = [x for x in open('day5.txt').read().strip().split('\n')]

pts = []
for line in ll:
	x1=int(line.split()[0].split(",")[0])
	y1=int(line.split()[0].split(",")[1])

	x2=int(line.split()[2].split(",")[0])
	y2=int(line.split()[2].split(",")[1])
	if x1==x2 or y1==y2:
		for x in range(min(x1,x2),max(x1,x2)+1):
			for y in range(min(y1,y2),max(y1,y2)+1):
				pts.append((x,y))

print(len([x for (x,y) in Counter(pts).items() if y>1]))


# Main container for all decks
#
import os
import threading
import logging
import pickle
from queue import Queue
import pkg_resources

from PIL import Image, ImageFont

from cockpitdecks import __version__, LOGFILE, FORMAT
from cockpitdecks import ID_SEP, SPAM, SPAM_LEVEL, ROOT_DEBUG
from cockpitdecks import CONFIG_FOLDER, CONFIG_FILE, SECRET_FILE, EXCLUDE_DECKS, ICONS_FOLDER, FONTS_FOLDER, RESOURCES_FOLDER
from cockpitdecks import DEFAULT_SYSTEM_FONT, DEFAULT_LABEL_FONT, DEFAULT_LABEL_SIZE, DEFAULT_LABEL_COLOR, DEFAULT_LABEL_POSITION
from cockpitdecks import DEFAULT_ICON_NAME, DEFAULT_ICON_COLOR, DEFAULT_ICON_TEXTURE, DEFAULT_LOGO, DEFAULT_WALLPAPER
from cockpitdecks import DEFAULT_ANNUNCIATOR_COLOR, ANNUNCIATOR_STYLES, DEFAULT_ANNUNCIATOR_STYLE, HOME_PAGE
from cockpitdecks import COCKPIT_COLOR, COCKPIT_TEXTURE
from cockpitdecks import Config
from cockpitdecks.resources.color import convert_color, has_ext
from cockpitdecks.simulator import DatarefListener
from cockpitdecks.decks import DECK_TYPES

logging.addLevelName(SPAM_LEVEL, SPAM)
logger = logging.getLogger(__name__)
# logger.setLevel(logging.DEBUG)

if LOGFILE is not None:
    formatter = logging.Formatter(FORMAT)
    handler = logging.FileHandler(
        LOGFILE, mode="a"
    )
    handler.setFormatter(formatter)
    logger.addHandler(handler)

class CockpitBase:
    """As used in Simulator

    [description]
    """
    def __init__(self):
        pass

    def set_logging_level(self, name):
        if name in self._debug:
            l = logging.getLogger(name)
            if l is not None:
                l.setLevel(logging.DEBUG)
                l.info(f"set_logging_level: {name} set to debug")
            else:
                logger.warning(f"logger {name} not found")

    def reload_pages(self):
        pass

class Cockpit(DatarefListener, CockpitBase):
    """
    Contains all deck configurations for a given aircraft.
    Is started when aicraft is loaded and aircraft contains CONFIG_FOLDER folder.
    """
    def __init__(self, simulator):
        CockpitBase.__init__(self)
        DatarefListener.__init__(self)
        self._debug = ROOT_DEBUG.split(",")   # comma separated list of module names like cockpitdecks.page or cockpitdeck.button_ext

        self._config = None          # content of aircraft/deckconfig/config.yaml
        self.default_config = None   # content of resources/config.yaml

        self.name = "Cockpitdecks"
        self.icao = "ZZZZ"

        self.sim = simulator(self)

        self.disabled = False
        self.default_pages = None      # for debugging

        self.has_reload = False
        self.reload_loop_run = False
        self.reload_loop_thread = None
        self.reload_queue = Queue()

        self.devices = []

        self.acpath = None
        self.cockpit = {}  # all decks: { deckname: deck }

        self.default_logo = DEFAULT_LOGO
        self.default_wallpaper = DEFAULT_WALLPAPER

        self.fonts = {}
        self.default_font = None
        self.default_label_font = DEFAULT_LABEL_FONT
        self.default_label_size = DEFAULT_LABEL_SIZE
        self.default_label_color = convert_color(DEFAULT_LABEL_COLOR)
        self.default_label_position = DEFAULT_LABEL_POSITION

        self.icon_folder = None
        self.icons = {}
        self.cache_icon = False
        self.default_icon_name = DEFAULT_ICON_NAME
        self.default_icon_color = convert_color(DEFAULT_ICON_COLOR)
        self.default_icon_texture = DEFAULT_ICON_TEXTURE
        self.default_annun_texture = None
        self.default_annun_color = convert_color(DEFAULT_ANNUNCIATOR_COLOR)

        self.fill_empty_keys = True
        self.annunciator_style = DEFAULT_ANNUNCIATOR_STYLE
        self.cockpit_color = convert_color(COCKPIT_COLOR)
        self.cockpit_texture = COCKPIT_TEXTURE

        self.default_home_page_name = HOME_PAGE

        self.init()

    def init(self):
        """
        Loads all devices connected to this computer.
        """
        self.scan_devices()

    def get_id(self):
        return self.name

    def get_button_value(self, name):
        a = name.split(ID_SEP)
        if len(a) > 0:
            if a[0] == self.name:
                if a[1] in self.cockpit.keys():
                    return self.cockpit[a[1]].get_button_value(ID_SEP.join(a[1:]))
                else:
                    logger.warning(f"so such deck {a[1]}")
            else:
                logger.warning(f"no such cockpit {a[0]}")
        else:
            logger.warning(f"invalid name {name}")
        return None

    def inspect(self, what: str = None):
        """
        This function is called on all instances of Deck.
        """
        logger.info(f"Cockpitdecks Rel. {__version__} -- {what}")

        if "thread" in what:
            logger.info(f"{[(t.name,t.isDaemon(),t.is_alive()) for t in threading.enumerate()]}")
        elif what.startswith("datarefs"):
            self.inspect_datarefs(what)
        elif what == "monitored":
            self.inspect_monitored(what)
        else:
            for v in self.cockpit.values():
                v.inspect(what)

    def inspect_datarefs(self, what: str = None):
        if what.startswith("datarefs"):
            for dref in self.sim.all_datarefs.values():
                logger.info(f"{dref.path} = {dref.value()} ({len(dref.listeners)})")
                if what.endswith("listener"):
                    for l in dref.listeners:
                        logger.info(f"  {l.name}")
        else:
            logger.info(f"to do")

    def inspect_monitored(self, what: str = None):
        for dref in self.sim.datarefs.values():
            logger.info(f"{dref}")

    def scan_devices(self):
        if len(DECK_TYPES) == 0:
            logger.error(f"no driver")
            return
        logger.info(f"drivers installed for {', '.join([f'{decktype} {pkg_resources.get_distribution(decktype).version}' for decktype in DECK_TYPES.keys()])}; scanning..")
        for decktype, builder in DECK_TYPES.items():
            decks = builder[1]().enumerate()
            logger.info(f"found {len(decks)} {decktype}") # " ({decktype} {pkg_resources.get_distribution(decktype).version})")
            for name, device in enumerate(decks):
                device.open()
                serial = device.get_serial_number()
                device.close()
                if serial in EXCLUDE_DECKS:
                    logger.warning(f"deck {serial} excluded")
                    del decks[name]
                self.devices.append({
                    "type": decktype,
                    "device": device,
                    "serial_number": serial
                })
            logger.debug(f"using {len(decks)} {decktype}")
        logger.debug(f"..scanned")

    def get_device(self, req_serial: str, req_type: str):
        """
        Get a HIDAPI device for the supplied serial number.
        If found, the device is opened and reset and returned open.

        :param    req_serial:  The request serial
        :type      req_serial:  str
        """
        # No serial, return deck if only one deck of that type
        if req_serial is None:
            i = 0
            good = None
            for deck in self.devices:
                if deck["type"] == req_type:
                    good = deck
                    i = i + 1
            if i == 1 and good is not None:
                logger.debug(f"only one deck of type {req_type}, returning it")
                device = good["device"]
                device.open()
                if device.is_visual():
                    image_format = device.key_image_format()
                    logger.debug(f"key images: {image_format['size'][0]}x{image_format['size'][1]} pixels, {image_format['format']} format, rotated {image_format['rotation']} degrees")
                else:
                    logger.debug(f"no visual")
                device.reset()
                return device
            else:
                if i > 1:
                    logger.warning(f"more than one deck of type {req_type}, no serial to disambiguate")
            return None
        ## Got serial, search for it
        for deck in self.devices:
            if deck["serial_number"] == req_serial:
                device = deck["device"]
                device.open()
                if device.is_visual():
                    image_format = device.key_image_format()
                    logger.debug(f"key images: {image_format['size'][0]}x{image_format['size'][1]} pixels, {image_format['format']} format, rotated {image_format['rotation']} degrees")
                else:
                    logger.debug(f"no visual")
                device.reset()
                return device
        logger.warning(f"deck {req_serial} not found")
        return None

    def start_aircraft(self, acpath: str):
        """
        Loads decks for aircraft in supplied path and start listening for key presses.
        """
        self.load_aircraft(acpath)
        self.run()

    def load_aircraft(self, acpath: str):
        """
        Loads decks for aircraft in supplied path.
        """
        if self.disabled:
            logger.warning(f"Cockpitdecks is disabled")
            return
        # Reset, if new aircraft
        if len(self.cockpit) > 0:
            self.terminate_aircraft()
            self.sim.clean_datarefs_to_monitor()
            logger.warning(f"{os.path.basename(self.acpath)} unloaded")

        if len(self.devices) == 0:
            logger.warning(f"no device")
            return

        self.cockpit = {}
        self.icons = {}
        # self.fonts = {}
        self.acpath = None

        self.load_defaults()

        if acpath is not None and os.path.exists(os.path.join(acpath, CONFIG_FOLDER)):
            self.acpath = acpath
            self.load_icons()
            self.load_fonts()
            self.create_decks()
            self.load_pages()
        else:
            if acpath is None:
                logger.error(f"no aircraft folder")
            elif not os.path.exists(acpath):
                logger.error(f"no aircraft folder {acpath}")
            else:
                logger.error(f"no Cockpitdecks folder '{CONFIG_FOLDER}' in aircraft folder {acpath}")
            self.create_default_decks()

    def load_pages(self):
        if self.default_pages is not None:
            logger.debug(f"default_pages {self.default_pages.keys()}")
            for name, deck in self.cockpit.items():
                if name in self.default_pages.keys():
                    if self.default_pages[name] in deck.pages.keys() and deck.home_page is not None:  # do not refresh if no home page loaded...
                        deck.change_page(self.default_pages[name])
                    else:
                        deck.change_page()
            self.default_pages = None
        else:
            for deck in self.cockpit.values():
                deck.change_page()

    def reload_pages(self):
        for name, deck in self.cockpit.items():
            deck.reload_page()

    def load_defaults(self):
        """
        Loads default values for font, icon, etc. They will be used if no layout is found.
        """
        def locate_font(fontname: str) -> str:
            if fontname in self.fonts.keys():
                logger.debug(f"font {fontname} already loaded")
                return fontname

            # 1. Try "system" font
            try:
                test = ImageFont.truetype(fontname, self.default_label_size)
                logger.debug(f"font {fontname} found in computer system fonts")
                return fontname
            except:
                logger.debug(f"font {fontname} not found in computer system fonts")

            # 2. Try font in resources folder
            fn = None
            try:
                fn = os.path.join(os.path.dirname(__file__), RESOURCES_FOLDER, fontname)
                test = ImageFont.truetype(fn, self.default_label_size)
                logger.debug(f"font {fontname} found locally ({RESOURCES_FOLDER} folder)")
                return fn
            except:
                logger.debug(f"font {fontname} not found locally ({RESOURCES_FOLDER} folder)")

            # 3. Try font in resources/fonts folder
            fn = None
            try:
                fn = os.path.join(os.path.dirname(__file__), RESOURCES_FOLDER, FONTS_FOLDER, fontname)
                test = ImageFont.truetype(fn, self.default_label_size)
                logger.debug(f"font {fontname} found locally ({FONTS_FOLDER} folder)")
                return fn
            except:
                logger.debug(f"font {fontname} not found locally ({FONTS_FOLDER} folder)")

            logger.debug(f"font {fontname} not found")
            return None

        # 0. Some variables defaults
        fn = os.path.join(os.path.dirname(__file__), RESOURCES_FOLDER, CONFIG_FILE)
        self.default_config = Config(fn)

        # Load global defaults from resources/config.yaml file or use application default
        self._debug = self.default_config.get("debug", ",".join(self._debug)).split(",")
        self.set_logging_level(__name__)

        self.sim.set_roundings(self.default_config.get("roundings", {}))
        self.sim.set_slow_datarefs(self.default_config.get("slow-datarefs", {}))

        self.default_logo = self.default_config.get("default-logo", DEFAULT_LOGO)
        self.default_wallpaper = self.default_config.get("default-wallpaper", DEFAULT_WALLPAPER)
        self.default_label_font = self.default_config.get("default-label-font", DEFAULT_LABEL_FONT)
        self.default_label_size = self.default_config.get("default-label-size", DEFAULT_LABEL_SIZE)
        self.default_label_color = self.default_config.get("default-label-color", convert_color(DEFAULT_LABEL_COLOR))
        self.default_label_position = self.default_config.get("default-label-position", DEFAULT_LABEL_POSITION)
        self.cache_icon = self.default_config.get("cache-icon", self.cache_icon)
        self.default_icon_name = DEFAULT_ICON_NAME
        self.default_icon_texture = self.default_config.get("default-icon-texture", DEFAULT_ICON_TEXTURE)
        self.default_icon_color = self.default_config.get("default-icon-color", DEFAULT_ICON_COLOR)
        self.default_icon_color = convert_color(self.default_icon_color)
        self.default_annun_texture = self.default_config.get("default-annunciator-texture")
        self.default_annun_color = self.default_config.get("default-annunciator-color", DEFAULT_ANNUNCIATOR_COLOR)
        self.default_annun_color = convert_color(self.default_annun_color)
        self.annunciator_style = self.default_config.get("annunciator-style", DEFAULT_ANNUNCIATOR_STYLE.value)
        self.annunciator_style = ANNUNCIATOR_STYLES(self.annunciator_style)
        self.cockpit_texture = self.default_config.get("cockpit-texture", COCKPIT_TEXTURE)
        self.cockpit_color = self.default_config.get("cockpit-color", COCKPIT_COLOR)
        self.cockpit_color = convert_color(self.cockpit_color)
        self.default_home_page_name = self.default_config.get("default-homepage-name", HOME_PAGE)
        #
        #
        # DO NOT FORGET SET DEFAULTS IN create_decks()
        #
        #

        # 1. Load global icons
        #   (They are never cached when loaded without aircraft.)
        rf = os.path.join(os.path.dirname(__file__), RESOURCES_FOLDER, ICONS_FOLDER)
        if os.path.exists(rf):
            icons = os.listdir(rf)
            for i in icons:
                if has_ext(i, "png"):  # later, might load JPG as well.
                    fn = os.path.join(rf, i)
                    image = Image.open(fn)
                    self.icons[i] = image

        # 2. Finding a default font for Pillow
        #   WE MUST find a default, system font at least

        # 2.1 We try the requested "default label font"
        tryed_our_default = self.default_label_font == DEFAULT_LABEL_FONT
        if self.default_label_font not in self.fonts.keys():
            f = locate_font(self.default_label_font)
            if f is not None:  # found one, perfect
                self.fonts[self.default_label_font] = f
                self.default_font = f
                logger.debug(f"default label font set to {self.default_label_font}")
            else:  # if we are here, self.default_label_font is not found, we must find another one
                self.default_label_font = None

        # 2.2 We try our "default provided label font"
        if self.default_label_font is None and not tryed_our_default:
            f = locate_font(DEFAULT_LABEL_FONT)
            if f is not None:  # found it, perfect
                self.default_label_font = DEFAULT_LABEL_FONT
                self.fonts[DEFAULT_LABEL_FONT] = f
                self.default_font = f
                logger.debug(f"default label font set to {DEFAULT_LABEL_FONT}")
            # if we are here, self.default_label_font is not found, we must find another one

        # 2.3 We try the "default system font"
        f = locate_font(DEFAULT_SYSTEM_FONT)
        if f is not None:  # found it, perfect, keep it as default font for all purposes
            self.fonts[DEFAULT_SYSTEM_FONT] = f
            self.default_font = f
            logger.debug(f"default font set to {DEFAULT_SYSTEM_FONT}")
            if self.default_label_font is None:  # additionnally, if we don't have a default label font, use it
                self.default_label_font = DEFAULT_SYSTEM_FONT
                logger.debug(f"default label font set to {DEFAULT_SYSTEM_FONT}")

        if self.default_label_font is None and len(self.fonts) > 0:
            first_one = list(self.fonts.keys())[0]
            self.default_label_font = first_one
            self.default_font = first_one
            logger.debug(f"no default font found, using first available font")

        if self.default_label_font is None:
            logger.error(f"no default font")

        # 4. report summary if debugging
        logger.debug(f"default fonts {self.fonts.keys()}, default={self.default_font}, default label={self.default_label_font}")

    def create_decks(self):
        sn = os.path.join(self.acpath, CONFIG_FOLDER, SECRET_FILE)
        serial_numbers = Config(sn)
        fn = os.path.join(self.acpath, CONFIG_FOLDER, CONFIG_FILE)
        self._config = Config(fn)
        if self._config.is_valid():
            #
            #
            # DO NOT FORGET SET DEFAULTS IN load_defaults()
            #
            #
            self.default_logo = self._config.get("default-logo", self.default_logo)
            self.default_wallpaper = self._config.get("default-wallpaper", self.default_wallpaper)
            self.default_label_font = self._config.get("default-label-font", self.default_label_font)
            self.default_label_size = self._config.get("default-label-size", self.default_label_size)
            self.default_label_color = self._config.get("default-label-color", self.default_label_color)
            self.default_label_color = convert_color(self.default_label_color)
            self.default_label_position = self._config.get("default-label-position", self.default_label_position)
            self.default_icon_texture = self._config.get("default-icon-texture", self.default_icon_texture)
            self.default_icon_color = self._config.get("default-icon-color", self.default_icon_color)
            self.default_icon_color = convert_color(self.default_icon_color)
            self.default_annun_texture = self._config.get("default-annunciator-texture", self.default_annun_texture)
            self.default_annun_color = self._config.get("default-annunciator-color", self.default_annun_color)
            self.default_annun_color = convert_color(self.default_annun_color)
            self.annunciator_style = self._config.get("annunciator-style", self.annunciator_style)
            self.annunciator_style = ANNUNCIATOR_STYLES(self.annunciator_style)
            self.cockpit_texture = self._config.get("cockpit-texture", self.cockpit_texture)
            self.cockpit_color = self._config.get("cockpit-color", self.cockpit_color)
            self.cockpit_color = convert_color(self.cockpit_color)
            self.default_home_page_name = self.default_config.get("default-homepage-name", self.default_home_page_name)

            logger.debug(f"label font={self.default_label_font}, logo={self.default_logo}, wallpaper={self.default_wallpaper}, texture={self.cockpit_texture}")
            decks = self._config.get("decks")
            if decks is not None:
                deck_type_count = {}
                for deck_config in decks:
                    ty = deck_config.get("type")
                    if ty is not None:
                        if ty not in deck_type_count:
                            deck_type_count[ty] = 0
                        deck_type_count[ty] = deck_type_count[ty] + 1

                cnt = 0
                for deck_config in decks:
                    name = deck_config.get("name", f"Deck {cnt}")

                    disabled = deck_config.get("disabled")
                    if type(disabled) != bool:
                        if type(disabled) == str:
                            disabled = disabled.upper() in ["YES", "TRUE"]
                        elif type(disabled) in [int, float]:
                            disabled = int(disabled) != 0
                    if disabled:
                        logger.info(f"deck {name} disabled, ignoring")
                        continue

                    decktype = deck_config.get("type")
                    if decktype not in DECK_TYPES.keys():
                        logger.warning(f"invalid deck type {decktype}, ignoring")
                        continue

                    serial = deck_config.get("serial")
                    if serial is None:  # get it from the secret file
                        serial = serial_numbers[name] if name in serial_numbers.keys() else None

                    # if serial is not None:
                    device = self.get_device(req_serial=serial, req_type=decktype)
                    if device is not None:
                        #
                        deck_config["model"] = device.deck_type()
                        if serial is None:
                            if deck_type_count[decktype] > 1:
                                logger.warning(f"only one deck of that type but more than one configuration in config.yaml for decks of that type, ignoring")
                                continue
                            deck_config["serial"] = device.get_serial_number()
                            logger.info(f"deck {decktype} {name} has serial {deck_config['serial']}")
                        else:
                            deck_config["serial"] = serial
                        if name not in self.cockpit.keys():
                            self.cockpit[name] = DECK_TYPES[decktype][0](name=name, config=deck_config, cockpit=self, device=device)
                            cnt = cnt + 1
                            logger.info(f"deck {decktype} {name} added")
                        else:
                            logger.warning(f"deck {name} already exist, ignoring")
                    # else:
                    #    logger.error(f"deck {decktype} {name} has no serial number, ignoring")
            else:
                logger.warning(f"no deck in config file {fn}")
        else:
            logger.warning(f"no config file {fn}")

    def create_default_decks(self):
        """
        When no deck definition is found in the aicraft folder, Cockpit loads
        a default X-Plane logo on all deck devices. The only active button is index 0,
        which toggle X-Plane map on/off.
        """
        self.acpath = None

        # {
        #    "type": decktype,
        #    "device": device,
        #    "serial_number": serial
        # }
        for deck in self.devices:
            decktype = deck.get("type")
            if decktype not in DECK_TYPES.keys():
                logger.warning(f"invalid deck type {decktype}, ignoring")
                continue
            device = deck["device"]
            device.open()
            device.reset()
            name = device.id()
            config = {
                "name": name,
                "model": device.deck_type(),
                "serial": device.get_serial_number(),
                "layout": None,   # Streamdeck will detect None layout and present default deck
                "brightness": 75  # Note: layout=None is not the same as no layout attribute (attribute missing)
            }
            self.cockpit[name] = DECK_TYPES[decktype][0](name, config, self, device)

    # #########################################################
    # Cockpit data caches
    #
    def load_icons(self):
        # Loading icons
        #
        dn = os.path.join(self.acpath, CONFIG_FOLDER, ICONS_FOLDER)
        if os.path.exists(dn):
            self.icon_folder = dn
            cache = os.path.join(dn, "_icon_cache.pickle")
            if os.path.exists(cache) and self.cache_icon:
                with open(cache, "rb") as fp:
                    self.icons = pickle.load(fp)
                logger.info(f"{len(self.icons)} icons loaded from cache")
            else:
                # # Global, resource folder icons
                # #                                   # #
                # # THEY ARE NOW LOADED IN LOAD_DEFAULTS # #
                # #                                   # #
                # rf = os.path.join(os.path.dirname(__file__), RESOURCES_FOLDER, ICONS_FOLDER)
                # if os.path.exists(rf):
                #    icons = os.listdir(rf)
                #    for i in icons:
                #        if has_ext(i, "png"):  # later, might load JPG as well.
                #            fn = os.path.join(rf, i)
                #            image = Image.open(fn)
                #            self.icons[i] = image

                # Aircraft specific folder icons
                icons = os.listdir(dn)
                for i in icons:
                    if has_ext(i, "png"):  # later, might load JPG as well.
                        fn = os.path.join(dn, i)
                        image = Image.open(fn)
                        self.icons[i] = image

                if self.cache_icon:  # we cache both folders of icons
                    with open(cache, "wb") as fp:
                        pickle.dump(self.icons, fp)
                    logger.info(f"{len(self.icons)} icons cached")
                else:
                    logger.info(f"{len(self.icons)} icons loaded")

    def load_fonts(self):
        # Loading fonts.
        # For custom fonts (fonts found in the fonts config folder),
        # we supply the full path for font definition to ImageFont.
        # For other fonts, we assume ImageFont will search at OS dependent folders or directories.
        # If the font is not found by ImageFont, we ignore it.
        # So self.icons is a list of properly located usable fonts.
        #
        # 1. Load fonts supplied by Cockpitdeck in its resource folder
        rn = os.path.join(os.path.dirname(__file__), RESOURCES_FOLDER, FONTS_FOLDER)
        if os.path.exists(rn):
            fonts = os.listdir(rn)
            for i in fonts:
                if has_ext(i, ".ttf") or has_ext(i, ".otf"):
                    if i not in self.fonts.keys():
                        fn = os.path.join(rn, i)
                        try:
                            test = ImageFont.truetype(fn, self.default_label_size)
                            self.fonts[i] = fn
                        except:
                            logger.warning(f"default font file {fn} not loaded")
                    else:
                        logger.debug(f"font {i} already loaded")

        # 2. Load fonts supplied by the user in the configuration
        dn = os.path.join(self.acpath, CONFIG_FOLDER, FONTS_FOLDER)
        if os.path.exists(dn):
            fonts = os.listdir(dn)
            for i in fonts:
                if has_ext(i, ".ttf") or has_ext(i, ".otf"):
                    if i not in self.fonts.keys():
                        fn = os.path.join(dn, i)
                        try:
                            test = ImageFont.truetype(fn, self.default_label_size)
                            self.fonts[i] = fn
                        except:
                            logger.warning(f"custom font file {fn} not loaded")
                    else:
                        logger.debug(f"font {i} already loaded")

        # 3. DEFAULT_LABEL_FONT and DEFAULT_SYSTEM_FONT loaded in load_defaults()

        logger.info(f"{len(self.fonts)} fonts loaded, default label font={self.default_label_font}")

    # #########################################################
    # Cockpit start/stop/reload procedures
    #
    # Note: Reloading the deck is done from a separate (dedicated) thread through a queue.
    #
    # The reason is that the reload is provoked by a keypress which is handled in a callback
    # from a deck thread. On reload, the deck will be stopped, initialized, and restarted
    # leading somehow in the destruction of the objects that had created the thread.
    # When pressing a new button, callback would terminate Cockpitdeck.
    # To prevent that, the callback just enqueue a request to perform a reload and exits right away.
    # We do the reload from another thread, external to the callback,
    # that cleanly stops, initializes, and restarts the deck.
    #
    # Note: Only started if has_reload is True. has_reload is set if a Reload button activation is configured.
    #      (Otherwise there is no need to start the reload loop since nothing can provoke it.)
    #
    def start_reload_loop(self):
        if not self.has_reload:
            logger.warning(f"no reload button detected, not starting")
            return
        if not self.reload_loop_run:
            self.reload_loop_thread = threading.Thread(target=self.reload_loop)
            self.reload_loop_thread.name = f"Cockpit::reloader"
            self.reload_loop_run = True
            self.reload_loop_thread.start()
            logger.debug(f"started")
        else:
            logger.warning(f"already running")

    def reload_loop(self):
        while self.reload_loop_run:
            e = self.reload_queue.get()  # blocks infinitely here
            if e == "reload":
                self.reload_decks(just_do_it=True)
            elif e == "stop":
                self.stop_decks(just_do_it=True)
        logger.debug(f"ended")

    def end_reload_loop(self):
        if self.reload_loop_run:
            self.reload_loop_run = False
            self.reload_queue.put("wake up!")  # to unblock the Queue.get()
            # self.reload_loop_thread.join()
            logger.debug(f"stopped")
        else:
            logger.warning(f"not running")

    def reload_decks(self, just_do_it: bool = False):
        """
        Development function to reload page yaml without leaving the page
        Should not be used in production...
        """
        # A security... if we get called we must ensure reloader is running...
        if not self.reload_loop_run:
            logger.warning(f"reload loop not running. Starting..")
            self.has_reload = True
            self.start_reload_loop()
        if just_do_it:
            logger.info(f"reloading decks..")
            self.default_pages = {}  # {deck_name: currently_loaded_page_name}
            for name, deck in self.cockpit.items():
                self.default_pages[name] = deck.current_page.name
            self.load_aircraft(self.acpath)  # will terminate it before loading again
            logger.info(f"..done")
        else:
            self.reload_queue.put("reload")
            logger.debug(f"enqueued")

    def stop_decks(self, just_do_it: bool = False):
        """
        Stop decks gracefully. Since it also terminates self.reload_loop_thread we cannot wait for it
        since we are called from it ... So we just tell it to terminate.
        """
        if just_do_it:
            logger.info(f"stopping decks..")
            self.stop()
        else:
            self.reload_queue.put("stop")
            logger.debug(f"enqueued")

    def dataref_changed(self, dataref):
        """
        This gets called when dataref AIRCRAFT_DATAREF is changed, hence a new aircraft has been loaded.
        """
        v = dataref.value()
        if v is not None and v == 1:
            logger.info(f"current aircraft loaded {dataref.path}={dataref.value()}")
        else:
            logger.info(f"new aircraft loaded {dataref.path}={dataref.value()}")

    def terminate_aircraft(self):
        logger.info(f"terminating..")
        for deck in self.cockpit.values():
            deck.terminate()
        self.cockpit = {}
        nt = len(threading.enumerate())
        if not self.sim.use_flight_loop and nt > 1:
            logger.info(f"{nt} threads")
            logger.info(f"{[t.name for t in threading.enumerate()]}")
        logger.info(f"..done")

    def terminate_devices(self):
        for deck in self.devices:
            decktype = deck.get("type")
            if decktype not in DECK_TYPES.keys():
                logger.warning(f"invalid deck type {decktype}, ignoring")
                continue
            device = deck["device"]
            DECK_TYPES[decktype][0].terminate_device(device, deck["serial_number"])

    def terminate_all(self, threads:int = 1):
        logger.info(f"terminating..")
        # Terminate decks
        self.terminate_aircraft()
        # Terminate dataref collection
        if self.sim is not None:
            logger.info("..terminating connection to simulator..")
            self.sim.terminate()
            logger.debug("..deleting connection to simulator..")
            del self.sim
            self.sim = None
            logger.debug("..connection to simulator deleted..")
        # Terminate reload loop
        if self.reload_loop_run:
            self.end_reload_loop()
        logger.info(f"..terminating devices..")
        self.terminate_devices()
        logger.info(f"..done")
        left = len(threading.enumerate())
        if left > threads:  # [MainThread and spinner]
            logger.error(f"{left} threads remaining")
            logger.error(f"{[t.name for t in threading.enumerate()]}")

    def run(self):
        if len(self.cockpit) > 0:
            # Each deck should have been started
            # Start reload loop
            logger.info(f"starting..")
            self.sim.connect()
            logger.info(f"..connect to simulator loop started..")
            self.start_reload_loop()
            logger.info(f"..reload loop started..")
            if not self.sim.use_flight_loop:
                logger.info(f"{len(threading.enumerate())} threads")
                logger.info(f"{[t.name for t in threading.enumerate()]}")
                logger.info(f"..started")
                logger.info(f"serving {self.name}")
                for t in threading.enumerate():
                    try:
                        t.join()
                    except RuntimeError:
                        pass
                logger.info(f"terminated")
        else:
            logger.warning(f"no deck")
            if self.acpath is not None:
                self.terminate_all()

    # #########################################################
    # XPPython Plugin Hooks
    #
    def start(self):
        logger.info(f"starting..")
        # do nothing, started in when enabled
        logger.info(f"done")

    def stop(self):
        logger.info(f"stopping..")
        self.terminate_all()
        logger.info(f"done")

    def enable(self):
        self.load(self.acpath)
        self.disabled = False
        logger.info(f"enabled")

    def disable(self):
        self.terminate_aircraft()
        self.disabled = True
        logger.info(f"disabled")


from conan import ConanFile
from conan.tools.files import get, copy
import os

required_conan_version = ">=2.0.6"

class PrebuiltPicolibc(ConanFile):
    name = "prebuilt-picolibc"
    settings = "os", "arch", "compiler", "build_type"
    package_type = "static-library"
    build_policy = "missing"
    short_paths = True
    options = {
        "crt0": [
            "semihost",
            "hosted",
            "minimal",
        ]
    }
    default_options = {
        "crt0": "semihost",
    }

    def package_id(self):
        self.info.clear()

    def build(self):
        get(self,
            **self.conan_data["sources"][self.version],
            destination=self.build_folder)

    def package(self):
        destination = os.path.join(self.package_folder, "")
        copy(self, pattern="arm-none-eabi/*", src=self.build_folder,
             dst=destination, keep_path=True)
        copy(self, pattern="bin/*", src=self.build_folder,
             dst=destination, keep_path=True)
        copy(self, pattern="lib/*", src=self.build_folder,
             dst=destination, keep_path=True)

    def package_info(self):
        self.cpp_info.set_property("cmake_target_name", "picolibc")

        self.cpp_info.libs = []
        self.cpp_info.includedirs = []
        self.cpp_info.bindirs = []
        self.cpp_info.frameworkdirs = []
        self.cpp_info.libdirs = []
        self.cpp_info.resdirs = []

        short_to_long_version = {
            "12.2": "12.2.1",
            "12.3": "12.3.1",
        }
        long_version = short_to_long_version[self.version]
        specs_path = f"lib/gcc/arm-none-eabi/{long_version}/picolibcpp.specs"
        prefix = os.path.join(self.package_folder, 'arm-none-eabi')
        picolibcpp_specs = os.path.join(self.package_folder, specs_path)

        self.cpp_info.exelinkflags = [
            f"-specs={picolibcpp_specs}",
            f"--picolibc-prefix={prefix}",
            f"-oslib={str(self.options.crt0)}",
        ]

        self.output.info(f"link flags: {self.cpp_info.exelinkflags}")
        self.output.info(f"crt0: {str(self.options.crt0)}")


import dlib
import face_recognition
import cv2
from PIL import Image, ImageDraw
import numpy as np

# Load a sample picture and learn how to recognize it.
wacef_image = face_recognition.load_image_file("C:/Users/hp/Desktop/Travail_Stage/Faces_data/faces/F1/F16.jpg")
wacef_face_encoding = face_recognition.face_encodings(wacef_image)[0]
# Create arrays of known face encodings and their names
known_face_encodings = [
    wacef_face_encoding
    ]
known_face_names = [
    "Wacef Chachia"
]

cam = cv2.VideoCapture(0)
while True:
    ret, frame = cam.read()

    # Load an image with an unknown face
    #unknown_image = face_recognition.load_image_file("C:/Users/hp/Desktop/Travail_Stage/Faces_data/faces/F1/F24.jpg")

    # Find all the faces and face encodings in the unknown image

    face_locations = face_recognition.face_locations(frame) ######## model='cnn' with GPU #######
    face_encodings = face_recognition.face_encodings(frame, face_locations)

    # Convert the image to a PIL-format image so that we can draw on top of it with the Pillow library
    # See http://pillow.readthedocs.io/ for more about PIL/Pillow
    pil_image = Image.fromarray(frame)
    # Create a Pillow ImageDraw Draw instance to draw with
    draw = ImageDraw.Draw(pil_image)

    # Loop through each face found in the unknown image
    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
        # See if the face is a match for the known face(s)
        matches = face_recognition.compare_faces(known_face_encodings, face_encoding) #tolerance = 0.6 per default

        name = "Unknown"

        face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
        best_match_index = np.argmin(face_distances)
        if matches[best_match_index]:
            name = known_face_names[best_match_index]
            #print(name)
        else:
            #show the face which we talk about
            draw1 = draw.copy()
            draw1.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))
            cv2.imshow('Face detected',draw1)
            #
            rep = input('Unknown person !. Do you want to save it ? y : yes or n : no')
            while rep not in ['y','n']:
                rep = input('Unknown person !. Do you want to save it ? y : yes or n : no')
            if rep == 'y':
                name = input('So enter his name here : ')
                known_face_names.append(name)
                known_face_encodings.append(face_encoding)
            cv2.destroyWindow('Face detected')

        # Draw a box around the face using the Pillow module
        draw.rectangle(((left, top), (right, bottom)), outline=(0, 0, 255))

        # Draw a label with a name below the face
        text_width, text_height = draw.textsize(name)
        draw.rectangle(((left, bottom - text_height - 10), (right, bottom)), fill=(0, 0, 255), outline=(0, 0, 255))
        draw.text((left + 6, bottom - text_height - 5), name, fill=(255, 255, 255, 255))

    # Remove the drawing library from memory as per the Pillow docs
    del draw

    # Display the resulting image
    pil_image.show()

    # You can also save a copy of the new image to disk if you want by uncommenting this line
    if name != "Unknown":
        img_name = name + '.jpg'
        pil_image.save(img_name)

    #Show final result
    cv2.imshow('image',draw)
    ##Close window
    k = cv2.waitKey(1)
    if k == ord('q'):
        print("Closing the window")
        break

cam.release()

cv2.destroyAllWindows()


def point_in_polygon(lat, lon, polygon):
    """Ray-casting algorithm based on:
    http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html"""
    x = lon
    y = lat

    inside = False
    for i in range(len(polygon) - 1):
        # i vertex
        xi = polygon[i][1]
        yi = polygon[i][0]
        # j vertex
        xj = polygon[i + 1][1]
        yj = polygon[i + 1][0]

        # conditions and ecuation of a line
        intersect = ((yi > y) != (yj > y)) and (
            x < (xj - xi) * (y - yi) / (yj - yi) + xi
        )

        # if intersections are an odd number, then the point is inside the polygon
        if intersect is True:
            inside = not inside

    return inside


import os
from shutil import copyfile
from Utility.Logging_Extension import logger
from Utility.File_Handler.Trajectory_File_Handler import TrajectoryFileHandler
from Utility.OS_Extension import mkdir_safely
from Utility.CloudCompare.CloudCompare import CloudCompare

def copy_ground(gt_general_idp, gt_specific_idp, lazy):

    ground_model_ply_ofp = os.path.join(
        gt_specific_idp, 'Ground.ply'
    )

    if not lazy or not os.path.isfile(ground_model_ply_ofp):
        ground_model_ply_ifp = os.path.join(
            gt_general_idp, 'Ground.ply'
        )
        copyfile(ground_model_ply_ifp, ground_model_ply_ofp)

def copy_vehicle_for_each_time_step(gt_general_idp, gt_specific_dp, lazy):

    vehicle_model_name = os.path.basename(
        os.path.dirname(gt_specific_dp))
    vehicle_model_ply_ifp = os.path.join(
        gt_general_idp, vehicle_model_name, 'CarBody.ply')

    trajectory_ifp = os.path.join(
        gt_specific_dp,
        'animation_transformations.txt')

    camera_object_trajectory = TrajectoryFileHandler.parse_camera_and_object_trajectory_file(
        trajectory_ifp)

    vehicle_model_odp = os.path.join(
        gt_specific_dp,
        'object_ground_truth_in_world_ground_truth_coordinates')
    mkdir_safely(vehicle_model_odp)

    for frame_name in camera_object_trajectory.get_frame_names_sorted():
        logger.vinfo('frame_name', frame_name)
        obj_matrix_world = camera_object_trajectory.get_object_matrix_world(frame_name)
        vehicle_model_ply_ofp = os.path.join(vehicle_model_odp, frame_name + '.ply')

        CloudCompare.apply_transformation(
            vehicle_model_ply_ifp,
            obj_matrix_world,
            vehicle_model_ply_ofp,
            save_point_clouds=False,
            save_meshes=True,
            lazy=True)

def post_process_ground_truth(gt_specific_dp,
                              gt_general_idp):

    logger.info('create_ground_truth: ...')
    logger.vinfo('gt_specific_idp', gt_specific_dp)
    logger.vinfo('gt_general_idp', gt_general_idp)

    copy_ground(
        gt_general_idp,
        gt_specific_dp,
        lazy=True)

    copy_vehicle_for_each_time_step(
        gt_general_idp,
        gt_specific_dp,
        lazy=True)

    logger.info('create_ground_truth: Done')


import pytest
from fastapi.testclient import TestClient
from sqlalchemy.orm import Session

from app.core.config import get_settings

settings = get_settings()

def test_read_data_sources(client: TestClient, db: Session) -> None:
    r = client.get(f"{settings.API_V1_STR}/data_source/")
    assert r.status_code == 200

# [1, 2, 3, 4] are the ID's of the data sources which should be tested in the database.
@pytest.mark.parametrize("data_source_id", [1, 2, 3, 4])
def test_return_200_for_existing_data_source(
    client: TestClient, data_source_id: int, db: Session
) -> None:
    r = client.get(f"{settings.API_V1_STR}/data_source/{data_source_id}")
    assert r.status_code == 200
    response_ = r.json()
    assert response_["id"] == data_source_id


from django.urls import reverse
from .base_home import HomeBaseTest
from apps.client.models import Person, ItemList

class HomeViewDoingTest(HomeBaseTest):
    def test_home_view_doing_returns_correct_amount_DOING_entity(self):
        self.create_and_login()
        person = Person.objects.get(id=self.person.id)

        for status in ['DOING'] * 3:
            person.item_list.add(self.create_card(
                author=self.user, status=status
            ))

        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.get(url)
        context = response.context['item_list'].count()

        person_DOING = person.item_list.filter(status='DOING').count()

        self.assertEqual(context, person_DOING)

    def test_home_view_doing_returns_correct_person(self):
        self.create_and_login()
        person = Person.objects.get(id=self.person.id)

        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.get(url)
        context = response.context['person']

        self.assertIs(person.id, context.id)

    def test_home_view_doing_returns_correct_amount_DOING_entity_logout(self):
        self.user = self.create_user(username='DOING')

        for status in ['DOING'] * 3:
            self.create_card(author=self.user, status=status)

        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.get(url)
        context = response.context['item_list'].count()

        doing = ItemList.objects.filter(
            type='A', status='DOING', root=True
        ).count()

        self.assertEqual(context, doing)

    def test_home_view_doing_invalid_request_error_message(self):
        url = reverse('home:specific_status', kwargs={'status': 'doing'})
        response = self.client.put(url, follow=True)
        content = response.content.decode('utf-8')

        redirect_url = reverse('home:home')
        self.assertIn('Requisição inválida.', content)
        self.assertEqual(redirect_url, response.wsgi_request.path)

    def test_home_view_doing_invalid_status(self):
        url = reverse('home:specific_status', kwargs={'status': 'invalid'})
        response = self.client.put(url, follow=True)
        content = response.content.decode('utf-8')

        redirect_url = reverse('home:home')
        self.assertIn('Status inválido.', content)
        self.assertEqual(redirect_url, response.wsgi_request.path)


# whole registration workflow

import matlab.engine
import numpy as np
import subprocess
import os
import sys
import statistics
from shutil import copyfile
from pathlib import Path

eng = matlab.engine.start_matlab()

source_file = "C:\\Registration\\test_gls_algo\\meshes\\small_meshes_for_test\\larger_rescaling\\bunny_simp.ply"
target_file = "C:\\Registration\\test_gls_algo\\meshes\\small_meshes_for_test\\larger_rescaling\\bunny_simp_rX45_t0-4-3_s0.5.ply"
executable_FGR = "C:\\Registration\\FGR\\FastGlobalRegistration-build\\FastGlobalRegistration\\Release\\FastGlobalRegistration.exe"
transform_prefix = "transform_r45_t0_4_3_s05_K12_lambda"
transform_path = "C:\\Registration\\FGR\\gls_example"
pairs_path = "C:\\Registration\\test_gls_algo\\matching_pairs"
pairs_prefix = "12pairs_lambda"
pairs_suffix = "_file";
target_transformed_path = "C:\\Registration\\FGR\\gls_example\\transformed_target"
ext = ".txt"
mean_and_std_path = "C:\\Registration\\FGR\\gls_example\\mean&std"
executable_cloudCompare = "C:\\Program Files\\CloudCompare\\CloudCompare.exe"
all_means_file = "mean_file.txt";
open(os.path.join(mean_and_std_path, all_means_file), 'w').close()

for i in range(0, 101, 1):
    transform_file = transform_prefix + str(i) + ext;
    pairs_file = pairs_prefix + str(i) + pairs_suffix + ext
    # compute registration
    args = executable_FGR + " " + source_file + " " + target_file + " " + os.path.join(pairs_path, pairs_file) + " " + os.path.join(transform_path, transform_file)
    subprocess.call(args, stdin=None, stdout=None, stderr=None)
    # process registration
    estimated_transform_struct = eng.importdata(os.path.join(transform_path, transform_file),' ', 1)
    estimated_transform = eng.getfield(estimated_transform_struct, 'data')
    output_ply_file = os.path.join(target_transformed_path, transform_prefix + str(i) + ".ply")
    eng.register_pcs(source_file, target_file, estimated_transform, output_ply_file, nargout = 0)
    # compute target registered to source distance
    fgr_c2m_result_file = os.path.join(mean_and_std_path, transform_prefix + str(i) +'_c2m_results.txt')
    open(fgr_c2m_result_file, 'w').close()
    args_c2m = executable_cloudCompare + " -SILENT" + " -o " + output_ply_file + " -o " + source_file + " -NO_TIMESTAMP -C_EXPORT_FMT ASC -c2m_dist"  # compute C2M distance
    subprocess.call(args_c2m, stdin=None, stdout=None, stderr=None)
    # process cloudCompare output
        # get file with c2m distances
    for file in os.listdir(target_transformed_path):
        if "lambda" + str(i) + "_C2M_DIST.asc" in file:
            c2m_file = file

    # get everything in column 4 for c2m
    col_num = 3
    col_data = []
    delimiter = " "
    with open(Path(target_transformed_path) / c2m_file) as f:
        data = f.readlines()
        for line in data:
            col_data.append(line.strip().split(delimiter)[col_num])

    distances_list = list(map(float, col_data))
    signed_mean_c2m_dist = statistics.mean(distances_list)
    unsigned_mean_C2M_dist = statistics.mean(list(map(abs, distances_list)))
    signed_std_c2m = statistics.stdev(distances_list)
    unsigned_std_C2M = statistics.stdev(list(map(abs, distances_list)))
    out_file =open(fgr_c2m_result_file, "a+")
    out_file.write("Mean distance = %5.6f / std deviation = %5.6f\n" % (unsigned_mean_C2M_dist, unsigned_std_C2M))
    out_file.close()
    general_mean_file =open(os.path.join(mean_and_std_path, all_means_file), "a+")
    general_mean_file.write("%5.6f \n" % (unsigned_mean_C2M_dist))
    general_mean_file.close()


from scene import Scene
from textwrap import dedent
from stats_inventory import Person, Inventory
import numpy as np

class Bridge(Scene):

  def enter(self):
    print(dedent("""
        You find yourself on bridge #7 and you are not alone.
        The captain of the ship 'Dicey Roll' is blocking
        your path to the podbay, your only hope of escape.
        Do you 'flee' or 'fight'?
        """))

    choice = input('> ')

    if 'flee' in choice:
      print(dedent("""Looking around the bridge you see four
      doors to the 'port', 'forward', 'starboard' and
      'aft'. As the 'forward' door is block you choose
      another."""))
      choice = input("> ")
      while choice.lower() != "quit":
        choice = choice.lower()
        if "port" in choice or choice == 'p':
          return 'communication'
        elif "starboard" in choice or choice == 's':
          return 'armory'
        elif "aft" in choice or choice == 'a':
          return 'engineroom'
        else:
          print(dedent("""You stand frozen in place trying to
          decide which door to open. You can go 'port',
          'startboard' or 'aft'. This is a ship afterall."""))
          choice = input("> ")
    else:
      print("Get ready to fight!")
      capHealth = 10
      bonusDamage = 0
      choice = input("If you have a weapon now would be good time to 'use' it > ")
      if "use" in choice and ("stick" in choice or "buzz" in choice):
        myRoot = Inventory.item.insertKey("Lincoln Head Penny 1909 VBS")
        foundNode = Inventory.item.searchBST("Buzz Stick", myRoot)
        if foundNode is not None:
          bonusDamage = 3
        else:
          print("You were unable to pull it out in time if you actually have one.")
      print(dedent("""At first you attempt to throw him off-guard with
      vast knowledge discrete mathmatics"""))
      if Person.earthling.euler < 8:
        print(dedent("""(The captain is not amused by anecdotes on
        'Finite State Machines and gets in the first hit."""))
        Person.earthling.health -= np.random.randint(1,3)
      else:
        print(dedent("""Your knowledge of graphs and set theory stuns him, allowing
        you the first strike."""))
      while capHealth > 0:
        damage = np.random.randint(1,5) + bonusDamage + (Person.earthling.strength - 8)
        capHealth -= damage
        if bonusDamage != 0:
          print("You swing at him with your Buzz Stick and hit him hard!\n")
        else:
          print("You swing at him with your fist and make contact.\n")
        if capHealth > 0:
          print("The captain swings at you\n")
          Person.earthling.health -= np.random.randint(1,4)
          if Person.earthling.health <= 0:
            return 'disaster'
    print(dedent("""You have defeated the captain! You find a small manual labeled 'Launch codes for the escape pod Joj. You add this to your inventory. You can go 'port', 'aft', 'starboard' or 'forward' to the podbay."""))
    myRoot = Inventory.item.insertKey("Launch Codes for Joj")
    print("\nCurrent Inventory: ")
    Inventory.item.inOrder(myRoot)
    choice = input("> ")
    while choice.lower() != "quit":
      choice = choice.lower()
      if "port" in choice or choice == 'p':
        return 'communication'
      elif "starboard" in choice or choice == 's':
        return 'armory'
      elif "aft" in choice or choice == 'a':
        return 'engineroom'
      elif "forward" in choice or choice == 'f':
        return 'podbay'
      elif "inventory" in choice or choice == 'i':
        myRoot = Inventory.item.insertKey("Lincoln Head Penny 1909 VBS")
        print("Your inventory:")
        Inventory.item.inOrder(myRoot)

      print(dedent("""\nYou stand frozen in place trying to
      decide which door to open. You can go 'port',
      'startboard' or 'aft'. This is a ship afterall."""))
      choice = input("> ")


from qgis.core import *
from qgis.gui import *
from qgis.PyQt.QtCore import *
from qgis.PyQt.QtGui import *

import os
import math
from osgeo import gdal
import geopandas as gp
import sys
import os

# make tiler
# python3 utils/image-export.py "qgis/full-nz.qgz" 32000000,16000000,8000000
# OR
# make QGISPROJECT=qgis/full-nz.qgz.qgz SCALES=32000000,16000000,8000000 image-exports

project_path = sys.argv[1]
scales = sys.argv[2].split(",")

print((scales))

grid = "data/vector/100k_grid.gpkg"

dir_name = os.path.basename(project_path).split(".")[0]
out_base = os.path.join("cog-outputs", dir_name)
os.makedirs(out_base, exist_ok=True)

# Resolutions and scales set per LINZ map tiles standards:
# https://www.linz.govt.nz/data/linz-data-service/guides-and-documentation/nztm2000-map-tile-service-schema
meter_to_inch = 39.3701
dpi = 90.71428571428571

# Supply path to qgis install location
# Create a reference to the QgsApplication.  Setting the
# second argument to False disables the GUI.
qgs = QgsApplication([], False)
QgsApplication.setPrefixPath("/usr", True)
qgs.initQgis()

project = QgsProject.instance()

project.read(project_path)

layers = QgsProject.instance().mapLayers().values()

# Project Extent
proj_extent = project.mapLayersByName("nz-extent")[0].extent()

# Scales
# scales = [32000000, 16000000, 8000000, 4000000, 2000000, 1000000, 500000, 250000, 100000, 50000]
root_scale = min(scales)
sorted_list = sorted(scales, reverse=False)
list_length = len(sorted_list)
gpGrid = gp.read_file(grid)

for index, gtile in gpGrid.iterrows():

    # Set Paths
    raw_path = os.path.join(out_base, str(index), "raw")
    os.makedirs(raw_path, exist_ok=True)

    # Get bounds for processing
    xmin = gtile.geometry.bounds[0]
    ymin = gtile.geometry.bounds[1]
    xmax = gtile.geometry.bounds[2]
    ymax = gtile.geometry.bounds[3]

    # Setting overview and base file name
    ovr_ext = ".ovr"
    ovr_name = str(root_scale) + ".tif"

    # Loop sorted scales list
    for ovr in sorted_list:
        print(f"Scale: {str(ovr)}")
        if ovr != root_scale:
            ovr_name = ovr_name + ovr_ext

        width = math.ceil(
            abs(
                (((xmin - xmax) * meter_to_inch) / float(ovr))
                * dpi
            )
        )
        height = math.ceil(
            abs(
                (((ymin - ymax) * meter_to_inch) / float(ovr))
                * dpi
            )
        )

        file_name = str(ovr) + "_images.png"
        image_path = os.path.join(out_base, file_name)

        # Start Map Settings
        settings = QgsMapSettings()
        settings.setOutputSize(QSize(width, height))

        settings.setDestinationCrs(QgsCoordinateReferenceSystem.fromEpsgId(2193))

        p = QPainter()
        img = QImage(QSize(width, height), QImage.Format_ARGB32_Premultiplied)
        p.begin(img)
        p.setRenderHint(QPainter.Antialiasing)

        # Set layers to render. Only renders "checked" layers
        layers = list([lyr for lyr in project.layerTreeRoot().checkedLayers()])
        settings.setLayers(layers)

        # Set Extent
        settings.setExtent(QgsRectangle(xmin, ymin, xmax, ymax))

        # setup qgis map renderer
        print("Rendering...")
        render = QgsMapRendererCustomPainterJob(settings, p)
        render.start()
        render.waitForFinished()
        p.end()

        # save the image
        print("Saving Image...")
        img.save(image_path, "png")

        gtif_file_name = str(ovr) + "_gtiff_images.tif"
        gtif_path = os.path.join(raw_path, gtif_file_name)

        print("Running Translate...")
        gdal.Translate(gtif_path, image_path, outputBounds=[xmin, ymax, xmax, ymin], bandList=[1,2,3], outputSRS="EPSG:2193")
        os.remove(image_path)