from typing import Dict, List, Any, Union, Tuple

import requests
from bs4 import BeautifulSoup
import unidecode
import datetime
from dateutil.rrule import rrule, WEEKLY
import logging

BASE_URL_DATA = "https://www.stw.berlin/xhr/speiseplan-und-standortdaten.html"
BASE_URL_MENU = "https://www.stw.berlin/xhr/speiseplan-wochentag.html"

mensa2id = {
    **dict.fromkeys(["hardenberg", "haupt", "hauptmensa", "hardenbergmensa", "321"], "321"),
    **dict.fromkeys(["skyline cafe", "skyline", "cafe skyline" "tel", "657"], "657"),
    **dict.fromkeys(["march", "mar", "marmensa", "marchgebäude", "mar cafe", "march cafeteria", "538"], "538"),
    **dict.fromkeys(["wetterleuchte", "wetterleuchten", "hauptgebaudecafe", "cafe wetterleuchte",
                    "wetterleuchten cafe", "541"], "541"),
    # TODO: add more cafeterias
}

id2mensa = {
    "321": "Hardenbergmensa",
    "657": "Skyline Café",
    "538": "March Cafeteria",
    "541": "Wetterleuchten Café"
}

def get_mensa_id(mensa):
    # get's a raw mensa-name transforms this to lowercase and replaces unicode characters with
    # normal ascii characters (ä -> a) and if that name exist the corresponding id is returned
    return mensa2id.get(unidecode.unidecode(mensa.lower()))

def get_mensa_name(mensa_id):
    # defines the name for mensas
    return id2mensa.get(mensa_id)

class MensaRequest:

    weekday_translation = {
        "Mo.": 0,
        "Di.": 1,
        "Mi.": 2,
        "Do.": 3,
        "Fr.": 4,
        "Sa.": 5,
        "So.": 6
    }

    def __init__(self, mensa, date=None):
        if not isinstance(mensa, str):
            raise ValueError("mensa  must be from type list and only contain strings")
        if date and not (isinstance(date, datetime.datetime)):
            raise ValueError("date must be of type datetime.datetime or None")
        if not date:
            date = datetime.datetime.now()

        self.mensa = mensa
        self.mensa_id = get_mensa_id(mensa)
        self.date = date

        logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
        logging.getLogger("requests").setLevel(logging.DEBUG)
        logging.getLogger("urllib3").setLevel(logging.DEBUG)
        logging.getLogger("chardet.charsetprober").setLevel(logging.DEBUG)

    def _get_page_soup(self, url, date=None):
        # expects a mensa which is contained in the mensa_dict and can handle a date in the format YYYY-MM-DD
        # returns the page content as BeautifulSoup object

        # all the payload for the POST request
        if not self.mensa_id:
            logging.debug("Mensa: " + self.mensa + " not found")
            return None
        data = {"resources_id": self.mensa_id, "date": date}
        headers = {"User-Agent": "Mozilla/5.0"}

        # HTTP request
        page = requests.post(url, data, headers=headers)
        if page.status_code != 200:
            raise ConnectionRefusedError("Couldn't connect to the stw-website ERROR: {}".format(page.status_code))

        # logging.debug(page.content)
        return BeautifulSoup(page.content, "html.parser")

    def get_mensa_menu(self):
        # cf. https://gitlab.tubit.tu-berlin.de/thilo.michael/alex-studiprojekt-ss17/blob/mensa/mensa/mensaCrawler
        # /crawler.py this function requests all dishes available in a specific day for a specific mensa return a
        # list of dictionaries
        # TODO: describe datatype somewhere
        # logging.debug("\nMensa: " + self.mensa + '\n' + "Date: " + str(self.date))
        url = BASE_URL_MENU
        date_for_request = self.date.strftime("%Y-%m-%d")
        page_soup = self._get_page_soup(url, date_for_request)
        if not page_soup:
            return None
        food_offer = unidecode.unidecode(page_soup.find("div", class_="container-fluid splGroupWrapper")
                                         .get_text().strip().lower())
        if food_offer == "kein speisenangebot":
            logging.debug("No food food_offer on: "
                          + self.date.strftime("%d-%m-%Y") + " for Mensa: " + self.mensa_id)
            return self.mensa_id, self.date, None

        # list to be filled in
        food_list = []
        icon_translations = {
            "ampel_gruen_70x65.png": "green",
            "ampel_gelb_70x65.png": "yellow",
            "ampel_rot_70x65.png": "red",
            "1.png": "vegetarian",
            "15.png": "vegan",
            "18.png": "bio",
            "38.png": "marine",
            "43.png": "climate"
        }

        for course in page_soup.findAll("div", class_="container-fluid splGroupWrapper"):
            curr_course = course.find_next("div", class_="col-md-12 splGroup").get_text()
            for dish in course.findAll("div", class_="row splMeal"):
                food_item = _MensaFood()
                # extract course information
                food_item.course = curr_course

                # extract name information
                food_item.name = dish.find_next("span").get_text()

                # extract price information
                # logging.info("Price: " + dish.find_next("div", class_="col-xs-6 col-md-3 text-right")
                # .get_text().strip())
                prices = dish.find_next("div", class_="col-xs-6 col-md-3 text-right").get_text().strip()
                if prices != "":
                    prices = list(map(float, dish.find_next("div", class_="col-xs-6 col-md-3 text-right").get_text()
                                      .split()[1].replace(',', '.').split('/')))
                    if len(prices) == 3:
                        food_item.price_student = prices[0]
                        food_item.price_employee = prices[1]
                        food_item.price_extern = prices[2]
                    else:
                        food_item.price_student = food_item.price_employee = food_item.price_extern = prices[0]

                # extract tag information
                # HINT: this has to be a String because there are tags like "21a"
                food_item.tags = dish.find_next("div", class_="kennz ptr toolt").contents[0] \
                    .strip("\n\r ()").split(", ")

                # extract information based on icons
                for icon in dish.find_next("div", class_="col-xs-12 col-md-3").findAll("img"):
                    icon_src = icon.get("src").split('/')[-1:][0]
                    if "ampel" in icon_src:
                        food_item.traffic_light = icon_translations[icon_src]
                    else:
                        setattr(food_item, icon_translations[icon_src], True)
                food_list.append(food_item.get_mensa_food_dict())

        return self.mensa_id, self.date, food_list

    def get_mensa_data(self) -> (str, dict):
        # {
        # "name": ..,
        # "address": ..,
        # "website": ..,
        # "email": ..,
        # "phone": ..,
        # "opening_hours": ..,
        # "opening_hours_additional": ..,
        # "transfer": ..,
        # }
        url = BASE_URL_DATA
        page_soup = self._get_page_soup(url)
        if not page_soup:
            return None
        # dict to be filled in
        mensa_data: Dict[str, Union[Union[None, str, List[Tuple[List[Any], List[Any]]], List[str]], Any]] = {
            "name": None,
            "address": None,
            "website": None,
            "email": None,
            "phone": None,
            "opening_hours": None,
            "opening_hours_additional": None,
            "transfer": None
        }
        # extracting information
        # HINT: this uses an icon as orientation, which isn't that nice
        # extract name information
        name_information = page_soup.find(selected="selected").get_text()
        mensa_data["name"] = name_information
        # extract address information
        address_elements = page_soup.find(class_="glyphicon glyphicon-map-marker").parent.find_next("div")
        street = address_elements.contents[0].strip()
        postcode = address_elements.contents[4].strip()
        district = address_elements.find_all_next("small")[1].contents[0].strip("()")
        mensa_data["address"] = '\n'.join([street, postcode, district])

        # extract website information
        mensa_data["website"] = page_soup.find(id="directlink").get_text()
        # extract email information
        mensa_data["email"] = page_soup.find(class_="glyphicon glyphicon-envelope").parent.find_next("a").contents[0]

        # extract phone information
        mensa_data["phone"] = page_soup.find(class_="glyphicon glyphicon-earphone") \
            .parent.find_next("div").contents[0].strip()

        # extract opening hours
        def _create_opening_hours_list(hours):
            # function to create a data format, which makes it possible to check
            # if a mensa is open on a specific day/time
            # data format: opening_hours_list = [([opening-datetime-of-weekday-for-next-four-weeks],
            #                                           [closing-datetime-of-weekday-for-next-four-weeks]), ...]
            # TODO: explain/code check_if_open(when<datetime>)
            opening_hours_list = []
            if unidecode.unidecode(hours[1]) == '-':  # handling day interval
                for day in range(self.weekday_translation[hours[0]], self.weekday_translation[hours[2]] + 1):
                    opening_unformatted = hours[3].split(':')
                    opening = list(rrule(dtstart=datetime.datetime.now()
                                         .replace(hour=int(opening_unformatted[0]), minute=int(opening_unformatted[1]),
                                                  second=0), freq=WEEKLY, count=4, byweekday=day))
                    closing_unformatted = hours[5].split(':')
                    closing = list(rrule(dtstart=datetime.datetime.now().
                                         replace(hour=int(closing_unformatted[0]), minute=int(closing_unformatted[1]),
                                                 second=0), freq=WEEKLY, count=4, byweekday=day))
                    opening_hours_list.append((opening, closing))
            else:  # handling a single day
                day = self.weekday_translation[hours[0]]
                opening_unformatted = hours[1].split(':')
                opening = list(rrule(dtstart=datetime.datetime.now()
                                     .replace(hour=int(opening_unformatted[0]), minute=int(opening_unformatted[1]),
                                              second=0), freq=WEEKLY, count=4, byweekday=day))
                closing_unformatted = hours[3].split(':')
                closing = list(rrule(dtstart=datetime.datetime.now().
                                     replace(hour=int(closing_unformatted[0]), minute=int(closing_unformatted[1]),
                                             second=0), freq=WEEKLY, count=4, byweekday=day))
                opening_hours_list.append((opening, closing))
            return opening_hours_list

        opening_hours_information_list = []
        opening_hours_additional_information = []
        curr_div = page_soup.find(class_="glyphicon glyphicon-time").parent.find_next("div")
        while len(curr_div.contents) < 2 or "transfer" not in str(curr_div.contents[1]):
            if len(curr_div.contents) > 4:
                opening_hours_information = curr_div.contents[3]
                if opening_hours_information and not isinstance(opening_hours_information, str):
                    opening_hours_information_formatted = opening_hours_information.get_text().split()
                    if opening_hours_information_formatted[0] in self.weekday_translation.keys():
                        opening_hours_information_list \
                            .extend(_create_opening_hours_list(opening_hours_information_formatted))
                    else:
                        opening_hours_additional_information.append(' '.join(opening_hours_information_formatted))

            curr_div = curr_div.find_next("div")
        mensa_data["opening_hours"] = opening_hours_information_list
        mensa_data["opening_hours_additional"] = opening_hours_additional_information
        # extract transfer information
        transfer_information_list = []
        transfer_elements = page_soup.find(class_="glyphicon glyphicon-transfer").parent.find_next("div").contents
        for element in transfer_elements:
            if isinstance(element, str):
                if element.strip():
                    transfer_information_list.append(element.replace('\xa0', ' '))
            else:
                transfer_information_list.append(element.get_text().strip())
        mensa_data["transfer"] = ''.join(transfer_information_list)
        return self.mensa_id, mensa_data

