from unittest import skip
from django.http import HttpRequest
from django.test import TestCase, Client, RequestFactory
from django.urls import reverse

from store.models import Product, Category
from store.views import ProductDetailView

@skip("demonstrating skipping")
class TestSkip(TestCase):
    def test_skip_example(self):
        pass

class TestViewResponses(TestCase):
    def setUp(self):
        self.client = Client()
        self.factory = RequestFactory()

        self.category1 = Category.objects.create(
            name="Books",
            slug="books",
            description="Book Category",
            # image = models.ImageField(blank=True),
        )

        self.category2 = Category.objects.create(
            name="CDs",
            slug="cds",
            description="CD Category",
            # image = models.ImageField(blank=True),
        )

        self.product1 = Product.objects.create(
            name="Book Product",
            slug="book_product",
            description="This is Testing Product.",
            price=1000,
            image="test_image",
            stock=100,
        )
        self.product1.categories.add(self.category1)

        self.product2 = Product.objects.create(
            name="CD Product",
            slug="cd_product",
            description="This is Testing Product.",
            price=1000,
            image="test_image",
            stock=100,
        )
        self.product2.categories.add(self.category2)

    def test_allowed_host(self):
        """
        Test allowed host.
        """
        response = self.client.get('/')
        self.assertEqual(response.status_code, 200)

    def test_store_page(self):
        """
        Test store response status
        """

        # Send get request to index page and store response
        response = self.client.get('/store/')

        # Make sure status code is 200
        self.assertEqual(response.status_code, 200)

        # Make sure all products are returned in the context
        self.assertEqual(response.context["products"].count(), 2)

    def test_products_by_category(self):
        """
        Test products_by_category filter
        """

        # Send get request to index page and store response
        response = self.client.get(reverse('store:products_by_category', args=['books']))
        # response = self.client.get('/store/categories/books/')

        # Make sure status code is 200
        self.assertEqual(response.status_code, 200)

        # Make sure just selected category products are returned in the context
        self.assertEqual(response.context["products"].count(), 1)

    def test_product_detail_page(self):
        """
        Test product_detail page response status
        """

        # Send get request to index page and store response
        response = self.client.get(reverse('store:product_detail', args=['book_product']))
        # response = self.client.get('/store/products/book_product/')

        # Make sure status code is 200
        self.assertEqual(response.status_code, 200)

        # Make sure Product is correct.
        html = response.content.decode('utf8')
        self.assertIn('Book Product', html)

    def test_no_product_found(self):
        """
        Test no matching product
        """
        response = self.client.get('/store/products/dummy/')
        self.assertEqual(response.status_code, 404)


# python3

import sys, threading
sys.setrecursionlimit(10**6) # max depth of recursion
threading.stack_size(2**27)  # new thread will get stack of such size

# preorder , inorder  ,postorder = 1,2,3 th time we visit the particuar object while traversing the treee
class TreeOrders:
  def read(self):
    self.n = int(sys.stdin.readline())
    self.key = [0 for i in range(self.n)]
    self.left = [0 for i in range(self.n)]
    self.right = [0 for i in range(self.n)]
    for i in range(self.n):
      [a, b, c] = map(int, sys.stdin.readline().split())
      self.key[i] = a
      self.left[i] = b
      self.right[i] = c

  def inOrder(self):
    # print("i am in inOrder function")
    self.result = []
    id = 0
    stack = []
    # Finish the implementation
    # You may need to add a new recursive method to do that
    while True:
      if id !=-1:
        stack.append(id)
        id = self.left[id]
      elif stack:
        id = stack.pop()
        # yield self.key[id]
        self.result.append(self.key[id])
        # self.result.append(self.key[stack.pop()])
        id = self.right[id]
      else:
        break

    return self.result

  def preOrder(self):
    self.result = []
    # Finish the implementation
    # You may need to add a new recursive method to do that
    id = 0
    stack = []
    while True:
      if id !=-1:
        self.result.append(self.key[id])
        stack.append(id)
        id = self.left[id]
      elif stack:
        id = stack.pop()
        id = self.right[id]
      else:
        break
    return self.result

  def postOrder(self):
    self.result = []
    # Finish the implementation
    # You may need to add a new recursive method to do that
    stack=[0]
    while stack:
      id = stack.pop()
      self.result.append(self.key[id])
      left_id = self.left[id]
      right_id = self.right[id]
      if left_id != -1:
          stack.append(left_id)
      if right_id != -1:
          stack.append(right_id)
    self.result.reverse()
    return self.result

def main():
	tree = TreeOrders()
	tree.read()
	print(" ".join(str(x) for x in tree.inOrder()))
	print(" ".join(str(x) for x in tree.preOrder()))
	print(" ".join(str(x) for x in tree.postOrder()))

threading.Thread(target=main).start()


import unittest
from multi_arm_bandit.arms import BernouliArm
from multi_arm_bandit.epsilon_greedy import EpsilonGreedy
import random
import codecs

class TestEpsilonGreedy(unittest.TestCase):
    def setUp(self):
        pass

    def test_arithmetic(self):
        self.assertEquals(1, 1)

    def test_epsilon_greedy_simulation(self):
        # For repeatability
        random.seed(2)

        # Success rate for the arms
        means = [0.1, 0.1, 0.1, 0.1, 0.9]
        # Shuffle the arm means to test if the algorithm picks the right arm
        random.shuffle(means)

        # Arms are initialized as Bernouli Arm (to represent marketing success rate for ex: CTI)
        arms = []
        for mean in means:
            arms.append(BernouliArm(mean))

        for arm in arms:
            print(arm, arm.s, arm.pull())

        print("Best Arm is " + str(means.index(max(means))))
        opt_file = codecs.open("./output_files/opt_file.txt", "w", "utf-8")

        for epsilon in [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]:
            # Initialize the the algo
            algo = EpsilonGreedy(len(arms), epsilon)

            # Run the tester for a given set of epsilon values
            results = self.epsilon_greedy_tester(algo, arms, 5000, 250)
            # Results are expected to have [trial_nums, ticks, chosen_arms, rewards, cumulative_rewards]
            trials = results[0]
            for i in range(len(trials)):
                write_string = str(epsilon) + "\t"
                # opt_file.write()
                write_string += "\t".join([str(results[j][i]) for j in range(len(results))]) + "\n"
                opt_file.write(write_string)
                # print(write_string, end="")
                # columns [ 'epsilon', 'sim index',  'tick index', 'chosen arm', 'reward', 'cum reward']

        opt_file.close()
    def epsilon_greedy_tester(self, algo, arms, simulation_count, tick_horizon):
        chosen_arms = [0.0] * (simulation_count * tick_horizon)
        rewards = [0.0] *  (simulation_count * tick_horizon)
        cumulative_rewards = [0.0] * (simulation_count * tick_horizon)
        simulation_number = [0.0] *(simulation_count * tick_horizon)
        ticks = [0.0] * (simulation_count * tick_horizon)

        for sim in range(simulation_count):
            sim += 1
            algo.initialize(len(arms))

            for t in range(tick_horizon):
                t += 1
                index = (sim - 1) * tick_horizon + t - 1
                simulation_number[index] = sim
                ticks[index] = t
                chosen_arm = algo.choose_arm()
                chosen_arms[index] = chosen_arm

                reward = arms[chosen_arms[index]].pull()
                rewards[index] = reward

                if t == 1:
                    cumulative_rewards[index] = reward
                else:
                    cumulative_rewards[index] = cumulative_rewards[index - 1] + reward
                algo.update_performance(chosen_arm, reward)
        return[simulation_number, ticks, chosen_arms, rewards, cumulative_rewards]

if __name__ == "__main__":
    unittest.main()


s = input()
if len(s) % 2 != 0:
    print("No")
    exit()

i = 0
while i <= len(s) - 2:
    if s[i:i + 2] == "hi":
        i += 2
    else:
        print("No")
        exit()
print("Yes")


from array import array
from ctypes import Array
from typing import Tuple

def binary_search(numbers: Array, value: int) -> Tuple[bool, int]:
    p=0
    k=len(numbers)-1
    while(p<=k):
        middle = int((p+k)/2)
        if value==numbers[middle]:
            return True,middle
        elif value>numbers[middle]:
            p+=1
        else:
            k-=1
    return False,-1

x = array('i',[0,4,7,11,55,99])
print(binary_search(x,2))
print(binary_search(x,55))


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

#Importing required libraries
from string import punctuation
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.tokenize import sent_tokenize
import urllib.request
import bs4 as BeautifulSoup
import nltk
from nltk.cluster.util import cosine_distance
import numpy as np
import networkx as nx
import re

def read_article(text):

    sentences =[]

    sentences = sent_tokenize(text) #module in nltk
    for sentence in sentences:
        sentence.replace("[^a-zA-Z0-9]"," ")

    return sentences

def generate_summary2(lnk):
    text = urllib.request.urlopen(lnk)
    article = text.read()
    article_parsed = BeautifulSoup.BeautifulSoup(article,'html.parser')
    paragraphs = article_parsed.find_all('p')
    article_content = ''
    for p in paragraphs:
        article_content += p.text
    sentencel = read_article(article_content)
    tokens = word_tokenize(article_content)
    nltk.download("stopwords")
    stop_words = stopwords.words('english')
    from string import punctuation
    punctuation = punctuation + '\n'
    word_frequencies = {}
    for word in tokens:
        if word.lower() not in stop_words:
            if word.lower() not in punctuation:
                if word not in word_frequencies.keys():
                    word_frequencies[word] = 1
                else:
                    word_frequencies[word] += 1
    max_frequency = max(word_frequencies.values())
    for word in word_frequencies.keys():
        word_frequencies[word] = word_frequencies[word]/max_frequency
    sent_token = sent_tokenize(article_content)
    sentence_scores = {}
    for sent in sent_token:
        sentence = sent.split(" ")
        for word in sentence:
            if word.lower() in word_frequencies.keys():
                if sent not in sentence_scores.keys():
                    sentence_scores[sent] = word_frequencies[word.lower()]
                else:
                    sentence_scores[sent] += word_frequencies[word.lower()]
    from heapq import nlargest
    select_length = int(len(sent_token)*0.3)
    summary = nlargest(select_length, sentence_scores, key = sentence_scores.get)
    final_summary = [word for word in summary]
    summary = ' '.join(final_summary)
    summaryl = read_article(summary)
    return summary,len(sentencel),len(summaryl)


""""
Write a Python program named can_sizes.py that computes and prints the storage efficiency for each of the following 12 steel can sizes. Then visually examine the output and answer this question, "Which can size has the highest storage efficiency?"

name	       radius   Height    Cost per Can
 centimeter  (centimeters)   (U.S. dollars)
#1 Picnic	    6.83	10.16	$0.28
#1 Tall	        7.78	11.91	$0.43
#2	            8.73	11.59	$0.45
#2.5	        10.32	11.91	$0.61
#3 Cylinder	    10.79	17.78	$0.86
#5	            13.02	14.29	$0.83
#6Z	            5.40	8.89	$0.22
#8Z short	    6.83	7.62	$0.26
#10	            15.72	17.78	$1.53
#211	        6.83	12.38	$0.34
#300	        7.62	11.27	$0.38
#303	        8.10	11.11	$0.42

Your program must compute the volume of all 12 can sizes.
Your program must compute the surface area of all 12 can sizes.
Your program must compute and print the storage efficiency of all 12 can sizes.
"""

import math

