import scrapy

#  1-  extraer fecha y hora actual:
from datetime import datetime
# instalar la libreria datetime, para extraer la fecha y hora actual para el reporte

fecha = datetime.now().today()
hora = datetime.now().time()

# darle formato que necesito a la fecha y hora:
fHorasMinutos = "%H:%M"
horaActual = hora.strftime(fHorasMinutos)

fDiaMesAño = "%d-%m-%Y"
fechaActual = fecha.strftime(fDiaMesAño)

# 2-  Cnfigurar el spider para la extraccion de datos:

#A - Defino la araña, con su nombre unico y las paginas donde buscara:
class QuotesSpider(scrapy.Spider):
    name = "quotes"
    start_urls = [
        "https://quotes.toscrape.com/page/1/",
        #"https://quotes.toscrape.com/page/2/",  ACA defino puntualmente una pagina
    ]

#B - establesco la funcion parse para que extraiga los datos que necesito, basandome en las etiquetas de html de la web
    def parse(self, response):
        for quote in response.css("div.quote"): # quote es la clase presente en el html de la pagina
            yield { # palabra reservada de python para la devolucion de datos
                "fecha": fechaActual,
                "hora": horaActual,
                "pagina": response.css("li.next a::attr(href)").get(),
                "text": quote.css("span.text::text").get(),
                "author": quote.css("small.author::text").get(),
                "tags": quote.css("div.tags a.tag::text").getall(),
            }
        # Extraer datos de las paginas siguientes:
        next_page = response.css("li.next a::attr(href)").get()
        if next_page is not None:
            next_page = response.urljoin(next_page) # se crea el enlace de la pagina siguiente y la solucitud
            yield scrapy.Request(next_page, callback=self.parse)

# Extrer los datos:  scrapy runspider 03.py -o citas3.csv


import numpy as np
import cv2
import os

def align_photos(img1, img2):
    #function to align a photo to a template using akaze descriptors and homography matrix
    img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)
    img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB)

    akaze = cv2.AKAZE_create()
    kpts1, desc1 = akaze.detectAndCompute(img1, None)
    kpts2, desc2 = akaze.detectAndCompute(img2, None)

    #get the
    bf = cv2.BFMatcher(cv2.NORM_HAMMING)
    knn_matches = bf.knnMatch(desc2, desc1, k=2)  # typo fixed

    # filter the best matches using ratio =0.7
    ratio_thresh = 0.7
    good_matches = []
    for m, n in knn_matches:
        if m.distance < ratio_thresh * n.distance:
            good_matches.append(m)

    points1 = np.zeros((len(good_matches), 2), dtype=np.float32)
    points2 = np.zeros((len(good_matches), 2), dtype=np.float32)

    for i, match in enumerate(good_matches):
        points1[i, :] = kpts1[match.trainIdx].pt
        points2[i, :] = kpts2[match.queryIdx].pt

    #aply homography matrix
    h, mask = cv2.findHomography(points2, points1, cv2.RANSAC)

    # Use homography
    height, width, channels = img1.shape
    image_warped = cv2.warpPerspective(img2, h, (width, height), flags=cv2.INTER_NEAREST)
    image_warped = cv2.cvtColor(image_warped, cv2.COLOR_RGB2BGR)
    return image_warped

def filter_circles(image_path):
#get the contours for each circle in the template image of task1
  image = cv2.imread(image_path)
#apply threshold and find contours
  img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
  ret, thresh = cv2.threshold(img_gray, 60, 130, cv2.THRESH_BINARY)

  contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)

  list_contours = []

  for c in contours:
    #filter contours that have width and height bigger than 2
    (x,y,w,h) = cv2.boundingRect(c)
    if w > 200 and h > 200:
      list_contours.append(c)

  list_contours = list_contours[1:]
  return list_contours

def detect_circle(point, list_contours):
#having the ten circles of the first board we can detect if a point is a region
#if a circle contains the point and the bigger circle than previous doesnt contain it
  is_in_contour = -1
  for i, contour in enumerate(list_contours):
    result = cv2.pointPolygonTest(contour, point, False)
    if result >= 0:
      is_in_contour = i

  return is_in_contour+1

#create folders for task1
os.mkdir('Iordachescu_Anca_407')
os.mkdir('Iordachescu_Anca_407/Task1')

path_test_data = 'new_test/Task1/'

#load template data
image_path = 'auxiliary_images/template_task1.jpg'
list_contours = filter_circles(image_path)

template = cv2.imread(image_path)