class _MensaFood:
    name = None
    course = None
    price_student = None
    price_employee = None
    price_extern = None
    tags = None
    traffic_light = None
    vegetarian = None
    vegan = None
    climate = None
    bio = None
    marine = None

    def __init__(self):
        self.vegetarian = False
        self.vegan = False
        self.climate = False
        self.bio = False
        self.marine = False
        return

    def get_mensa_food_dict(self):
        mensa_food_dict = {
            "name": self.name,
            "course": self.course,
            "price_student": self.price_student,
            "price_employee": self.price_employee,
            "price_extern": self.price_extern,
            "tags": self.tags,
            "traffic_light": self.traffic_light,
            "vegetarian": self.vegetarian,
            "vegan": self.vegan,
            "climate": self.climate,
            "bio": self.bio,
            "marine": self.marine
        }
        return mensa_food_dict


import tvdb_api

from webcine.models import Series, Season

def update_tvdb_data():
    tvdb = tvdb_api.Tvdb()

    for series in Series.select():
        tvdb_series = tvdb[series.name]
        for season in tvdb_series:
            if season > 0:
                try:
                    Season.get(Season.series == series, Season.number == season)
                except:
                    print("Creating season info for {} season {}".format(series.name, season))
                    episodes = len(tvdb_series[season].keys())
                    Season.create(series=series, number=season, episodes=episodes)


"""
Testowanie czujnika hall'a w celu zastosowania go do odczytywania ilości obrótów w silnikach DC.

Obserwacja: czujnik w zależności od położenia/ sposobu przesunięcia magnesu może zmienić permamentnie
z 0 na 1 lub z 1 na 0. Możliwe że magnes kórego używam wytwarza podówje pole które generuje 2 impulsy,
ale czasami wygeneruje tylko 1 podczas przesunięcia i obserwowany jest taki efekt. Do sprawdzenia z
innymi magnesami.

Rozpiska wyprowadzeń RPI3
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 | ALT0 | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 | ALT0 | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 0 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 0 | 11 || 12 | 0 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 0 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 0 | 15 || 16 | 0 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 0 | IN   | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI | ALT0 | 0 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO | ALT0 | 0 | 21 || 22 | 0 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK | ALT0 | 0 | 23 || 24 | 1 | OUT  | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | OUT  | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 0 | IN   | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 0 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 0 | 35 || 36 | 0 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 0 | 37 || 38 | 0 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 0 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+
https://www.dummies.com/article/technology/computers/hardware/raspberry-pi/raspberry-pi-gpio-pin-alternate-functions-143761/
"""
import time

import RPi.GPIO as GPIO

HALL_BCM = 21
# BCM - opisy pinów zgodnie z płytką
# BOARD - opisy pinów zgodnie z wyprowadzeniami procesora
GPIO.setmode(GPIO.BCM)
GPIO.setup(HALL_BCM, GPIO.IN)   #, pull_up_down=GPIO.PUD_DOWN)

def test_hall_hl401():
    """
    Idea polega na zliczaniu zboczy opadających 1 -> 0.
    Czujnik Hall'a podłączony jest do portu GPIO ustawionego jako wejście.
    Pomocnicza zmienna hall_status_aktualny trzyma informację o aktualnym
    stanie wejścia. Jeśli nastąpi zmiana z 1 -> 0 wówczas zaliczany jest
    impuls. W przypadku braku zmiany 0 -> 0, lub 1 -> 1 sprawdzanie stanu
    GPIO jest kontunuowane.
    """
    hall_status_aktualny = 0
    licznik = 0
    while True:
        hall_status = GPIO.input(HALL_BCM)
        if hall_status == 0 and hall_status_aktualny == 1:
            hall_status_aktualny = hall_status
            licznik += 1
            print(f"puls {licznik}")
        elif hall_status == 1 and hall_status_aktualny == 0:
            hall_status_aktualny = hall_status

def test_generator():
    """
    Test z generatorem sygnału.
    Zlicznie impulsów generatora przez zadany okres czasu.
    Ustawienie generatora z OWON 200Hz, Aplituda 3vpp, Offset 0.
    Dla 1s przy czestotliwości generatora 1kH powinno wyjść 1000 impulsów.
    Najpierw uruchamiany jest generator pootem program.
    Wyniki pomiarow dla prostokątnego sygnału dla 10 prób:
    --------+--------
    f       |  Błędy
    --------+--------
    2kHz    |   0
    3kHz    |   1
    10kHz   |   7
    --------+--------
    """
    hall_status_aktualny = 0
    licznik = 0
    timer_start_ns = time.time_ns()
    while time.time_ns() - timer_start_ns < 1e9:    # przez zadany okres np 1s zliczaj impulsy
        hall_status = GPIO.input(HALL_BCM)
        if hall_status == 0 and hall_status_aktualny == 1:
            hall_status_aktualny = hall_status
            licznik += 1
        elif hall_status == 1 and hall_status_aktualny == 0:
            hall_status_aktualny = hall_status
    print(f"zliczone impulsy:{licznik} czas: {time.time_ns() - timer_start_ns} [ns]")

if __name__=='__main__':
    try:
        #test_hall_hl401()
        test_generator()
    except KeyboardInterrupt:
        print("Zakonczenie poprzez ctrl+c")
    except Exception as unknown_exception:
        print(f"To nie powinno sie wydarzyc! {unknown_exception:}")
    finally:
        print("Czyszczenie GPIO")
        GPIO.cleanup()


# Сериализация класса
#
# Ваша задача научить классы конвертиться к json-строке
# при помощи миксина под названием JsonSerializableMixin,
# который добавляет метод to_json() в любой класс,
# использующий этот миксин. Метод to_json() конвертирует
# словарь атрибутов экземпляра в строку JSON, используя
# стандартную библиотеку json в Python.

import json

class JsonSerializableMixin:

    def to_json(self):

        return json.dumps(self.__dict__)

# Ниже код для проверки миксина JsonSerializableMixin
class Car(JsonSerializableMixin):
    def __init__(self, make: str, color: str):
        self.make = make
        self.color = color

class Book(JsonSerializableMixin):
    def __init__(self, title: str, author: str):
        self.title = title
        self.author = author

class Person(JsonSerializableMixin):
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

car = Car("Toyota", "red")
assert car.to_json() == '{"make": "Toyota", "color": "red"}'

book = Book("The Catcher in the Rye", "J.D. Salinger")
assert book.to_json() == '{"title": "The Catcher in the Rye", "author": "J.D. Salinger"}'
book.ratings = [5, 4, 5, 4, 5]
book.is_bestseller = True
book.to_json() == '{"title": "The Catcher in the Rye", "author": "J.D. Salinger", "ratings": [5, 4, 5, 4, 5], "is_bestseller": true}'

person = Person("John", 30)
assert person.to_json() == '{"name": "John", "age": 30}'
print('Good')


from tkinter import *
import math

class threeSplitTree(object):
    def __init__(self,level):
        self.level = level

    def drawBranch(self,canvas,xtop,ytop,xbottom,ybottom,height,width=10,color="#947A6F"):
        canvas.create_line(xtop,ytop,xbottom,ybottom,fill=color,width=width)

    def drawTree(self,canvas,height,level,xtop,ytop,xbottom,ybottom,width=10,color="#947A6F"):
        if (level<=0):
            return
        else:
            self.drawBranch(canvas,xtop,ytop,xbottom,ybottom,height,width,color)
            height = height/2
            branch1dx = height / 2
            branch1dy = height / (2 * 3**0.5)
            self.drawTree(canvas,height,level-1,xtop-branch1dx,ytop-branch1dy,xtop,ytop,width/2,color)
            branch2dy = height * math.cos(10)
            branch2dx = (height**2 - branch2dy**2)**0.5
            self.drawTree(canvas,height,level-1,xtop-branch2dx,ytop+branch2dy,xtop,ytop,width/2,color)
            branch3dx = (height**2)/2
            branch3dy = height * math.sin(10)
            self.drawTree(canvas,height,level-1,xtop+branch1dx,ytop-branch1dy,xtop,ytop,width/2,color)
            self.drawTree(canvas,height,level-1,xtop+branch2dx,ytop+branch3dy,xtop,ytop,width/2,color)


"""This module supports loading JSON documents when memory is tight.

Attributes:
  load_data (function): Loads JSON data from a file.
"""

import json
from typing import Any, Dict, List, Union

JsonType = Union[
    Dict[str, Any],
    List[Any],
]

def load_data() -> JsonType:
    """Loads JSON data from a file.

    Data is taken from small.json.

    Returns:
      The deserialized data.
    """

    try:
        with open("small.json", encoding="utf8") as json_file:
            return json.load(json_file)
    except MemoryError:
        return []


# type: noqa
from copy import copy
from dataclasses import asdict
from datetime import datetime
import functools
import logging
import time
from typing import (
    Any, Callable, Dict, List, Mapping, NamedTuple, Optional, Tuple,
    Type, TypeVar, Union, cast, overload
)

F = TypeVar("F", bound=Callable[..., Any])

class DictConversionError(Exception):
    pass

LOGGER = logging.getLogger()
LOGGER.setLevel(logging.INFO)

def generate_timestamp() -> str:
    return datetime.utcnow().isoformat(timespec='microseconds') + 'Z'

def pluck(obj, *args) -> Tuple[Optional[Any], ...]:
    return tuple([obj[key] if key in obj else None for key in args])

def filter_empty_properties(mapping: Mapping[Any, Any]) -> Dict[Any, Any]:
    return {k: v for k, v in mapping.items() if v}

def response_asdict(fn=None):
    @functools.wraps(fn)
    def _wrapper(*args, **kwargs):
        result = fn(*args, **kwargs)
        result = convert_to_dict(result)
        return result
    return _wrapper

def isnamedtupleinstance(x) -> bool:
    t = type(x)
    b = t.__bases__
    if (len(b) != 1
       or b[0] != tuple):
        return False
    f = getattr(t, '_fields', None)
    if not isinstance(f, tuple):
        return False
    return all(type(n) == str for n in f)

def is_dataclass_instance(obj):
    return hasattr(type(obj), '__dataclass_fields__')