def main():

    can_sizes = [
        ["#1 Picnic", 6.83, 10.16, 0.28],
        ["#1 Tall", 7.78, 11.91, 0.43],
        ["#2", 8.73, 11.59, 0.45],
        ["#2.5", 10.32, 11.91, 0.61],
        ["#3 Cylinder", 10.79, 17.78, 0.86],
        ["#5", 13.02, 14.29, 0.83],
        ["#6Z", 5.40, 8.89, 0.22],
        ["#8Z Short", 6.83, 7.62, 0.26],
        ["#10", 15.72, 17.78, 1.53],
        ["#211", 6.83, 12.38, 0.38],
        ["#300", 7.62, 11.27, 0.38],
        ["#303", 8.10, 11.11, 0.42]
    ]

    storage_eff_max = 0
    storage_eff_can = ""
    cost_eff_max = 0
    cost_eff_can = ""

    for i in can_sizes:
        can = i[0]
        radius = i[1]
        height = i[2]
        cost_per_can = i[3]

        storage_eff = compute_storage_efficiency(radius, height)
        cost_effciency = compute_cost_efficiency(radius, height, cost_per_can)
        print(f"{can} {storage_eff:.1f} {cost_effciency:.0f}")

        if storage_eff_max < storage_eff:
            storage_eff_can = can
            storage_eff_max = storage_eff

        if cost_eff_max < cost_effciency:
            cost_eff_can = can
            cost_eff_max = cost_effciency

    print(f"The most efficient with storage is {storage_eff_can} at {storage_eff_max:.1f}")
    print(f"The most efficient with cost is {cost_eff_can} at {cost_eff_max:.0f}.")
    pass

def compute_volume(radius, height):
    volume = math.pi * radius ** 2 * height
    return volume

def compute_surface_area(radius, height):
    #surface_area = 2 * math.pi * (radius + height)
    surface_area = 2 * math.pi * radius * height + 2 * math.pi * radius ** 2
    return surface_area

def compute_storage_efficiency(radius, height):
    volume = compute_volume(radius, height)
    surface_area = compute_surface_area(radius, height)
    return volume / surface_area

def compute_cost_efficiency(radius, height, cost_per_can):
    return compute_volume(radius, height) / cost_per_can

main()


import errno
import logging
import os
import subprocess
import re
import shutil
import socket
import tempfile

from . import qmp

LOG = logging.getLogger(__name__)

# Mapping host architecture to any additional architectures it can
# support which often includes its 32 bit cousin.
ADDITIONAL_ARCHES = {
    "x86_64" : "i386",
    "aarch64" : "armhf"
}

def kvm_available(target_arch=None):
    host_arch = os.uname()[4]
    if target_arch and target_arch != host_arch:
        if target_arch != ADDITIONAL_ARCHES.get(host_arch):
            return False
    return os.access("/dev/kvm", os.R_OK | os.W_OK)

#: Maps machine types to the preferred console device types
CONSOLE_DEV_TYPES = {
    r'^clipper$': 'isa-serial',
    r'^malta': 'isa-serial',
    r'^(pc.*|q35.*|isapc)$': 'isa-serial',
    r'^(40p|powernv|prep)$': 'isa-serial',
    r'^pseries.*': 'spapr-vty',
    r'^s390-ccw-virtio.*': 'sclpconsole',
    }

class QEMUMachineError(Exception):
    """
    Exception called when an error in QEMUMachine happens.
    """

class QEMUMachineAddDeviceError(QEMUMachineError):
    """
    Exception raised when a request to add a device can not be fulfilled

    The failures are caused by limitations, lack of information or conflicting
    requests on the QEMUMachine methods.  This exception does not represent
    failures reported by the QEMU binary itself.
    """

class MonitorResponseError(qmp.QMPError):
    """
    Represents erroneous QMP monitor reply
    """
    def __init__(self, reply):
        try:
            desc = reply["error"]["desc"]
        except KeyError:
            desc = reply
        super(MonitorResponseError, self).__init__(desc)
        self.reply = reply

class QEMUMachine(object):
    """
    A QEMU VM

    Use this object as a context manager to ensure the QEMU process terminates::

        with VM(binary) as vm:
            ...
        # vm is guaranteed to be shut down here
    """

    def __init__(self, binary, args=None, wrapper=None, name=None,
                 test_dir="/var/tmp", monitor_address=None,
                 socket_scm_helper=None):
        '''
        Initialize a QEMUMachine

        @param binary: path to the qemu binary
        @param args: list of extra arguments
        @param wrapper: list of arguments used as prefix to qemu binary
        @param name: prefix for socket and log file names (default: qemu-PID)
        @param test_dir: where to create socket and log file
        @param monitor_address: address for QMP monitor
        @param socket_scm_helper: helper program, required for send_fd_scm()
        @note: Qemu process is not started until launch() is used.
        '''
        if args is None:
            args = []
        if wrapper is None:
            wrapper = []
        if name is None:
            name = "qemu-%d" % os.getpid()
        self._name = name
        self._monitor_address = monitor_address
        self._vm_monitor = None
        self._qemu_log_path = None
        self._qemu_log_file = None
        self._popen = None
        self._binary = binary
        self._args = list(args)     # Force copy args in case we modify them
        self._wrapper = wrapper
        self._events = []
        self._iolog = None
        self._socket_scm_helper = socket_scm_helper
        self._qmp = None
        self._qemu_full_args = None
        self._test_dir = test_dir
        self._temp_dir = None
        self._launched = False
        self._machine = None
        self._console_device_type = None
        self._console_address = None
        self._console_socket = None

        # just in case logging wasn't configured by the main script:
        logging.basicConfig()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.shutdown()
        return False

    # This can be used to add an unused monitor instance.
    def add_monitor_null(self):
        self._args.append('-monitor')
        self._args.append('null')

    def add_fd(self, fd, fdset, opaque, opts=''):
        """
        Pass a file descriptor to the VM
        """
        options = ['fd=%d' % fd,
                   'set=%d' % fdset,
                   'opaque=%s' % opaque]
        if opts:
            options.append(opts)

        # This did not exist before 3.4, but since then it is
        # mandatory for our purpose
        if hasattr(os, 'set_inheritable'):
            os.set_inheritable(fd, True)

        self._args.append('-add-fd')
        self._args.append(','.join(options))
        return self

    # Exactly one of fd and file_path must be given.
    # (If it is file_path, the helper will open that file and pass its
    # own fd)
    def send_fd_scm(self, fd=None, file_path=None):
        # In iotest.py, the qmp should always use unix socket.
        assert self._qmp.is_scm_available()
        if self._socket_scm_helper is None:
            raise QEMUMachineError("No path to socket_scm_helper set")
        if not os.path.exists(self._socket_scm_helper):
            raise QEMUMachineError("%s does not exist" %
                                   self._socket_scm_helper)

        # This did not exist before 3.4, but since then it is
        # mandatory for our purpose
        if hasattr(os, 'set_inheritable'):
            os.set_inheritable(self._qmp.get_sock_fd(), True)
            if fd is not None:
                os.set_inheritable(fd, True)

        fd_param = ["%s" % self._socket_scm_helper,
                    "%d" % self._qmp.get_sock_fd()]

        if file_path is not None:
            assert fd is None
            fd_param.append(file_path)
        else:
            assert fd is not None
            fd_param.append(str(fd))

        devnull = open(os.path.devnull, 'rb')
        proc = subprocess.Popen(fd_param, stdin=devnull, stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT, close_fds=False)
        output = proc.communicate()[0]
        if output:
            LOG.debug(output)

        return proc.returncode

    @staticmethod
    def _remove_if_exists(path):
        """
        Remove file object at path if it exists
        """
        try:
            os.remove(path)
        except OSError as exception:
            if exception.errno == errno.ENOENT:
                return
            raise

    def is_running(self):
        return self._popen is not None and self._popen.poll() is None

    def exitcode(self):
        if self._popen is None:
            return None
        return self._popen.poll()

    def get_pid(self):
        if not self.is_running():
            return None
        return self._popen.pid

    def _load_io_log(self):
        if self._qemu_log_path is not None:
            with open(self._qemu_log_path, "r") as iolog:
                self._iolog = iolog.read()

    def _base_args(self):
        if isinstance(self._monitor_address, tuple):
            moncdev = "socket,id=mon,host=%s,port=%s" % (
                self._monitor_address[0],
                self._monitor_address[1])
        else:
            moncdev = 'socket,id=mon,path=%s' % self._vm_monitor
        args = ['-chardev', moncdev,
                '-mon', 'chardev=mon,mode=control',
                '-display', 'none', '-vga', 'none']
        if self._machine is not None:
            args.extend(['-machine', self._machine])
        if self._console_device_type is not None:
            self._console_address = os.path.join(self._temp_dir,
                                                 self._name + "-console.sock")
            chardev = ('socket,id=console,path=%s,server,nowait' %
                       self._console_address)
            device = '%s,chardev=console' % self._console_device_type
            args.extend(['-chardev', chardev, '-device', device])
        return args

    def _pre_launch(self):
        self._temp_dir = tempfile.mkdtemp(dir=self._test_dir)
        if self._monitor_address is not None:
            self._vm_monitor = self._monitor_address
        else:
            self._vm_monitor = os.path.join(self._temp_dir,
                                            self._name + "-monitor.sock")
        self._qemu_log_path = os.path.join(self._temp_dir, self._name + ".log")
        self._qemu_log_file = open(self._qemu_log_path, 'wb')

        self._qmp = qmp.QEMUMonitorProtocol(self._vm_monitor,
                                            server=True)

    def _post_launch(self):
        self._qmp.accept()

    def _post_shutdown(self):
        if self._qemu_log_file is not None:
            self._qemu_log_file.close()
            self._qemu_log_file = None

        self._qemu_log_path = None

        if self._console_socket is not None:
            self._console_socket.close()
            self._console_socket = None

        if self._temp_dir is not None:
            shutil.rmtree(self._temp_dir)
            self._temp_dir = None

    def launch(self):
        """
        Launch the VM and make sure we cleanup and expose the
        command line/output in case of exception
        """

        if self._launched:
            raise QEMUMachineError('VM already launched')

        self._iolog = None
        self._qemu_full_args = None
        try:
            self._launch()
            self._launched = True
        except:
            self.shutdown()

            LOG.debug('Error launching VM')
            if self._qemu_full_args:
                LOG.debug('Command: %r', ' '.join(self._qemu_full_args))
            if self._iolog:
                LOG.debug('Output: %r', self._iolog)
            raise

    def _launch(self):
        """
        Launch the VM and establish a QMP connection
        """
        devnull = open(os.path.devnull, 'rb')
        self._pre_launch()
        self._qemu_full_args = (self._wrapper + [self._binary] +
                                self._base_args() + self._args)
        LOG.debug('VM launch command: %r', ' '.join(self._qemu_full_args))
        self._popen = subprocess.Popen(self._qemu_full_args,
                                       stdin=devnull,
                                       stdout=self._qemu_log_file,
                                       stderr=subprocess.STDOUT,
                                       shell=False,
                                       close_fds=False)
        self._post_launch()

    def wait(self):
        """
        Wait for the VM to power off
        """
        self._popen.wait()
        self._qmp.close()
        self._load_io_log()
        self._post_shutdown()

    def shutdown(self):
        """
        Terminate the VM and clean up
        """
        if self.is_running():
            try:
                self._qmp.cmd('quit')
                self._qmp.close()
            except:
                self._popen.kill()
            self._popen.wait()

        self._load_io_log()
        self._post_shutdown()

        exitcode = self.exitcode()
        if exitcode is not None and exitcode < 0:
            msg = 'qemu received signal %i: %s'
            if self._qemu_full_args:
                command = ' '.join(self._qemu_full_args)
            else:
                command = ''
            LOG.warn(msg, -exitcode, command)

        self._launched = False

    def qmp(self, cmd, conv_keys=True, **args):
        """
        Invoke a QMP command and return the response dict
        """
        qmp_args = dict()
        for key, value in args.items():
            if conv_keys:
                qmp_args[key.replace('_', '-')] = value
            else:
                qmp_args[key] = value

        return self._qmp.cmd(cmd, args=qmp_args)

    def command(self, cmd, conv_keys=True, **args):
        """
        Invoke a QMP command.
        On success return the response dict.
        On failure raise an exception.
        """
        reply = self.qmp(cmd, conv_keys, **args)
        if reply is None:
            raise qmp.QMPError("Monitor is closed")
        if "error" in reply:
            raise MonitorResponseError(reply)
        return reply["return"]

    def get_qmp_event(self, wait=False):
        """
        Poll for one queued QMP events and return it
        """
        if len(self._events) > 0:
            return self._events.pop(0)
        return self._qmp.pull_event(wait=wait)

    def get_qmp_events(self, wait=False):
        """
        Poll for queued QMP events and return a list of dicts
        """
        events = self._qmp.get_events(wait=wait)
        events.extend(self._events)
        del self._events[:]
        self._qmp.clear_events()
        return events

    def event_wait(self, name, timeout=60.0, match=None):
        """
        Wait for specified timeout on named event in QMP; optionally filter
        results by match.

        The 'match' is checked to be a recursive subset of the 'event'; skips
        branch processing on match's value None
           {"foo": {"bar": 1}} matches {"foo": None}
           {"foo": {"bar": 1}} does not matches {"foo": {"baz": None}}
        """
        def event_match(event, match=None):
            if match is None:
                return True

            for key in match:
                if key in event:
                    if isinstance(event[key], dict):
                        if not event_match(event[key], match[key]):
                            return False
                    elif event[key] != match[key]:
                        return False
                else:
                    return False

            return True

        # Search cached events
        for event in self._events:
            if (event['event'] == name) and event_match(event, match):
                self._events.remove(event)
                return event

        # Poll for new events
        while True:
            event = self._qmp.pull_event(wait=timeout)
            if (event['event'] == name) and event_match(event, match):
                return event
            self._events.append(event)

        return None

    def get_log(self):
        """
        After self.shutdown or failed qemu execution, this returns the output
        of the qemu process.
        """
        return self._iolog

    def add_args(self, *args):
        """
        Adds to the list of extra arguments to be given to the QEMU binary
        """
        self._args.extend(args)

    def set_machine(self, machine_type):
        """
        Sets the machine type

        If set, the machine type will be added to the base arguments
        of the resulting QEMU command line.
        """
        self._machine = machine_type

    def set_console(self, device_type=None):
        """
        Sets the device type for a console device

        If set, the console device and a backing character device will
        be added to the base arguments of the resulting QEMU command
        line.

        This is a convenience method that will either use the provided
        device type, of if not given, it will used the device type set
        on CONSOLE_DEV_TYPES.

        The actual setting of command line arguments will be be done at
        machine launch time, as it depends on the temporary directory
        to be created.

        @param device_type: the device type, such as "isa-serial"
        @raises: QEMUMachineAddDeviceError if the device type is not given
                 and can not be determined.
        """
        if device_type is None:
            if self._machine is None:
                raise QEMUMachineAddDeviceError("Can not add a console device:"
                                                " QEMU instance without a "
                                                "defined machine type")
            for regex, device in CONSOLE_DEV_TYPES.items():
                if re.match(regex, self._machine):
                    device_type = device
                    break
            if device_type is None:
                raise QEMUMachineAddDeviceError("Can not add a console device:"
                                                " no matching console device "
                                                "type definition")
        self._console_device_type = device_type

    @property
    def console_socket(self):
        """
        Returns a socket connected to the console
        """
        if self._console_socket is None:
            self._console_socket = socket.socket(socket.AF_UNIX,
                                                 socket.SOCK_STREAM)
            self._console_socket.connect(self._console_address)
        return self._console_socket