for i in range(1, 26):
    #read images from dataset
    img = None
    if i < 10:
        img = cv2.imread(path_test_data + '0' + str(i) + '.jpg')
    else:
        img = cv2.imread(path_test_data + str(i) + '.jpg')

    #align photo to template
    aligned_photo = align_photos(template, img)

    #change to hsv and obtain a mask to get the barrel of each arrow
    hsv = cv2.cvtColor(aligned_photo, cv2.COLOR_BGR2HSV)
    hsv_low = np.array([8, 42, 57], np.uint8)
    hsv_high = np.array([31, 255, 255], np.uint8)

    mask = cv2.inRange(hsv, hsv_low, hsv_high)
    res = cv2.bitwise_and(img, img, mask=mask)

    #apply different morphological operations to get better the barrel of each row
    ret, gray = cv2.threshold(mask, 127, 255, 0)

    kernel = np.ones((3, 3), np.uint8)
    img_dilation = cv2.dilate(gray, kernel, iterations=1)

    edges = cv2.Canny(img_dilation, 50, 150)

    #draw lines on the barrel of each arrow using color (255, 255, 0)
    lines = cv2.HoughLinesP(gray, 1, np.pi / 180, 40, minLineLength=50, maxLineGap=4)

    for line in lines:
        new_line = line[0]
        cv2.line(aligned_photo, (new_line[0], new_line[1]), (new_line[2], new_line[3]), (255, 255, 0), 10)

    #now mask contains only regions of the barrel of each row
    #apply some dilatation to make it even clear
    mask1 = cv2.inRange(aligned_photo, (255, 255, 0), (255, 255, 0))
    kernel = np.ones((5, 5), np.uint8)
    img_dilation = cv2.dilate(mask1, kernel, iterations=1)

    #get contour of each barrel of each row
    contours, hierarchy = cv2.findContours(img_dilation,
                                           cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

    file = None
    if i < 10:
        file = 'Iordachescu_Anca_407/Task1/0' + str(i) + '_predicted.txt'
    else:
        file = 'Iordachescu_Anca_407/Task1/' + str(i) + '_predicted.txt'
    f = open(file, "w")
    #number of contours means the number of barrels detected
    f.write(str(len(contours)) + '\n')
    for contour in contours:
        #due to the fact that i only detected the barrel and i have to estimate the tip of the arrow
        #i calculate the centor of each detected barrel and estimate the line that gets through barrel
        #and using a heuristic idea i estimate the tip on a distance of 130 from the center
        M = cv2.moments(contour)
        centru = (int(M["m10"] / M["m00"]), int(M["m01"] / M["m00"]))
        unghi = 0.5 * np.arctan2(2 * M["mu11"], M["mu20"] - M["mu02"])
        point_1 = -130 * np.cos(unghi) + centru[0]
        point_2 = -130 * np.sin(unghi) + centru[1]
        pos = detect_circle((point_1, point_2), list_contours)
        f.write(str(pos) + '\n')

    f.close()


while True:
    yak = []
    n = int(input())
    if n == -1:
        break
    for i in range(1, n):
        if n%i == 0:
            yak.append(i)
    if n == sum(yak):
        print(f"{n} = ", end='')
        for i in yak:
            if i != yak[-1]:
                print(f"{i} + ", end='')
            elif i == yak[-1]:
                print(i)
    else:
        print(f"{n} is NOT perfect.")


# coding=utf-8

"""
Functionality for building wheels
"""

import glob
import os.path as path
import shutil
import subprocess
import tempfile

from packaging import tags
from pkg_resources import Distribution, Requirement

from wheel_filename import InvalidFilenameError, parse_wheel_filename
from wheel_inspect import inspect_wheel
from wheel_inspect.classes import WheelFile

class BuildError(Exception):
    def __init__(self, package, version, root_exception=None):
        version = version or ""
        super(BuildError, self).__init__('Failed to create wheel for {} {}:\n{}\nOutput:\n{}'.format(
            package,
            version,
            root_exception,
            root_exception.output if hasattr(root_exception, 'output') and root_exception.output else ''
        ))

class Builder(object):
    """
    Provides a context in which wheels can be generated. If the context goes out of scope
    all created files will be removed.
    """
    def __enter__(self):
        self.scratch_dir = tempfile.mkdtemp()
        self.wheelhouse = path.join(self.scratch_dir, 'wheels')
        return lambda *args: self.build(*args)

    def __exit__(self, exc_type, exc_val, exc_tb):
        shutil.rmtree(self.scratch_dir)

    @staticmethod
    def _standardize_package_name(name):
        return name.replace(".", "-")

    def _matches_requirement(self, requirement, wheels):
        """
        List wheels matching a requirement.

        :param requirement:str : The requirement to satisfy
        :param wheels: List of wheels to search.
        """
        req = Requirement.parse(requirement)

        matching = []
        for wheel in wheels:
            w = wheel.parsed_filename
            dist = Distribution(project_name=self._standardize_package_name(w.project), version=w.version)
            if dist in req:
                matching.append(wheel.path)
        return matching

    def _find_wheel(self, name, version):
        """
        Find a wheel with the given name and version
        """
        candidates = [WheelFile(filename) for filename in glob.iglob(path.join(self.wheelhouse, '*.whl'))]
        name = self._standardize_package_name(name)
        requirement = '{}=={}'.format(name, version) if version else name
        matches = self._matches_requirement(requirement, candidates)
        if len(matches) > 0:
            return str(matches[0])
        else:
            raise BuildError(name, version, 'Failed to find the build wheel for {} {}'.format(name, version))

    def build(self, package, version):
        """
        Build a wheel for the given version of the given project.

        :param package: The name of the project
        :param version: The version to generate the wheel for
        :return: The path of the build wheel. Valid until the context is exited.
        """
        try:
            subprocess.check_output([
                'pip', 'wheel',
                '--wheel-dir=' + self.wheelhouse,
                '{}=={}'.format(package, version) if version else package,
            ], stderr=subprocess.STDOUT)
            return self._find_wheel(package, version)
        except subprocess.CalledProcessError as e:
            raise BuildError(package, version, e)

def is_pure(wheel):
    """
    Check whether wheel given by the passed path is pure.

    Pure wheels operate independent of the specific Python version and platform.

    :param wheel: The path to the wheel to inspect
    :return: True if the wheel is pure
    """
    return (
        inspect_wheel(wheel)
            .get("dist_info", {})
            .get("wheel", {})
            .get("root_is_purelib")
    )

def is_compatible(package):
    """
    Check whether the given python package is a wheel compatible with the
    current platform and python interpreter.

    Compatibility is based on https://www.python.org/dev/peps/pep-0425/
    """
    try:
        w = parse_wheel_filename(package)
        for systag in tags.sys_tags():
            for tag in w.tag_triples():
                if systag in tags.parse_tag(tag):
                    return True
    except InvalidFilenameError:
        return False

def has_compatible_wheel(packages):
    """
    Check for a compatible wheel in the given list of python packages
    """
    return any(is_compatible(pkg) for pkg in packages)


"""
This module contains different problem types to be solved by our evolutioanry algorithms.
"""

from abc import ABC, abstractmethod
from collections import namedtuple
from itertools import compress

import numpy as np

class Problem(ABC):
    """
    A Problem is anything that has a given number of dimensions
    and can map a possible solution to a fitness
    """

    def __init__(self, num_dimensions):
        """
        :parameter num_dimensions: The number of dimensions of the problem.
        Equals the length of the phenotype of a solution genome.
        """
        self.num_dimensions = num_dimensions

    @abstractmethod
    def evaluate(self, solution, fitness=True):
        """
        :parameter solution: The solution to evaluate
        :parameter fitness:
            If True, return the fitness value that is used by the evolutionary algorithm
            If false, return a value for logging, e.g. unclipped function value
        :return: The fitness of the solution
        """
        pass

class KnapSackProblem(Problem):
    """
    Implements the one-dimensional 0-1 knapsack problem

    The KnapSackProblem is a combinatorial optimization problem where there are
    n items, each associated with a value and weight.

    The goal is to maximize the value of all chosen items while keeping the the sum
    of the weights of all chosen items under a certain limit.
    """

    def __init__(self, item_weights, item_values, weight_limit):
        """
        Creates an instance of the KnapSackProblem.
        item_weights and item_values must be ordered iterables
        , with item_weights[n] and item_values[n] storing the weight and value
        for the same item n.
        """

        super().__init__(len(item_weights))

        self.weight_limit = weight_limit

        Item = namedtuple('Item', ['weight', 'value'])
        self.items = []

        for weight, value in zip(item_weights, item_values):
            self.items.append(Item(weight=weight, value=value))

    def evaluate(self, solution, fitness=True):
        item_selection = solution.decode().data

        picked_items = list(compress(self.items, item_selection))

        value = 0

        for item in picked_items:
            value += item.value

        return value

    def is_feasible(self, solution):
        """
        Check whether the given solution violates the weight constraint

        :return: True, if the solution does not violate the weight constraint.
        Else False
        """
        item_selection = solution.decode().data
        picked_items = list(compress(self.items, item_selection))

        weight_list = [item.weight for item in picked_items]

        return sum(weight_list) <= self.weight_limit

    def get_weights(self):
        """
        :return: A list of the weights of all items
        """
        return [item.weight for item in self.items]

    def get_values(self):
        """
        :return: A list of the values of all items
        """
        return [item.value for item in self.items]

class TravellingSalesmanProblem(Problem):
    """
    Implements the traveling salesman problem for fully connected graphs.
    The goal is to find a hamilton circle with maximum weights in the
    graph.

    Edge weights are encoded in an adjacency matrix.
    """
    def __init__(self, adjacency_matrix, check_feasibility):

        super().__init__(len(adjacency_matrix))

        self.adjacency_matrix = adjacency_matrix
        self.check_feasibility = check_feasibility

    def evaluate(self, solution, fitness=True):
        value = 0

        # Iterate over genome, adding up distance from node in chromosome k to chromosome k+1
        # Wrap around at end of genome
        for i, start in enumerate(solution.data[:-1]):
            value += self.adjacency_matrix[start, solution.data[i+1]]

        value += self.adjacency_matrix[solution.data[-1], solution.data[0]]

        return value

    def is_feasible(self, solution):
        """
        Returns, whether the solution is a permutation of node indeces.
        """
        if not self.check_feasibility:
            return True

        else:
            sorted_data = np.sort(solution.data)

            if np.array_equal(sorted_data, np.arange(len(sorted_data))):
                return True
            else:
                raise ValueError('Genomes should always be valid permutations')

class ContinuousFunction(Problem):
    """
    This is the base class for all continuous optimization functions.

    We differentiate between fitness calculation and evaluating the objective function.
    In the former case, values are clipped to max(1e-20, actual_value).
    In the latter, the unchanged value is used (e.g. for validation).

    TODO: Replace hard-caded function implementations with interface to some library.
    """

    def __init__(self, num_dimensions, constraints):
        """
        :param num_dimensions: Number of problem dimensions
        :param constraints: Iterable of tuples, each tuple containing a lower and upper limit for one problem dimension.
        """
        super().__init__(num_dimensions)
        self.constraints = constraints

    def is_feasible(self, solution):
        for constraint, value in zip(self.constraints, solution.data):
            if value < constraint[0] or value > constraint[1]:
                return False

        return True

class RastriginFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions < 1:
            raise ValueError('Unsupported number of dimensions')

        constraints = []

        for _ in range(num_dimensions):
            constraint = (-1, 1)
            constraints.append(constraint)

        super().__init__(num_dimensions, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data * 5.12
        tmp = np.sum(np.square(x) - 10*np.cos(2 * np.pi * x))

        result = (10 * self.num_dimensions + tmp)

        if fitness:
            return -np.log10(np.maximum(1e-20, result))
        else:
            return result

class AckleyFunction(ContinuousFunction):
    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 5
        y = solution.data[1] * 5

        tmp_1 = -20 * np.exp(-0.2 *np.sqrt(0.5 * (x**2 + y**2)))
        tmp_2 = - np.exp(0.5 * (np.cos(2 * np.pi * x) + np.cos(2 * np.pi * y)))
        result = tmp_1 + tmp_2 + np.e + 20

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class SphereFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions < 1:
            raise ValueError('Unsupported number of dimensions')

        constraints = []

        for _ in range(num_dimensions):
            constraint = (-1, 1)
            constraints.append(constraint)

        super().__init__(num_dimensions, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data * 20

        result = np.sum(np.square(x))

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class RosenbrockFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions < 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = []

        for _ in range(num_dimensions):
            constraint = (-1, 1)
            constraints.append(constraint)

        super().__init__(num_dimensions, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data * 10

        result = 0
        for i in range(self.num_dimensions - 1):

            result += 100 * (x[i+1] - x[i]**2)**2 + (1 - x[i]**2) ** 2

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class BealeFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 4.5
        y = solution.data[1] * 4.5

        result = (1.5 - x + x*y) ** 2
        result += (2.25 -x + x*(y**2)) ** 2
        result += (2.625 -x + x * (y ** 3)) ** 2

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class GoldsteinPriceFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 2
        y = solution.data[1] * 2

        tmp_1 = (x + y + 1) ** 2
        tmp_1 *= (19 - 14*x + 3 * (x**2) - 14 * y + 6 * x * y + 3 * (y ** 2))
        tmp_1 += 1

        tmp_2 = (2 *x - 3 * y) ** 2
        tmp_2 *= (18 - 32 * x +12 * (x ** 2) + 48* y - 36 * x * y + 27 * (y ** 2))
        tmp_2 += 30

        result = tmp_1 * tmp_2

        if fitness:
            return -np.log10(np.maximum(1e-20,result - 3))
        else:
            return result - 3

class BoothFunction(ContinuousFunction):

    def __init__(self, num_dimensions, fitness=True):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 10
        y = solution.data[1] * 10

        result = (x + 2 *y - 7) ** 2
        result += (2 * x  + y - 5) ** 2

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class BukinFunctionN6(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 5 - 10
        y = solution.data[1] * 3

        result = 100 * np.sqrt(np.abs(y - 0.01 * (x ** 2)))
        result += 0.01 * np.abs (x + 10)

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class MatyasFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 10
        y = solution.data[1] * 10

        result = 0.26 * (x ** 2 + y **2) - 0.48 * x * y

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class LeviFunctionN13(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 10
        y = solution.data[1] * 10

        tmp_1 = np.sin(3 * np.pi * x) ** 2

        tmp_2 = (x - 1) ** 2
        tmp_2 *= (1 + np.sin(3 * np.pi * y) ** 2)

        tmp_3 = (y - 1) ** 2
        tmp_3 *= (1 + np.sin(2 * np.pi * y) ** 2)

        result = tmp_1 + tmp_2 + tmp_3

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class HimmelblausFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 5
        y = solution.data[1] * 5

        result = (x ** 2 + y - 11) ** 2 + (x + y **2 -7) **2

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class ThreeHumpCamelFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 5
        y = solution.data[1] * 5

        result = 2 * x**2 - 1.05 * x**4 + (x**6) / 6 + x * y + y **2

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class EasomFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 100
        y = solution.data[1] * 100

        result = -1 * np.cos(x) * np.cos(y)
        result *= np.exp(-1 * ((x - np.pi) **2 + (y - np.pi) ** 2))

        if fitness:
            return -np.log10(np.maximum(1e-20,result + 1))
        else:
            return result + 1

class CrossInTrayFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 10
        y = solution.data[1] * 10

        tmp_1 = np.sqrt(x **2 + y **2) / np.pi
        tmp_1 = np.exp(np.abs(100 - tmp_1))

        tmp_2 = np.sin(x) * np.sin(y)

        result = np.abs(tmp_2 * tmp_1) +1
        result = result ** 0.1
        result *= -0.0001

        if fitness:
            return -np.log10(np.maximum(1e-20,result + 2.06261187082274))
        else:
            return result + 2.06261187082274

class EggHolderFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 512
        y = solution.data[1] * 512

        tmp_1 = x / 2 + y + 47
        tmp_1 = np.sin(np.sqrt(np.abs(tmp_1)))
        tmp_1 = -1 * (y + 47) * tmp_1

        tmp_2 = x * np.sin(np.sqrt(np.abs(x - (y + 47))))

        result = tmp_1 - tmp_2

        if fitness:
            return -np.log10(np.maximum(1e-20,result + 959.640662720850743))
        else:
            return result + 959.640662720850743

class HoelderTableFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 10
        y = solution.data[1] * 10

        tmp_1 = 1 - np.sqrt(x **2 + y **2) / np.pi
        tmp_1 = np.exp(np.abs(tmp_1))

        tmp_2 = np.sin(x) * np.cos(y)

        result = -1 * np.abs(tmp_1 * tmp_2)

        if fitness:
            return -np.log10(np.maximum(1e-20,result + 19.20850256788676))
        else:
            return result + 19.20850256788676

class McCormickFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 2.75 + 1.25
        y = solution.data[1] * 3.5 + 0.5

        result = np.sin(x + y)
        result += (x - y) ** 2
        result -= 1.5 * x
        result += 2.5 * y + 1

        if fitness:
            return -np.log10(np.maximum(1e-20,result + 1.913222954981038))
        else:
            return result + 1.913222954981038

class SchafferFunctionN2(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 100
        y = solution.data[1] * 100

        tmp_1 = np.sin(x **2 - y**2) ** 2 - 0.5
        tmp_2 = (1 + 0.001 * (x**2 + y **2)) ** 2

        result = 0.5 + tmp_1 / tmp_2

        if fitness:
            return -np.log10(np.maximum(1e-20,result))
        else:
            return result

class SchafferFunctionN4(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions is not 2:
            raise ValueError('Unsupported number of dimensions')

        constraints = [(-1, 1), (-1, 1)]

        super().__init__(2, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data[0] * 100
        y = solution.data[1] * 100

        tmp_1 = np.cos(np.sin(np.abs(x **2 - y**2))) ** 2 - 0.5
        tmp_2 = (1 + 0.001 * (x**2 + y **2)) ** 2

        result = 0.5 + tmp_1 / tmp_2

        if fitness:
            return -np.log10(np.maximum(1e-20,result - 0.292579))
        else:
            return result - 0.292579

class StyblinskiTangFunction(ContinuousFunction):

    def __init__(self, num_dimensions):
        if num_dimensions < 1:
            raise ValueError('Unsupported number of dimensions')

        constraints = []

        for _ in range(num_dimensions):
            constraint = (-1, 1)
            constraints.append(constraint)

        super().__init__(num_dimensions, constraints)

    def evaluate(self, solution, fitness=True):
        x = solution.data * 5

        result = np.sum(x ** 4 - 16 * (x ** 2) + 5 * x) / 2

        if fitness:
            return -np.log10(np.maximum(1e-20,result + 39.16617 * self.num_dimensions))
        else:
            return result + 39.16617 * self.num_dimensions


import numpy as np

import measurements.land_sea_mask.constants
import util.petsc.universal

import util.logging

def _check_land_sea_mask(land_sea_mask):
    # check input
    if land_sea_mask.ndim != 2:
        raise ValueError('The land sea mask must have 2 dimensions, but its shape is {}.'.format(land_sea_mask.shape))

def resolution_128x64x15():
    from .constants import LSM_128x64x15_PETSC_FILE, LSM_128x64x15_NPY_FILE

    try:
        land_sea_mask = np.load(LSM_128x64x15_NPY_FILE)

        util.logging.debug('Returning land-sea-mask loaded from {} file.'.format(LSM_128x64x15_NPY_FILE))

    except (OSError, IOError):
        land_sea_mask = util.petsc.universal.load_petsc_mat_to_array(LSM_128x64x15_PETSC_FILE, dtype=int)
        land_sea_mask = land_sea_mask.transpose()  # metos3d: x and y are changed

        _check_land_sea_mask(land_sea_mask)
        util.logging.debug('Saving land-sea-mask to {} file.'.format(LSM_128x64x15_NPY_FILE))
        np.save(LSM_128x64x15_NPY_FILE, land_sea_mask)
        util.logging.debug('Returning land-sea-mask loaded from petsc file.')

    return land_sea_mask

def resolution_128x64x15_normalized_volumes():
    from .constants import LSM_128x64x15_NORMALIZED_VLUMES_PETSC_FILE
    util.logging.debug('Loading normalized valumes from petsc file {}.'.format(LSM_128x64x15_NORMALIZED_VLUMES_PETSC_FILE))
    return util.petsc.universal.load_petsc_vec_to_numpy_array(LSM_128x64x15_NORMALIZED_VLUMES_PETSC_FILE)

# 60x180x138

def resolution_360x180x138():
    from .constants import LSM_360x180x138_TXT_FILE, LSM_360x180x138_NPY_FILE

    try:
        lsm = np.load(LSM_360x180x138_NPY_FILE)
        util.logging.debug('Returning land-sea-mask loaded from {} file.'.format(LSM_360x180x138_NPY_FILE))

    except (OSError, IOError):
        # read values from txt with axis order: x y z
        lsm = np.genfromtxt(LSM_360x180x138_TXT_FILE, dtype=float, delimiter=',', comments='#', usecols=(1, 0, 2))

        # normalize values
        min_values = lsm.min(axis=0)
        lsm[:, 0] = lsm[:, 0] - min_values[0]
        lsm[:, 1] = lsm[:, 1] - min_values[1]
        lsm[:, 2] = lsm[:, 2] - 1

        # convert to int
        lsm_int = lsm.astype(np.int16)

        assert np.all(lsm_int == lsm)
        assert lsm_int[:, 0].min() == 0 and lsm_int[:, 0].max() == 359 and lsm_int[:, 1].min() == 0 and lsm_int[:, 1].max() == 179 and lsm_int[:, 2].min() == 0 and lsm_int[:, 2].max() == 137

        # convert in 2 dim
        lsm = np.empty((360, 180), dtype=np.int16)
        for x, y, z in lsm_int:
            lsm[x, y] = z
        assert lsm.min() == 0 and lsm.max() == 137

        # save lsm as npy
        _check_land_sea_mask(lsm)
        util.logging.debug('Saving land-sea-mask to {} file.'.format(LSM_360x180x138_NPY_FILE))
        np.save(LSM_360x180x138_NPY_FILE, lsm)
        util.logging.debug('Returning land-sea-mask loaded from txt file.')

    return lsm

def depth_360x180x138():
    from .constants import DEPTH_360x180x138_TXT_FILE, DEPTH_360x180x138_NPY_FILE

    # read from cache
    try:
        depth = measurements.land_sea_mask.constants.DEPTH_360x180x138
        util.logging.debug('Returning depth levels from cache.')

    # read from npy file
    except AttributeError:
        try:
            depth = np.load(DEPTH_360x180x138_NPY_FILE)
            util.logging.debug('Returning depth levels loaded from {} file.'.format(DEPTH_360x180x138_NPY_FILE))
            measurements.land_sea_mask.constants.DEPTH_360x180x138 = depth

    # read from txt file
        except (OSError, IOError):
            # read values from txt with axis order: x y z
            depth = np.genfromtxt(DEPTH_360x180x138_TXT_FILE, dtype=np.int16, comments='#', usecols=(0,))
            assert depth.ndim == 1 and depth.shape[0] == 138

            # save depth as npy
            util.logging.debug('Saving depth to {} file.'.format(DEPTH_360x180x138_NPY_FILE))
            np.save(DEPTH_360x180x138_NPY_FILE, depth)
            util.logging.debug('Returning land-sea-mask loaded from txt file.')
            measurements.land_sea_mask.constants.DEPTH_360x180x138 = depth

    return depth


import random

import numpy
from pandas import DataFrame

import matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib import cm
from matplotlib import colors
from mpl_toolkits.axes_grid1 import make_axes_locatable

import cartopy.crs as ccrs
import cartopy.feature as cfeature
from cartopy.io.shapereader import Reader
from cartopy.feature import ShapelyFeature

from collections import namedtuple

from .geometry import midpoint, points_circumference, buffer_convex_hull, build_isogloss

DPI = 1200

class MattangError(Exception):
    pass

class FeatureMap:
    """Visualise linguistic data from a spreadsheet.
    """
    def __init__(self):

        self.projection = None
        self.shapefile = None
        self.extent = None
        self.discrete_markers = []
        self.continuous_markers = []
        self.colourbars = []
        self.contours = []

    def load_data(self, dataframe: DataFrame):
        """Precompute various things needed to plot the supplied languages and their features.
        """
        self.dataframe = dataframe
        self._plotdata = {}
        self.projection = ccrs.PlateCarree()

        for feature in self.dataframe.columns:
            data = self.dataframe[feature]
            ndata = len(data)
            try:
                if self.dataframe.dtypes[feature] in ["float64", "int64"]:
                    dtype = "continuous"
                    dnorm = colors.Normalize(min(data), max(data))
                    dgroups = self.dataframe.groupby(feature)
                    drange = int(ndata / 2)
                else:
                    dtype = "discrete"
                    dnorm = colors.BoundaryNorm([i for i in range(ndata)], ndata)
                    dgroups = self.dataframe.groupby(feature)
                    drange = len(dgroups)

                self._plotdata[feature] = {"type": dtype, "norm": dnorm, "groups": dgroups, "range": drange,}
            except TypeError as error:
                # Some field types can have unhashable stuff that can't be groupby'd, so we skip them
                print("Skipping feature {} due to error \"{}\"".format(feature, error))

    def init_map(self, shapefile="", extent=None, projection=ccrs.PlateCarree()):
        """Set up map figure and axis.
        """
        self.projection = projection
        self.fig, self.axis = plt.subplots(1, 1, subplot_kw=dict(projection=projection))

        if shapefile:
            shape = ShapelyFeature(
                Reader(shapefile).geometries(),
                projection,
                edgecolor="k",
                facecolor="none",
            )
            self.axis.add_feature(shape)
            self.shapefile = shapefile
        else:
            self.axis.coastlines(resolution='50m', color='black', linewidth=1)
        if extent:
            self.axis.set_extent(extent, projection)
            self.extent = extent

    def _draw_pie_marker(self, language, features, colours, size=250):
        """sections: (feattype, proportion)
        """
        colourmaps = []
        for f, c in zip(features, colours):
            colourmaps.append(cm.get_cmap(c, self._plotdata[f]["range"]))

        cumsum = numpy.cumsum([2 for f in features])
        cumsum = cumsum / cumsum[-1]
        pie = [0] + cumsum.tolist()

        slices = []
        for r1, r2, feat, cmap in zip(pie[:-1], pie[1:], features, colourmaps):
            # Compute colour for this feature slice
            norm = self._plotdata[feat]["norm"]
            value = language[feat]
            if self._plotdata[feat]["type"] == "discrete":
                value = self._plotdata[feat]["groups"].get_group(value).index[0]
            colour = cmap(norm(value))

            # Build the pie slice
            angles = numpy.linspace(2 * numpy.pi * r1, 2 * numpy.pi * r2)
            x = [0] + numpy.cos(angles).tolist()
            y = [0] + numpy.sin(angles).tolist()
            xy = numpy.column_stack([x, y])
            marker = {"marker": xy, "facecolor": colour, "s": size, "alpha": 1,}
            slices.append(marker)

            # Save the markers for clearing the map, drawing the legend, etc.
            if self._plotdata[feat]["type"] == "discrete":
                self.discrete_markers.append(marker)
            else:
                self.continuous_markers.append(marker)

        # Draw the slices on the axis
        for slyce in slices:
            self.axis.scatter(
                [language["longitude"]],
                [language["latitude"]],
                **slyce,
                transform=self.projection,
            )

    def _draw_pie_markers(self, features, colours):
        for _, lang in self.dataframe.iterrows():
            self._draw_pie_marker(lang, features, colours)
        return

    def _draw_colourbars(self, features, colours):
        colourmaps = [cm.get_cmap(c) for c in colours]
        divider = make_axes_locatable(self.axis)

        # Need to make dummy mappables for the colourbars since we plotted the markers one by one
        for feat, cmap in zip(features, colourmaps):
            if self._plotdata[feat]["type"] == "continuous":
                mappable = cm.ScalarMappable(cmap=cmap, norm=self._plotdata[feat]["norm"])
                ax_cb = divider.new_horizontal(size="5%", pad=0.5, axes_class=plt.Axes)
                self.fig.add_axes(ax_cb)
                bar = plt.colorbar(mappable, cax=ax_cb)
                bar.set_label(feat)
                self.colourbars.append(bar)
        return

    def _draw_legend(self):
        self.axis.legend(self.discrete_markers)
        return

    def _draw_isogloss(self, feature, colour, style, padding):
        groupby = self._plotdata[feature]["groups"]
        group_xy = zip(
            [series.latitude for group, series in groupby],
            [series.longitude for group, series in groupby],
        )
        group_points = [list(zip(lons, lats)) for lats, lons in group_xy]
        for points in group_points:
            filtered = [p for p in points if True not in numpy.isnan(p)]
            print("points:", points, "filtered:", filtered)
            if filtered:
                isogloss = build_isogloss(filtered, padding=padding)
                for point in isogloss:
                    x, y = point
                    self.axis.plot(x, y, "".join([colour, style]), transform=self.projection)

    def _draw_isoglosses(self, features, colour="k", style="-", padding=.1):
        for feature in features:
            self._draw_isogloss(feature, colour, style, padding)
        return

    def draw(self, filename, features, colours=[], isoglosses=[]):
        # Clear the map
        self.init_map(self.shapefile, self.extent, self.projection)

        # Check user input
        if not features:
            raise MattangError("Must specify at least one feature to plot!")

        for f in features:
            if f not in self.dataframe.columns:
                raise MattangError("{} is not a valid feature".format(f))

        if not colours:
            # Use randomly selected colourmaps
            allcolours = plt.colormaps()
            colours = [random.choice(allcolours) for f in features]

        if len(features) != len(colours):
            raise MattangError("Feature and colour list lengths must match")

        # Build and show the map
        self._draw_pie_markers(features, colours)
        if isoglosses:
            self._draw_isoglosses(isoglosses)
        #self._draw_legend()
        self._draw_colourbars(features, colours)
        self.fig.set_dpi(DPI)
        self.fig.tight_layout()
        plt.savefig(filename)


#1.kısım

liste = []
for n in range(0,9):
    sayi = int(input('Sayı Giriniz: '))
    liste.append(sayi)

en_buyuk = max(liste)

print("Liste İçindeki En Büyük Sayı :", en_buyuk )

#2.kısım

x = int(input("Bir üst limit değeri giriniz: "))

for v in range(0, x+2 ,2):
  print(v)

#3.kısım

a = int(input("Bir üst limit değeri giriniz: "))
y = int(input("Bir alt limit değeri giriniz: "))

for i in range(y, a):
    if i%2 == 0:
        print(i)


import numpy as np
from scipy.integrate import quad,dblquad
from numpy import linalg as LA
from scipy.integrate import solve_ivp

def breakage(N, bmat, Svec):
    # N is vector of particle numbers and moments
    # b is discretized breakage function
    # S is discretized selection rate
    n = len(N)
    R1 = np.zeros(n)

    # Mechanism 1 (i=1~n, j=i~n) !!! with index 1~n
    for i in range(n):
        R1[i] = np.sum(bmat[i, i:] * Svec[i:] * N[i:])

    # Mechanism 2 (i=2~n)
    R2 = Svec[1:] * N[1:]
    R2 = np.insert(R2, 0, 0.0)

    dNdt = R1 - R2

    return dNdt

def breakage_moment(Y, bmat, Svec, L):
    n = len(Y) - 4
    N = Y[0:n]

    dNdt = breakage(N, bmat, Svec)

    m0 = np.sum(dNdt)
    m1 = np.sum(L @ dNdt)
    m2 = np.sum(np.power(L, 2) @ dNdt)
    m3 = np.sum(np.power(L, 3) @ dNdt)

    dydt = np.append(dNdt,[m0,m1,m2,m3])

    return dydt

def breakage_discretize(Sfunc, bfunc, L, n, k):
    L = np.insert(L, 0, 0)
    bd = np.zeros((n, n))

    def num_func(x,y):
        return x**3 * Sfunc(y, k) * bfunc(x, y, k)

    def den_func(x):
        return x**3 * Sfunc(x, k)

    for i in range(n):
        den, err = quad(den_func, L[i], L[i+1])
        assert den != 0, 'breakage_discretize: division by zero'
        for j in range(i):
            num, err = dblquad(num_func, L[i], L[i+1],
                               lambda x: L[j], lambda x: L[j+1])
            Li = (L[i]+L[i+1])/2
            Lj = (L[j]+L[j+1])/2
            bd[j, i] = (Li / Lj)**3 * num / den
        num, err = dblquad(num_func, L[i], L[i+1],
                           lambda x: L[i], lambda x: x)
        bd[i, i] = num / den

    return bd

def particle_number(bfunc, y, k):
    Nb, err = quad(lambda x:bfunc(x, y, k), 0, y)
    return Nb

def selection_discretize(Sfunc, bfunc, L, n, k, bd):
    Sd = np.empty(n)
    L = np.insert(L, 0, 0)

    def integrand(y):
        int = (particle_number(bfunc, y, k) - 1) * Sfunc(y, k)
        return int

    for i in range(1, n):
        integ, err = quad(integrand, L[i], L[i+1])
        num = integ / (L[i+1] - L[i])
        sum = np.sum(bd[:i+1, i])
        den = sum - 1
        assert den != 0, 'selection_discretize: division by zero'
        Sd[i] = num / den

    Sd[0] = 0.0
    return Sd

def integ_breakage(breakage, z0, dbs, t, n, p, delta):
    def dzdt(t, z):
        return phi_breakage(breakage, z, dbs, n, p, delta)
    solution = solve_ivp(dzdt, [t[0],t[-1]], z0, method = 'Radau', t_eval = t)
    return solution.y, solution.success

def integ_breakage_onestep(breakage, z, dbs, t, n, p, delta):
    def dxdt(t, x):
        return phi_breakage(breakage, x, dbs, n, p, delta)
    solution = solve_ivp(dxdt, [t[0],t[-1]], z, method = 'Radau', t_eval = t)
    Z = solution.y[:,-1]
    return Z, solution.success

def phi_breakage(breakage, z, dbs, n, p, delta):
    # dbs: discretized breakage and selection functions
    z = z.astype(np.float)
    y = z[0:n]
    J = z[n:].reshape((p, n)).transpose()
    phiz = np.empty(n * (p+1))
    dfdy = np.empty((n, n))
    dfdk = np.empty((p, n))

    for i in range(n):
        yr = y.copy()
        yl = y.copy()
        yr[i] += delta
        yl[i] -= delta
        dfdy[i] = (breakage(yr, dbs[0], dbs[1]) - \
                   breakage(yl, dbs[0], dbs[1])) / (2 * delta)
    dfdy = dfdy.transpose()

    for i in range(p):
        dfdk[i] = (breakage(y, dbs[2][i], dbs[3][i]) - \
                   breakage(y, dbs[4][i], dbs[5][i])) / (2 * delta)
    dfdk = dfdk.transpose()

    dJdt = dfdy @ J + dfdk
    phiz[0:n] = breakage(y, dbs[0], dbs[1])
    phiz[n:] = dJdt.transpose().flatten()
    return phiz

def discretize(Sfunc, bfunc, L, n, p, k, delta=1e-8):
    print('discretizing')
    bd = np.empty((n,n))
    Sd = np.empty(n)
    bdr = np.empty((p,n,n))
    bdl = np.empty((p,n,n))
    Sdr = np.empty((p,n))
    Sdl = np.empty((p,n))

    bd = breakage_discretize(Sfunc, bfunc, L, n, k)
    Sd = selection_discretize(Sfunc, bfunc, L, n, k, bd)

    for i in range(p):
        kr = k.copy()
        kl = k.copy()
        kr[i] += delta
        kl[i] -= delta
        bdr[i] = breakage_discretize(Sfunc, bfunc, L, n, kr)
        bdl[i] = breakage_discretize(Sfunc, bfunc, L, n, kl)
        Sdr[i] = selection_discretize(Sfunc, bfunc, L, n, kr, bdr[i])
        Sdl[i] = selection_discretize(Sfunc, bfunc, L, n, kl, bdl[i])

    return bd, Sd, bdr, Sdr, bdl, Sdl

from scipy.special import erfc

def lnpdf(x, mu, sigma):
    num = np.exp(-(np.log(x) - mu)**2 / (2 * sigma**2))
    den = x * sigma * np.sqrt(2 * np.pi)
    return num / den

def lognorm_b(x, l, mu, sigma):
    assert sigma > 0, "sigma must be larger than 0"

    num = lnpdf(x, mu, sigma)
    den = erfc(-(np.log(l) - mu) / (np.sqrt(2) * sigma))/2

    # In case 'l' is too small compared to 'mu',
    # 'den' can be numerically zero
    # if it is smaller than the machine precision epsilon
    # which is not correct theoretically
    if den == 0:
        den = np.finfo(float).eps
    # convert volume to number
    return (l/x)**3 * num / den

def breakagefunc(x, y, k):
    return x**2 * y * k[1]

def selectionfunc(y, k):
    return k[0] * y**3

if __name__ == '__main__':
    n = 10
    k = [1.0, 2.0]
    p = len(k)
    L = np.linspace(1.0, 20, n)
    res = discretize(selectionfunc, breakagefunc, L, n, p, k, delta=1e-8)


# Import the libraries required for running the program
import urllib.request
import json

# To ensure that this script is able to access the API url
url = ""
class AppURLopener(urllib.request.FancyURLopener):
    version = "Mozilla/5.0"

# Set the initial counter/conditional variables
globalHDCounterTrue = 0
globalHDCounterFalse = 0
checkMore = True
testVar = 1

# Store the test url for reference as a variable
urlTester = "http://api.viki.io/v4/videos.json?app=100250a&per_page=10&page="

# Define the primary condition
while (checkMore == True):
    url = ""
    url = urlTester + str(testVar)

# Convert the JSON object returned as a response to Python
    opener = AppURLopener()
    response = opener.open(url)
    data = json.loads(response.read().decode("utf8"))

# Access the response key which is an array of more JSON objects - 'flags' and within it, a key called 'hd'
    checkMore = data['more']
    checkOther = data['response']
    checkFlags = data['response'][0]['flags']
    checkHD = data['response'][0]['flags']['hd']

# Set counters and conditional statement to calculate the response objects that have flags:hd set to true and false
    i=0
    hdTrue = 0
    hdFalse = 0
    for something in data['response'][i]['flags']:
        if (data['response'][i]['flags']['hd']):
            hdTrue = hdTrue + 1
        else:
            hdFlase = hdFalse + 1
        i = i+1

# Increment page number of the test url
    testVar = testVar + 1

# A global counter to compute the value of response objects - flags:hd set to true and false
    globalHDCounterTrue = globalHDCounterTrue + hdTrue
    globalHDCounterFalse = globalHDCounterFalse + hdFalse

# Print the final results
print ("Total no. of pages parsed are")
print(testVar-1)
print ("Total no. of response objects that have the flag:hd value set to True is")
print(globalHDCounterTrue)
print("Total no. of response objects that have the flag:hd value set to False is")
print(globalHDCounterFalse)


#!/usr/bin/env python2.7

import re

class NewblerMetrics( object ):
    def __init__( self, filepath ):
        self.filepath = filepath

    def __getattr__( self, name ):
        return self.parse_metrics( name )

    def parse_metrics( self, metricname ):
        '''
            Parses run metrics into a dictionary of key values

            @param metricname - Name of metric such as runMetric

            @return Dictionary of all the key,value \w = .*;
        '''
        with open( self.filepath ) as fh:
            m = re.search( metricname + '\n\s{0,}{(.*?)}', fh.read(), re.S )

        if not m:
            raise ValueError( "Could not find metrics {} in {}".format( metricname, self.filepath ) )

        return self.parse_section( m.group(0) )

    def parse_section( self, sectiontext ):
        '''
            Parses a section such as
                runMetrics
                {
                    key = value;
                }

            @param sectiontext - Section text inside of 454NewblerMetrics.txt
            @return dictionary keyed by word before = and value of text after =
                If the text after the = has a comma a tuple will be set as the value for that key
        '''
        m = re.findall( '(\w+)\s+=\s+(.*);', sectiontext )
        if not m:
            raise ValueError( "section is malformed" )

        # Turn the list of tuples into a dictionary
        ret = dict( m )

        # Fix the values so they are the correct types
        for k,v in ret.items():
            # Value is a list
            if ', ' in v:
                lst = v.replace( ' ', '' ).split( ',' )
                newval = []
                for x in lst:
                    newval.append( self.guess_type( x ) )
                ret[k] = tuple( newval )
            else:
                ret[k] = self.guess_type( v )

        return ret

    def guess_type( self, value ):
        '''
            Try to guess the type of value

            @param value - String value
            @returns the same value but hopefully of the correct type
        '''
        if '.' in value:
            value = float( value.replace( '%', '' ) )
        else:
            try:
                value = int( value )
            except ValueError as e:
                pass
        return value


#-*- coding: utf-8 -*-
#!E:\python\python.exe

from flask import render_template, Flask, redirect, flash, session, request, make_response
from app import app
from .forms import LoginForm
from .redis_model import CRedis
from .python_db   import *
import json
import sys
import time

@app.route('/', methods = ['GET', 'POST'])
@app.route('/login', methods = ['GET', 'POST'])
def login():
    form = LoginForm()
    redis_model = CRedis()

    user = redis_model.get('user')
    if not user:
        sys.exit()

    user_array = json.loads(user)

    #如果session有值得话
    if request.cookies.get('username') == 'zhang':
        return redirect('/index')

    #登录成功后
    if form.validate_on_submit():

        if (user_array.get('username') == request.form['username']) and (user_array.get('password') == request.form['password']):

            session['username'] = request.form['username']
            redis_model.set(request.form['username'],request.form['username'])

            response = make_response(redirect('/list_log'))
            response.set_cookie('username',request.form.get("username"))

            return response
        else:
            str = '登录失败'
            flash(str.decode('utf8'))
            return redirect('/login')

    html = make_response(render_template('login.html',
        title = 'Sign In',
        form = form))

    return html

@app.route('/index')
def index():

    redis_model = CRedis()
    username = redis_model.get('zhang')
    return 'Hello,%s'% username

@app.route('/list_log')
def list_log():

    limit_num = request.args.get('limit_num','')
    id        = request.args.get('id','')
    today_num  = request.args.get('today_num',1)

    if id:
        where_sql = {'id':id}
    else:
        where_sql = {}

    if today_num:
        previous = (int(today_num) -  1) * 10
    else:
        previous = 0

    if limit_num:
        limit_sql = str(previous)+','+str(limit_num)
    else :
        limit_sql = str(previous)+',10'

    mysql_model = LinkMysql()
    accept_list = mysql_model._select('sos_api_accept_log','*',where_sql,' id desc ',limit_sql)
    if accept_list:
        for_list = list(accept_list)
        for k,i in enumerate(for_list):

            for_list[k] = list(for_list[k])
            time_local = 0
            time_local = time.localtime(int(for_list[k][4]))

            if str(for_list[k][5]).find('Android') != -1:
                for_list[k].append(u'安卓')
            elif str(for_list[k][5]).find('iPhone') != -1:
                for_list[k].append(u'苹果')
            else:
                for_list[k].append(u'电脑端')

            for_list[k][4] = time.strftime("%Y-%m-%d %H:%M:%S",time_local)

    html = make_response(
		render_template(
		'list.html',
        title = 'Sign In',
        list  = for_list,
        id = id,
        limit_num = limit_num,
        previous = int(today_num) - 1,
        next     = int(today_num) + 1,
		))
    return html

@app.route('/list_log_display')
def list_log_display():

    log_id =  request.args.get('log_id')
    type   =  request.args.get('type')
    mysql_model = LinkMysql()
    accept_list = mysql_model._find('sos_api_accept_log','*',{'id':log_id})

    html = make_response(
		render_template(
		'list_log_display.html',
        title = 'Sign In',
        accept_list = accept_list,
        type  = int(type),
		))
    return html


info = [
    {
        'name': 'Alice',
        'age': 30 ,
        'city':"pune",
        "skills":["python","java","javascript"]
    },
    {
        'name': 'Bob',
        'age': 22,
        'city':"sangamner",
        "skills":["css3","sql","powerBI"]

    },
    {
        'name': 'Charlie',
        'age': 28,
        'city':"pune",
        "skills":["css3","sql","powerBI"]
    },
    {
        'name': 'David',
        'age': 26,
        'city':"nagpur",
        "skills":["css3","flutter","c#"]
    },
    {
        'name': 'Eve',
        'age': 19,
        'city':"jaipur",
        "skills":["css3","flutter","c#"]
    }
]

# program 1

listA = [11,22,33,44,55,66]
print(list(map(lambda x:x+1,listA)))

# program 1
print(list(map(lambda person:person.get('city'),info)))

#program 2
# add  git as skill to every people
print(list(map(lambda person:person['skills'].append("git"),info)))
print(info)
for x in info:
    x['skills'].append("Accountant")
print(info)

# people belong to pune city
# program3
q1 = list(filter(lambda person: person['city'] == "pune",info))
for a in q1:
    print(a['name'])

# program 4
# alice:3
q2 = list(map(lambda person:person['name']+":" + str(len(person['skills'])),info))
print(q2)

# program 5
j = [11,22,33]

from functools import *
print(reduce(lambda acc,y:acc+y,j,5))
print(reduce(lambda acc,person:acc+person['age'],info,0)/len(info))


from django.core.management.base import BaseCommand

from spire.scraper.classes.buildings.raw_building import get_raw_building_room

class Command(BaseCommand):
    help = "Testing for queries."

    def handle(self, *args, **options):

        matched_out = open("./matched", "w")
        unmatched_out = open("./unmatched", "w")

        with open("./possible_rooms", "r") as f:
            matched = 0
            total = 0
            for line in f:
                line = line.strip()
                total += 1

                match = get_raw_building_room(line)
                if not match.endswith("None"):
                    matched += 1

                print(match, file=matched_out if not match.endswith("None") else unmatched_out)

        print(matched / total, file=matched_out)
        print((total - matched) / total, file=unmatched_out)


import logging

import pytest

from dumbo_asp.primitives import Model, Predicate
from xasp.queries import compute_stable_model, compute_minimal_assumption_set, \
    compute_explanation, compute_explanation_dag, compute_serialization, compute_minimal_assumption_sets, \
    compute_explanations, compute_explanation_dags, compute_atoms_explained_by_initial_well_founded

logging.getLogger().setLevel(logging.DEBUG)

def test_compute_stable_model():
    model = compute_stable_model("a.")
    assert len(model) == 1
    assert model[0].predicate_name == "a"

def test_compute_stable_may_return_none():
    model = compute_stable_model("a :- not a.")
    assert model is None

def test_compute_program_serialization():
    model = compute_serialization("""
        a.
        b :- a, not c.
    """, answer_set=Model.of_atoms("a", "b"), additional_atoms_in_base=Model.of_atoms("a", "b", "c"))
    assert model == compute_stable_model("""
        rule(r1).
          head(r1,a).

        rule(r2).
          head(r2,b).
          pos_body(r2,a).
          neg_body(r2,c).

        true(a).
        true(b).
        false(c).
    """)

def test_compute_program_serialization_for_aggregates_with_two_bounds():
    model = compute_serialization("""
        :- 0 <= #sum{X : p(X)} <= 1.
    """, answer_set=Model.of_atoms("p(-1)", "p(1)"), additional_atoms_in_base=Model.of_atoms("p(-1)", "p(1)", "p(2)"))
    assert model == compute_stable_model("""
        rule(r1).
          pos_body(r1,agg1).

        aggregate(agg1, sum, "in", (0,1)).
          agg_set(agg1,p(-1), -1, ()).
          agg_set(agg1,p(1), 1, ()).
          agg_set(agg1,p(2), 2, ()).

        true(p(-1)).
        true(p(1)).
        false(p(2)).
    """)

@pytest.fixture
def running_example_1():
    return compute_serialization("""
        1 <= {arc(X,Y); arc(Y,X)} <= 1 :- edge(X,Y).
        reach(X,X) :- source(X).
        reach(X,Y) :- reach(X,Z), arc(Z,Y).
        fail(X,Y) :- source(X), sink(Y), not reach(X,Y).
        :- threshold(T), #sum{1,X,Y : fail(X,Y)} > T.

        edge(a,b).
        edge(a,d).
        edge(d,c).

        source(a).
        source(b).

        sink(c).

        threshold(0).
    """, answer_set=Model.of_atoms(atom.strip() for atom in """
        edge(a,b)
        edge(a,d)
        edge(d,c)
        source(a)
        source(b)
        sink(c)
        reach(a,a)
        reach(b,b)
        reach(b,a)
        reach(a,d)
        reach(a,c)
        reach(b,d)
        reach(b,c)
        arc(b,a)
        arc(a,d)
        arc(d,c)
        threshold(0)
    """.strip().split('\n')), additional_atoms_in_base=Model.of_atoms(atom.strip() for atom in """
        arc(a,b)
        arc(d,a)
        arc(c,d)
        fail(a,c)
        fail(b,c)
        reach(a,b)
        reach(c,a)
        reach(c,b)
        reach(c,c)
        reach(c,d)
        reach(d,a)
        reach(d,b)
        reach(d,c)
        reach(d,d)
    """.strip().split('\n')))

def test_running_example_1(running_example_1):
    minimal_assumption_set = compute_minimal_assumption_set(running_example_1)
    assert len(minimal_assumption_set) == 0
    explanation = compute_explanation(running_example_1)
    assert len(explanation) == 32

def test_process_aggregate_with_variables():
    assert compute_serialization(
        """
            :- a(X), #sum{Y : b(X,Y)} > 0.
        """,
        answer_set=Model.of_atoms("a(1) a(2) b(1,2)".split()),
        additional_atoms_in_base=Model.of_atoms("b(2,1)")) == compute_stable_model("""
        rule(r1(1)).
            pos_body(r1(1), a(1)).
            pos_body(r1(1), agg1(1)).
            aggregate(agg1(1), sum, ">", 0).
            agg_set(agg1(1), b(1,2), 2, ()).
        rule(r1(2)).
            pos_body(r1(2), a(2)).
            pos_body(r1(2), agg1(2)).
            aggregate(agg1(2), sum, ">", 0).
            agg_set(agg1(2), b(2,1), 1, ()).
        true(a(1)).
        true(a(2)).
        true(b(1,2)).
        false(b(2,1)).
    """)

def test_lack_of_explanation_1():
    serialization = compute_serialization("""
        a :- not b.
        b :- not a.
    """, answer_set=Model.of_atoms('b'), additional_atoms_in_base=Model.of_atoms('a'),
                                          atoms_to_explain=Model.of_atoms('a'))
    minimal_assumption_set = compute_minimal_assumption_set(serialization)
    assert len(minimal_assumption_set) == 1
    assert minimal_assumption_set == compute_stable_model("assume_false(a).")

def test_lack_of_explanation_2():
    serialization = compute_serialization("{a}.", answer_set=Model.of_atoms(),
                                          additional_atoms_in_base=Model.of_atoms('a'),
                                          atoms_to_explain=Model.of_atoms('a'))
    minimal_assumption_set = compute_minimal_assumption_set(serialization)
    assert len(minimal_assumption_set) == 1
    assert minimal_assumption_set == compute_stable_model("assume_false(a).")

def test_lack_of_explanation_3():
    serialization = compute_serialization("a :- #sum{1 : a} >= 0.", answer_set=Model.of_atoms('a'),
                                          additional_atoms_in_base=Model.of_atoms(),
                                          atoms_to_explain=Model.of_atoms('a'))
    with pytest.raises(TypeError):
        compute_minimal_assumption_set(serialization)

def test_atom_inferred_by_constraint_like_rules_can_be_linked_to_false():
    serialization = compute_serialization(
        """
            a :- not b.
            b :- not a.
            :- b.
        """,
        answer_set=Model.of_atoms('a'),
        additional_atoms_in_base=Model.of_atoms('b'),
        atoms_to_explain=Model.of_atoms("a"))
    dag = compute_explanation_dag(serialization)
    assert dag == compute_stable_model("""
        link(1,b,(required_to_falsify_body,r3),"false").
        link(2,a,(support,r1),b).
    """)

def test_atom_inferred_by_choice_rules_can_be_linked_to_false():
    serialization = compute_serialization("""
        {a} <= 0.
    """, answer_set=Model.of_atoms(), additional_atoms_in_base=Model.of_atoms('a'),
                                          atoms_to_explain=Model.of_atoms("a"))
    dag = compute_explanation_dag(serialization)
    assert dag == compute_stable_model("""
        link(1,a,(choice_rule,r1),"false").
    """)

def test_3_col():
    true_atoms = [atom.strip() for atom in """
    color(red)
    color(blue)
    color(yellow)
    node(1)
    node(2)
    node(3)
    node(4)
    node(5)
    edge(1,3)
    edge(2,4)
    edge(2,5)
    edge(3,4)
    edge(3,5)
    colored(3,blue)
    colored(1,yellow)
    colored(4,red)
    colored(2,blue)
    colored(5,yellow)
    """.strip().split('\n')]
    serialization = compute_serialization("""
    node(1).
    node(2).
    node(3).
    node(4).
    node(5).
    edge(1,3).
    edge(2,4).
    edge(2,5).
    edge(3,4).
    edge(3,5).

    {colored(X,C)} :- node(X), color(C).
    :- node(X), #count{C : colored(X,C)} != 1.

    color(red).
    color(blue).
    color(yellow).

    :- edge(X,Y), colored(X, Z), colored(Y, Z).
    """, answer_set=Model.of_atoms(true_atoms), additional_atoms_in_base=Model.of_atoms(atom.strip() for atom in """
    colored(3,yellow)
    colored(3,red)
    colored(2,yellow)
    colored(1,blue)
    colored(4,blue)
    colored(5,red)
    colored(4,yellow)
    colored(1,red)
    colored(5,blue)
    colored(2,red)
    """.strip().split('\n')), atoms_to_explain=Model.of_atoms("colored(4,red)"))
    dag = compute_explanation_dag(serialization)
    assert len(dag) == 4

def test_compute_all_minimal_assumption_sets():
    serialization = compute_serialization(
        """
            a :- not b.
            b :- not a.
            c :- not a.
            a :- not c.
        """,
        answer_set=Model.of_atoms("a"),
        additional_atoms_in_base=Model.of_atoms("b", "c"),
        atoms_to_explain=Model.of_atoms("a")
    )
    minimal_assumption_sets = compute_minimal_assumption_sets(serialization, atoms_to_explain=Model.of_atoms("a"))
    assert len(minimal_assumption_sets) == 2

def test_rule_with_arithmetic():
    serialization = compute_serialization(
        """
            a(X) :- X = 1..2.
        """,
        answer_set=Model.of_atoms("a(1)", "a(2)"),
        additional_atoms_in_base=Model.of_atoms(),
        atoms_to_explain=Model.of_atoms("a(1)")
    )
    minimal_assumption_set = compute_minimal_assumption_set(serialization)
    assert len(minimal_assumption_set) == 0
    assert compute_explanation(serialization) == compute_stable_model("""
        explained_by(1,a(1),(support,r1(1))).
    """)
    assert compute_explanation_dag(serialization) == compute_stable_model("""
        link(1,a(1),(support,r1(1)),"true").
    """)

def test_compute_explanations():
    serialization = compute_serialization(
        """
            {a; b}.
            :- a, not b.
            :- b, not a.
            c :- a, b.
        """,
        answer_set=Model.of_atoms(),
        additional_atoms_in_base=Model.of_atoms("a", "b", "c"),
        atoms_to_explain=Model.of_atoms("c")
    )
    explanations = compute_explanations(serialization, atoms_to_explain=Model.of_atoms("c"))
    assert len(explanations) == 2

def test_compute_dags():
    serialization = compute_serialization(
        """
            {a; b}.
            c :- a, b.
        """,
        answer_set=Model.of_atoms(),
        additional_atoms_in_base=Model.of_atoms("a", "b", "c"),
        atoms_to_explain=Model.of_atoms("c")
    )
    assert len(compute_explanation_dags(serialization, Model.of_atoms("c"))) == 2

def test_choice_rule_with_condition_arithmetic():
    serialization = compute_serialization(
        """
            {a(X) : X = 1..2} = 1.
        """,
        answer_set=Model.of_atoms("a(1)"),
        additional_atoms_in_base=Model.of_atoms("a(2)"),
        atoms_to_explain=Model.of_atoms("a(2)")
    )
    explanation = compute_explanation(serialization).project(Predicate.parse("explained_by/3"), 1)
    assert "explained_by(a(2),(choice_rule,r1))." in explanation.as_facts

def test_choice_rule_with_condition_involving_atoms():
    serialization = compute_serialization(
        """
            {a(X) : X = 1..5, b(X)} = 1.
            b(0).
            b(3).
        """,
        answer_set=Model.of_atoms("a(3)", "b(0)", "b(3)"),
        additional_atoms_in_base=Model.of_atoms(),
        atoms_to_explain=Model.of_atoms("a(3)")
    )
    dag = compute_explanation_dag(serialization)
    assert 'link(1,a(3),(support,r1),"true").' in dag.as_facts

def test_rule_with_compressed_head():
    serialization = compute_serialization(
        "a(1;2).",
        answer_set=Model.of_atoms("a(1)", "a(2)"),
        additional_atoms_in_base=Model.of_atoms(),
        atoms_to_explain=Model.of_atoms("a(1)")
    )
    explanation = compute_explanation(serialization)
    assert "explained_by(1,a(1),(support,r1))." in explanation.as_facts

def test_strong_negation():
    serialization = compute_serialization("""
        {a; -a}.
    """, answer_set=Model.of_atoms("a"), additional_atoms_in_base=Model.of_atoms("a", "-a"),
                                          atoms_to_explain=Model.of_atoms("-a"))
    explanation = compute_explanation(serialization)
    assert "explained_by(2,-a,(required_to_falsify_body,r2))." in explanation.as_facts

def test_atoms_in_negative_literals_are_added_to_the_base_during_serialization():
    serialization = compute_serialization("a :- not b.", answer_set=Model.of_atoms("a"),
                                          additional_atoms_in_base=Model.empty(),
                                          atoms_to_explain=Model.of_atoms("a"))
    assert "false(b)." in serialization.as_facts
    minimal_assumption_set = compute_minimal_assumption_set(serialization)
    assert len(minimal_assumption_set) == 0

def test_compute_well_founded():
    serialization = compute_serialization("""
        a :- c, not b.
        b :- not a.
        c.
        d :- e, not f.
        d :- f, not g.
        d :- h.
        e :- d.
        f :- e.
        f :- not c.
        i :- c, not d.
    """, answer_set=Model.of_atoms("c", "i", "a"), additional_atoms_in_base=Model.of_atoms("a b c d e f g h i".split()),
                                          atoms_to_explain=Model.empty())
    well_founded = compute_atoms_explained_by_initial_well_founded(serialization)
    assert compute_stable_model("""
        explained_by(d,initial_well_founded).
        explained_by(e,initial_well_founded).
        explained_by(f,initial_well_founded).
        explained_by(g,initial_well_founded).
        explained_by(h,initial_well_founded).
    """) == well_founded

def test_minimal_assumption_set_block_up_must_take_into_account_weights():
    serialization = compute_serialization("""
        {a; b}.
        c :- a.
        c :- b.
    """, answer_set=Model.empty(), atoms_to_explain=Model.of_atoms("c"))
    sets = compute_minimal_assumption_sets(serialization, Model.of_atoms("c"))
    for s in sets: print(s.as_facts ,'-')
    assert "c." not in sets[0].as_facts
    assert len(sets) == 1


# from .views import CategoryListView, CategoryDetailView, CategoryViewSet, ProductViewSet
from . import views
from django.conf.urls import url, include
from rest_framework.urlpatterns import format_suffix_patterns

product_list = views.ProductViewSet.as_view({
    'get': 'list',
    'post': 'create'
})
product_detail = views.ProductViewSet.as_view({
    'get': 'retrieve',
    'put': 'update',
    'patch': 'partial_update',
    'delete': 'destroy'
})

product_list_by_category  = views.ProductCategoryList.as_view()

urlpatterns = [
    url(r'^$', product_list, name="product-list"),
    url(r'^(?P<slug>[-\w]+)/$', product_detail, name="product-detail"),
    url(r'^category/(?P<slug>[-\w]+)/$', product_list_by_category, name='product-category-list'),

]

urlpatterns = format_suffix_patterns(urlpatterns)


from random import *

def random_number():
    global comp_number
    comp_number = randint(1,10)
    #print(comp_number)
    return comp_number

def user_input():
    user_guess = 0
    global count
    count = 1
    random_number()
    while user_guess!= comp_number:
        print("Guess #", count)
        user_guess = input("Type your number: ")
        if user_guess.isdigit():
            guesses(user_guess)
            count+=1
        else:
            print("This is not a number! Try again!")
            count+=1
            pass

def guesses(user_guess):
    if int(user_guess) > comp_number:
        number_is_bigger()
    elif int(user_guess)<comp_number:
        number_is_smaller()
    else:
        number_is_equal()

def number_is_bigger():
    print("Your number is bigger!")

def number_is_smaller():
    print("Your number is smaller!")

def number_is_equal():
    print("You won from the", count, 'try!')
    exit(0)

if __name__ == '__main__':
    user_input()
else:
    print("imported")


from datetime import datetime
from time import sleep

import requests
from pandas import DataFrame
from bs4 import BeautifulSoup

CNB_NEWS_ARCHIVE_URL = ("https://www.cnb.gov.sg/newsandevents/news/archive"
                        "/archivesubnews/index/{year}")

event_write_up = []
event_titles = []
dates = []
links = []
for year in range(2012, 2023):
    resp = requests.get(CNB_NEWS_ARCHIVE_URL.format(year=year))
    soup = BeautifulSoup(resp.text, 'html.parser')
    timeline_panels = soup.find_all('div', 'tl-heading')
    for tp in timeline_panels:
        event_title = tp.find('h4').get_text()
        event_link = tp.find('a').get('href')
        event_date = datetime.strptime(tp.find('p').get_text(), ' %d %b %Y')
        event_date = event_date.strftime('%Y-%m-%d')
        dates.append(event_date)
        links.append('https://www.cnb.gov.sg' + event_link)
        event_titles.append(event_title)
        article_resp = requests.get(links[-1])
        if article_resp.status_code != 200:
            continue
        art_soup = BeautifulSoup(article_resp.text, 'html.parser')
        p_tags = art_soup.find_all('p')
        write_up = ' '.join([p_tag.text for p_tag in p_tags])
        event_write_up.append(write_up)
        sleep(0.1)

DataFrame(
  {'title': event_titles,
   'date': dates,
   'link': links,
   'article': event_write_up}).to_csv("cnb_articles.csv")


import numpy
import scipy.linalg
A = numpy.zeros((101,101))
i,j = numpy.indices(A.shape)
A[i==j+1]=1
A[i==j]=1
A[i==j+2]=1
B = numpy.arange(101)
print(scipy.linalg.solve(A,B))
print(A)


# -*- coding: utf-8 -*-
badwordsfile = open("badwords.txt","r")
badwords = []
for line in badwordsfile:
    line = line.strip("\n")
    line = line.lower()
    badwords.append(line)
def check(message):
    message = message.lower()
    badwordsnumber = 0
    for badword in badwords:
        if badword in message:
            badwordsnumber = badwordsnumber + 1
    print (badwordsnumber)
    return badwordsnumber

#check ('Idiot Dummi Arsch Pfosten Stupid Ashole Fuck Scheiße') # Example


from electronics_abstract_parts import *
from .JlcPart import JlcPart

class SmtLed(Led, FootprintBlock):
  def contents(self):
    super().contents()
    self.footprint(
      'D', 'LED_SMD:LED_0603_1608Metric',
      {
        '2': self.a,
        '1': self.k,
      },
      part='LED',
    )

class ThtLed(Led, FootprintBlock):
  def contents(self):
    super().contents()
    self.footprint(
      'D', 'LED_THT:LED_D5.0mm',
      {
        '2': self.a,
        '1': self.k,
      },
      part='LED',
    )

class Smt0606RgbLed(RgbLedCommonAnode, JlcPart, FootprintBlock):
  def contents(self):
    super().contents()
    self.footprint(
      'D', 'LED_SMD:LED_LiteOn_LTST-C19HE1WT',
      {  # ABGR configuration - also pins 1/2 and 3/4 are swapped on this pattern
        '2': self.a,
        '1': self.k_blue,
        '4': self.k_green,
        '3': self.k_red,
      },
      mfr='Everlight Electronics Co Ltd', part='EAST1616RGBB2'
    )
    self.assign(self.lcsc_part, 'C264517')
    self.assign(self.actual_basic_part, False)

class Smt0404RgbLed(RgbLedCommonAnode, JlcPart, FootprintBlock):
  def contents(self):
    super().contents()
    self.footprint(
      'D', 'LED_SMD:LED_Lumex_SML-LX0404SIUPGUSB',
      {
        '1': self.a,
        '2': self.k_red,
        '3': self.k_green,
        '4': self.k_blue,
      },
      mfr='Foshan NationStar Optoelectronics', part='FC-B1010RGBT-HG'
    )
    self.assign(self.lcsc_part, 'C158099')
    self.assign(self.actual_basic_part, False)

class ThtRgbLed(RgbLedCommonAnode, FootprintBlock):
  def contents(self):
    super().contents()
    self.footprint(
      'D', 'LED_THT:LED_D5.0mm-4_RGB_Staggered_Pins',
      {  # RAGB configuration
        '1': self.k_red,
        '2': self.a,
        '3': self.k_green,
        '4': self.k_blue,
      },
      mfr='Sparkfun', part='COM-09264'
    )


import time
import os
import shutil
import multiprocessing

def copy_item(item):
    source_item, destination_item = item
    try:
        if os.path.isfile(source_item):
            shutil.copy2(source_item, destination_item)
        else:
            shutil.copytree(source_item, destination_item)
        # print(f"Copied item: {destination_item}")
    except Exception as e:
        print(f"Failed to copy item: {e}")

if __name__ == '__main__':
    start_time = time.time()
    # Configuration
    source_path = "demo_files4/"
    destination_path = "/home/tmp"

    # Create a multiprocessing.Pool
    with multiprocessing.Pool() as pool:
        # Iterate over files and directories in source path
        for root, dirs, files in os.walk(source_path):
            for file in files:
                source_file = os.path.join(root, file)
                destination_file = os.path.join(
                    destination_path,
                    os.path.relpath(source_file, source_path)
                )
                item = (source_file, destination_file)
                pool.apply_async(copy_item, (item,))
            for dir in dirs:
                source_dir = os.path.join(root, dir)
                destination_dir = os.path.join(
                    destination_path,
                    os.path.relpath(source_dir, source_path)
                )
                item = (source_dir, destination_dir)
                pool.apply_async(copy_item, (item,))

        # Close the pool and wait for all processes to finish
        pool.close()
        pool.join()

    print("All items copied and took seconds =",
          time.time() - start_time)


import pygame
import os
import math

from AnimatedSprite import AnimatedSprite
from Dust import Dust

class Game:

    def __init__(self, input_handler, win):
        self.win = win
        self.objects = [[],[],[],[],[]]
        self.ticktack_receivers = []
        self.mouse_tracking = []
        self.input_handler = input_handler
        self.game_window = (1024,768)
        self.game_window = (1280,720)
        self.window_center = pygame.math.Vector2(self.game_window[0]//2, self.game_window[1]//2)
        self.clock = pygame.time.Clock()
        self.focused = []
        self.time = 0
        self.initial_zoom = 0.00001
        self.zoom = self.initial_zoom
        self.zoom_speed = 15
        self.zoom_locked = None
        self.zoom_enabled = True
        self.stop_time = None
        self.camera = [ 0, 0 ]
        self.animations = {
            'explosion' : AnimatedSprite( "explosion.png", 8, 6, 96, False ),
            'spark' : AnimatedSprite( "spark.png", 4, 4, 16, False ),
            'shield' : AnimatedSprite( "shield.png", 5, 5, 96, True ),
        }
        self.paused = True
        self.key_handlers = {}
        self.font = pygame.font.Font('assets/Komika-Display/Komika_display.ttf', 16)
        self.drag_rect = None
        self.reset_fieldview()
        self.team = None

    def reset_fieldview( self ) :
        max_width = self.game_window[0]
        max_height = self.game_window[1]
        self.optimal_fieldview = pygame.Rect(-max_width//2,-max_height//2,max_width,max_height)
        self.target_zoom = 1

    def add_object(self, obj):
        self.objects[obj.Z].append( obj )

    def add_ticktack_receiver(self, receiver) :
        self.ticktack_receivers.append(receiver)

    def add_command_receiver(self, receiver) :
        self.command_receivers.append(receiver)

    def remove_object(self, obj):
        if obj in self.objects[obj.Z] :
            self.objects[obj.Z].remove(obj)
        if obj in self.focused :
            self.focused.remove( obj )

    def get_focused( self ) :
        if len(self.focused) > 0 :
            return self.focused[0]
        else :
            return None

    def set_focused(self, focused) :
        self.focused = [ focused ]

    def push_focused(self, focused) :
        if focused == None :
            raise ValueError("focused can't be None")
        self.focused.insert( 0, focused )

    def pop_focused( self ) :
        if len(self.focused) > 0 :
            removed = self.focused.pop(0)
            removed.on_focus_lost()

    def get_collisions(self, pygame_rect ):
        collisions = []
        for obj in self.objects[0]:
            if obj.can_be_hit and obj.get_collision_rect().colliderect(pygame_rect):
                collisions.append(obj)
        return collisions

    def get_selections(self, pygame_rect ):
        selections = []
        for obj in self.objects[0]:
            if obj.can_be_hit and obj.get_collision_rect(1).colliderect(pygame_rect):
                selections.append(obj)
        return selections

    def get_objects_in_range(self, x, y, range) :
        res = []
        for obj in self.objects[0] :
            if obj.can_be_hit and obj.distance_to_xy(x, y) <= range :
                res.append( obj )
        return res

    def get_time( self ) :
        return self.time

    def get_visible_rectangle( self, layer, zoom = None ) :
        if zoom == None :
            zz = self.zoom
        else :
            zz = zoom
        if layer == 0 :
            z = 1
        elif layer == 1 :
            z = 2.5
        else :
            z = 5
        width = self.game_window[0] * z / zz
        height = self.game_window[1] * z / zz
        rect = pygame.Rect(0, 0, width, height)
        rect.center = self.camera
        return rect

    def move_to_contain( self, rect1, rect2 ) :
        "move rect1 so that it contains rect2"
        if rect1.right < rect2.right :
            rect1.move_ip(rect2.right - rect1.right, 0)
        elif rect2.left < rect1.left :
            rect1.move_ip(rect2.left - rect1.left, 0)
        if rect2.top < rect1.top :
            rect1.move_ip(0, rect2.top - rect1.top)
        elif rect1.bottom < rect2.bottom :
            rect1.move_ip(0, rect2.bottom - rect1.bottom)
        return rect1

    def compute_optimal_fieldview( self ) :
        if self.zoom_locked != None and self.zoom_locked > self.get_time() :
            return
        max_width = self.game_window[0]
        max_height = self.game_window[1]
        important_objects = [obj for obj in self.objects[0] if obj.is_important]
        if len(important_objects)==0 :
            print(f'compute_optimal_fieldview: NO IMPORTANT OBJECTS')
            self.reset_fieldview()
            return
        all_ships_fieldview = important_objects[0].get_rect()
        for obj in important_objects[1:] :
            all_ships_fieldview = all_ships_fieldview.union(obj.get_rect())
        all_fit = True
        if all_ships_fieldview.width <= max_width and all_ships_fieldview.height <= max_height :
            if self.target_zoom != 1 :
                self.toggle_zoom({'force':True})
                self.optimal_fieldview = all_ships_fieldview
        elif all_ships_fieldview.width > 2 * max_width or all_ships_fieldview.height >= 2 * max_height :
            all_fit = False
            if self.target_zoom != 1 :
                self.toggle_zoom({'force':True})
                self.optimal_fieldview.inflate_ip(-max_width, -max_height)
        elif self.target_zoom == 1 :
            self.optimal_fieldview.inflate_ip(max_width,max_height)
            max_widht = 2 * self.game_window[0]
            max_height = 2 * self.game_window[1]
            self.toggle_zoom({'force':True})
        else :
            max_width = 2 * self.game_window[0]
            max_height = 2 * self.game_window[1]
        focused_rect = all_ships_fieldview # guard
        if len(self.focused) > 0 :
            focused_rect = self.focused[0].get_rect().inflate(200,200)
            fv = all_ships_fieldview.union(focused_rect)
            if all_fit :
                if fv.width <= max_width and fv.height <= max_height :
                    all_ships_fieldview = fv
            else :
                if fv.width <= max_width and fv.height <= max_height :
                    all_ships_fieldview = fv
                else :
                    all_ships_fieldview = focused_rect
        if not self.optimal_fieldview.contains(all_ships_fieldview) :
            self.optimal_fieldview = self.move_to_contain(self.optimal_fieldview, all_ships_fieldview)
        self.optimal_fieldview.inflate_ip(
            self.game_window[0] / self.target_zoom - self.optimal_fieldview.width,
            self.game_window[1] / self.target_zoom - self.optimal_fieldview.height )
        assert self.optimal_fieldview.width == self.game_window[0] / self.target_zoom
        assert self.optimal_fieldview.height == self.game_window[1] / self.target_zoom

    def get_optimal_camera( self ) :
        return self.optimal_fieldview.center

    def compute_pans(self) :
        self.pan1 = (
            self.camera[0]-self.game_window[0]/2/self.zoom,
            self.camera[1]-self.game_window[1]/2/self.zoom )
        self.pan2 = (
            self.camera[0]/2.5/self.zoom-self.game_window[0]/2/2.5/self.zoom,
            self.camera[1]/2.5/self.zoom-self.game_window[1]/2/2.5/self.zoom)
        self.pan3 = (self.camera[0]/5-self.game_window[0]/2/self.zoom,self.camera[1]/5-self.game_window[1]/2/self.zoom)

    def pan_camera(self) :
        optimal_camera = self.get_optimal_camera()
        d = (optimal_camera[0]-self.camera[0], optimal_camera[1]-self.camera[1])
        recompute_pans = abs(d[0])>=1 or abs(d[1])>=1
        if not recompute_pans :
            return
        if abs(d[0]>10) or abs(d[1]>10) :
            self.camera[0] = self.approach_value(self.camera[0],optimal_camera[0],15)
            self.camera[1] = self.approach_value(self.camera[1],optimal_camera[1],15)
        else :
            d = ( max(1,d[0]/10) if d[0]>=0 else min(-1,d[0]/10),
                  max(1,d[1]/10) if d[1]>=0 else min(-1,d[1]/10) )
            self.camera[0] += d[0]
            self.camera[1] += d[1]
        if recompute_pans :
            self.compute_pans()

    def toggle_zoom(self, args) :
        if not self.zoom_enabled :
            return
        if args.get('force', False) or self.zoom == self.target_zoom :
            Dust.remove_dust(self)
            self.target_zoom = 1.5 - self.target_zoom
            Dust.make_dust(self, self.target_zoom)
        if args.get('lock',False) :
            self.zoom_locked = self.get_time() + 5000

    def toggle_pause(self) :
        print('Toggle pause')
        self.paused = not self.paused

    def get_display_xy( self, x, y, layer = 0 ) :
        "given game coords, give display coords"
        if layer == 0 :
            xy_rel_camera = ( x - self.camera[0], y - self.camera[1] )
            xy_from_layer = xy_rel_camera
            xy_from_zoom = ( self.zoom * xy_from_layer[0], self.zoom * xy_from_layer[1] )
            return (self.game_window[0] / 2 + xy_from_zoom[0], self.game_window[1] / 2 + xy_from_zoom[1])
        elif layer == 1 :
            xy_rel_camera = ( x - self.camera[0], y - self.camera[1] )
            xy_from_layer = ( xy_rel_camera[0] / 2.5, xy_rel_camera[1] / 2.5 )
            xy_from_zoom = ( self.zoom * xy_from_layer[0], self.zoom * xy_from_layer[1] )
            return (self.game_window[0] / 2 + xy_from_zoom[0], self.game_window[1] / 2 + xy_from_zoom[1])
        else :
            return (self.zoom*(x - self.pan3[0]), self.zoom*(y - self.pan3[1]))

    def get_screen_distance_from_center( self, x, y ) :
        p1 = pygame.math.Vector2(*self.get_display_xy( x, y ))
        return self.window_center.distance_to(p1)

    def get_screen_centerism( self, x, y ) :
        v = self.get_screen_distance_from_center(x,y)
        t = min(self.game_window[0]//2, self.game_window[1]//2)
        if v > t : return 0
        return (t-v) / t

    def get_xy_display( self, x, y, layer = 0 ) :
        "given display coords, give game coords (in layer 0)"
        return (
            x - self.game_window[0] / 2 / self.zoom + self.camera[0],
            y - self.game_window[1] / 2 / self.zoom + self.camera[1]
        )

    def get_display_rect( self, rect, layer ) :
        (left, top) = self.get_display_xy( rect.left, rect.top, layer )
        if layer == 0 :
            layer_factor = 1
        elif layer == 1 :
            layer_factor = 2.5
        else :
            layer_factor = 5
        width = rect.width * self.zoom / layer_factor
        height = rect.height * self.zoom / layer_factor
        return pygame.Rect( left, top, width, height )

    def compute_bounding_rect_old(self) :
        important_objects = [obj for obj in self.objects[0] if obj.is_important]

        if not important_objects:
            return None  # Return None if there are no important objects

        # Initialize the bounding rectangle with the first object's rectangle
        bounding_rect = important_objects[0].get_rect()

        # Expand the bounding rectangle to include all other important objects
        for obj in important_objects[1:]:
            bounding_rect.union_ip(obj.get_rect())

        print(f'important_objects: {len(important_objects)}, bounding_rect: {bounding_rect}')
        return bounding_rect

    def game_loop( self ):
        self.running = True
        while self.running:
            self.time += 1

            if self.stop_time != None and self.stop_time <= self.time :
                self.running = False

            self.clock.tick(60)  # Limit the game loop to 60 frames per second

            self.compute_optimal_fieldview()

            self.zoom = Game.approach_value(self.zoom, self.target_zoom, self.zoom_speed)

            self.win.fill((0, 0, 0))
            if self.input_handler.handle_input(len(self.mouse_tracking)>0) == False :
                self.running = False

            # world_surface = pygame.Surface((self.game_window[0]/self.zoom,self.game_window[1]/self.zoom))  # The surface that represents the game world

            self.compute_pans()

            #if not self.paused :
                # self.pan_camera(bounding_rect)
            self.pan_camera()

            for receiver in self.ticktack_receivers :
                receiver.ticktack()

            for z_list in reversed(self.objects) :
                for obj in z_list :
                    if not self.paused or not obj.affected_by_pause :
                        obj.ticktack()

            for z_list in reversed(self.objects) :
                for obj in z_list :
                    if obj.visible :
                        obj.repaint( self.win ) # span1, pan2, pan3)
                    # obj.repaint(world_surface, pan1, pan2, pan3 )
            focus_painted = False
            for obj in self.focused :
                if obj.focus_visible and not focus_painted :
                    obj.draw_select(self.win, (0,255,0))
                    focus_painted = True
                if obj.visible :
                    obj.repaint_focused( self.win )
            if self.drag_rect != None :
                pygame.draw.rect(self.win, (0,180,255), self.drag_rect, 1)

            # Resize world_surface to achieve a zoom effect
            # zoomed_surface = pygame.transform.smoothscale(world_surface, self.game_window)

            # Then draw zoomed_surface onto self.win
            # self.win.blit(zoomed_surface, (0, 0))

            pygame.display.flip()

    def get_animation(self, animation_name) :
        return self.animations[animation_name]

    def set_mouse_tracking(self, obj, tracking_enabled) :
        if tracking_enabled :
            self.mouse_tracking.append( obj )
        else :
            self.mouse_tracking.remove( obj )

    def mouse_track( self, x, y ) :
        dc = self.get_xy_display( x, y )
        for obj in self.mouse_tracking :
            if obj.get_collision_rect().collidepoint( *dc ) :
                obj.mouse_track( dc, (x,y) )

    def click( self, x, y ) :
        if len(self.focused) > 0 :
            print(f'focused click')
            gxy = self.get_xy_display( x, y )
            if self.focused[0].click( *gxy ) :
                return
            print(f'focused click ignored')
        print(f'unfocused click')
        game_coords = self.get_xy_display( x, y )
        objects_here = self.get_selections(pygame.Rect(*game_coords,1,1))
        objects_selectable = [ obj for obj in objects_here if obj.is_selectable ]
        if len(objects_selectable) > 0 :
            self.set_focused( objects_selectable[0] )

    def click3( self, x, y ) :
        if len(self.focused) > 0 :
            game_coords = self.get_xy_display( x, y )
            objects_here = self.get_selections(pygame.Rect(*game_coords,1,1))
            self.focused[0].default_action(game_coords, objects_here)

    def on_key_pressed(self, key, mod = None) :
        print(f"Game: on_key_pressed: {key}")
        handler = self.key_handlers.get( key )
        if handler != None :
            handler.on_key_pressed( key, mod )

    def register_key_handler(self, key, handler) :
        self.key_handlers[ key ] = handler

    def on_stop_request(self) :
        self.zoom_locked = self.get_time() + 1000
        for ol in self.objects :
            for o in ol :
                o.on_stop_request()
        for o in self.ticktack_receivers :
            o.on_stop_request()
        Dust.remove_dust(self)
        self.stop_time = self.get_time() + 50
        self.zoom = 1
        self.target_zoom = self.initial_zoom
        self.zoom_speed = 15

    def get_font( self ) :
        return self.font

    def set_camera(self, pos) :
        self.set_optimal_camera( pos )
        self.camera[0] = self.optimal_camera[0]
        self.camera[1] = self.optimal_camera[1]

    def set_optimal_camera(self, pos) :
        self.optimal_fieldview.center = pos
        self.optimal_camera = pos
        self.zoom_locked = self.get_time() + 1000

    def drag_start(self, pos) :
        self.drag_p1 = pos

    def drag_continue(self, pos) :
        self.drag_p2 = pos
        top_left_x = min(self.drag_p1[0], self.drag_p2[0])
        top_left_y = min(self.drag_p1[1], self.drag_p2[1])
        width = abs(self.drag_p1[0] - self.drag_p2[0])
        height = abs(self.drag_p1[1] - self.drag_p2[1])
        self.drag_rect = pygame.Rect(top_left_x, top_left_y, width, height)
        self.default_group.remove_all()
        for obj in self.objects[0] :
            if not obj.is_selectable or obj.is_hostile(self.team) :
                continue
            if obj.is_inside_display_rect(self.drag_rect) :
                self.default_group.add_ship(obj)
        if self.default_group.is_empty() :
            if len(self.focused) > 0 and self.focused[0]==self.default_group :
                self.pop_focused()
        else :
            self.set_focused( self.default_group )

    def drag_stop(self, pos) :
        self.drag_p1 = None
        self.drag_p2 = None
        self.drag_rect = None

    def set_team(self, team, default_group) :
        self.team = team
        self.default_group = default_group

    def set_default_group(self, default_group) :
        print(f"Set default group: {default_group.number}")
        self.default_group = default_group
        self.set_focused(self.default_group)

    @staticmethod
    def is_acute_angle(dir1, dir2):
        # Calculate the difference between the two directions
        diff = abs(dir1 - dir2) % 360
        # Adjust for the case where the angle crosses the 0/360 boundary
        if diff > 180:
            diff = 360 - diff
        # Check if the angle is acute
        return diff < 90

    @staticmethod
    def approach_value(value, target, delay) :
        speed = max(0.002,abs(value - target) / delay)
        if value < target :
            return min( target, value + min(speed, target - value) )
        elif value > target :
            return max( target, value - min(speed, value - target) )
        else :
            return value