def convert_to_dict(data) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
    if data is None:
        return data
    if isinstance(data, dict):
        return cast(Dict[str, Any], dict(data))
    if is_dataclass_instance(data):
        return asdict(data)
    if isnamedtupleinstance(data):
        return cast(NamedTuple, data)._asdict()
    if isinstance(data, list) or isinstance(data, tuple):
        return cast(List[Dict[str, Any]], [convert_to_dict(item) for item in data])
    raise DictConversionError(f'Failed to convert to dictionary: {data}')

@overload
def retry(_func: F) -> F:
    ...

@overload
def retry(*, max_retries: int = 3, delay_seconds: int = 5,
          allowable_exceptions: List[Type[Exception]] = []) -> Callable[[F], F]:
    ...

def retry(fn=None, *, max_retries=3, delay_seconds=5, allowable_exceptions: List[Type[Exception]] = []):

    @functools.wraps(fn)
    def retry_decorator(_fn):

        @functools.wraps(_fn)
        def _wrapper(*args, **kwargs):
            num_tries = 1
            while True:
                try:
                    return _fn(*args, **kwargs)
                except Exception as ex:
                    if num_tries >= max_retries:
                        raise ex
                    if not allowable_exceptions or any([exc == type(ex) for exc in allowable_exceptions]):
                        time.sleep(delay_seconds)
                        LOGGER.warning(f'Calling {_fn.__name__}, Number of tries: {num_tries}')
                        LOGGER.warning(f'{ex}')
                        num_tries += 1
                        continue
                    raise ex

        return _wrapper

    if fn:
        return retry_decorator(fn)
    else:
        return retry_decorator

def walk_keys(mappings: Union[Mapping[str, Any], List[Mapping[str, Any]]],
              apply_fn: Callable[[str, Any], Optional[Tuple[Optional[str], Any]]]
              ) -> Union[Dict[str, Any], List[Dict[str, Any]]]:
    if isinstance(mappings, Mapping):
        new_mappings = {}
        for key, value in mappings.items():
            new_value = copy(value)
            item = apply_fn(key, new_value)
            if not item:
                continue

            next_key = item[0] if item[0] else key
            next_value = item[1] if item[1] else value
            if isinstance(next_value, Mapping) or isinstance(next_value, List):
                new_mappings[next_key] = walk_keys(next_value, apply_fn)
            else:
                new_mappings[next_key] = next_value

        return new_mappings

    elif isinstance(mappings, List):
        new_mappings = []
        for value in mappings:
            new_mappings.append(walk_keys(value, apply_fn))

        return new_mappings

    return mappings


from functools import reduce

def num(lista):
    resultado = list(filter((lambda x: x % 2), lista))
    print("Lista de numeros: \n",resultado)

lista = list(range(50))
num(lista)

suma = reduce( (lambda x, y: x + y), lista)
print("Sumatoria de los elementos: ",suma)


import re
from advent import Solver

# https://adventofcode.com/2022/day/5
# This was a fun one - I accumulated stacks and instructions and then built the stacks from the input after parsing
# entire file. I could not figure a way to build stacks while reading the file. Glad I didn't, as second part had to
# start from the initial status again. I know parsing isn't the most elegant.
# But we had regexp for the instructions!

RE_INSTRUCTION = re.compile(r"move (\d+) from (\d+) to (\d+)")

class Solution(Solver):
    def __init__(self):
        self.stack_defs = []
        self.stacks = []
        self.instructions = []
        self.parse_instructions = False

    def parse(self, line: str):
        if not line:
            self.parse_instructions = True
            return
        if self.parse_instructions:
            self.add_instructions(line)
        else:
            self.stack_defs.append(line)

    def solve(self):
        self.stack_defs.reverse()
        self.build_stacks()
        self.move_singles()
        result = "".join([st.pop() for st in self.stacks])
        print(f"[1] Top stacks values: {result}")
        self.build_stacks()
        self.move_multiples()
        result = "".join([st.pop() for st in self.stacks])
        print(f"[2] Top stacks values: {result}")

    def add_instructions(self, line):
        mo = RE_INSTRUCTION.match(line)
        assert mo is not None
        self.instructions.append({"num": int(mo.group(1)), "from": int(mo.group(2)), "to": int(mo.group(3))})

    def build_stacks(self):
        num_stacks = None
        for level in self.stack_defs:
            if not num_stacks:
                num_stacks = int(level.rsplit(" ", maxsplit=1)[-1].strip())
                print(f"Found {num_stacks} stacks")
                self.stacks = [[] for _ in range(num_stacks)]
                continue

            i = 0
            while i < num_stacks:
                start = i*4
                end = i*4+3
                if end > len(level):
                    break
                if level[start:end] != "   ":
                    self.stacks[i].append(level[start+1])
                i += 1

    def move_singles(self):
        for i in self.instructions:
            moves = i["num"]
            while moves > 0:
                self.stacks[i["to"] - 1].append(self.stacks[i["from"] - 1].pop())
                moves -= 1

    def move_multiples(self):
        for i in self.instructions:
            for k in range(i["num"]):
                self.stacks[i["to"] - 1].append(self.stacks[i["from"] - 1][-i["num"] + k])
            del self.stacks[i["from"] - 1][-i["num"]:]


# -*- coding: utf-8 -*-
"""
Created on Mon Nov 23 00:46:52 2020

@author: bbari
"""
import pandas as pd
import wikipedia
import io, sys, os, hashlib
from selenium import webdriver
from image_scrapper import search_and_download
import wikipedia
column_names = ["personName", "birthDate", "imageUrl", "info"]

df = pd.DataFrame(columns = column_names)

dataset = pd.read_csv('moovies.csv' )

dataset = dataset.iloc[:, -3:-1].values

pure_names = []

## awwww shit what the heckkkk!!! written when high otherwise, wouldn't bother to mess this shit
for item in dataset:
    for name in item:
        if("," in name):
            names = name.split(",")
            for string in names :
                if("(" in string):
                    if("|" in string.split("(")[0]):
                        pure_names.append( string.split("(")[0].split("|")[0])
                    else:
                        pure_names.append( string.split("(")[0])
                else:
                    if("|" in string):
                        pure_names.append( string.split("|")[0])
                    else:
                        pure_names.append( string)
        else:
            if("(" in name):
                pure_names.append(name.split("(")[0])
            else:
                if("|" in name):
                    pure_names.append(name.split("|")[0])
                else:
                    pure_names.append(name)

pure_names.remove("actors") ##// some fucked headers
pure_names.remove("writers") ##// dont mind these lines

chrome_options = webdriver.chrome.options.Options()
chrome_options.add_argument("--disable-extensions")
chrome_options.add_argument("--disable-gpu")
chrome_options.add_argument("--headless")

i = 0
from webdriver_manager.chrome import ChromeDriverManager
wd = webdriver.Chrome(ChromeDriverManager().install(), chrome_options=chrome_options)
for name in pure_names:
    try:
        information = wikipedia.summary(name, auto_suggest= False)
    except:
        try:
            information = wikipedia.summary(name+ " (actor)", auto_suggest= True)
        except:
            continue
    try:
        birthDate = information.split("born")[1].split(")")[0]
    except:
        birthDate = "NaN"
    df2 = pd.DataFrame([[name, birthDate,  search_and_download(wd, name, 'chromedriver.exe', number_images=1), information]], columns = column_names)
    df = pd.concat([df2, df])

    i = i+1
    print("Progress: %" + "{:06.2f}".format((i/len(pure_names)*100)))

df.to_csv('person_row.csv', mode='a', header=False, index=False)


import flwr as fl
import utils
import tensorflow as tf

def fit_round(rnd):
  """Send round number to client."""
  return {"rnd": rnd}

def get_eval_fn(model):
  """Return an evaluation function for server-side evaluation."""

  # Load test data here to avoid the overhead of doing it in `evaluate` itself
  x_test, y_test = utils.load_data('test.csv', 15)

  # The `evaluate` function will be called after every round
  def evaluate(parameters):
    # Update model with the latest parameters
    model.set_weights(parameters)
    loss, accuracy = model.evaluate(x_test, y_test)
    return loss, {"accuracy": accuracy}

  return evaluate

# Start Flower server for three rounds of federated learning
if __name__ == "__main__":

    #set random seed, so all radom numbers genation process can be reproceduced between executions
    tf.random.set_seed(42)

    #create the model
    model=tf.keras.Sequential([
      tf.keras.Input(shape=(24,)),
      tf.keras.layers.Dense(48,activation="relu"),
      tf.keras.layers.Dense(4,activation="softmax")
    ])

    #compile the model
    model.compile(
      loss=tf.keras.losses.SparseCategoricalCrossentropy(),
      optimizer=tf.keras.optimizers.Adam(),
      metrics="accuracy"
    )

    strategy = fl.server.strategy.FedAvg(
        min_available_clients=2,
        eval_fn=get_eval_fn(model),
        on_fit_config_fn=fit_round,
    )

    fl.server.start_server("0.0.0.0:8080", strategy=strategy, config={"num_rounds": 2})


#
# @lc app=leetcode id=508 lang=python3
#
# [508] Most Frequent Subtree Sum
#
# https://leetcode.com/problems/most-frequent-subtree-sum/description/
#
# algorithms
# Medium (59.65%)
# Total Accepted:    86.2K
# Total Submissions: 144.5K
# Testcase Example:  '[5,2,-3]'
#
# Given the root of a binary tree, return the most frequent subtree sum. If
# there is a tie, return all the values with the highest frequency in any
# order.
#
# The subtree sum of a node is defined as the sum of all the node values formed
# by the subtree rooted at that node (including the node itself).
#
#
# Example 1:
#
#
# Input: root = [5,2,-3]
# Output: [2,-3,4]
#
#
# Example 2:
#
#
# Input: root = [5,2,-5]
# Output: [2]
#
#
#
# Constraints:
#
#
# The number of nodes in the tree is in the range [1, 10^4].
# -10^5 <= Node.val <= 10^5
#
#
#
# Definition for a binary tree node.

# find compute the subtree sum. Then compute the mode using 501.

from typing import Dict, List, no_type_check

class TreeNode:
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class Solution:
    def findFrequentTreeSum(self, root: TreeNode) -> List[int]:
        freq = {}
        self.findFrequentTreeSumHelper(root, freq)
        modes = []
        max_freq = -1
        for val, curr_freq in freq.items():
            if curr_freq > max_freq:
                modes = [val]
                max_freq = curr_freq
            elif curr_freq == max_freq:
                modes.append(val)

        return modes

    def findFrequentTreeSumHelper(self, root: TreeNode, freq: Dict[int, int]) -> int:
        if root is None:
            return 0

        # compute sum recursively
        left_sum = self.findFrequentTreeSumHelper(root.left, freq)
        right_sum = self.findFrequentTreeSumHelper(root.right, freq)

        node_sum = left_sum + right_sum + root.val

        if node_sum not in freq:
            freq[node_sum] = 0

        freq[node_sum] += 1

        return node_sum