from django.shortcuts import render
from .models import Post, Contact, Social, WebElement, Soupiska
from .forms import NewUserForm
from django.contrib.auth import login
from django.contrib import messages

social = Social.objects
webelement = WebElement.objects
post = Post.objects.order_by("-pub_date")

# co všechno se má odeslat z databáze na stránku a podle jakého templatu má stránka vypadat

def IndexView(response):
    return render(
        response,
        "website/index.php",
        {"post": post, "social": social, "webelement": webelement},
    )

def ContactView(response):
    contacts = Contact.objects
    return render(
        response,
        "website/contacts.php",
        {"contacts": contacts, "social": social, "webelement": webelement},
    )

def GroupView(response, group):
    return render(
        response,
        "website/group.php",
        {"group": group, "post": post, "social": social, "webelement": webelement},
    )

def AboutUsView(response):
    return render(
        response,
        "website/about.php",
        {"social": social, "webelement": webelement},
    )

def SoupiskaView(response, group):
    soupiska = Soupiska.objects
    return render(
        response,
        "website/soupiska.php",
        {
            "group": group,
            "soupiska": soupiska,
            "social": social,
            "webelement": webelement,
        },
    )

def SignUpView(response):
    if response.method == "POST":
        form = NewUserForm(response.POST)
        if form.is_valid():
            user = form.save()
            login(response, user)
            messages.success(response, "Registration successful.")
            return render(
                response,
                "website/index.php",
                {"post": post, "social": social, "webelement": webelement},
            )
        messages.error(response, "Unsuccessful registration. Invalid information.")
    form = NewUserForm()
    return render(
        response,
        "website/signup.php",
        {"register_form": form, "social": social, "webelement": webelement},
    )


"""
Definition of Base Run Handler
"""

from abc import abstractmethod
from io import BytesIO
from os import environ as env_vars
from os.path import exists
from subprocess import check_call as run_shell_command
from zipfile import ZipFile

from mlflow.tracking import MlflowClient
from shared.logger.job_lifecycle_manager import JobLifecycleManager
from shared.models.mlflow_models import SqlArtifact

from ..base_handler import BaseHandler

__author__: str = "Splice Machine, Inc."
__copyright__: str = "Copyright 2019, Splice Machine Inc. All Rights Reserved"
__credits__: list = ["Amrit Baveja"]

__license__: str = "Proprietary"
__version__: str = "2.0"
__maintainer__: str = "Amrit Baveja"
__email__: str = "abaveja@splicemachine.com"

DOWNLOAD_PATH: str = f'{env_vars["WORKER_HOME"]}/pmml'

class BaseDeploymentHandler(BaseHandler):
    """
    Base class for run handlers--
    handlers that execute jobs (AWS Deployment etc.)
    """

    def __init__(self, task_id: int) -> None:
        """
        :param task_id: (int) id of the task to execute
        """
        BaseHandler.__init__(self, task_id)
        self.downloaded_model_path: str = DOWNLOAD_PATH + str(
            task_id)  # So when we temporarily download the model we don't overwrite other models
        self.mlflow_run: object = None
        self.artifact = None
        self.artifact_buffer: bytearray or None = None

    def retrieve_run_from_mlflow(self) -> None:
        """
        Retrieve the current run from mlflow tracking server
        """
        self.logger.info("Retrieving Run from MLFlow Tracking Server...", send_db=True)
        client: MlflowClient = MlflowClient(tracking_uri=env_vars['MLFLOW_URL'])
        try:
            self.mlflow_run: object = client.get_run(self.task.parsed_payload['run_id'].strip())
        except Exception:
            raise Exception(
                "Error: The Run associated with the ID specified could not be retrieved"
            )

    def _retrieve_model_binary_stream_from_db(self) -> None:
        """
        Use SQLAlchemy to retrieve the model artifact
        from Database with the specified path
        and associated Run UUID
        """
        self.logger.info("Reading Model Artifact Stream from Splice Machine", send_db=True)
        run_id: str = self.mlflow_run.info.run_uuid

        self.logger.info(f"Extracting Model from DB with Name: {self.model_dir}", send_db=True)
        try:
            self.artifact = self.Session.query(SqlArtifact) \
                .filter_by(name=self.model_dir) \
                .filter_by(run_uuid=run_id).one()

        except IndexError:
            self.logger.exception(
                f"No artifact could be found in database with name {self.model_dir} and run_id "
                f"{run_id}", send_db=True
            )
            raise Exception("Model with the specified Run ID and Name could not be found!")

    def _deserialize_artifact_stream(self) -> None:
        """
        Take the BLOB Retrieved from the database.py,
        convert it into a model,
        and then serialize it to the disk for deployment
        """
        self.logger.info("Decoding Model Artifact Binary Stream for Deployment", send_db=True)

        try:
            if exists(self.downloaded_model_path):
                run_shell_command(('rm', '-Rf', self.downloaded_model_path))

            artifact_buffer = BytesIO()
            artifact_buffer.write(self.artifact.binary)
            artifact_buffer.seek(0)
            self.logger.info("Decompressing Model Artifact", send_db=True)
            ZipFile(artifact_buffer).extractall(path=self.downloaded_model_path)

        except KeyError as e:
            self.logger.exception("Unable to find the specified file extension handler", send_db=True)
            raise Exception(f"Unable to find the specified fix extension {self.artifact.file_extension}")

    def _cleanup(self) -> None:
        """
        Cleanup after the model is deployed
        """
        self.logger.info("Cleaning up deployment", send_db=True)
        temp_glob: str = "/tmp/tmp*"  # remove all temp files generated by MLFlow

        run_shell_command(('rm', '-Rf', self.downloaded_model_path))
        run_shell_command(('rm', '-Rf', temp_glob))  # cleanup azure deployment files

    @abstractmethod
    def execute(self) -> None:
        """
        Subclass specific run functionality
        """
        pass

    def exception_handler(self, exc: Exception):
        """
        Function that runs if there is an error
        executing a job
        :param exc: the exception thrown
        """
        self.logger.error(f"Running Exception Callback because of encountered: '{exc}'", send_db=True)

    def _handle(self) -> None:
        """
        We add the MLFlow Run URL as a parameter
        that can be displayed in a GUI for all
        of these Jobs.
        """
        try:
            self.retrieve_run_from_mlflow()
            run_url: str = f"#/experiments/{self.mlflow_run.info.experiment_id}/" \
                           f"runs/{self.mlflow_run.info.run_uuid}"

            self.logger.info(f"Retrieved MLFlow Run", send_db=True)

            self.model_dir: str = self.mlflow_run.data.tags.get('splice.model_name')
            if not self.model_dir:
                self.logger.exception(f"No model was found for run {self.mlflow_run.info.run_uuid}. Ensure that"
                                      f"the splice.model_name tag is available for this model", send_db=True)
                raise Exception(f'No model was found for run {self.mlflow_run.info.run_uuid}')

            # populates a link to the associated Mlflow run that opens in a new tab.
            self.logger.info("Updating MLFlow Run for the UI", send_db=True)
            self.task.mlflow_url = f"Link to Mlflow Run"

            # WHEN UPDATING JOBS, WE *MUST* USE THE MANAGER SESSION, NOT THE RUN SESSION
            # TO PREVENT EARLY COMMITTING OF THE DDL TRANSACTIONS WHEN WE UPDATE STATUS/LOGS
            self.manager.Session.add(self.task)
            self.manager.Session.commit()

            self.execute()
            self._cleanup()
        except Exception as e:
            self.exception_handler(exc=e)  # can be overriden by subclasses
            self._cleanup()  # always run cleanup, regardless of success or failure
            raise e


'''
1. Use a string concatenation to join the text and print the result.
first_part = “The + operator joins all the”
second_part = “operand strings and returns”
third_part = “a concatenated string.” '''

first_part = "The + operator joins all the"
second_part = "operand strings and returns"
third_part = "a concatenated string."

result = first_part + " " + second_part + " " + third_part
print(result)

'''
2. Get “SDET” characters from the text variable (Hint: use the optional argument of slicing)
text = "Sally Dolly Ellie Tired"
'''
text = "Sally Dolly Ellie Tired"
new_text = text.split()
print(new_text[0][0]+new_text[1][0] + new_text[2][0] + new_text[3][0])

'''
3. Return the string without any whitespace at the beginning or the end.
description = "   The method removes any whitespace from the beginning or the end       "
'''
description = "   The method removes any whitespace from the beginning or the end       "

result = description.strip()
print(result)

'''
4. Replace the character “.” with a “!”
method_description = The method replaces a string with another string.
'''
method_description ="The method replaces a string with another string."
print(method_description.replace(".","!"))

'''
5. Write a Python program to calculate the area of a trapezoid (սեղան). Note: A trapezoid is a quadrilateral (քառանկյուն)
with two sides parallel. An isosceles trapezoid (հավասարասրուն սեղան) is a trapezoid in which the base angles are equal so.
Test data: Height: 5
                   Base, first value: 5
                   Base, second value: 6
                Expected Output: Area is: 27.5

'''
first_base = 5
second_base = 6
height = 5
area = (first_base + second_base)/2 * height
print(area)

'''
6. Find the length of the following strings and print the sentence using formatting.
“The variable A has ___ length, the variable C has ___ length and the variable B has ___ length.”
A = “Geography”
B = “Biology”
C = “Mathematics”

'''
A = "Geography"
B = "Biology"
C = "Mathematics"

length_A = len(A)
length_B = len(B)
length_C = len(C)
text = "The variable A has {} length, the variable C has {} length and the variable B has {} length."
print(text.format(length_A,length_C,length_B))


import sys

from pyspark import SparkConf, SparkContext
from pyspark.sql import SQLContext
import pyspark.sql.functions as F

from users_datamart import distance

def main():

    date = sys.argv[1]
    events_base_path = sys.argv[2]
    geo_base_path = sys.argv[3]
    second_table_save = sys.argv[4]

    conf = SparkConf().setAppName(f"ZonesDatamart-{date}")
    sc = SparkContext(conf=conf)
    sql = SQLContext(sc)

    date_pivot=F.to_date(F.lit(date), "yyyy-MM-dd")
    def count_event_zone(df,event,slice):
        return df\
            .select(F.col('id').alias('zone_id'),F.col('event_type'))\
            .filter(F.col('event_type')==event)\
            .groupBy('zone_id')\
            .agg(F.count('*').alias(f'{slice}_{event}'))

    def count_registration(df, message, slice, date):
        if slice == 'month':
            messages_without_pivot = message.select('event.message_from').where(
                (F.month("date") < F.month(date_pivot)) & (F.year("date") <= F.year(date_pivot)))
        elif slice == 'week':
            messages_without_pivot = message.select('event.message_from').where(
                (F.weekofyear("date") < F.weekofyear(date_pivot)) & (F.year("date") <= F.year(date_pivot)))

        return df.select(F.col('event.message_from'),F.col('id').alias('zone_id'))\
                .join(messages_without_pivot, 'message_from', 'left_anti') \
                .distinct() \
                .groupBy('zone_id')\
                .agg(F.count('*').alias(f'{slice}_user'))

    date_pivot=F.to_date(F.lit(date), "yyyy-MM-dd")

    message = sql.read.parquet(events_base_path) \
                .where(F.col('date') <= date_pivot)\
                .withColumn('lat1', F.radians(F.col('lat'))) \
                .withColumn('lon1', F.radians(F.col('lon'))) \
                .drop('lat','lon')

    event_week = sql.read.parquet(events_base_path) \
        .where((F.col('date') <= F.lit(date_pivot)) &
            (F.weekofyear(F.col('date')) == F.weekofyear(date_pivot)) &
            (F.year(F.col('date')) == F.year(date_pivot))) \
        .withColumn('lat1', F.radians(F.col('lat'))) \
        .withColumn('lon1', F.radians(F.col('lon'))) \
        .drop('lat','lon')

    event_month = sql.read.parquet(events_base_path) \
                .where((F.col('date') <= F.lit(date_pivot)) &
                    (F.month(F.col('date')) == F.month(date_pivot)) &
                    (F.year(F.col('date')) == F.year(date_pivot)))\
                .withColumn('lat1', F.radians(F.col('lat'))) \
                .withColumn('lon1', F.radians(F.col('lon'))) \
                .drop('lat','lon')

    geo = sql.read.option("delimiter", ";").option("header", True).csv(geo_base_path) \
            .withColumn('lat2', F.radians(F.col('lat'))) \
            .withColumn('lon2', F.radians(F.col('lng'))) \
            .drop('lat', 'lng')

    event_week_city = distance(event_week, geo)
    event_month_city = distance(event_month, geo)

    count_event_week = count_event_zone(event_week_city, 'message', 'week') \
        .join(count_event_zone(event_week_city, 'reaction', 'week'), 'zone_id','full') \
        .join(count_event_zone(event_week_city, 'subscription', 'week'), 'zone_id','full') \
        .join(count_registration(event_week_city, message, 'week', date_pivot),'zone_id','full')

    count_event_month = count_event_zone(event_month_city, 'message', 'month').drop('user_id','event_type') \
        .join(count_event_zone(event_month_city, 'reaction', 'month'), 'zone_id','full') \
        .join(count_event_zone(event_month_city, 'subscription', 'month'), 'zone_id','full') \
        .join(count_registration(event_month_city, message, 'month', date_pivot),'zone_id','full')

    zones_datamart = geo.select(
        F.weekofyear(date_pivot).alias('week'),
        F.month(date_pivot).alias('month'),
        F.col('id').alias('zone_id'))\
        .join(count_event_week, 'zone_id', 'full')\
        .join(count_event_month, 'zone_id', 'full')

    zones_datamart.write.parquet(f"{second_table_save}/date={date}")

if __name__ == '__main__':
    main()


from django.urls import path

from . import views

app_name = "shifter_files"
urlpatterns = [
    path('', views.FileUploadView.as_view(), name='index'),
    path('files', views.FileListView.as_view(), name='myfiles'),
    path('files/<str:file_hex>', views.FileDetailView.as_view(),
         name='file-details'),
    path('download/<str:file_hex>', views.FileDownloadLandingView.as_view(),
         name='file-download-landing'),
    path('f/<str:file_hex>', views.FileDownloadView.as_view(),
         name='file-download'),
    path('files/<str:file_hex>/delete', views.FileDeleteView.as_view(),
         name='file-delete'),
]


from typing import Literal, Optional

from ._base import BaseWidget, TkWidget
from ._variables import Float

class ProgressBar(BaseWidget):
    _tcl_class = "ttk::progressbar"
    _keys = {
        "focusable": (bool, "takefocus"),
        "max": float,
        "mode": str,
        "orientation": (str, "orient"),
        "value": float,
        "variable": Float,
    }

    def __init__(
        self,
        parent: Optional[TkWidget] = None,
        focusable: Optional[bool] = None,
        max: Optional[int] = 100,
        mode: Optional[Literal["determinate", "indeterminate"]] = None,
        orientation: Optional[Literal["horizontal", "vertical"]] = None,
        value: Optional[int] = None,
        variable: Optional[Float] = None,
    ) -> None:
        BaseWidget.__init__(
            self,
            parent,
            maximum=max,
            mode=mode,
            orient=orientation,
            takefocus=focusable,
            value=value,
            variable=variable,
        )

    def _repr_details(self):
        return f"mode={self.mode!r}, max={self.max!r}, value={self.value!r}"

    def get(self) -> float:
        return self.value

    def set(self, value: float = 0) -> None:
        self.value = value

    def start(self, steps_per_second: int = 20) -> None:
        if steps_per_second > 1000:
            raise ValueError("error")
        interval = int(1000 / steps_per_second)
        self._tcl_call(None, self, "start", interval)

    def stop(self) -> None:
        self._tcl_call(None, self, "stop")

    def step(self, amount: int = 1) -> None:
        self._tcl_call(None, self, "step", amount)

    def __add__(self, other: int):
        self.set(self.get() + other)
        return self

    def __sub__(self, other: int):
        self.set(self.get() - other)
        return self


#!/usr/bin/python3
import sys
import csv
import operator

venue = ""

mapper = []
for line in sys.stdin:
	line = line.strip()
	venue, batsman, runs = line.split(';')

	mapper.append(venue+";"+batsman+";"+runs)

#print(mapper)

runs = dict()
balls = dict()
run_rate = dict()

stadiums = []

final = []

for line in mapper:
        l = line.split(";")
        #print(l)
        k = l[0] + ";" + l[1]
        if(k not in runs):
            runs[k] = int(l[2])
            balls[k] = 1
        else:
            runs[k] = runs[k] + int(l[2])
            balls[k] = balls[k] + 1

        if(l[0] not in stadiums):
            stadiums.append(l[0])

for y in balls:
    if(balls[y] >= 10):
        run_rate[y] = round((runs[y]*100)/balls[y], 2)

for x in stadiums:
    temp = []
    for z in run_rate:
        y = z.split(";")
        if(y[0] == x):
                temp.append(run_rate[z])
    if(len(temp) > 0):
        maximum = max(temp)
        players = []
        for z in run_rate:
            y = z.split(";")
            if(y[0] == x and run_rate[z] == maximum):
                players.append(z)
        if(len(players) == 1):
            final.append(players[0])
        else:
                m = 0
                player = ""
                for t in players:
                        if(runs[t] > m):
                                m = runs[t]
                                player = t
                final.append(player)

final = sorted(final)
final_1 = []
for x in final:
        y = x.split(";")
        final_1.append(y[0]+","+y[1])
for x in final_1:
        print(x)


'''

PROBLEM:

Given a string, rearrange it so that any two adjacent characters are not the same.
If such a reorganization of the characters is possible, output any possible valid
arrangement. Otherwise, return an empty string.

------------------------
PATTERN: TOP K ELEMENTS
------------------------

'''

# importing libraries
from collections import Counter
import heapq