import torch
import torch.nn as nn
import torch.nn.functional as F
from network.classification import Classification, Classification2
import torchvision.models as models

class ToySynNet_Pretrained_ResNet(nn.Module):
    def __init__(self, clip_length):
        super().__init__()
        self.clip_length = clip_length

        self.conv1 = nn.Conv2d(3, 6, 3, 1)
        self.conv2 = nn.Conv2d(6, 16, 3, 1)
        # self.fc1 = nn.Linear(54*54*16, 120)
        self.fc1 = nn.Linear(198 * 198 * 16, 120)
        self.fc2 = nn.Linear(120, 84)

        # self.classification1 = Classification(self.clip_length)
        self.classification2 = Classification2(self.clip_length)
        # self.conv_encoder = ConvEncoder()

    def forward(self, clip1, clip2):
        # clip1 = self.conv_encoder(clip1)
        # clip2 = self.conv_encoder(clip2)
        clip1 = F.relu(self.conv1(clip1)) # [10, 3, 800, 800]
        clip2 = F.relu(self.conv1(clip2))

        clip1 = F.max_pool2d(clip1, 2, 2)
        clip2 = F.max_pool2d(clip2, 2, 2)

        clip1 = F.relu(self.conv2(clip1))
        clip2 = F.relu(self.conv2(clip2))

        clip1 = F.max_pool2d(clip1, 2, 2)
        clip2 = F.max_pool2d(clip2, 2, 2)

        # clip1 = clip1.view(-1, 54*54*16)
        # clip2 = clip2.view(-1, 54*54*16)
        clip1 = clip1.view(-1, 198 * 198 * 16)
        clip2 = clip2.view(-1, 198 * 198 * 16)

        clip1 = F.relu(self.fc1(clip1))
        clip2 = F.relu(self.fc1(clip2))

        clip1 = F.relu(self.fc2(clip1))
        clip2 = F.relu(self.fc2(clip2))  # torch.Size([10, 84])

        # print('classification result: ', self.classification(clip1, clip2))
        # start_time1 = time.time()
        # classification1 = self.classification1(clip1, clip2)
        # end_time1 = time.time()
        # print('1111111 spent time: ', end_time1 - start_time1)
        # print('classification1111: ', classification1)

        # start_time2 = time.time()
        classification2 = self.classification2(clip1, clip2)
        # end_time2 = time.time()
        # print('2222222 spent time: ', end_time2 - start_time2)
        # print('classification2222: ', classification2)

        return classification2

class ToySynNet(nn.Module):
    def __init__(self, clip_length):
        super().__init__()
        self.clip_length = clip_length

        self.conv1 = nn.Conv2d(3, 6, 3, 1)
        self.conv2 = nn.Conv2d(6, 16, 3, 1)
        # self.fc1 = nn.Linear(54*54*16, 120)
        self.fc1 = nn.Linear(198 * 198 * 16, 120)
        self.fc2 = nn.Linear(120, 84)

        # self.classification1 = Classification(self.clip_length)
        self.classification2 = Classification2(self.clip_length)
        # self.conv_encoder = ConvEncoder()

    def encoder(self, frame):
        frame = F.relu(self.conv1(frame))
        frame = F.max_pool2d(frame, 2, 2)
        frame = F.relu(self.conv2(frame))
        frame = F.max_pool2d(frame, 2, 2)
        frame = frame.view(-1, 198 * 198 * 16)
        frame = F.relu(self.fc1(frame))
        frame = F.relu(self.fc2(frame))
        return frame

    def forward(self, clip1, clip2):
        clip1 = torch.stack([self.encoder(torch.unsqueeze(frame, 0)) for frame in clip1], dim=0)
        clip2 = torch.stack([self.encoder(torch.unsqueeze(frame, 0)) for frame in clip2], dim=0)
        clip1 = torch.squeeze(clip1)
        clip2 = torch.squeeze(clip2)

        classification2 = self.classification2(clip1, clip2)

        return classification2

class ToySynNetOnlyClassification(nn.Module):
    def __init__(self, clip_length):
        super().__init__()
        self.clip_length = clip_length
        self.classification = Classification2(clip_length)

    def forward(self, clip1, clip2):
        classification = self.classification(clip1, clip2)
        return classification


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 11/13/18 21:11
# @Author  : Kaiwen Xue
# @File    : US29.py
# @Software: PyCharm
# US29 List deceased

def list_deceased(indi_list):
    dead_list=[]

    for people in indi_list:

        if people['DEAT'] != 'NA':
            dead_list.append(people['INDI'])

    print('INFO: US29: All deceased people:', dead_list)


import collections