def reorganize_string(input_string):

    output = [""] * len(input_string)
    counter = Counter(input_string)

    max_heap = [[-val, key] for key, val in counter.items()]
    heapq.heapify(max_heap)

    if len(input_string) % 2 == 0 and (-max_heap[0][0]) > len(input_string) // 2 :
        return ""
    elif (-max_heap[0][0]) > (len(input_string) // 2) + 1 :
        return ""

    i = 0
    previous = None
    while i < len(input_string) :

        if max_heap :

            freq, char = heapq.heappop(max_heap)

            output[i] = char

            i += 1
            freq += 1

            if previous :
                heapq.heappush(max_heap, previous)
                previous = None

            if i < len(input_string) and freq < 0 :
                previous = [freq,char]

        elif previous : return ""
        else : break

    return ''.join(output)


import re

from entiteiten.meetwaarde import Meetwaarde, convertlist2tags
from entiteiten.sensor import Schakelaar, BewegingSchakelaar, TemperatuurSensor, LichtSensor

class WoningGateway:

    def __init__(self):
        self.bridge = None

    def get_meetwaarden(self):
        meetwaarden = []
        if self.bridge is None:
            raise ModuleNotFoundError("Bridge device not set")
        meetwaarden.extend(self._get_meetwaarden_lichten())
        meetwaarden.extend(self._get_meetwaarden_sensoren())
        return meetwaarden

    def alarmeer_lichten_in_groep(self):
        if self.bridge is None:
            raise ModuleNotFoundError("Bridge device not set")
        lights2alert = []
        for licht in self.bridge.get_alle_lichten_in_alarmeergroep():
            lights2alert.append(licht)
        self.bridge.alert_lights(lights2alert)

    def _get_meetwaarden_lichten(self):
        meetwaarden = []
        for licht in self.bridge.get_alle_lichten():
            meetwaarden.append(Meetwaarde(eenheid='licht_aan', waarde=licht.aan,
                                          tags=convertlist2tags(set_naam_id(licht.naam, licht.unique_id))))
            meetwaarden.append(Meetwaarde(eenheid='bereikbaar', waarde=licht.bereikbaar,
                                          tags=convertlist2tags(set_naam_id(licht.naam, licht.unique_id))))
        return meetwaarden

    def _get_meetwaarden_sensoren(self):
        meetwaarden = []
        for sensor in self.bridge.get_alle_sensors():
            meetwaarden.append(Meetwaarde(eenheid='batterijpercentage', waarde=sensor.batterijpercentage,
                                          tags=convertlist2tags(set_naam_id(sensor.naam, sensor.unique_id))))
            meetwaarden.append(Meetwaarde(eenheid='bereikbaar', waarde=sensor.bereikbaar,
                                          tags=convertlist2tags(set_naam_id(sensor.naam, sensor.unique_id))))
            if isinstance(sensor, Schakelaar):
                meetwaarden.append(Meetwaarde(eenheid='knop_event', waarde=sensor.knop_event,
                                              tags=convertlist2tags(set_naam_id(sensor.naam, sensor.unique_id))))
            if isinstance(sensor, BewegingSchakelaar):
                meetwaarden.append(Meetwaarde(eenheid='aanwezigheid', waarde=sensor.beweging_gesignaleerd,
                                              tags=convertlist2tags(set_naam_id(sensor.naam, sensor.unique_id))))
            if isinstance(sensor, TemperatuurSensor):
                meetwaarden.append(Meetwaarde(eenheid='temperatuur_celsius', waarde=sensor.temperature_celsius,
                                              tags=convertlist2tags(set_naam_id(sensor.naam, sensor.unique_id))))
            if isinstance(sensor, LichtSensor):
                meetwaarden.append(Meetwaarde(eenheid='lichtwaarde_lux', waarde=sensor.lichtniveau_lux,
                                              tags=convertlist2tags(set_naam_id(sensor.naam, sensor.unique_id))))
        return meetwaarden

def non_alphanumeric_chars(inputvalue):
    output = re.sub(r'\W+', '', inputvalue)
    return output

def set_naam_id(naam, unique_id):
    return ["naam:" + naam, "id:" + non_alphanumeric_chars(unique_id)]


'''
Input: __init__(feature_size), eeg_features
Output: the noised data from gaussian layer
'''

import torch
from torch import nn

class MoGLayer(nn.Module):

    def __init__(self, noise_dim: tuple):
        super(MoGLayer, self).__init__()

        pre_std = torch.zeros(noise_dim)
        pre_std = torch.nn.init.uniform_(pre_std, -0.2, 0.2)
        self.std = nn.Parameter(pre_std, requires_grad=True)

        pre_mean = torch.zeros(noise_dim)
        pre_mean = torch.nn.init.uniform_(pre_mean, -1.0, 1.0)
        self.mean = nn.Parameter(pre_mean, requires_grad=True)

    def set_dev(self, DEV):
        self.dev = DEV

    def forward(self, noise):
        return self.mean.to(self.dev) + (self.std.to(self.dev) * noise.to(self.dev))


#%%
"""
    Transition Matrix with checkout,
    Random probability calulator for entrance,
    and function for getting the number of customer per minute.

    THANK YOU BEHZAD!!!
"""

import pandas as pd
import numpy as np

#%%
# loading the cleaned data that was built in EDA.ipynb file
final = pd.read_csv('../data/cleaned_up/clean_final.csv', index_col=0)
final
#%% [markdown]
### Building Transition Matrix
#%%
# adding next location column
final['next_location'] = final['location'].shift(-1)
# frequency table for number of customers in each state
final.groupby('location')['next_location'].value_counts().unstack()
# leaving the 'checkout' rows from location to be able to add the 'absorbing state' later on
df_1 = final[final['location'] != 'checkout'].copy()
# probability table without checkout in location
trans_without_checkout= pd.crosstab(df_1['location'], df_1['next_location'], normalize=0)
# Hardcoding the absorbing state into transition matrix
prob = np.array([1.0,0.0,0.0,0.0,0.0,
                0.138084,0.330109,0.186343,0.232072,0.113392,
                0.143430,0.326136,0.183015,0.232778,0.114641,
                0.127124,0.334015,0.173851,0.246696,0.118314,
                0.131730,0.329882,0.174737,0.239726,0.123925
                ]).reshape(5,5)
trans_matrix = pd.DataFrame(prob,columns=['checkout','dairy','drinks','fruit','spices'],
                index=['checkout','dairy','drinks','fruit','spices'])
trans_matrix

#%%
# random probability for entrance (for visualization purposes)

entrance = np.identity(1)

# Add a random drift term.  We can guarantee that the diagonal terms

entrance = entrance + np.random.uniform(low=0. , size=(1, 4))

# Lastly, divide by row-wise sum to normalize to 1.

ent_prob = entrance / entrance.sum(axis=1, keepdims=1)

ent_prob = ent_prob.reshape(4,)
ent_prob

#%%
# dataframe with the time and average number of daily customers entering the supermarket per minute
entrance_number = (round(
    final[final["section_order"] == "first"]
    .groupby(["time"])[["cust_id"]]
    .count()
    / 5, 0)
)
remaining_minutes = pd.DataFrame(data=np.zeros(9,),columns=['cust_id'],index=['21:51:00','21:52:00','21:53:00','21:54:00','21:55:00','21:56:00','21:57:00','21:58:00','21:59:00'])
entrance_number = pd.concat([entrance_number,remaining_minutes])
entrance_number
#%%
# def get_customer_number(time):

#     '''
#         Given the time in string format 'HH:MM:SS',
#         return the number of customer enter to the supermarket.
#     '''
#     for row, number in zip(entrance_number.index, entrance_number['cust_id']):
#         if row == time:
#             return(number)
#         else:
#             return('Supermarket is closed')


import numpy as np

#initialize - schedule function
def initialize(context):
    schedule_function(check_pairs,date_rules.every_day(),time_rules.market_close(minutes=60))

    context.aa = sid(45971)
    context.ual = sid(28051)

    context.long_on_spread = False
    context.shorting_spread = False

#check_pairs
def check_pairs(context,data):

    aa = context.aa
    ual = context.ual

    prices = data.history([aa,ual],'price',30,'1d')

    short_prices = prices.iloc[-1:]

    # SPREAD
    mavg_30 = np.mean(prices[aa] - prices[ual])
    std_30 = np.std(prices[aa] - prices[ual])

    mavg_1 = np.mean(short_prices[aa] - short_prices[ual])

    if std_30 > 0:
        zscore = (mavg_1 - mavg_30)/std_30

        if zscore > 1.0 and not context.shorting_spread:
            # SPREAD = AA - UAL
            # This implies that American Airlines is overvalued and its price will come down ,short the shares
            order_target_percent(aa,-0.5)
            order_target_percent(ual,0.5)
            context.shorting_spread = True
            context.long_on_spread = False

        elif zscore < 1.0 and not context.long_on_spread:
            # This implies that United Airlines is overvalued ,short it
            order_target_percent(ual,-0.5)
            order_target_percent(aa,0.5)
            context.shorting_spread = False
            context.long_on_spread = True

        elif abs(zscore) < 0.1:
            order_target_percent(aa,0)
            order_target_percent(ual,0)
            context.shorting_spread = False
            context.long_on_spread = True

        record(z_score = zscore)


import collections, math
def solution(fees, records):
    cars_park_record, cars_park_time = collections.defaultdict(list), collections.defaultdict(int)
    for record in records:
        time, car_num, _ = record.split()
        cars_park_record[car_num].append(time)

    for car_num in cars_park_record:
        times = cars_park_record[car_num]
        for i in range((len(times) + 1) // 2):
            in_hour, in_minute = map(int, times[i * 2].split(':'))
            print(in_hour, in_minute)
            if i * 2 + 1 >= len(times):
                out_hour, out_minute = 23, 59
            else:
                out_hour, out_minute = map(int, times[i * 2 + 1].split(':'))
            time = (out_hour - in_hour) * 60 + (out_minute - in_minute)
            cars_park_time[car_num] += time

    answer = []
    for car_num in sorted(cars_park_time):
        time = cars_park_time[car_num]
        if time <= fees[0]:
            answer.append(fees[1])
        else:
            fee = fees[1] + math.ceil((time - fees[0]) / fees[2]) * fees[3]
            answer.append(fee)

    return answer

주차 요금 계산_HW.py


import numpy as np
from matplotlib import pyplot as plt
import os
from . import settings

plt.rcParams['font.sans-serif'] = ['Microsoft YaHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.rcParams['figure.dpi'] = 300  # 分辨率
plt.rcParams['figure.figsize'] = (5.771, 5.771 * 0.618)  # 图片大小，单位是inches
np.set_printoptions(edgeitems=30, linewidth=200000)  # 输出不换行
np.set_printoptions(precision=2, suppress=True)  # 精度，不使用科学计数
np.set_printoptions(threshold=np.inf)  # 过多的行，不会变成省略号

def check_and_set_ticks(axes, xticks, yticks):
    xticks is not None and axes.xaxis.set_ticks(xticks)
    xticks is not None and axes.xaxis.limit_range_for_scale(min(xticks), max(xticks))
    yticks is not None and axes.yaxis.set_ticks(yticks)
    yticks is not None and axes.yaxis.limit_range_for_scale(min(yticks), max(yticks))

def plot_line(
        x, y, *args, figure: plt.Figure = None, axes: plt.Axes = None,
        xticks=None, yticks=None, xlabel=None, ylabel=None, **kwargs):
    figure: plt.Figure = plt.gcf() if figure is None else figure
    axes: plt.Axes = plt.gca() if axes is None else axes

    # 设置刻度
    check_and_set_ticks(axes, xticks, yticks)

    xlabel is None or axes.set_xlabel(xlabel)
    ylabel is None or axes.set_ylabel(ylabel)

    axes.plot(x, y, *args, **kwargs)
    return figure

def plot_surface(
        data, show_colorbar=True, extent=None, vmin=None, vmax=None, xticks=None, yticks=None,
        axes: plt.Axes = None, figure: plt.Figure = None, reverse=True):
    assert len(set(map(len, data))) == 1
    # 对数据进行倒序，以保证初值在最下边
    if reverse:
        data = data[::-1]
    # 获取图像和坐标轴对象
    figure = plt.figure() if figure is None else figure
    axes = plt.axes() if axes is None else axes
    # 计算最大值和最小值
    vmin = vmin is None and np.min(np.min(data)) or vmin
    vmax = vmax is None and np.max(np.max(data)) or vmax
    # 设置刻度
    check_and_set_ticks(axes, xticks, yticks)
    # 计算图像范围
    if not extent:
        if xticks is not None and yticks is not None:
            extent = (min(xticks), max(xticks), min(yticks), max(yticks))
        else:
            extent = (-1, 1, -1, 1)
    # 绘制二维图
    image = axes.imshow(
        data, vmin=vmin, vmax=vmax, interpolation='nearest',
        cmap=plt.cm.jet, extent=extent, aspect='auto')
    # 显示彩虹条图例
    if show_colorbar:
        plt.colorbar(image, ax=axes)

    return figure

def get_figure_path(file_name):
    path = os.path.join(settings.FIGURE_PATH, file_name)
    dir_name = os.path.dirname(path)
    os.path.exists(dir_name) or os.makedirs(dir_name)
    return path


import time
import torch

def train_hebb(model, loader, device, measures=None, criterion=None):
    """
    Train only the hebbian blocks
    """
    t = time.time()
    loss_acc = (not model.is_hebbian()) and (criterion is not None)
    with torch.no_grad():
        for inputs, target in loader:
            # print(inputs.min(), inputs.max(), inputs.mean(), inputs.std())
            ## 1. forward propagation
            inputs = inputs.float().to(device)  # , non_blocking=True)
            output = model(inputs)

            # print(r"%s"%(time.time()-t))

            if loss_acc:
                target = target.to(device, non_blocking=True)

                ## 2. loss calculation
                loss = criterion(output, target)

                ## 3. Accuracy assessment
                predict = output.data.max(1)[1]
                acc = predict.eq(target.data).sum()
                # Save if measurement is wanted
                conv, r1 = model.convergence()
                measures.step(target.shape[0], loss.clone().detach().cpu(), acc.cpu(), conv, r1, model.get_lr())
            model.update()

    info = model.radius()
    convergence, R1 = model.convergence()
    return measures, model.get_lr(), info, convergence, R1

def train_unsup(model, loader, device,
                blocks=[]):  # fixed bug as optimizer is not used or pass in the only use it has in this repo currently
    """
    Unsupervised learning only works with hebbian learning
    """
    model.train(blocks=blocks)  # set unsup blocks to train mode
    _, lr, info, convergence, R1 = train_hebb(model, loader, device)
    return lr, info, convergence, R1


#!/usr/bin/env python
"""
Tests covering the parsing functions that read in light characteristics.
"""

import pytest

from light_character import light_character

@pytest.mark.parametrize(
    "test_input",
    [
        'F', 'Fl', 'LFl', 'Oc', 'Iso', 'Q'
    ]
)
def test_parse_pattern_simple(test_input):
    """
    Parse pattern returns the pattern name in lower case.
    If there are no explicit groups, there is an implicit single
    group of 1.
    """
    actual = light_character.parse_pattern(test_input)
    assert actual == (test_input.lower(), [1])

@pytest.mark.parametrize(
    "test_input, expected",
    [
        ('F.', ('f', [1])),
        ('Fl.(3+1)', ('fl', [3, 1])),
        ('L.Fl.(2)', ('lfl', [2])),
        ('Oc.(1+2+3)', ('oc', [1, 2, 3]))
    ]
)
def test_parse_pattern(test_input, expected):
    """
    Parse pattern returns the pattern name in lower case, filtered for dots.
    If there are explicit groups, they are also returned.
    """
    assert light_character.parse_pattern(test_input) == expected

def test_period_error():
    try:
        light_character.parse_period([])
        assert False
    except IndexError:
        assert True

@pytest.mark.parametrize(
    "fragments,expected",
    [
        (['xyz', '1'], 1000),
        (['xyz', '10s'], 10000),
        (['xyz', '15', 's'], 15000),
        (['xyz', '1.5s'], 1500)
    ]
)
def test_period(fragments, expected):
    """
    The period is the last part of the characteristic.
    It may or may not be marked with 's' for seconds.
    The output value is in milliseconds.
    """
    assert light_character.parse_period(fragments) == expected

@pytest.mark.parametrize(
    "fragments,expected",
    [
        (['R'], 'R'),
        (['W'], 'W'),
        (['G', '1s'], 'G'),
        (['Y'], 'Y'),
    ]
)
def test_colour_code(fragments, expected):
    assert light_character.get_colour_code(fragments) == (
        expected,
        fragments[1:]
    )

def test_colour_code_default():
    """
    A characteristic without an explicit colour is white
    :return:
    """
    assert light_character.get_colour_code(['1s']) == (
        'W',
        ['1s']
    )


import os
import sys
import traceback
import uuid
import time
import copy
from .requester import Requester
from .resources import Resources, Resource
from .writer import Writer
from .window import Window
from .asset import Asset
from .threads import Threader
from .pages import Pages, Page
from .stripper import Stripper
from urlparse import urlparse, urljoin
from threading import *

class Generic(object):
    pass

#TODO NEED TO TREAT DATA LIKE SCRIPTS and replace references

class Ripper(object):

    def __init__(self, logger=None, threads=4):
        self.logger = logger
        self.threads = threads
        self.stats = {}
        self.assets = []
        self.errors = []
        self.pages = []
        self.is_threading = False
        self.extension = ".html"
        self.totals = {"pages":1,"assets":0, "pages_down":0, "assets_down":0}
        self.lock = Lock()

    def rip(self,url,base, top_level_pages=True):
        self.url = url
        self.base = base
        self.index_file = os.path.join(base,"index" + self.extension)
        self.stats = {}
        self.assets = []
        self.pages = []

        index = self._get_page(self.url);
        self._update_totals("pages_down",1)

        if not index:
            raise ValueError('Could not access website. Is the URL correct?')

        self.pages = self._get_page_links(self.url,index)

        if top_level_pages:

            self._update_totals("pages",len(self.pages))

            for p in self.pages:
                if not p.exists:
                    if p.replace_reference:
                        content = self._get_page(p.url);
                        if not content:
                            content = "<html></html>"
                        else:
                            content = self._update_page_links(content,self.extension)
                            pages = self._get_page_links(self.url,content)
                            content = self._update_page_links(content,self.extension)
                            content = self._remove_page_links(content,pages)
                            content = self._remove_trackers(content)
                            p.downloaded = True

                        Writer.write(content,os.path.join(self.base,p.name + self.extension))
                    self.logger(self,p)
                    self._update_totals("pages_down",1)

            index = self._update_page_links(index,self.extension)
        else:
            index = self._remove_page_links(index,self.pages,False)

        index = self._remove_trackers(index)
        Writer.write(index,self.index_file)
        self.logger(self,Page(urlparse(self.url).path,self.url,"index",False))

    def _get_page(self,url,relative_assets=False):

        requester = Requester()
        page = requester.get_source(url)

        if page:

            content = page.text
            marker = str(uuid.uuid4())

            threader = False
            if not self.is_threading:
                threader = Threader(self.threads,self._log_asset)
                threader.start(True)
                self.is_threading = True

            resources = Resources(page)
            self._update_totals("assets",self._get_total_assets_to_download(resources))

            for r in resources:

                if threader:
                    threader.add((self._get_asset,{"resource" : r, "marker" : marker}))
                else:
                    asset = self._get_asset(r,marker)
                    self._log_asset(asset)

            if threader:
                threader.finish()
                if threader.errors:
                    self.errors += threader.errors

            return self._update_page_assets(content,marker,relative_assets)
        else:
            return False

    def _get_page_links(self,url,content):
        pages = []
        for p in Pages(url,content):
            if p.reference in map(lambda x: x.url, self.assets):
                p.replace_reference = False
            pages.append(p)
        return pages

    def _get_asset(self,resource,marker):
        requester = Requester()
        asset_exists = self._find_asset_by_reference(resource,marker)
        if asset_exists:
            return asset_exists
        else:
            asset = Asset(self.base,resource,marker)
            if asset.mime:
                x = requester.get_stream(asset.source.url) if asset.mime.stream else self._get_page(asset.source.url,False if asset.mime.category == "scripts" else True)
                if x:
                    Writer.write(x,asset.path)
                    asset.downloaded = True
            return asset

    def _find_asset_by_reference(self,resource,marker):
        find = self._check_asset_exists(resource)
        if find:
            asset = copy.deepcopy(find)
            asset.resource = resource
            asset.marker = marker
            asset.existing = True
            return asset
        else:
            return False

    def _check_asset_exists(self,resource):
        find = filter(lambda a: a.source.reference == resource.reference or a.source.url == resource.url,list(self.assets))
        if len(find) > 0:
            return find[0]
        else:
            return False

    def _log_asset(self,asset):
        if asset.downloaded:
            self._update_stats(asset.mime)
            if not asset.existing:
                self._update_totals("assets_down",1)
        self.assets.append(asset)
        self.logger(self,asset)

    def _update_page_assets(self,content,marker,relative_assets):
        for asset in self.assets:
            if asset.downloaded == True and asset.marker == marker:
                content = self._find_and_replace(content,asset.source.reference,asset.relative_url if relative_assets else asset.url)
        return content

    def _update_page_links(self,content,extension):
        for page in self.pages:
            if page.replace_reference:
                wrap = "{0}{1}{0}"
                content = self._find_and_replace(content,wrap.format('"',page.reference),wrap.format('"',page.name + extension))
                content = self._find_and_replace(content,wrap.format("'",page.reference),wrap.format("'",page.name + extension))
        return content

    def _remove_page_links(self,content,pages,check_pages=True):

        for page in pages:
            if len(filter(lambda p: p.name == page.name,self.pages)) == 0 or not check_pages:
                if page.replace_reference:
                    wrap = "{0}{1}{0}"
                    content = self._find_and_replace(content,wrap.format('"',page.reference),wrap.format('"#',page.name))
                    content = self._find_and_replace(content,wrap.format("'",page.reference),wrap.format("'#",page.name))
        return content

    def _remove_trackers(self, content):
        return Stripper.Strip(content)

    def _find_and_replace(self,text,find,replace):
        text = text.replace(find,replace)
        return text

    def _update_stats(self,mime):
        if mime.category in self.stats:
            self.stats[mime.category] += 1
        else:
            self.stats[mime.category] = 1

    def _update_totals(self,key,value):
        with self.lock:
            self.totals[key] += value

    def _get_total_assets_to_download(self,resources):
        #TODO this needs to compare both the reference and the url just like the _find_asset_by_reference
        return len(list(filter(lambda r: self._check_asset_exists(r),list(resources))))
        #return len(list(filter(lambda r: r.reference not in map(lambda a: a.source.reference,list(self.assets)),list(resources._resources))))


def merge(b, c):
    i = 0
    j = 0
    Z = []
    c_end = False
    b_end = False
    for k in range(len(b) + len(c)):
        if (float(b[i]) < float(c[j]) or c_end) and not b_end:
            Z.append(b[i])
            if i == len(b)-1:
                b_end = True
            else:
                i += 1
        else:
            Z.append(c[j])
            if j == len(c)-1:
                c_end = True
            else:
                j += 1
    return Z

def sort(A):
    if len(A) == 2:
        if float(A[0]) < float(A[1]):
            return A
        else:
            return [A[1], A[0]]
    elif len(A) == 1:
        return A
    else:
        n2 = len(A) // 2
        x = sort(A[:n2])
        y = sort(A[n2:])
        return merge(x, y)

def run_algo():
    A = input().split(' ')
    output = sort(A)
    print(output)

if __name__ == '__main__':
    run_algo()


# use Python 3.9
# python3.9 -m venv env
# source new3.9/bin/activate
# pip3.9 install -r requirements.txt

import random
import math
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
import scipy
from scipy.special import softmax
import numpy as np

# Typing
import typing
from typing import TypeVar, Generic
from collections.abc import Callable

from tqdm import tqdm
from sklearn.cluster import KMeans
import statistics
import dataclasses
from dataclasses import dataclass
from tensorflow.keras.optimizers import Adam
from tensorflow.keras import datasets, layers, models
#import keras.backend as K
import copy
from copy import deepcopy
import tensorflow as tf

from pd_paramters import pop_descent_classes

import time
start_time = time.time()

# FUNCTIONS FOR NN IMPLEMENTATION
def new_NN_individual():

	# # FM Model (small)
	# model = tf.keras.Sequential([
	# tf.keras.layers.Flatten(input_shape=(28, 28)),
 #    tf.keras.layers.Dense(128, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(l=.001)),
 #    tf.keras.layers.Dense(64, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(l=.001)),
 #    tf.keras.layers.Dense(10)
	# ])

	# # FM Model (small --> get equal results with PD and .fit)
	# model = tf.keras.Sequential([
	# tf.keras.layers.Flatten(input_shape=(28, 28)),
 #    tf.keras.layers.Dense(128, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(l=.0001)), # good rate from hyperparameter search = 1e-4, 1e-5
 #    tf.keras.layers.Dense(64, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(l=.0001)),
 #    tf.keras.layers.Dense(10)
	# ])

	# # Keras Tutorial Model --> use for just overfitting rn
	# model = tf.keras.Sequential([
	# tf.keras.layers.Flatten(input_shape=(28, 28)),
	# tf.keras.layers.Dense(2, activation='tanh', kernel_regularizer=tf.keras.regularizers.l2(l=.0001)),
	# tf.keras.layers.Dense(10)
	# ])

	# # model #3: for trying to avoid overfitting, hyperparameter vs PD
	model = tf.keras.Sequential([
	tf.keras.layers.Flatten(input_shape=(28, 28)),
	tf.keras.layers.Dense(1024),
	tf.keras.layers.Dense(512),
	tf.keras.layers.Dense(256),
    tf.keras.layers.Dense(128, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(l=.001)),
    tf.keras.layers.Dense(64, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(l=.001)),
    tf.keras.layers.Dense(10)
	])

	# ## big keras model

	# model = tf.keras.Sequential()
	# model.add(layers.Conv2D(128, kernel_size=(3, 3), activation='relu', input_shape=FM_input_shape))
	# model.add(layers.Activation('relu'))
	# model.add(layers.Conv2D(filters=96, kernel_size=(3,3), strides=2))
	# model.add(layers.Activation('relu'))

	# # model.add(layers.Conv2D(filters=192, kernel_size=(3,3)))
	# # model.add(layers.Activation('relu'))
	# # model.add(layers.Conv2D(filters=192, kernel_size=(3,3), strides=2))
	# # model.add(layers.Activation('relu'))

	# model.add(layers.Flatten())
	# model.add(layers.BatchNormalization())
	# model.add(layers.Dense(128, activation='relu', kernel_regularizer=tf.keras.regularizers.l2(l=.001)))
	# model.add(layers.Dense(256, kernel_regularizer=tf.keras.regularizers.l2(l=.001)))
	# model.add(layers.Dense(512))

	# model.add(layers.Activation('relu'))

	# model.add(layers.Dense(10, activation="softmax"))

	optimizer = tf.keras.optimizers.Adam(learning_rate=1e-4) # 1e-3
	LR_constant = 10**(np.random.normal(-4, 2))
	reg_constant = 10**(np.random.normal(0, 2))
	print(LR_constant, reg_constant)

	# creating NN object with initialized parameters
	NN_object = NN_Individual(model, optimizer, LR_constant, reg_constant)
	return NN_object

def NN_optimizer_manual_loss(NN_object):

	# classification_NN_compiler(NN_object.nn)
	batch_size = 64
	epochs = 1
	normalized_training_loss, normalized_validation_loss = [], []

	optimizer = NN_object.opt_obj
	lossfn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)

	indices = np.random.choice(59999, size = (batch_size*21, ), replace=False)
	vIndices = np.random.choice(4999, size = (batch_size*10, ), replace=False)

	# FM dataset
	random_batch_FM_train_images, random_batch_FM_train_labels = FM_train_images[indices], FM_train_labels[indices]
	random_batch_FM_validation_images, random_batch_FM_validation_labels = FM_validation_images[vIndices], FM_validation_labels[vIndices]

	# NN_object.nn.fit(random_batch_FM_train_images, random_batch_FM_train_labels, validation_data = (random_batch_FM_validation_images, random_batch_FM_validation_labels), epochs=epochs, verbose=1, batch_size = batch_size)

	for e in range(epochs):

		with tf.GradientTape() as tape:

			# make a prediction using the model and then calculate the loss
			model_loss = lossfn(random_batch_FM_train_labels, NN_object.nn(random_batch_FM_train_images))

			# use regularization constant
			regularization_loss = NN_object.nn.losses
			reg_loss = regularization_loss[0]
			# reg_loss = ((regularization_loss[0] + regularization_loss[1]))
			mreg_loss = reg_loss * NN_object.reg_constant
			# mreg_loss = reg_loss * 1

			# total_training_loss = tf.math.multiply(NN_object.LR_constant, model_loss) # LR randomization
			# total_training_loss = model_loss + mreg_loss # REG randomization
			total_training_loss = NN_object.LR_constant * (model_loss + mreg_loss) # LR + REG randomization

			tf.print("training loss: %s" % model_loss)
			# print("mreg los: %s" % mreg_loss), print("")
			# print("total loss: %s" % total_training_loss), print("")

			validation_loss = lossfn(random_batch_FM_validation_labels, NN_object.nn(random_batch_FM_validation_images))
			tf.print("validation loss: %s" % validation_loss)
			print("")
	# 	# print(" %s --> unnormalized training loss: %s" % model_loss), print("")

	# 	# # calculate the gradients using our tape and then update the model weights
		grads = tape.gradient(model_loss, NN_object.nn.trainable_variables)
		# grads = tape.gradient(total_training_loss, NN_object.nn.trainable_variables) ## with LR randomization
		optimizer.apply_gradients(zip(grads, NN_object.nn.trainable_variables))

	normalized_training_loss.append(2/(2+(model_loss)))
	normalized_training_loss = np.array(normalized_training_loss)

	normalized_validation_loss.append(2/(2+(validation_loss)))
	normalized_validation_loss = np.array(normalized_validation_loss)

	print(""), print("normalized training loss: %s" % normalized_training_loss)
	print("normalized validation loss: %s" % normalized_validation_loss)

	#print(model_loss)
	return normalized_training_loss, normalized_validation_loss

def NN_randomizer_manual_loss(NN_object, normalized_amount):
	print(""), print("RANDOMIZING")
	# original: (0, 1e-3), (0, normalized_amount), (0, normalized amount)

	factor = 25

	# randomizing NN weights
	model_clone = tf.keras.models.clone_model(NN_object.nn)
	model_clone.set_weights(np.array(NN_object.nn.get_weights()))

	mu, sigma = 0, (1e-2) #1e-4 for sin
	gNoise = (np.random.normal(mu, sigma))*(normalized_amount)

	weights = np.array((NN_object.nn.get_weights()))
	randomized_weights = weights + gNoise
	model_clone.set_weights(randomized_weights)

	# randomizing regularization rate
	mu, sigma = 0, (normalized_amount*factor) # 0.7, 1 #10 # 0.3
	print(mu, sigma)
	print("")
	randomization = 2**(np.random.normal(mu, sigma))
	new_reg_constant = (NN_object.reg_constant) * randomization

	print("reg randomization: %s" % randomization)
	print("%s NN_object.reg_constant" % NN_object.reg_constant)
	# print(normalized_amount)
	print("%s new_reg_constant" % new_reg_constant), print("")

	# randomizing learning_rates
	mu, sigma = 0, (normalized_amount*factor) # 0.7, 1 #10 # 0.3
	randomization = 2**(np.random.normal(mu, sigma))
	new_LR_constant = (NN_object.LR_constant) * randomization

	print("LR randomization: %s" % randomization)
	print("%s NN_object.LR_constant" % NN_object.LR_constant)
	print(normalized_amount)
	print("%s new_lr_constant" % new_LR_constant)
	print(""), print("factor=%s" % factor)

	new_NN_Individual = NN_Individual(model_clone, NN_object.opt_obj, new_LR_constant, new_reg_constant) # without randoimzed LR

	return new_NN_Individual

# unnormalized
def observer(NN_object, tIndices):
	random_batch_FM_test_images, random_batch_FM_test_labels = FM_test_images[tIndices], FM_test_labels[tIndices]

	lossfn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
	test_loss = lossfn(random_batch_FM_test_labels, NN_object.nn(random_batch_FM_test_images))

	ntest_loss = 1/(1+test_loss)

	return test_loss

def graph_history(history, trial, parameter_string, loss_data_string, best_training_model_string, best_test_model_loss_string):
	integers = [i for i in range(1, (len(history))+1)]
	x = [j * rr for j in integers]
	y = history

	plt.scatter(x, history, s=20)
	# plt.rcParams.update({'font.size': 10})
	# figure(figsize=(3, 2), dpi=80)

	plt.tight_layout()
	plt.title("PD trial #%s" % trial)
	plt.ylabel('unnormalized loss of best model')
	plt.xlabel('iterations')

	plt.xlabel("%s\n\n%s\n\n%s\n\n%s" % (parameter_string, loss_data_string, best_training_model_string, best_test_model_loss_string))

	# for i,j in zip(x,y):
	# 	plt.annotate(str(j),xy=(i,j))
	plt.text(x[(len(x))-1], y[(len(y))-1], y[(len(y))-1])
	plt.axhline(y = y[(len(y))-1])

	plt.tight_layout()
	plt.savefig("TEST_DATA/PD_trial_%s.png" % trial)
	plt.show(block=True), plt.pause(0.5), plt.close()

def evaluator(NN_object):
	# classification_NN_compiler(NN_object) # only if using manual loss optimizer/randomizer
	batch_size = 64

	np.random.seed(0)
	tIndices = np.random.choice(4999, size = (batch_size*25, ), replace=False)
	random_batch_FM_test_images, random_batch_FM_test_labels = FM_test_images[tIndices], FM_test_labels[tIndices]

	print(""), print(""), print("Evaluating models on test data after randomization")

	# test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)
	lossfn = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
	test_loss = lossfn(random_batch_FM_test_labels, NN_object.nn(random_batch_FM_test_images))

	# test_loss, test_acc = NN_object.nn.evaluate(random_batch_FM_test_images, random_batch_FM_test_labels, batch_size = batch_size)

	ntest_loss = 1/(1+test_loss)
	print("unnormalized test loss: %s" % test_loss)
	print("normalized (1/1+loss) test loss: %s" % ntest_loss)

	return ntest_loss

# def classification_NN_compiler(NN_object):
# 	NN_object.nn.compile(optimizer=NN_object.opt_obj,
#               loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
#               metrics=['accuracy'])
# 	return

# External Evaluator
def Parameter_class_evaluator(population):
	all_test_loss, all_acc = [], []

	for i in range(len(population)):
		individual_total_loss = evaluator(population[i])

		all_test_loss.append(individual_total_loss)

	avg_total_test_loss = np.mean(all_test_loss)
	best_test_model_loss = np.max(all_test_loss)

	return avg_total_test_loss, best_test_model_loss

# CLASSES
Individual = TypeVar('Individual')

@dataclass
class Parameters(Generic[Individual]):

	population: Callable[[int], np.array]
	randomizer: Callable[[np.array, float], np.array]
	optimizer: Callable[[np.array], np.array]
	observer: Callable[[np.array], np.array] # check this for typing
	randomization: bool
	CV_selection: bool
	rr: int
	history: [np.array]

# updated np typing
	# population: Callable[[int], npt.NDArray[Individual]]
	# randomizer: Callable[[npt.NDArray[Individual], float], np.Array[Individual]]
	# optimizer: Callable[[npt.NDArray[Individual]], np.Array[Individual]]

@dataclass
class NN_Individual:

	nn: models.Sequential()
	opt_obj: Adam()
	LR_constant: np.cfloat
	reg_constant: np.cfloat

def individual_to_params(
	pop_size: int,
	new_individual: Callable[[], Individual],
	individual_randomizer: Callable[[Individual, float], Individual],
	individual_optimizer: Callable[[Individual], Individual],
	observer: Callable[[Individual], float],
	randomization: bool,
	CV_selection: bool,
	rr: int, # randomization rate
	history: [float]
	) -> Parameters[Individual]:

	def Parameter_new_population(pop_size: int) -> np.array(Individual):
		population = []
		for i in range(pop_size):
			individual = new_individual()
			population.append(individual)
		population = np.array(population)

		return population

	def Parameter_class_randomizer(population: np.array(Individual), normalized_amount: float) -> np.array(Individual):
		randomized_population = []
		for i in range(len(population)):
			new_object = individual_randomizer(population[i], normalized_amount[i])
			randomized_population.append(new_object)
		randomized_population = np.array(randomized_population)

		return randomized_population

	def Parameter_class_optimizer(population: np.array(Individual)) -> np.array(Individual):
		lFitnesses, vFitnesses = [], []
		for i in range(len(population)):
			print(""), print("model #%s" % (i+1)), print("")
			normalized_training_loss, normalized_validation_loss = individual_optimizer(population[i])
			lFitnesses.append(normalized_training_loss)
			vFitnesses.append(normalized_validation_loss)

		lFitnesses = np.array(lFitnesses)
		lFitnesses = lFitnesses.reshape([len(lFitnesses), ])

		vFitnesses = np.array(vFitnesses)
		vFitnesses = vFitnesses.reshape([len(vFitnesses), ])

		return lFitnesses, vFitnesses

	# (during optimization)
	def Parameter_class_observer(population, history):

		batch_size = 64
		tIndices = np.random.choice(4999, size = (batch_size*10, ), replace=False)

		all_test_loss = []
		for i in range(len(population)):
			unnormalized_model_loss = observer(population[i], tIndices)
			all_test_loss.append(unnormalized_model_loss)

		avg_test_loss = np.mean(all_test_loss)
		best_test_model_loss = np.min(all_test_loss)

		history.append(best_test_model_loss) ## main action of observer (to graph optimization progress later)

		return

	Parameters_object = Parameters(Parameter_new_population, Parameter_class_randomizer, Parameter_class_optimizer, Parameter_class_observer, randomization, CV_selection, rr, history)
	return Parameters_object

def create_Parameters_NN_object(pop_size, randomization, CV_selection, rr):
	history = []

	object = individual_to_params(pop_size, new_NN_individual, NN_randomizer_manual_loss, NN_optimizer_manual_loss, observer, randomization=randomization, CV_selection=CV_selection, rr=rr, history=history)
	object.population = object.population(pop_size) # initiazling population

	return object

# Fashion-MNIST dataset
fashion_mnist = tf.keras.datasets.fashion_mnist
(FM_train_images, FM_train_labels), (FM_test_images, FM_test_labels) = fashion_mnist.load_data()

sample_shape = FM_train_images[0].shape
img_width, img_height = sample_shape[0], sample_shape[1]
FM_input_shape = (img_width, img_height, 1)

# Reshape data
FM_train_images = FM_train_images.reshape(len(FM_train_images), FM_input_shape[0], FM_input_shape[1], FM_input_shape[2])
FM_test_images  = FM_test_images.reshape(len(FM_test_images), FM_input_shape[0], FM_input_shape[1], FM_input_shape[2])

# normalizing data
FM_train_images, FM_test_images = FM_train_images / 255.0, FM_test_images / 255.0

# FM_validation_images, FM_validation_labels = FM_train_images[50000:59999], FM_train_labels[50000:59999]
# FM_train_images, FM_train_labels = FM_train_images[0:50000], FM_train_labels[0:50000]

FM_validation_images, FM_validation_labels = FM_test_images[0:5000], FM_test_labels[0:5000]
FM_test_images, FM_test_labels = FM_test_images[5000:], FM_test_labels[5000:]

class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

trial = 1

# Parameters
iterations = 125
pop_size = 4
number_of_replaced_individuals = 2
randomization = True
CV_selection = True
rr = 15 # leash for exploration

batch_size = 64
batches = 21

## MAIN RUNNING CODE
if __name__ == "__main__":

	Parameters_object = create_Parameters_NN_object(pop_size, randomization, CV_selection, rr)

	loss_data, acc_data, total_test_loss, batch_test_loss, total_test_acc = [], [], [], [], []

	for i in range(1):

		print(""), print("MAJOR ITERATION %s: " % (i+1)), print("")

		optimized_population, lfitnesses, vfitnesses, history = pop_descent_classes(Parameters_object, number_of_replaced_individuals = number_of_replaced_individuals, iterations = iterations)

		print(""), print(""), print("time:"), print("--- %s seconds ---" % (time.time() - start_time)), print(""), print("")

		best_model = np.max(lfitnesses)

		lmean = statistics.mean(lfitnesses)
		loss_data.append(lmean)

		# evaluate from outside
		total_hist, batch_hist = [], []
		avg_total_loss, best_test_model_loss = Parameter_class_evaluator(optimized_population)

	print(""), print("Title: PD vs Hyperparameter Search")
	parameter_string = "CV_sel: %s, randomize=%s, %s iterations, %s models, %s replaced, rr=%s" % (CV_selection, randomization, iterations, pop_size, number_of_replaced_individuals, rr)
	print(""), print(parameter_string)
	print(""), print("")
	loss_data_string = "avg normalized training loss of population on last epoch: %s" % loss_data
	print(loss_data_string)
	best_training_model_string = "normalized training loss of best model: %s" % best_model
	print(best_training_model_string)

	print("")
	# print("normalized average test loss: %s" % avg_total_loss)
	print("")
	best_test_model_loss_string = "normalized (1/1+loss) best model test loss: %s" % best_test_model_loss
	print(best_test_model_loss_string)
	print("")

	graph_history(history, trial, parameter_string, loss_data_string, best_training_model_string, best_test_model_loss_string)

print("--- %s seconds ---" % (time.time() - start_time))


import asyncio
import functools
import time
from colorama import Fore
from XAgentServer.exts.exception_ext import XAgentTimeoutError, XAgentCloseError

from inputimeout import inputimeout, TimeoutOccurred
from XAgentServer.application.global_val import redis
import math

def timer(func):
    """
    Decorator function to time the execution of a function.

    Args:
        func (Function): The function to be timed.

    Returns:
        wrapper (Function): The wrapped function with added timing functionality.
    """
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        try:
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
        except:
            pass
    return wrapper

class CommandLineInput:
    """
    Class for handling command line input.

    This child class extends from BaseInput and implements methods to handle and manage command line input data.

    Attributes:
        do_interrupt (bool): If True, input will be interrupted.
        max_wait_seconds (int): Maximum wait time for input in seconds.
    """
    def __init__(self,
                 do_interrupt: bool = False,
                 max_wait_seconds: int = 600,
                 logger=None):
        self.do_interrupt = do_interrupt
        self.max_wait_seconds = max_wait_seconds
        self.logger = logger

    def run(self, input_data):
        """
        Run the command line input method.

        Args:
            input_data (Any): The original input data to be processed.

        Returns:
            data (Any): The processed input data.
        """
        if self.do_interrupt:
            data = self.interrupt(input_data)
        else:
            data = input_data
        return data

    def get_each_input(self, key, value, res, timeout):
        """
        Returns the input from the command line for a single key-value pair.

        Args:
            key (str): The key for which to get input.
            value (Any): The current value associated with the key.
            res (dict): The result dictionary where inputs collected will be stored.
            timeout (int): Timeout in seconds for the input.

        Returns:
            Any: The input data.
        """
        self.logger.typewriter_log(
            f"Now, ASK For {key}, Origin Input: {value}",
            Fore.RED,
            f""
        )
        self.logger.typewriter_log(
            f"Now, you can modify the current field by entering some information, and then press 'Enter' to continue, if you want to keep the original input, please enter '-1' and then press 'Enter':",
            Fore.GREEN
        )
        temp = inputimeout(prompt=f'You have {timeout} seconds to input:\n', timeout=timeout)
        if temp == "-1":
            return value
        else:
            return temp

    def get_input(self, origin_data):
        """
        Get input for all fields of the original data from the command line.

        Args:
            origin_data (dict): The original data for which to get input.

        Returns:
            dict: The dictionary with updated inputs.
        """
        self.logger.typewriter_log(
                "Next, you can start modifying the original input by typing 'Y/y/yes' or skip this step by typing 'N/n/no' and then press 'Enter' to continue the loop:",
                Fore.RED
            )
        update = inputimeout(prompt=f'You have to make a decision within 60 seconds:\n', timeout=60)
        res = {"args": {}}
        if update in ['y', 'Y', 'yes']:
            execute_time = self.max_wait_seconds
            if isinstance(origin_data, dict):
                args = origin_data.get("args", "")
                self.logger.typewriter_log(
                    f"Next, you will have a total of {self.max_wait_seconds} seconds to modify each option:",
                    Fore.RED,
                )
                for key, value in args.items():
                    if key == "done":
                        res[key] = False
                        continue
                    start_time = time.time()
                    res["args"][key] = self.get_each_input(key, value, res, execute_time)
                    end_time = time.time()
                    execute_time = math.floor(execute_time - (end_time - start_time))
            self.logger.info(f"modify the input, receive the data: {res}")
        else:
            res = origin_data
            self.logger.info("skip this step")
        self.logger.info("continue the loop")
        res["done"] = True
        return res

    def interrupt(self, input_data):
        """
        Interrupts the current input process and returns the current data.

        Args:
            input_data (dict): The original input data.

        Returns:
            dict: The current data collected so far.

        Raises:
            XAgentIOTimeoutError: If the input times out.
        """
        try:
            data = self.get_input(input_data)
            return data
        except TimeoutOccurred:
            self.logger.error(f"Waiting timemout, close connection!")
            raise XAgentTimeoutError("timeout!")