# Complete the sherlockAndAnagrams function below.
def sherlockAndAnagrams(s):
    counter = collections.Counter()
    for size in range(1, len(s)):
        for i in range(len(s) - size + 1):
            key = ''.join(sorted(s[i:i+size]))
            counter[key] += 1
    return sum((s * (s - 1) // 2) for s in counter.values())

def main():
    cases = [
        'abba',
        'ifailuhkqq',
        'kkkk',
        'cdcd',
    ]
    for case in cases:
        print(sherlockAndAnagrams(case))

if __name__ == '__main__':
    main()


#$env:FLASK_APP = "server2.py"
#flask run
from flask import Flask, request,render_template
import sqlite3

app = Flask(__name__)

#lägger till i min databas
@app.route('/postjson', methods=['POST'])
def add_weather():
    conn = sqlite3.connect('databas.db')
    c = conn.cursor()
    p = (request.json['sensor'], request.json['temperature'], request.json['humidity'], request.json['pressure'], request.json['wind'])
    c.execute('INSERT INTO SensorData (sensor, temperature, humidity, pressure, wind) VALUES(?,?,?,?,?)',p)
    conn.commit()
    return f"Successful"

#läser in ifrån databas till html tablen
@app.route('/')
def w_data():
    conn = sqlite3.connect('databas.db')
    c = conn.cursor()
    c.execute('''SELECT id, date, sensor, temperature, humidity, pressure, wind FROM SensorData''')
    w_data = c.fetchall()
    return render_template ('weather.html', w_data=w_data)
#tar bort min info

@app.route('/delete')
def delete():
    conn = sqlite3.connect('databas.db')
    c = conn.cursor()
    c.execute('''DELETE FROM SensorData''')
    conn.commit()
    return render_template('deleted.html')

app.run(debug=True)


#AkeyOverse.py
from xo import *
import shortuuid
akeyo = xo.akeyo

class Entity(dict):
	empty = None
	def save(self, *args, **kwargs):
		# return self.saveAsyn(None)
		t1 = Thread(target = self.saveAsyn, kwargs= kwargs)
		t1.start()

	def saveAsyn(self, **kwargs):
		if "delay" in kwargs:
			time.sleep(kwargs["delay"])
		# print("TYPE ::: ",type(self))
		recent = self._recentSave
		self._recentSave += 1
		recent += 1

		# etype = str(type(self))
		if self["id"][0] not in akeyo.index.children():
			akeyo.index[self["id"][0]] = []
		akeyo.index[self["id"][0]] += self["id"]
		akeyo.index[self["id"]] = self
		print(f"SAVED {self['id']}")

		if False:
			# print()
			# print("self.__dir__()")
			# for key in self.__dir__():
			# 	print(key)
			# print()
			# print("type(self).__dir__()")
			# for key in type(self).__dir__(""):
			# 	print(key)
			# print()
			# print("type(self).__dir__(Entity)")
			# for key in type(self).__dir__(Entity):
			# 	print(key)
			try:
			# if True:
				for key in self.__dir__():
					# if True:
					if recent == self._recentSave:
						if key not in Entity.empty.__dir__() and "_" not in key:
							atr = self.__getattribute__(key)
							if "method" not in str(type(atr)):
								print(f"SAVING {self._recentSave} {str(type(atr))}::: akeyo.index[{self['id']}][{key}]")
								akeyo.index[self["id"]][key].set(self.__getattribute__(key))

			except:
				pass
			# 	print(f"stopping save {recent}")
			try:
			# if True:
				for key in self:
					# if True:
					if recent == self._recentSave:
						atr = self[key]
						if "method" not in str(type(atr)):
							print(f"SAVING  {self._recentSave} {str(type(atr))}::: akeyo.index[{self['id']}][{key}]")
							akeyo.index[self["id"]][key].set(self[key])
			except:
				pass
			# 	print(f"stopping save {recent}")

	def math(*args, **kwargs):
		print("got argumets:")
		for arg in args:
			print(":::",arg,":::",type(arg))
		for arg in kwargs:
			print(":::",arg,":::",kwargs[arg],":::",type(kwargs[arg]))
		print(args)

	math(1,3,"adgo", do = "multiply")

	def __init__(self,*args,**kwargs):
		self._recentSave = 0
		if Entity.empty is None:
			Entity.empty = "xxxxxxx"
			Entity.empty = Entity(__empty__ = True)
		if "__empty__" not in kwargs:
			if "_known_" in kwargs:
				known = kwargs.pop("_known_")
				firstArgs, lastArgs = args[:len(known)],args[len(known):]
				c = 0
				for a in known:
					kwargs[a] = firstArgs[c]
					c+=1
				args = lastArgs

			etype = str(type(self)).split(".")[-1].split("'")[0]
			print("Created Entity "+etype+f", {args}, {kwargs}")
			eid = etype[0] +"-"+ str(shortuuid.uuid())
			kwargs["id"] = eid
			kwargs["created"] = datetime.now() #datetime.now().timestamp() == time.time()
			c = 0
			for a in args:
				kwargs["id_"+str(c)] = a
				c+=1
			for a in kwargs:
				self[a] = kwargs[a]
			print()
			self.save()
			if etype[0] in ["D"]:
				akeyo.manager.new = eid
				# manager.trigger(eid)

class User(Entity):
	personas = dict()
	def __init__(self,*args,**kwargs):
		kwargs["type"] = type(self)
		super().__init__(*args,**kwargs)
		self.personas = dict()
		self["personas"] = []
		self["currentPersona"] = ""
		alpha  = self.newPersona(Alpha(*args,**kwargs))
		omega  = self.newPersona(Omega(*args,**kwargs))

	def msg(self, *args,**kwargs):
		print(f"<<<<<U>>>>>>>>> MSG me({type(self)},{self})",*args,**kwargs)

	def newPersona(self, entity, secret = False):
		if not secret:
			entity["parent"] = self["id"]
			for key in self:
				if key != "id":
					entity[key] = self[key]

		self.personas[entity["id"]] = entity
		self["personas"].append(entity["id"])
		self["currentPersona"] = entity["id"]
		self._currentPersona = entity
		self.save()
		return entity

# class Car():
# 	def __init__(self, owner):
# 		self.owner = owner
# 	def drive(self):
# 		print(self.owner, "is driving")

# class TelsaCar(Car):
# 	def manufacter(*args,**kwargs):
# 		print("Tesla")
#
# 	def len(self)
#
#
# 	def selfdrive(self):
# 		print(f" driving to {self.owner}'s home")

# class Honda(Car):
# 	def manufacter(*args,**kwargs):
# 		print("Honda")

class Omega(Entity):
	deltas = dict()

	# def msg(self, *args,**kwargs):
	# 	print(f"<<<<<O>>>>>>>>> MSG me({type(self)},{self})",args,kwargs)

	def recieveMsg(self, *args,**kwargs):
		# print(f"<<<<<A>>>>>>>>> MSG me({type(self)},{self})",*args,**kwargs)
		xo.notify[self["id"]] = kwargs
	def __init__(self,*args,**kwargs):
		# kwargs["known"] = ["main","description","budget"]
		kwargs["type"] = type(self)
		super().__init__(*args,**kwargs)
		self["deltas"] = []
		self.deltas = {}
		xo.subscribe(f"notify.{self['id']}", self.notify)
		self.notifications = []
		self["chats"] = []
		self.chats = []
		self["contacts"] = []
		self.contacts =  []
		self.history = {"listening":[],"offers":{},"notifications":[]}

	def negotiate(self, delta, persona, *args,**kwargs):
		pass

	def accept(self, offer, *args,**kwargs):
		print("ACCEPTING OFFER!!!!!!!!!!!!!\n"*10,offer)
		delta = offer["delta"]
		kwargs["main"] = "OFFER ACCEPTED"
		kwargs["delta"] = delta
		kwargs["offer"] = offer
		offer.accept()
		# alpha.offerAccepted(*args,**kwargs)

	def chat(self, id = None, delta=None, offer = None, persona = None, *args,**kwargs):
		if id is not None:
			persona = id
		if delta is not None:
			persona = delta["parent"]
			kwargs["delta"] = delta["id"]
		if offer is not None:
			persona = offer["parent"]
			delta = offer["delta"]
			kwargs["offer"] = offer["id"]
			if delta is not None:
				# persona = delta["parent"]
				kwargs["delta"] = delta["id"]
		if persona is not None:
			# kwargs["parent"] = self["id"]
			kwargs["sender"] = self["id"]
			# get from db
			# listening = akeyo.index[alphaid].value()["listening"]
			print("PERSONA",persona,"selfID",self["id"],)
			alpha = akeyo.index[persona].value()
			alpha.recieveMsg(*args,**kwargs)

	def delta(self, *args,**kwargs):
		return self.createDelta(*args,**kwargs)

	def createDelta(self, *args,**kwargs):
		# known = ["main","description","budget"]
		# firstArgs, lastArgs = args[:len(known)],args[len(known):]
		# c = 0
		# for a in known:
		# 	kwargs[a] = firstArgs[c]
		# 	c+=1
		kwargs["parent"] = self["id"]
		d = Delta(*args,**kwargs)
		# d = Delta(*lastArgs,**kwargs)
		self["deltas"].append(d["id"])
		self.deltas[d["id"]] = d
		self.save()
		return d

	def notify(self, data,*args,**kwargs):
		full = (data,"::::::::",args,kwargs)
		msg = f"{self['id']} ::: New Offer from Alpha!!! ::: {full}!"
		print("\n"+("@"*int(len(msg)/2)+"\n"*1))
		# print(msg)
		print(data)
		print("@"*20)
		print(args)
		print("@"*20)
		print(kwargs)
		# print(("@"*len(msg)+"\n")*4+"\n")
		print(("@"*int(len(msg)/2)+"\n")*1+"\n")
		# self["hello"]
		# self.hello
		self.notifications.append(data)
		self.history["notifications"].append(data)

class Alpha(Entity):
	def __init__(self,*args,**kwargs):
		kwargs["type"] = type(self)
		super().__init__(*args,**kwargs)
		self["listening"] = []
		xo.notify[self['id']] = None
		xo.subscribe(f"notify.{self['id']}", self.notify)
		self.history = {"listening":[],"offers":{},"notifications":[]}
		self.notifications = []

	def chat(self, id = None, delta=None, offer = None, persona = None, *args,**kwargs):
		if id is not None:
			persona = id
		if delta is not None:
			persona = delta["parent"]
			kwargs["delta"] = delta["id"]
		if offer is not None:
			delta = offer["delta"]
			persona = delta["parent"]
			kwargs["offer"] = offer["id"]
			# if delta is not None:
			# 	# persona = delta["parent"]
			# 	kwargs["delta"] = delta["id"]
		if persona is not None:
			# kwargs["parent"] = self["id"]
			kwargs["sender"] = self["id"]
			# get from db
			# listening = akeyo.index[alphaid].value()["listening"]
			# print("PERSONA",persona,"selfID",self["id"],)
			o = akeyo.index[persona].value()
			o.recieveMsg(*args,**kwargs)

	def recieveMsg(self, *args,**kwargs):
		# print(f"<<<<<A>>>>>>>>> MSG me({type(self)},{self})",*args,**kwargs)
		xo.notify[self["id"]] = kwargs

	def offerAccepted(self, *args,**kwargs):
		# print(f"<<<<<A>>>>>>>>> MSG me({type(self)},{self})",*args,**kwargs)
		xo.notify[self["id"]] = kwargs

	def giveOffer(self,delta,*args,**kwargs):
		kwargs["parent"] = self["id"]
		kwargs["delta"] = delta
		kwargs["omega"] = delta["parent"]
		offer = Gamma(*args,**kwargs)
		delta.offer(self["id"],offer)
		self.history["offers"][offer['id']] = offer
		self.save()
		return offer

	def notify(self, data,*args,**kwargs):
		full = (data,"::::::::",args,kwargs)
		# msg = f"Someone wishes for {full}!"
		msg = f"{data}"
		# print("\n"+("!"*len(msg)+"\n")*4)
		print("\n"+("!"*int(len(msg)/2)+"\n"*1))
		# print("!"*20)
		print(data)
		# if data is not None:
		# 	for d in data:
		# 		print(data[d])
		# 		print("!"*20)
		print(args)
		print("!"*20)
		print(kwargs)
		print(("!"*int(len(msg)/2)+"\n")*1+"\n")
		self.notifications.append(data)
		self.history["notifications"].append(data)

	def listen(self, keywords, *args):
		if "list" in str(type(keywords)):
			keywords += list(args)
		else:
			args = list(args)
			args.append(keywords)
			keywords = args
		for phrase in keywords:
			for word in phrase.split("\n"):
				if word not in self["listening"]:
					self.history["listening"].append(word)
					self["listening"].append(word)
					print(f"{self['id']} listening to {word}")

		# self.save(delay = 1)
		self.save()

	def silent(self, keywords, *args):
		if "list" in str(type(keywords)):
			keywords += args
		else:
			args.append(keywords)
			keywords = args
		for phrase in keywords:
			for word in phrase.split("\n"):
				if word in self["listening"]:
					self["listening"].remove(word)
					print(f"{self['id']} removed {word} from notifications")
		self.save()

class Gamma(Entity):
	# known = ["main","description","budget"]
	def __init__(self,*args,**kwargs):
		# kwargs["_known_"] = Delta.known
		kwargs["type"] = type(self)
		super().__init__(*args,**kwargs)
		self["seen"] = False
		self["accepted"] = False

	def accept(self,*args,**kwargs):
		kwargs["main"] = "OFFER ACCEPTED BY OMEGA!"
		kwargs["offer"] = self["id"]
		self["accepted"] = True, datetime.now()
		self.save()
		xo.notify[self["parent"]] = kwargs

class Delta(Entity):
	known = ["main","description","budget"]
	def __init__(self,*args,**kwargs):
		kwargs["_known_"] = Delta.known
		kwargs["type"] = type(self)
		super().__init__(*args,**kwargs)
		self["offers"] = []
		self.offers = {}
		self["open"] = True

	def offer(self,alphaid,offer,*args,**kwargs):
		if "parent" not in offer:
			offer["parent"] = alphaid
		self["offers"].append(offer["id"])
		# maybe group by alpha
		# if alphaid not in self.offers:
		# 	self.offers[alphaid] = {}
		# self.offers[alphaid][offer["id"]] = offer
		self.offers[offer["id"]] = offer
		print()
		print(f"{self['id']} ::: GOT NEW OFFER! ::: {offer}")
		print()
		xo.notify[self["parent"]] = offer
		self.save()

# class Indexer(dict):
# 	shared = None
# 	def __init__(self):
# 		if Indexer.shared is None:
# 			Indexer.shared = self
# index = Indexer()
# index = Indexer.shared

class Manager(dict):
	shared = None
	def __init__(self):
		if Manager.shared is None:
			Manager.shared = self
		self.new = []
		xo.subscribe("akeyo.manager.new", self.trigger)

	def get(self, id):
		return akeyo.index[id].value()

	def manageNotifications(*args, **kwargs):
		print("::: Managing Notifications")
		self = Manager.shared
		while True:
			current = None
			new = None
			try:
				if len(self.new) > 0:
					new = self.new.pop(0)
					print("!!!!!!!!!!!"+str(type(new)))
					if "delta" in str(type(new)).lower():
						delta = new
						print(f" Manager ::: Processing {delta}")
						for alphaid in akeyo.index["A"].value():
							if alphaid[0] == "A":
								print(" AAAAAAA ::::: ",alphaid)
								alpha = akeyo.index[alphaid].value()
								listening = alpha["listening"]
								# add listening entity to check radius and other info
								print(" LLLLLL ::::: ",listening)
								desc = str(delta["main"])+" "+delta["description"]
								notify = [False, [],None]
								for phrase in listening:
									for word in phrase.lower().split(" "):
										if word.lower() in desc:
											notify[0] = True
											notify[1].append(word)
											notify[2] = delta

							if notify[0]:
								msg = f"Sending notification to alpha {alphaid}!,{notify[1]}"
								print("\n"+("#"*len(msg)+"\n")*1)
								print(msg)
								print(("#"*len(msg)+"\n")*1+"\n")
								xo.notify[alphaid] = delta
								# index[alphaid].notify(notify)

			except:
				print()
				print(f"ERROR in manageNotifications ::: current : {current} ")
				traceback.print_exc()
				print()

	def trigger(self,eid,*args,**kwargs):
		print("TTTTTTTTTT MANAGER TRIGGER",eid,*args,**kwargs)
		entity = None
		try:
			try:
				tx = time.time()
				run = True
				while eid not in akeyo.index.children() and run:
					time.sleep(0.01)
					if time.time()-tx > 3: #timeout
						run = False
			except :
				pass
			entity = akeyo.index[eid].value()
			print("NNNNNNNNN",entity)
			if entity is not None:
				etype = entity["id"][0]
				if etype == "D":
					self.new.append(entity)
				if etype == "M":
					self.new.append(entity)
		except:
			print()
			print(f"ERROR in trigger ::: {eid} ::: {args} ::: {kwargs}")
			print(f"Entity ::: {entity}")
			traceback.print_exc()
			print()

# manager = Manager()
# manager = Manager.shared
# xo.asyn(manager.manageNotifications)

class Key(Entity):
	pass


import discord
from discord.ext import commands
#By Tomás Ryan
#tomasryanmann@gmail.com
##########
#tammi bot code
#last edited 5/1/2018
##########
#basically a warm up to get back into coding as im rusty as fuck
##########
bot = commands.Bot(command_prefix='yotam ', description='sure no bother')

@bot.event
async def on_ready():
    print('this is')
    print(bot.user.name)
#Bot command list
@bot.command()
async def hello():
    await bot.say('h0i! im TamMiB0t! c:')
@bot.command()
async def joke():
    await bot.say('make me')
@bot.command()
async def endWorld():
    await bot.say("couldn't be arsed tbh")
@bot.command()
async def say(*, something):
    await bot.say(something)

bot.run('MzA1MTc3MzExMzY2MzQ4ODEx.DTEsCg.XQL8D5MESGion9OtogvuW8dsyT8')

#https://discordapp.com/api/oauth2/authorize?client_id=305177311366348811&scope=bot&permissions=0


import logging
from itertools import chain

import numpy as np
from scipy.stats import halfnorm

from hyperspy.external.progressbar import progressbar
from hyperspy.misc.math_tools import check_random_state

_logger = logging.getLogger(__name__)

def _thresh(X, lambda1, vmax):
    """Soft-thresholding with clipping."""
    res = abs(X) - lambda1
    np.maximum(res, 0.0, out=res)
    res *= np.sign(X)
    np.clip(res, -vmax, vmax, out=res)
    return res

def _mrdivide(B, A):
    """Solves xB = A as per Matlab."""
    if isinstance(B, np.ndarray):
        if len(B.shape) == 2 and B.shape[0] == B.shape[1]:
            # square array
            return np.linalg.solve(A.T, B.T).T
        else:
            # Set rcond default value to match numpy 1.14 default value with
            # previous numpy version
            rcond = np.finfo(float).eps * max(A.shape)
            return np.linalg.lstsq(A.T, B.T, rcond=rcond)[0].T
    else:
        return B / A

def _project(W):
    newW = W.copy()
    np.maximum(newW, 0, out=newW)
    sumsq = np.sqrt(np.sum(W ** 2, axis=0))
    np.maximum(sumsq, 1, out=sumsq)
    return _mrdivide(newW, np.diag(sumsq))

def _solveproj(v, W, lambda1, kappa=1, h=None, e=None, vmax=None):
    m, n = W.shape
    v = v.T
    if vmax is None:
        vmax = v.max()

    if len(v.shape) == 2:
        batch_size = v.shape[1]
        eshape = (m, batch_size)
        hshape = (n, batch_size)
    else:
        eshape = (m,)
        hshape = (n,)
    if h is None or h.shape != hshape:
        h = np.zeros(hshape)
    if e is None or e.shape != eshape:
        e = np.zeros(eshape)

    eta = kappa / np.linalg.norm(W, "fro") ** 2

    maxiter = 1e6
    iters = 0

    while True:
        iters += 1
        # Solve for h
        htmp = h
        h = h - eta * W.T @ (W @ h + e - v)
        np.maximum(h, 0.0, out=h)

        # Solve for e
        etmp = e
        e = _thresh(v - W @ h, lambda1, vmax)

        # Stop conditions
        stoph = np.linalg.norm(h - htmp, 2)
        stope = np.linalg.norm(e - etmp, 2)
        stop = max(stoph, stope) / m
        if stop < 1e-5 or iters > maxiter:
            break

    return h, e

class ORNMF:
    """Performs Online Robust NMF with missing or corrupted data.

    The ORNMF code is based on a transcription of the online proximal gradient
    descent (PGD) algorithm MATLAB code obtained from the authors of [Zhao2016]_.
    It has been updated to also include L2-normalization cost function that
    is able to deal with sparse corruptions and/or outliers slightly faster
    (please see ORPCA implementation for details). A further modification
    has been made to allow for a changing subspace W, where X ~= WH^T + E
    in the ORNMF framework.

    Read more in the :ref:`User Guide <mva.rnmf>`.

    References
    ----------
    .. [Zhao2016] Zhao, Renbo, and Vincent YF Tan. "Online nonnegative matrix
        factorization with outliers." Acoustics, Speech and Signal Processing
        (ICASSP), 2016 IEEE International Conference on. IEEE, 2016.

    """

    def __init__(
        self,
        rank,
        store_error=False,
        lambda1=1.0,
        kappa=1.0,
        method="PGD",
        subspace_learning_rate=1.0,
        subspace_momentum=0.5,
        random_state=None,
    ):
        """Creates Online Robust NMF instance that can learn a representation.

        Parameters
        ----------
        rank : int
            The rank of the representation (number of components/factors)
        store_error : bool, default False
            If True, stores the sparse error matrix.
        lambda1 : float
            Nuclear norm regularization parameter.
        kappa : float
            Step-size for projection solver.
        method : {'PGD', 'RobustPGD', 'MomentumSGD'}, default 'PGD'
            * 'PGD' - Proximal gradient descent
            * 'RobustPGD' - Robust proximal gradient descent
            * 'MomentumSGD' - Stochastic gradient descent with momentum
        subspace_learning_rate : float
            Learning rate for the 'MomentumSGD' method. Should be a
            float > 0.0
        subspace_momentum : float
            Momentum parameter for 'MomentumSGD' method, should be
            a float between 0 and 1.
        random_state : None or int or RandomState instance, default None
            Used to initialize the subspace on the first iteration.

        """
        self.n_features = None
        self.iterating = False
        self.t = 0

        if store_error:
            self.E = []
        else:
            self.E = None

        self.rank = rank
        self.robust = False
        self.subspace_tracking = False
        self.lambda1 = lambda1
        self.kappa = kappa
        self.subspace_learning_rate = subspace_learning_rate
        self.subspace_momentum = subspace_momentum
        self.random_state = check_random_state(random_state)

        # Check options are valid
        if method not in ("PGD", "RobustPGD", "MomentumSGD"):
            raise ValueError("'method' not recognised")

        if method == "RobustPGD":
            self.robust = True

        if method == "MomentumSGD":
            self.subspace_tracking = True
            if subspace_momentum < 0.0 or subspace_momentum > 1:
                raise ValueError("'subspace_momentum' must be a float between 0 and 1")

    def _setup(self, X):
        self.h, self.e, self.v = None, None, None
        if isinstance(X, np.ndarray):
            n, m = X.shape
            avg = np.sqrt(X.mean() / m)
            iterating = False
        else:
            x = next(X)
            m = len(x)
            avg = np.sqrt(x.mean() / m)
            X = chain([x], X)
            iterating = True

        self.n_features = m
        self.iterating = iterating

        self.W = halfnorm.rvs(
            size=(self.n_features, self.rank), random_state=self.random_state
        )
        self.W = abs(avg * self.W / np.sqrt(self.rank))
        self.H = []

        if self.subspace_tracking:
            self.vnew = np.zeros_like(self.W)
        else:
            self.A = np.zeros((self.rank, self.rank))
            self.B = np.zeros((self.n_features, self.rank))

        return X

    def fit(self, X, batch_size=None):
        """Learn NMF components from the data.

        Parameters
        ----------
        X : {numpy.ndarray, iterator}
            [n_samples x n_features] matrix of observations
            or an iterator that yields samples, each with n_features elements.
        batch_size : {None, int}
            If not None, learn the data in batches, each of batch_size samples
            or less.

        """
        if self.n_features is None:
            X = self._setup(X)

        num = None
        prod = np.outer
        if batch_size is not None:
            if not isinstance(X, np.ndarray):
                raise ValueError("can't batch iterating data")
            else:
                prod = np.dot
                length = X.shape[0]
                num = max(length // batch_size, 1)
                X = np.array_split(X, num, axis=0)

        if isinstance(X, np.ndarray):
            num = X.shape[0]
            X = iter(X)

        h, e = self.h, self.e

        for v in progressbar(X, leave=False, total=num, disable=num == 1):
            h, e = _solveproj(v, self.W, self.lambda1, self.kappa, h=h, e=e)
            self.v = v
            self.e = e
            self.h = h
            self.H.append(h)
            if self.E is not None:
                self.E.append(e)

            self._solve_W(prod(h, h.T), prod((v.T - e), h.T))
            self.t += 1

        self.h = h
        self.e = e

    def _solve_W(self, A, B):
        if not self.subspace_tracking:
            self.A += A
            self.B += B
            eta = self.kappa / np.linalg.norm(self.A, "fro")

        if self.robust:
            # exactly as in the Zhao & Tan paper
            n = 0
            lasttwo = np.zeros(2)
            while n <= 2 or (
                abs((lasttwo[1] - lasttwo[0]) / lasttwo[0]) > 1e-5 and n < 1e9
            ):
                self.W -= eta * (self.W @ self.A - self.B)
                self.W = _project(self.W)
                n += 1
                lasttwo[0] = lasttwo[1]
                lasttwo[1] = 0.5 * np.trace(
                    self.W.T.dot(self.W).dot(self.A)
                ) - np.trace(self.W.T.dot(self.B))
        else:
            # Tom Furnival (@tjof2) approach
            # - copied from the ORPCA implementation
            #   of gradient descent in ./rpca.py
            if self.subspace_tracking:
                learn = self.subspace_learning_rate * (
                    1 + self.subspace_learning_rate * self.lambda1 * self.t
                )
                vold = self.subspace_momentum * self.vnew
                self.vnew = (self.W @ A - B) / learn
                self.W -= vold + self.vnew
            else:
                self.W -= eta * (self.W @ self.A - self.B)

            np.maximum(self.W, 0.0, out=self.W)
            self.W /= max(np.linalg.norm(self.W, "fro"), 1.0)

    def project(self, X, return_error=False):
        """Project the learnt components on the data.

        Parameters
        ----------
        X : {numpy.ndarray, iterator}
            [n_samples x n_features] matrix of observations
            or an iterator that yields n_samples, each with n_features elements.
        return_error : bool
            If True, returns the sparse error matrix as well. Otherwise only
            the weights (loadings)

        """
        H = []
        if return_error:
            E = []

        num = None
        if isinstance(X, np.ndarray):
            num = X.shape[0]
            X = iter(X)
        for v in progressbar(X, leave=False, total=num):
            h, e = _solveproj(v, self.W, self.lambda1, self.kappa, vmax=np.inf)
            H.append(h.copy())
            if return_error:
                E.append(e.copy())

        H = np.stack(H, axis=-1)
        if return_error:
            return H, np.stack(E, axis=-1)
        else:
            return H

    def finish(self):
        """Return the learnt factors and loadings."""
        if len(self.H) > 0:
            if len(self.H[0].shape) == 1:
                H = np.stack(self.H, axis=-1)
            else:
                H = np.concatenate(self.H, axis=1)
            return self.W, H
        else:
            return self.W, 1

def ornmf(
    X,
    rank,
    store_error=False,
    project=False,
    batch_size=None,
    lambda1=1.0,
    kappa=1.0,
    method="PGD",
    subspace_learning_rate=1.0,
    subspace_momentum=0.5,
    random_state=None,
):
    """Perform online, robust NMF on the data X.

    This is a wrapper function for the ORNMF class.

    Parameters
    ----------
    X : numpy array
        The [n_samples, n_features] input data.
    rank : int
        The rank of the representation (number of components/factors)
    store_error : bool, default False
        If True, stores the sparse error matrix.
    project : bool, default False
        If True, project the data X onto the learnt model.
    batch_size : {None, int}, default None
        If not None, learn the data in batches, each of batch_size samples
        or less.
    lambda1 : float
        Nuclear norm regularization parameter.
    kappa : float
        Step-size for projection solver.
    method : {'PGD', 'RobustPGD', 'MomentumSGD'}, default 'PGD'
        * 'PGD' - Proximal gradient descent
        * 'RobustPGD' - Robust proximal gradient descent
        * 'MomentumSGD' - Stochastic gradient descent with momentum
    subspace_learning_rate : float
        Learning rate for the 'MomentumSGD' method. Should be a
        float > 0.0
    subspace_momentum : float
        Momentum parameter for 'MomentumSGD' method, should be
        a float between 0 and 1.
    random_state : None or int or RandomState instance, default None
        Used to initialize the subspace on the first iteration.

    Returns
    -------
    Xhat : numpy array
        is the [n_features x n_samples] non-negative matrix
        Only returned if store_error is True.
    Ehat : numpy array
        is the [n_features x n_samples] sparse error matrix
        Only returned if store_error is True.
    W : numpy array, shape [n_features, rank]
        is the non-negative factors matrix
    H : numpy array, shape [rank, n_samples]
        is the non-negative loadings matrix

    """
    X = X.T

    _ornmf = ORNMF(
        rank,
        store_error=store_error,
        lambda1=lambda1,
        kappa=kappa,
        method=method,
        subspace_learning_rate=subspace_learning_rate,
        subspace_momentum=subspace_momentum,
        random_state=random_state,
    )
    _ornmf.fit(X, batch_size=batch_size)

    if project:
        W = _ornmf.W
        H = _ornmf.project(X)
    else:
        W, H = _ornmf.finish()

    if store_error:
        Xhat = W @ H
        Ehat = np.array(_ornmf.E).T

        return Xhat, Ehat, W, H
    else:
        return W, H


#!/usr/bin/python3
import yaml
import json
import re
from ETFiles import *
from DockerUtils import *

core_list = []
tss_list = []
engines_list = []
et_image_name_prefix = 'elastest/'
et_docker_image_name_prefix = 'ET_DOCKER_IMG'
preloaded_images = ['']

socat_image_property = 'et.socat.image'
chrome_browser = 'chrome'
firefox_browser = 'firefox'

images_to_pre_pulling = ['elastest/etm-socat',
                         'elastest/eus', 'elastest/etm-dockbeat']

class MyEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, (bytes, bytearray)):
            # <- or any other encoding of your choice
            return obj.decode("ASCII")
        # Let the base class default method raise the TypeError
        return json.JSONEncoder.default(self, obj)

##################################    Getters    ##################################

#*** Getters By Object ***#

def getValuesListOfKey(d, key):
    values_list = []
    if key in d:
        try:
            return [d[key]]
        except TypeError:
            print ('dict modified: ' + yaml.dump(d,
                                                 stream=None, default_flow_style=True))
            dm = yaml.dump(d, stream=None, default_flow_style=True)
            return [dm[key]]
    for k in d:
        if isinstance(d[k], dict):
            values_list = values_list + getValuesListOfKey(d[k], key)
    return values_list

def getImagesList(d):
    images = []
    if isinstance(d, dict):
        images = getValuesListOfKey(d, 'image')
    else:
        for yml in d:
            images = images + getValuesListOfKey(yml, 'image')
    return images

def getYmlFromETServicesJsonPath(path):
    data = getJson(path)
    return getYmlFromETServicesJsonFile(data['manifests'][0])

def getYmlFromETServicesJsonFile(json):
    try:
        ymls = []
        for yml in yaml.load_all(json['manifest_content']):
            ymls.append(yml)
        return ymls
    except KeyError:
        return yaml.load('')

def getPropertiesFromFile(path):
    separator = "="
    keys = {}
    with open(path) as f:
        for line in f:
            if separator in line:
                name, value = line.split(separator, 1)
                keys[name.strip()] = value.strip()
    return keys

def getETDockerImagesFromYml(yml):
    dynamic_images = []
    environment = 'environment'
    if environment in yml:
        for var in yml[environment]:
            try:
                if(var.startswith(et_docker_image_name_prefix)):
                    dynamic_images.append(var.split('=')[1])
            except TypeError:
                print ('Error getting ET_DOCKER_IMAGES')
        return dynamic_images
    for k in yml:
        if isinstance(yml[k], dict):
            dynamic_images = dynamic_images + getETDockerImagesFromYml(yml[k])
    return dynamic_images

#*** Images Lists Getters By File Type ***#

def getImagesFromYmlFilesList(files_list, get_from_env=True):
    # get_from_env is used to get images from declared env variables (example: ET_DOCKER_IMG_DOCKBEAT)
    files_images = []
    for path in files_list:
        files_images = files_images + getImagesList(getYml(path))
        if(get_from_env):
            files_images = files_images + \
                getETDockerImagesFromYml(getYml(path))
    return files_images

def getImageFromJsonFile(service_name):
    image = None
    file_path = getFilePathByImage(service_name)
    image = getImagesList(getYmlFromETServicesJsonPath(file_path))
    return image

def getImagesFromJsonFilesList(files_list):
    files_images = []
    for path in files_list:
        print('Obtaining images list from file at path ' + path)
        files_images = files_images + \
            getImagesList(getYmlFromETServicesJsonPath(path))
        files_images = files_images + \
            getETDockerImagesFromETServiceJsonFile(path)
    return files_images

def getETDockerImagesFromETServiceJsonFile(path):
    images = []
    json_file = getJson(path)
    ymls = getYmlFromETServicesJsonFile(json_file['manifests'][0])
    for yml in ymls:
        images = images + getETDockerImagesFromYml(yml)
    return images

#*** Images Lists Getters By Component Type ***#

def getCoreImages(get_from_env=True):
    return getImagesFromYmlFilesList(core_list, get_from_env)

def getTSSImages():
    return getImagesFromJsonFilesList(tss_list)

def getEnginesImages():
    return getImagesFromYmlFilesList(engines_list)

def getImageByServiceName(service_name):
    image = None
    image = getImageFromJsonFile(service_name)
    return image

def getBrowserImage(browser):
    properties = {}
    properties = getPropertiesFromFile(getFilePathByImage('eusBrowsers'))
    latest_version = 0
    browser_image = None

    for key, value in properties.iteritems():
        if browser in key:
            if re.findall('\d+', key)[0] > latest_version:
                latest_version = re.findall('\d+', key)[0]
                browser_image = value

    return browser_image

def getBrowsersImages():
    browser_images = []
    browser_images.append(getBrowserImage(chrome_browser))
    browser_images.append(getBrowserImage(firefox_browser))
    return browser_images

def getImageFromFileProperties(image_key, properties_type):
    image = None
    properties = {}
    properties = getPropertiesFromFile(getFilePathByImage(properties_type))
    image = properties.get(image_key, None)

    return image

##################################    Updaters    ##################################

def modifyImageTag(image, tag):
    new_image = image.split(':')[0]
    new_image = new_image + ':' + tag
    return new_image

def updateImagesTagOfReadYml(d, tag):
    key = 'image'
    if key in d:
        # If is ElasTest Image, set image tag
        try:
            if(d[key].startswith(et_image_name_prefix)):
                d[key] = modifyImageTag(d[key], tag)
                return d
        except TypeError:
            print ('dict modified: ' + yaml.dump(d, default_flow_style=False))
            dm = yaml.dump(d, stream=None, default_flow_style=True)
            if(dm[key].startswith(et_image_name_prefix)):
                dm[key] = modifyImageTag(dm[key], tag)
                return dm
            return dm
    for k in d:
        if isinstance(d[k], dict):
            d[k] = updateImagesTagOfReadYml(d[k], tag)
    return d

def updateImagesTagInYmlList(d, name, tag):
    if name in d:
        for container in d[name]:
            updateImagesTagOfReadYml(container, tag)
    for k in d:
        if isinstance(d[k], dict):
            d[k] = updateImagesTagInYmlList(d[k], name, tag)
    return d

def updateETDockerImagesTagYml(yml, tag):
    environment = 'environment'
    if environment in yml:
        for i, var in enumerate(yml[environment]):
            try:
                if(var.startswith(et_docker_image_name_prefix)):
                    yml[environment][i] = modifyImageTag(var, tag)
            except TypeError:
                print ('Error updating ET_DOCKER_IMAGES')
        return yml
    for k in yml:
        if isinstance(yml[k], dict):
            yml[k] = updateETDockerImagesTagYml(yml[k], tag)
    return yml

def updateImagesTagOfYmlFile(path, tag):
    print("Updating images of YML with path '" + path + "' with tag " + tag)
    yml_file = getYml(path)
    new_yml = updateImagesTagOfReadYml(yml_file, tag)
    new_yml = updateETDockerImagesTagYml(new_yml, tag)
    # Save new yml file with images tag updated
    saveYml(path, new_yml)

def updateImagesTagOfJsonFile(path, tag):
    json_file = getJson(path)

    # Update images version in the docker-compose files
    for manifest in json_file['manifests']:
        ymls = getYmlFromETServicesJsonFile(manifest)
        for yml in ymls:
            new_yml = updateImagesTagOfReadYml(yml, tag)
            new_yml = updateImagesTagInYmlList(new_yml, 'containers',tag)
            updateETDockerImagesTagYml(new_yml, tag)
        print("Manifest content updated: " + yaml.dump_all(ymls))
        manifest['manifest_content'] = json.loads(json.dumps(yaml.dump_all(
            ymls, encoding=('utf-8'), default_flow_style=False), cls=MyEncoder))

    # Save new json file with images tag updated
    saveJson(path, json_file)

#*** Images Lists Updaters By File Type ***#

def updateImagesTagOfYmlFiles(files_list, tag):
    for path in files_list:
        updateImagesTagOfYmlFile(path, tag)

def updateImagesTagOfJsonFilesList(files_list, tag):
    files_images = []
    for path in files_list:
        updateImagesTagOfJsonFile(path, tag)

#*** Images Lists Updaters By Component Type ***#

def updateCoreImagesTag(tag):
    updateImagesTagOfYmlFiles(core_list, tag)

def updateTSSImagesTag(tag):
    updateImagesTagOfJsonFilesList(tss_list, tag)

def updateEnginesImagesTag(tag):
    updateImagesTagOfYmlFiles(engines_list, tag)

##################################    Main functions    ##################################

# Loads lists of files
def loadETLists():
    global core_list
    core_list = getCoreList()
    global tss_list
    tss_list = getTSSList()
    global engines_list
    engines_list = getEnginesList()

def getAllImages():
    loadETLists()
    images_list = []
    images_list = images_list + getCoreImages()
    images_list = images_list + getTSSImages()
    images_list = images_list + getEnginesImages()
    return images_list

def getTSSImagesByServices(tss_list):
    image_list = []
    image_file_list = []
    for tss in tss_list:
        image_file_list.append(getTSSFile(tss))
    image_list = getImagesFromJsonFilesList(image_file_list)
    return image_list

def getAllImagesByExecMode(mode):
    images_list = []
    global core_list
    core_list = getCoreListByExecMode(mode)
    images_list = images_list + list(set(getCoreImages()))

    # All modes
    global tss_list
    tss_list = getTSSList()
    global engines_list
    engines_list = getEnginesList()
    images_list = images_list + getTSSImages()
    images_list = images_list + getEnginesImages()

    images_list.append(getContainerImage())

    return images_list

def getAllCoreImagesByExecMode(mode):
    images_list = []
    global core_list
    core_list = getCoreListByExecMode(mode)
    images_list = images_list + list(set(getCoreImages(False)))

    images_list.append(getContainerImage())

    return images_list

def getElastestImages(without_tag):
    images_list = getAllImages()

    elastest_images = []
    for image in images_list:
        if(image.startswith(et_image_name_prefix)):
            if(without_tag):
                image_splited = image.split(':')
                elastest_images.append(image_splited[0])
            else:
                elastest_images.append(image)
    return elastest_images

def getElastestImagesByExecMode(mode, without_tag):
    images_list = getAllImagesByExecMode(mode)

    elastest_images = []
    for image in images_list:
        if(image.startswith(et_image_name_prefix)):
            if(without_tag):
                image_splited = image.split(':')
                elastest_images.append(image_splited[0])
            else:
                elastest_images.append(image)
    return elastest_images

def getElasTestImagesAsString(mode):
    images_list = getElastestImagesByExecMode(mode, False)
    return ",".join(map(str, images_list))

def getElastestCoreImagesByExecMode(mode, without_tag):
    images_list = getAllCoreImagesByExecMode(mode)

    elastest_images = []
    for image in images_list:
        if(image.startswith(et_image_name_prefix)):
            if(without_tag):
                image_splited = image.split(':')
                elastest_images.append(image_splited[0])
            else:
                elastest_images.append(image)
    return elastest_images

def getElasTestCoreImagesAsString(mode):
    images_list = getElastestCoreImagesByExecMode(mode, False)
    return ",".join(map(str, images_list))

def getPreloadedImages(elastest_images):
    images_list = []
    for image_to_pulling in images_to_pre_pulling:
        for et_image in elastest_images:
            if image_to_pulling in et_image:
                images_list.append(et_image)
                break

    return images_list

def updateFilesImagesWithTag(tag):
    loadETLists()
    updateCoreImagesTag(tag)
    updateTSSImagesTag(tag)
    updateEnginesImagesTag(tag)

def pullAllImages():
    images_list = getAllImages()
    for image in images_list:
        pullImage(image)

def pullPreloadImages(elastest_images):
    images_list = getPreloadedImages(elastest_images)
    for image in images_list:
        if (not existsLocalImage(image)):
            pullImage(image)


import json
import logging
import os

from django.core import serializers
from django.core.management.base import BaseCommand
from django.core.management.base import CommandError
from django.db.models import Model

from kolibri.core.auth.models import FacilityUser
from kolibri.core.auth.serializers import FacilityUserSerializer
from kolibri.core.device.models import DevicePermissions

logger = logging.getLogger(__name__)

class Command(BaseCommand):
    help = "To allow administrators to comply with GDPR requests, this command dumps all associated data for a user to several files."

    def add_arguments(self, parser):
        parser.add_argument(
            "username", action="store", type=str, help="Username of user for data dump"
        )

    def handle(self, *args, **options):
        try:
            user = FacilityUser.objects.get(username=options["username"])
        except FacilityUser.DoesNotExist:
            raise CommandError(
                "User with username `{username}` does not exist.".format(
                    username=options["username"]
                )
            )

        # create username directory to hold associated files
        cwd = os.getcwd()
        directory_location = os.path.join(cwd, user.username)
        if not os.path.isdir(directory_location):
            os.makedirs(directory_location)

        # write basic user data to file
        file_name = "{user}.txt".format(user=user.username)
        file_location = os.path.join(directory_location, file_name)
        data = FacilityUserSerializer(user).data
        logger.info("Writing user data to {file}...".format(file=file_location))
        with open(file_location, "w") as outfile:
            json.dump(data, outfile, sort_keys=True, indent=4)

        # get related managers for user model
        managers = []
        for related_object in user._meta.related_objects:
            try:
                managers.append(getattr(user, related_object.get_accessor_name()))
            # regular users do not have device permissions
            except (DevicePermissions.DoesNotExist,):
                pass

        # write data for each model to a file
        for manager in managers:
            # currently accounts for one-to-one field on DevicePermissions
            if isinstance(manager, Model):
                file_name = "{model}.txt".format(
                    model=manager.__class__.__name__.lower()
                )
                models = [manager]
            else:
                file_name = "{model}.txt".format(model=manager.model.__name__.lower())
                models = manager.all()
            file_location = os.path.join(directory_location, file_name)
            # only create file if models exist
            if models:
                data = serializers.serialize("json", models, indent=4)
                logger.info("Writing data to {file}...".format(file=file_location))
                with open(file_location, "w") as outfile:
                    outfile.write(data)


from math import sqrt

num = int(input('The number you enter: '))
end = int(sqrt(num))
is_prime = True
for x in range(2, end+1):
    if num % x == 0:
        is_prime = False
        break

if is_prime and num != 1:
    print('%d is prime number' % num)
else:
    print('%d is Not a prime' % num)


# -*- coding: utf-8 -*-
import imp
import mmap
import sys

from toolz import memoize

from .discovery import find_transforms

class TransformFinderLoader(object):

    def find_module(self, fullname, path=None):
        self.fullname = fullname
        self.path = path

        try:
            self.found = imp.find_module(fullname.rpartition('.')[-1], path)
            (
                self.file,
                self.pathname,
                (self.suffix, self.mode, self.type)
            ) = self.found
        except Exception:
            return None

        if self.type in (
            imp.C_BUILTIN,
            imp.C_EXTENSION,
            imp.PY_COMPILED,
            imp.PY_FROZEN,
        ):
            return None

        if not self.file:
            return None

        if self.mode and (
            not self.mode.startswith(('r', 'U'))
            or '+' in self.mode
        ):
            return None

        triggered_transforms = self.get_triggered_transforms()

        if triggered_transforms:
            self.triggered_transforms = triggered_transforms
            return self

        return None

    def get_kwargs(self):
        return {
            key: getattr(self, key)
            for key in (
                'fullname', 'path', 'file', 'pathname', 'suffix',
                'mode', 'type', 'found', 'mmaped_file',
            )
        }

    def get_triggered_transforms(self):
        self.mmaped_file = mmap.mmap(
            self.file.fileno(),
            0,
            prot=mmap.PROT_READ
        )

        triggered_transforms = set()
        for transform in self.transforms:
            self.file.seek(0)
            self.mmaped_file.seek(0)

            if transform.trigger(**self.get_kwargs()):
                triggered_transforms.add(transform)

        self.mmaped_file.close()

        return triggered_transforms

    @property
    @memoize
    def transforms(self):
        return find_transforms()

    def is_package(self, name):
        if not name == self.fullname:
            raise ImportError('package name does not match')
        return self.type == imp.PKG_DIRECTORY

    def get_code(self, name):
        if not name == self.fullname:
            raise ImportError('package name does not match')

        data = self.file.read()

        for transform in self.triggered_transforms:
            data = transform.transform(data, **self.get_kwargs())

        code = compile(data, self.pathname, 'exec')
        return code

    def load_module(self, fullname):
        try:
            return sys.modules[fullname]
        except KeyError:
            pass

        try:
            module = imp.new_module(fullname)
            sys.modules[fullname] = module
            module.__file__ = self.pathname
            module.__loader__ = self

            if self.type == imp.PKG_DIRECTORY:
                module.__path__ = [self.pathname]
                module.__package__ = fullname
            elif self.type == imp.PY_SOURCE:
                module.__package__ = fullname.rpartition('.')[0]

            exec(self.get_code(self.fullname), module.__dict__)

        except Exception:
            if fullname in sys.modules:
                del sys.modules[fullname]
            raise

        return module

TRANSFORM_FINDER_LOADER = TransformFinderLoader()

def setup_meta_path():
    if TRANSFORM_FINDER_LOADER not in sys.meta_path:
        sys.meta_path.insert(0, TRANSFORM_FINDER_LOADER)


R = 300 # Max Radial Distance

SHOW_PIC = False

# Minutiae Score threshold
MIN_SCORE_THRESH = 0.0

# PCB Feature Set Params
PCB_STEP_RHO = 5 # RANGE 5 to 20
PCB_STEP_ALPHA = 15 # RANGE 15 to 40 Degrees
PCB_STEP_BETA = 15 # RANGE 15 to 40 Degrees

# DTB Feature Set Params
DTB_STEP_L = 15 # RANGE 15 to 25
DTB_STEP_ALPHA = 15 # RANGE 15 to 20 Degrees
DTB_STEP_O = 15 # RANGE 15 to 20 Degrees

# Feature Decorrelation Algorithm Params
LC = 20000 # Must be less than L*H*S
NS = 20000 # Must divide LC

# Projection Matrix Params
PROJ_MAT_SEED = 1337 # Must be 32-bit integer
PROJ_MAT_Y_DIM = 50 # Must be between 1-L*H*S

# Delaunay Code Permutation Params
PERM_PHI = 14

# Final Score Params
FINAL_RHO = 0.7

# are we using the 1v1 protocol
IS_1V1 = True

# Output NPY file name
NPY_FILE_NAME = "SPEEDTEST.npy"

# Are we using the enhanced version of the Decorrelation algorithm
IS_DBA_ENHANCED = False

DEL_TFT_LEN = 20000