from typing import List, Optional

import graphene
from graphql import GraphQLError

from ...permission.enums import ProductPermissions
from ...permission.utils import has_one_of_permissions
from ...product.models import ALL_PRODUCTS_PERMISSIONS
from ..channel import ChannelContext
from ..channel.utils import get_default_channel_slug_or_graphql_error
from ..core import ResolveInfo
from ..core.connection import create_connection_slice, filter_connection_queryset
from ..core.descriptions import ADDED_IN_310
from ..core.enums import ReportingPeriod
from ..core.fields import ConnectionField, FilterConnectionField, PermissionsField
from ..core.tracing import traced_resolver
from ..core.types import NonNullList
from ..core.utils import from_global_id_or_error
from ..core.validators import validate_one_of_args_is_in_query
from ..translations.mutations import (
    CategoryTranslate,
    CollectionTranslate,
    ProductTranslate,
    ProductVariantTranslate,
)
from ..utils import get_user_or_app_from_context
from .bulk_mutations import (
    CategoryBulkDelete,
    CollectionBulkDelete,
    ProductBulkDelete,
    ProductMediaBulkDelete,
    ProductTypeBulkDelete,
    ProductVariantBulkCreate,
    ProductVariantBulkDelete,
    ProductVariantBulkUpdate,
    ProductVariantStocksCreate,
    ProductVariantStocksDelete,
    ProductVariantStocksUpdate,
)
from .filters import (
    CategoryFilterInput,
    CollectionFilterInput,
    ProductFilterInput,
    ProductTypeFilterInput,
    ProductVariantFilterInput,
)
from .mutations import (
    CategoryCreate,
    CategoryDelete,
    CategoryUpdate,
    CollectionAddProducts,
    CollectionCreate,
    CollectionDelete,
    CollectionRemoveProducts,
    CollectionReorderProducts,
    CollectionUpdate,
    ProductCreate,
    ProductDelete,
    ProductMediaCreate,
    ProductMediaDelete,
    ProductMediaReorder,
    ProductMediaUpdate,
    ProductTypeCreate,
    ProductTypeDelete,
    ProductTypeUpdate,
    ProductUpdate,
    ProductVariantCreate,
    ProductVariantDelete,
    ProductVariantPreorderDeactivate,
    ProductVariantReorder,
    ProductVariantSetDefault,
    ProductVariantUpdate,
    VariantMediaAssign,
    VariantMediaUnassign,
)
from .mutations.attributes import (
    ProductAttributeAssign,
    ProductAttributeAssignmentUpdate,
    ProductAttributeUnassign,
    ProductReorderAttributeValues,
    ProductTypeReorderAttributes,
    ProductVariantReorderAttributeValues,
)
from .mutations.channels import (
    CollectionChannelListingUpdate,
    ProductChannelListingUpdate,
    ProductVariantChannelListingUpdate,
)
from .mutations.digital_contents import (
    DigitalContentCreate,
    DigitalContentDelete,
    DigitalContentUpdate,
    DigitalContentUrlCreate,
)
from .resolvers import (
    resolve_categories,
    resolve_category_by_id,
    resolve_category_by_slug,
    resolve_collection_by_id,
    resolve_collection_by_slug,
    resolve_collections,
    resolve_digital_content_by_id,
    resolve_digital_contents,
    resolve_product,
    resolve_product_type_by_id,
    resolve_product_types,
    resolve_product_variants,
    resolve_products,
    resolve_report_product_sales,
    resolve_variant,
)
from .sorters import (
    CategorySortingInput,
    CollectionSortingInput,
    ProductOrder,
    ProductOrderField,
    ProductTypeSortingInput,
    ProductVariantSortingInput,
)
from .types import (
    Category,
    CategoryCountableConnection,
    Collection,
    CollectionCountableConnection,
    DigitalContent,
    DigitalContentCountableConnection,
    Product,
    ProductCountableConnection,
    ProductType,
    ProductTypeCountableConnection,
    ProductVariant,
    ProductVariantCountableConnection,
)

def search_string_in_kwargs(kwargs: dict) -> bool:
    return bool(kwargs.get("filter", {}).get("search", "").strip())

def sort_field_from_kwargs(kwargs: dict) -> Optional[List[str]]:
    return kwargs.get("sort_by", {}).get("field") or None

class ProductQueries(graphene.ObjectType):
    digital_content = PermissionsField(
        DigitalContent,
        description="Look up digital content by ID.",
        id=graphene.Argument(
            graphene.ID, description="ID of the digital content.", required=True
        ),
        permissions=[
            ProductPermissions.MANAGE_PRODUCTS,
        ],
    )
    digital_contents = ConnectionField(
        DigitalContentCountableConnection,
        description="List of digital content.",
        permissions=[
            ProductPermissions.MANAGE_PRODUCTS,
        ],
    )
    categories = FilterConnectionField(
        CategoryCountableConnection,
        filter=CategoryFilterInput(description="Filtering options for categories."),
        sort_by=CategorySortingInput(description="Sort categories."),
        level=graphene.Argument(
            graphene.Int,
            description="Filter categories by the nesting level in the category tree.",
        ),
        description="List of the shop's categories.",
    )
    category = graphene.Field(
        Category,
        id=graphene.Argument(graphene.ID, description="ID of the category."),
        slug=graphene.Argument(graphene.String, description="Slug of the category"),
        description="Look up a category by ID or slug.",
    )
    collection = graphene.Field(
        Collection,
        id=graphene.Argument(
            graphene.ID,
            description="ID of the collection.",
        ),
        slug=graphene.Argument(graphene.String, description="Slug of the category"),
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
        description=(
            "Look up a collection by ID. Requires one of the following permissions to "
            "include the unpublished items: "
            f"{', '.join([p.name for p in ALL_PRODUCTS_PERMISSIONS])}."
        ),
    )
    collections = FilterConnectionField(
        CollectionCountableConnection,
        filter=CollectionFilterInput(description="Filtering options for collections."),
        sort_by=CollectionSortingInput(description="Sort collections."),
        description=(
            "List of the shop's collections. Requires one of the following permissions "
            "to include the unpublished items: "
            f"{', '.join([p.name for p in ALL_PRODUCTS_PERMISSIONS])}."
        ),
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
    )
    product = graphene.Field(
        Product,
        id=graphene.Argument(
            graphene.ID,
            description="ID of the product.",
        ),
        slug=graphene.Argument(graphene.String, description="Slug of the product."),
        external_reference=graphene.Argument(
            graphene.String, description=f"External ID of the product. {ADDED_IN_310}"
        ),
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
        description=(
            "Look up a product by ID. Requires one of the following permissions to "
            "include the unpublished items: "
            f"{', '.join([p.name for p in ALL_PRODUCTS_PERMISSIONS])}."
        ),
    )
    products = FilterConnectionField(
        ProductCountableConnection,
        filter=ProductFilterInput(description="Filtering options for products."),
        sort_by=ProductOrder(description="Sort products."),
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
        description=(
            "List of the shop's products. Requires one of the following permissions to "
            "include the unpublished items: "
            f"{', '.join([p.name for p in ALL_PRODUCTS_PERMISSIONS])}."
        ),
    )
    product_type = graphene.Field(
        ProductType,
        id=graphene.Argument(
            graphene.ID, description="ID of the product type.", required=True
        ),
        description="Look up a product type by ID.",
    )
    product_types = FilterConnectionField(
        ProductTypeCountableConnection,
        filter=ProductTypeFilterInput(
            description="Filtering options for product types."
        ),
        sort_by=ProductTypeSortingInput(description="Sort product types."),
        description="List of the shop's product types.",
    )
    product_variant = graphene.Field(
        ProductVariant,
        id=graphene.Argument(
            graphene.ID,
            description="ID of the product variant.",
        ),
        sku=graphene.Argument(
            graphene.String, description="Sku of the product variant."
        ),
        external_reference=graphene.Argument(
            graphene.String, description=f"External ID of the product. {ADDED_IN_310}"
        ),
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
        description=(
            "Look up a product variant by ID or SKU. Requires one of the following "
            "permissions to include the unpublished items: "
            f"{', '.join([p.name for p in ALL_PRODUCTS_PERMISSIONS])}."
        ),
    )
    product_variants = FilterConnectionField(
        ProductVariantCountableConnection,
        ids=NonNullList(
            graphene.ID, description="Filter product variants by given IDs."
        ),
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned."
        ),
        filter=ProductVariantFilterInput(
            description="Filtering options for product variant."
        ),
        sort_by=ProductVariantSortingInput(description="Sort products variants."),
        description=(
            "List of product variants. Requires one of the following permissions to "
            "include the unpublished items: "
            f"{', '.join([p.name for p in ALL_PRODUCTS_PERMISSIONS])}."
        ),
    )
    report_product_sales = ConnectionField(
        ProductVariantCountableConnection,
        period=graphene.Argument(
            ReportingPeriod, required=True, description="Span of time."
        ),
        channel=graphene.String(
            description="Slug of a channel for which the data should be returned.",
            required=True,
        ),
        description="List of top selling products.",
        permissions=[
            ProductPermissions.MANAGE_PRODUCTS,
        ],
    )

    @staticmethod
    def resolve_categories(_root, info: ResolveInfo, *, level=None, **kwargs):
        qs = resolve_categories(info, level=level)
        qs = filter_connection_queryset(qs, kwargs)
        return create_connection_slice(qs, info, kwargs, CategoryCountableConnection)

    @staticmethod
    @traced_resolver
    def resolve_category(_root, _info: ResolveInfo, *, id=None, slug=None, **kwargs):
        validate_one_of_args_is_in_query("id", id, "slug", slug)
        if id:
            _, id = from_global_id_or_error(id, Category)
            return resolve_category_by_id(id)
        if slug:
            return resolve_category_by_slug(slug=slug)

    @staticmethod
    @traced_resolver
    def resolve_collection(
        _root, info: ResolveInfo, *, id=None, slug=None, channel=None
    ):
        validate_one_of_args_is_in_query("id", id, "slug", slug)
        requestor = get_user_or_app_from_context(info.context)

        has_required_permissions = has_one_of_permissions(
            requestor, ALL_PRODUCTS_PERMISSIONS
        )
        if channel is None and not has_required_permissions:
            channel = get_default_channel_slug_or_graphql_error()
        if id:
            _, id = from_global_id_or_error(id, Collection)
            collection = resolve_collection_by_id(info, id, channel, requestor)
        else:
            collection = resolve_collection_by_slug(
                info, slug=slug, channel_slug=channel, requestor=requestor
            )
        return (
            ChannelContext(node=collection, channel_slug=channel)
            if collection
            else None
        )

    @staticmethod
    def resolve_collections(_root, info: ResolveInfo, *, channel=None, **kwargs):
        requestor = get_user_or_app_from_context(info.context)
        has_required_permissions = has_one_of_permissions(
            requestor, ALL_PRODUCTS_PERMISSIONS
        )
        if channel is None and not has_required_permissions:
            channel = get_default_channel_slug_or_graphql_error()
        qs = resolve_collections(info, channel)
        kwargs["channel"] = channel
        qs = filter_connection_queryset(qs, kwargs)
        return create_connection_slice(qs, info, kwargs, CollectionCountableConnection)

    @staticmethod
    def resolve_digital_content(_root, _info: ResolveInfo, *, id):
        _, id = from_global_id_or_error(id, DigitalContent)
        return resolve_digital_content_by_id(id)

    @staticmethod
    def resolve_digital_contents(_root, info: ResolveInfo, **kwargs):
        qs = resolve_digital_contents(info)
        return create_connection_slice(
            qs, info, kwargs, DigitalContentCountableConnection
        )

    @staticmethod
    @traced_resolver
    def resolve_product(
        _root,
        info: ResolveInfo,
        *,
        id=None,
        slug=None,
        external_reference=None,
        channel=None,
    ):
        validate_one_of_args_is_in_query(
            "id", id, "slug", slug, "external_reference", external_reference
        )
        requestor = get_user_or_app_from_context(info.context)

        has_required_permissions = has_one_of_permissions(
            requestor, ALL_PRODUCTS_PERMISSIONS
        )

        if channel is None and not has_required_permissions:
            channel = get_default_channel_slug_or_graphql_error()

        product = resolve_product(
            info,
            id=id,
            slug=slug,
            external_reference=external_reference,
            channel_slug=channel,
            requestor=requestor,
        )

        return ChannelContext(node=product, channel_slug=channel) if product else None

    @staticmethod
    @traced_resolver
    def resolve_products(_root, info: ResolveInfo, *, channel=None, **kwargs):
        if sort_field_from_kwargs(kwargs) == ProductOrderField.RANK:
            # sort by RANK can be used only with search filter
            if not search_string_in_kwargs(kwargs):
                raise GraphQLError(
                    "Sorting by RANK is available only when using a search filter."
                )
        if search_string_in_kwargs(kwargs) and not sort_field_from_kwargs(kwargs):
            # default to sorting by RANK if search is used
            # and no explicit sorting is requested
            product_type = info.schema.get_type("ProductOrder")
            kwargs["sort_by"] = product_type.create_container(
                {"direction": "-", "field": ["search_rank", "id"]}
            )

        requestor = get_user_or_app_from_context(info.context)
        has_required_permissions = has_one_of_permissions(
            requestor, ALL_PRODUCTS_PERMISSIONS
        )
        if channel is None and not has_required_permissions:
            channel = get_default_channel_slug_or_graphql_error()
        qs = resolve_products(info, requestor, channel_slug=channel)
        kwargs["channel"] = channel
        qs = filter_connection_queryset(qs, kwargs)
        return create_connection_slice(qs, info, kwargs, ProductCountableConnection)

    @staticmethod
    def resolve_product_type(_root, _info: ResolveInfo, *, id):
        _, id = from_global_id_or_error(id, ProductType)
        return resolve_product_type_by_id(id)

    @staticmethod
    def resolve_product_types(_root, info: ResolveInfo, **kwargs):
        qs = resolve_product_types(info)
        qs = filter_connection_queryset(qs, kwargs)
        return create_connection_slice(qs, info, kwargs, ProductTypeCountableConnection)

    @staticmethod
    @traced_resolver
    def resolve_product_variant(
        _root,
        info: ResolveInfo,
        *,
        id=None,
        sku=None,
        external_reference=None,
        channel=None,
    ):
        validate_one_of_args_is_in_query(
            "id", id, "sku", sku, "external_reference", external_reference
        )
        requestor = get_user_or_app_from_context(info.context)
        has_required_permissions = has_one_of_permissions(
            requestor, ALL_PRODUCTS_PERMISSIONS
        )

        if channel is None and not has_required_permissions:
            channel = get_default_channel_slug_or_graphql_error()

        variant = resolve_variant(
            info,
            id,
            sku,
            external_reference,
            channel_slug=channel,
            requestor=requestor,
            requestor_has_access_to_all=has_required_permissions,
        )

        return ChannelContext(node=variant, channel_slug=channel) if variant else None

    @staticmethod
    def resolve_product_variants(
        _root, info: ResolveInfo, *, ids=None, channel=None, **kwargs
    ):
        requestor = get_user_or_app_from_context(info.context)
        has_required_permissions = has_one_of_permissions(
            requestor, ALL_PRODUCTS_PERMISSIONS
        )
        if channel is None and not has_required_permissions:
            channel = get_default_channel_slug_or_graphql_error()
        qs = resolve_product_variants(
            info,
            ids=ids,
            channel_slug=channel,
            requestor_has_access_to_all=has_required_permissions,
            requestor=requestor,
        )
        kwargs["channel"] = qs.channel_slug
        qs = filter_connection_queryset(qs, kwargs)
        return create_connection_slice(
            qs, info, kwargs, ProductVariantCountableConnection
        )

    @staticmethod
    @traced_resolver
    def resolve_report_product_sales(
        _root, info: ResolveInfo, *, period, channel, **kwargs
    ):
        qs = resolve_report_product_sales(period, channel_slug=channel)
        kwargs["channel"] = qs.channel_slug
        return create_connection_slice(
            qs, info, kwargs, ProductVariantCountableConnection
        )

class ProductMutations(graphene.ObjectType):
    product_attribute_assign = ProductAttributeAssign.Field()
    product_attribute_assignment_update = ProductAttributeAssignmentUpdate.Field()
    product_attribute_unassign = ProductAttributeUnassign.Field()

    category_create = CategoryCreate.Field()
    category_delete = CategoryDelete.Field()
    category_bulk_delete = CategoryBulkDelete.Field()
    category_update = CategoryUpdate.Field()
    category_translate = CategoryTranslate.Field()

    collection_add_products = CollectionAddProducts.Field()
    collection_create = CollectionCreate.Field()
    collection_delete = CollectionDelete.Field()
    collection_reorder_products = CollectionReorderProducts.Field()
    collection_bulk_delete = CollectionBulkDelete.Field()
    collection_remove_products = CollectionRemoveProducts.Field()
    collection_update = CollectionUpdate.Field()
    collection_translate = CollectionTranslate.Field()
    collection_channel_listing_update = CollectionChannelListingUpdate.Field()

    product_create = ProductCreate.Field()
    product_delete = ProductDelete.Field()
    product_bulk_delete = ProductBulkDelete.Field()
    product_update = ProductUpdate.Field()
    product_translate = ProductTranslate.Field()

    product_channel_listing_update = ProductChannelListingUpdate.Field()

    product_media_create = ProductMediaCreate.Field()
    product_variant_reorder = ProductVariantReorder.Field()
    product_media_delete = ProductMediaDelete.Field()
    product_media_bulk_delete = ProductMediaBulkDelete.Field()
    product_media_reorder = ProductMediaReorder.Field()
    product_media_update = ProductMediaUpdate.Field()

    product_type_create = ProductTypeCreate.Field()
    product_type_delete = ProductTypeDelete.Field()
    product_type_bulk_delete = ProductTypeBulkDelete.Field()
    product_type_update = ProductTypeUpdate.Field()
    product_type_reorder_attributes = ProductTypeReorderAttributes.Field()
    product_reorder_attribute_values = ProductReorderAttributeValues.Field()

    digital_content_create = DigitalContentCreate.Field()
    digital_content_delete = DigitalContentDelete.Field()
    digital_content_update = DigitalContentUpdate.Field()

    digital_content_url_create = DigitalContentUrlCreate.Field()

    product_variant_create = ProductVariantCreate.Field()
    product_variant_delete = ProductVariantDelete.Field()
    product_variant_bulk_create = ProductVariantBulkCreate.Field()
    product_variant_bulk_update = ProductVariantBulkUpdate.Field()
    product_variant_bulk_delete = ProductVariantBulkDelete.Field()
    product_variant_stocks_create = ProductVariantStocksCreate.Field()
    product_variant_stocks_delete = ProductVariantStocksDelete.Field()
    product_variant_stocks_update = ProductVariantStocksUpdate.Field()
    product_variant_update = ProductVariantUpdate.Field()
    product_variant_set_default = ProductVariantSetDefault.Field()
    product_variant_translate = ProductVariantTranslate.Field()
    product_variant_channel_listing_update = ProductVariantChannelListingUpdate.Field()
    product_variant_reorder_attribute_values = (
        ProductVariantReorderAttributeValues.Field()
    )
    product_variant_preorder_deactivate = ProductVariantPreorderDeactivate.Field()

    variant_media_assign = VariantMediaAssign.Field()
    variant_media_unassign = VariantMediaUnassign.Field()


from selenium import webdriver
from selenium.webdriver.common.by import By
import requests
import io
from PIL import Image
import time

path = "C:\\Users\\user\\Desktop\\archive_2\\webdriver\\chromedriver.exe"

wd = webdriver.Chrome(executable_path=path)

def get_images_from_google(wd, delay, max_images):
    def scroll_down(wd):
        wd.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(delay)

    #url = "https://www.google.com/search?q=wildfire+from+above&tbm=isch&ved=2ahUKEwj6ubWRo9v8AhU36rsIHTcuDpcQ2-cCegQIABAA&oq=wildfire+from+above&gs_lcp=CgNpbWcQAzIFCAAQgAQ6BAgAEEM6BggAEAcQHjoGCAAQCBAeOgcIABCABBAYOggIABAIEAcQHlDICVirK2CyMGgAcAB4AIABsAGIAfQFkgEDMC41mAEAoAEBqgELZ3dzLXdpei1pbWfAAQE&sclient=img&ei=8jjNY_r4CrfU7_UPt9y4uAk&bih=722&biw=1536&hl=EN"
    url = "https://www.google.com/search?q=california+wildfires+2021&hl=EN&tbm=isch&sxsrf=AJOqlzXCvOn4HVl8XRB1ZqZ634lWbtU99A%3A1674495861559&source=hp&biw=1536&bih=722&ei=dcfOY9msH6uFxc8PrIGK0A0&iflsig=AK50M_UAAAAAY87VhebdbowDyd6bXjW_efunjkvOOlx9&oq=california+wild&gs_lcp=CgNpbWcQAxgDMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDIFCAAQgAQyBQgAEIAEMgUIABCABDoECCMQJzoHCCMQ6gIQJzoHCAAQgAQQE1AAWOQxYOdHaANwAHgAgAGFAYgB-hCSAQQwLjE4mAEAoAEBqgELZ3dzLXdpei1pbWewAQo&sclient=img"
    wd.get(url)

    image_urls = set()
    skips = 0
    while len(image_urls) + skips < max_images:
        scroll_down(wd)
        thumbnails = wd.find_elements(By.CLASS_NAME, "Q4LuWd")

        for img in thumbnails[len(image_urls) + skips:max_images]:
            try:
                img.click()
                time.sleep(delay)
            except:
                continue

            images = wd.find_elements(By.CLASS_NAME, "n3VNCb")
            for image in images:
                if image.get_attribute("src") in image_urls:
                    max_images += 1
                    skips += 1
                    break
                if image.get_attribute("src") and "https" in image.get_attribute("src"):
                    image_urls.add(image.get_attribute("src"))
                    #download_image()
                    print(f"Found image {len(image_urls)}")

    return image_urls

def download_image(download_path, url, file_name):
    try:
        image_content = requests.get(url).content
        image_file = io.BytesIO(image_content) #binary data
        image = Image.open(image_file)
        file_path = download_path + file_name

        with open(file_path, "wb") as f:
           image.save(f, "JPEG")

        print("Successful")
    except Exception as e:
        print("FAILED -", e)

#download_image("", image_url, "fire.jpg") #function

urls = get_images_from_google(wd, 2, 500)
print(urls)

for i, url in enumerate(urls):
    download_image("wildfire/", url, str(i) + "california" + ".jpg")
wd.quit()


from myhdl import *
import os

import xfcp
import i2c

module = 'xfcp_mod_i2c_master'
testbench = 'test_%s' % module

srcs = []

srcs.append("../rtl/%s.v" % module)
srcs.append("../lib/i2c/rtl/i2c_master.v")
srcs.append("%s.v" % testbench)

src = ' '.join(srcs)

build_cmd = "iverilog -o %s.vvp %s" % (testbench, src)

def bench():

    # Parameters
    XFCP_ID_TYPE = 0x2C00
    XFCP_ID_STR = "I2C Master"
    XFCP_EXT_ID = 0
    XFCP_EXT_ID_STR = ""
    DEFAULT_PRESCALE = 1

    # Inputs
    clk = Signal(bool(0))
    rst = Signal(bool(0))
    current_test = Signal(intbv(0)[8:])

    up_xfcp_in_tdata = Signal(intbv(0)[8:])
    up_xfcp_in_tvalid = Signal(bool(0))
    up_xfcp_in_tlast = Signal(bool(0))
    up_xfcp_in_tuser = Signal(bool(0))
    up_xfcp_out_tready = Signal(bool(0))
    i2c_scl_i = Signal(bool(1))
    i2c_sda_i = Signal(bool(1))

    s1_scl_i = Signal(bool(1))
    s1_sda_i = Signal(bool(1))

    s2_scl_i = Signal(bool(1))
    s2_sda_i = Signal(bool(1))

    # Outputs
    up_xfcp_in_tready = Signal(bool(0))
    up_xfcp_out_tdata = Signal(intbv(0)[8:])
    up_xfcp_out_tvalid = Signal(bool(0))
    up_xfcp_out_tlast = Signal(bool(0))
    up_xfcp_out_tuser = Signal(bool(0))
    i2c_scl_o = Signal(bool(1))
    i2c_scl_t = Signal(bool(1))
    i2c_sda_o = Signal(bool(1))
    i2c_sda_t = Signal(bool(1))

    s1_scl_o = Signal(bool(1))
    s1_scl_t = Signal(bool(1))
    s1_sda_o = Signal(bool(1))
    s1_sda_t = Signal(bool(1))

    s2_scl_o = Signal(bool(1))
    s2_scl_t = Signal(bool(1))
    s2_sda_o = Signal(bool(1))
    s2_sda_t = Signal(bool(1))

    # XFCP ports
    up_xfcp_port_out_pause = Signal(bool(0))
    up_xfcp_port_in_pause = Signal(bool(0))

    up_xfcp_port = xfcp.XFCPPort()

    up_xfcp_port_logic = up_xfcp_port.create_logic(
        clk=clk,
        rst=rst,
        xfcp_in_tdata=up_xfcp_out_tdata,
        xfcp_in_tvalid=up_xfcp_out_tvalid,
        xfcp_in_tready=up_xfcp_out_tready,
        xfcp_in_tlast=up_xfcp_out_tlast,
        xfcp_in_tuser=up_xfcp_out_tuser,
        xfcp_out_tdata=up_xfcp_in_tdata,
        xfcp_out_tvalid=up_xfcp_in_tvalid,
        xfcp_out_tready=up_xfcp_in_tready,
        xfcp_out_tlast=up_xfcp_in_tlast,
        xfcp_out_tuser=up_xfcp_in_tuser,
        pause_source=up_xfcp_port_in_pause,
        pause_sink=up_xfcp_port_out_pause,
        name='up_xfcp_port'
    )

    # I2C memory model 1
    i2c_mem1 = i2c.I2CMem(1024)

    i2c_mem_logic1 = i2c_mem1.create_logic(
        scl_i=s1_scl_i,
        scl_o=s1_scl_o,
        scl_t=s1_scl_t,
        sda_i=s1_sda_i,
        sda_o=s1_sda_o,
        sda_t=s1_sda_t,
        abw=2,
        address=0x50,
        latency=0,
        name='slave1'
    )

    # I2C memory model 2
    i2c_mem2 = i2c.I2CMem(1024)

    i2c_mem_logic2 = i2c_mem2.create_logic(
        scl_i=s2_scl_i,
        scl_o=s2_scl_o,
        scl_t=s2_scl_t,
        sda_i=s2_sda_i,
        sda_o=s2_sda_o,
        sda_t=s2_sda_t,
        abw=2,
        address=0x51,
        latency=1000,
        name='slave2')

    # DUT
    if os.system(build_cmd):
        raise Exception("Error running build command")

    dut = Cosimulation(
        "vvp -m myhdl %s.vvp -lxt2" % testbench,
        clk=clk,
        rst=rst,
        current_test=current_test,

        up_xfcp_in_tdata=up_xfcp_in_tdata,
        up_xfcp_in_tvalid=up_xfcp_in_tvalid,
        up_xfcp_in_tready=up_xfcp_in_tready,
        up_xfcp_in_tlast=up_xfcp_in_tlast,
        up_xfcp_in_tuser=up_xfcp_in_tuser,
        up_xfcp_out_tdata=up_xfcp_out_tdata,
        up_xfcp_out_tvalid=up_xfcp_out_tvalid,
        up_xfcp_out_tready=up_xfcp_out_tready,
        up_xfcp_out_tlast=up_xfcp_out_tlast,
        up_xfcp_out_tuser=up_xfcp_out_tuser,

        i2c_scl_i=i2c_scl_i,
        i2c_scl_o=i2c_scl_o,
        i2c_scl_t=i2c_scl_t,
        i2c_sda_i=i2c_sda_i,
        i2c_sda_o=i2c_sda_o,
        i2c_sda_t=i2c_sda_t
    )

    @always_comb
    def bus():
        # emulate I2C wired AND
        i2c_scl_i.next = i2c_scl_o & s1_scl_o & s2_scl_o;
        i2c_sda_i.next = i2c_sda_o & s1_sda_o & s2_sda_o;

        s1_scl_i.next = i2c_scl_o & s1_scl_o & s2_scl_o;
        s1_sda_i.next = i2c_sda_o & s1_sda_o & s2_sda_o;

        s2_scl_i.next = i2c_scl_o & s1_scl_o & s2_scl_o;
        s2_sda_i.next = i2c_sda_o & s1_sda_o & s2_sda_o;

    @always(delay(4))
    def clkgen():
        clk.next = not clk

    def wait_normal():
        i = 8
        while i > 0:
            i = max(0, i-1)
            if not up_xfcp_port.idle() or not i2c_scl_i or not i2c_sda_i:
                i = 8
            yield clk.posedge

    def wait_pause_source():
        i = 4
        while i > 0:
            i = max(0, i-1)
            if not up_xfcp_port.idle() or not i2c_scl_i or not i2c_sda_i:
                i = 4
            up_xfcp_port_in_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            up_xfcp_port_in_pause.next = False
            yield clk.posedge

    def wait_pause_sink():
        i = 4
        while i > 0:
            i = max(0, i-1)
            if not up_xfcp_port.idle() or not i2c_scl_i or not i2c_sda_i:
                i = 4
            up_xfcp_port_out_pause.next = True
            yield clk.posedge
            yield clk.posedge
            yield clk.posedge
            up_xfcp_port_out_pause.next = False
            yield clk.posedge

    @instance
    def check():
        yield delay(100)
        yield clk.posedge
        rst.next = 1
        yield clk.posedge
        rst.next = 0
        yield clk.posedge
        yield delay(100)
        yield clk.posedge

        # testbench stimulus

        yield clk.posedge
        print("test 1: write")
        current_test.next = 1

        pkt = xfcp.XFCPFrame()
        pkt.ptype = 0x2C
        pkt.payload = b'\xD0\x1C\x06\x00\x04\x11\x22\x33\x44'

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt)

            yield clk.posedge

            yield wait()
            yield clk.posedge

            data = i2c_mem1.read_mem(0, 32)
            for i in range(0, len(data), 16):
                print(" ".join(("{:02x}".format(c) for c in bytearray(data[i:i+16]))))

            assert i2c_mem1.read_mem(4,4) == b'\x11\x22\x33\x44'

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0x2D
            assert rx_pkt.payload.data == b'\xD0\x1C\x06\x00\x04\x11\x22\x33\x44'

            yield delay(100)

        yield clk.posedge
        print("test 2: read")
        current_test.next = 2

        pkt = xfcp.XFCPFrame()
        pkt.ptype = 0x2C
        pkt.payload = b'\xD0\x14\x02\x00\x04\x1A\x04'

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt)

            yield clk.posedge

            yield wait()
            yield clk.posedge

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0x2D
            assert rx_pkt.payload.data == b'\xD0\x14\x02\x00\x04\x1A\x04\x11\x22\x33\x44'

            yield delay(100)

        yield clk.posedge
        print("test 3: write to slave 2")
        current_test.next = 3

        pkt = xfcp.XFCPFrame()
        pkt.ptype = 0x2C
        pkt.payload = b'\xD1\x04\x00\x04\x04\x04\x44\x04\x33\x04\x22\x0C\x11'

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt)

            yield clk.posedge

            yield wait()
            yield clk.posedge

            data = i2c_mem2.read_mem(0, 32)
            for i in range(0, len(data), 16):
                print(" ".join(("{:02x}".format(c) for c in bytearray(data[i:i+16]))))

            assert i2c_mem2.read_mem(4,4) == b'\x44\x33\x22\x11'

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0x2D
            assert rx_pkt.payload.data == b'\xD1\x04\x00\x04\x04\x04\x44\x04\x33\x04\x22\x0C\x11'

            yield delay(100)

        yield clk.posedge
        print("test 4: read from slave 2")
        current_test.next = 4

        pkt = xfcp.XFCPFrame()
        pkt.ptype = 0x2C
        pkt.payload = b'\xD1\x04\x00\x04\x04\x02\x02\x02\x0A'

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt)

            yield clk.posedge

            yield wait()
            yield clk.posedge

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0x2D
            assert rx_pkt.payload.data == b'\xD1\x04\x00\x04\x04\x02\x44\x02\x33\x02\x22\x0A\x11'

            yield delay(100)

        yield clk.posedge
        print("test 5: test configuration and status")
        current_test.next = 5

        pkt = xfcp.XFCPFrame()
        pkt.ptype = 0x2C
        pkt.payload = b'\x60\x04\x00\x60\x01\x00\x40'

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt)
            yield clk.posedge

            yield wait()
            yield clk.posedge

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0x2D
            assert rx_pkt.payload.data == b'\x60\x04\x00\x60\x01\x00\x40\x00'

            yield delay(100)

        yield clk.posedge
        print("test 6: test id")
        current_test.next = 6

        pkt = xfcp.XFCPFrame()
        pkt.ptype = 0xFE
        pkt.payload = b''

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt)
            yield clk.posedge

            yield wait()
            yield clk.posedge

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0xff
            assert len(rx_pkt.payload.data) == 32

            yield delay(100)

        yield clk.posedge
        print("test 7: test id with trailing bytes")
        current_test.next = 7

        pkt1 = xfcp.XFCPFrame()
        pkt1.ptype = 0xFE
        pkt1.payload = b'\0'*256

        pkt2 = xfcp.XFCPFrame()
        pkt2.ptype = 0xFE
        pkt2.payload = b'\0'*8

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt1)
            up_xfcp_port.send(pkt2)
            yield clk.posedge

            yield wait()
            yield clk.posedge

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0xff
            assert len(rx_pkt.payload.data) == 32

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.ptype == 0xff
            assert len(rx_pkt.payload.data) == 32

            yield delay(100)

        yield clk.posedge
        print("test 8: test with rpath")
        current_test.next = 8

        pkt1 = xfcp.XFCPFrame()
        pkt1.rpath = [1, 2, 3]
        pkt1.ptype = 0xFE
        pkt1.payload = b'\0'*8

        pkt2 = xfcp.XFCPFrame()
        pkt2.rpath = [4, 5, 6]
        pkt2.ptype = 0x2C
        pkt2.payload = b'\xD0\x04\x00\x04\x04\x02\x02\x02\x0A'

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt1)
            up_xfcp_port.send(pkt2)

            yield clk.posedge

            yield wait()
            yield clk.posedge

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.rpath == [1, 2, 3]
            assert rx_pkt.ptype == 0xff
            assert len(rx_pkt.payload.data) == 32

            rx_pkt = up_xfcp_port.recv()

            print(rx_pkt)
            assert rx_pkt.rpath == [4, 5, 6]
            assert rx_pkt.ptype == 0x2D
            assert rx_pkt.payload.data == b'\xD0\x04\x00\x04\x04\x02\x11\x02\x22\x02\x33\x0A\x44'

            yield delay(100)

        yield clk.posedge
        print("test 9: test invalid packets")
        current_test.next = 9

        pkt1 = xfcp.XFCPFrame()
        pkt1.ptype = 0x99
        pkt1.payload = b'\x00'*8

        pkt2 = xfcp.XFCPFrame()
        pkt2.path = [0]
        pkt2.ptype = 0xFE
        pkt2.payload = b''

        for wait in wait_normal, wait_pause_source, wait_pause_sink:
            up_xfcp_port.send(pkt1)
            up_xfcp_port.send(pkt2)
            yield clk.posedge

            yield wait()
            yield clk.posedge

            rx_pkt = up_xfcp_port.recv()

            assert rx_pkt is None

            yield delay(100)

        raise StopSimulation

    return instances()

def test_bench():
    sim = Simulation(bench())
    sim.run()

if __name__ == '__main__':
    print("Running test...")
    test_bench()


from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from .models import Product, Order, Supplier
from .forms import ProductForm, OrderForm, SupplierForm
from django.contrib import messages
from django.contrib.auth.models import User

# Create your views here.
@login_required(login_url='user-login')
def index(request):
    orders = Order.objects.all()
    products = Product.objects.all()
    clients = Supplier.objects.all()
    orders_count = orders.count()
    product_count = products.count()
    clients_count = clients.count()
    workers_count = User.objects.all().count()
    if request.method == 'POST':
        form = OrderForm(request.POST)
        if form.is_valid():
            instance = form.save(commit=False)
            instance.staff = request.user
            instance.save()
            return redirect('dashboard-index')
    else:
        form = OrderForm()
    context = {
        'orders': orders,
        'form': form,
        'products': products,
        'product_count': product_count,
        'workers_count': workers_count,
        'orders_count': orders_count,
        'clients_count': clients_count,
    }
    return render(request, 'dashboard/index.html', context)

@login_required(login_url='user-login')
def staff(request):
    workers = User.objects.all()
    workers_count = workers.count()
    orders_count = Order.objects.all().count()
    clients_count = Supplier.objects.all().count()
    product_count = Product.objects.all().count()
    context = {
        'workers': workers,
        'workers_count': workers_count,
        'orders_count': orders_count,
        'clients_count': clients_count,
        'product_count': product_count
    }
    return render(request, 'dashboard/staff.html', context)

@login_required(login_url='user-login')
def staff_delete(request, pk):
    workers = User.objects.get(id=pk)
    if request.method == 'POST':
        workers.delete()
        return redirect('dashboard-staff')
    context = {
        'workers': workers
    }
    return render(request, 'dashboard/staff_delete.html', context)

def staff_detail(request, pk):
    workers = User.objects.get(id=pk)
    context = {
        'workers': workers,
    }
    return render(request, 'dashboard/staff_detail.html', context)

@login_required(login_url='user-login')
def product(request):
    items = Product.objects.all()
    product_count = items.count()
    workers_count = User.objects.all().count()
    orders_count = Order.objects.all().count()
    clients_count = Supplier.objects.all().count()
    if request.method == 'POST':
        form = ProductForm(request.POST)
        if form.is_valid():
            form.save()
            product_name = form.cleaned_data.get('name')
            messages.success(request, f'{product_name} has been added')
            return redirect('dashboard-product')
    else:
        form = ProductForm()
    context = {
        'items': items,
        'form': form,
        'workers_count': workers_count,
        'orders_count': orders_count,
        'clients_count': clients_count,
        'product_count': product_count,
    }
    return render(request, 'dashboard/product.html', context)

@login_required(login_url='user-login')
def product_detail(request, pk):
    items = Product.objects.get(id=pk)
    context = {
        'items': items,
    }
    return render(request, 'dashboard/staff_detail.html', context)

@login_required(login_url='user-login')
def product_delete(request, pk):
    item = Product.objects.get(id=pk)
    if request.method == 'POST':
        item.delete()
        return redirect('dashboard-product')
    context = {
        'item': item
    }
    return render(request, 'dashboard/product_delete.html', context)

@login_required(login_url='user-login')
def product_update(request, pk):
    item = Product.objects.get(id=pk)
    if request.method == 'POST':
        form = ProductForm(request.POST, instance=item)
        if form.is_valid():
            form.save()
            return redirect('dashboard-product')
    else:
        form = ProductForm(instance=item)
    context = {
        'form': form,
    }
    return render(request, 'dashboard/product_update.html', context)

@login_required(login_url='user-login')
def supplier(request):
    clients = Supplier.objects.all()
    clients_count = clients.count()
    workers_count = User.objects.all().count()
    orders_count = Order.objects.all().count()
    product_count = Product.objects.all().count()
    if request.method == 'POST':
        form = SupplierForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('dashboard-supplier')
    else:
        form = SupplierForm()
    context = {
        'clients': clients,
        'form': form,
        'workers_count': workers_count,
        'orders_count': orders_count,
        'clients_count': clients_count,
        'product_count': product_count,

    }
    return render(request, 'dashboard/supplier.html', context)

@login_required(login_url='user-login')
def supplier_delete(request, pk):
    clients = Supplier.objects.get(id=pk)
    if request.method == 'POST':
        clients.delete()
        return redirect('dashboard-supplier')
    context = {
        'clients': clients
    }
    return render(request, 'dashboard/supplier_delete.html', context)

@login_required(login_url='user-login')
def supplier_detail(request, pk):
    clients = Supplier.objects.get(id=pk)
    context = {
        'clients': clients,
    }
    return render(request, 'dashboard/supplier_detail.html', context)

@login_required(login_url='user-login')
def order(request):
    orders = Order.objects.all()
    orders_count = orders.count()
    workers_count = User.objects.all().count()
    clients_count = Supplier.objects.all().count()
    product_count = Product.objects.all().count()
    context = {
        'orders': orders,
        'workers_count': workers_count,
        'orders_count': orders_count,
        'clients_count': clients_count,
        'product_count': product_count,
    }
    return render(request, 'dashboard/order.html', context)

@login_required(login_url='user-login')
def order_detail(request, pk):
    orders = Order.objects.get(id=pk)
    context = {
        'orders': orders,
    }
    return render(request, 'dashboard/order_detail.html', context)
    print(orders)
    return render(request, 'dashboard/order_detail.html', context)

@login_required(login_url='user-login')
def order_delete(request, pk):
    orders = Order.objects.get(id=pk)
    if request.method == 'POST':
        orders.delete()
        return redirect('dashboard-order')
    context = {
        'orders': orders
    }
    return render(request, 'dashboard/order_delete.html', context)


import os, sys
extractable_endings = ['.rar', '.zip']
extractable = None
if not sys.argv[1]:
    quit()
for file in os.listdir(sys.argv[1]):
	for ending in extractable_endings:
		if file.endswith(ending):
			extractable = file
if extractable:
	os.system('7z e -oc {1} {2}'.format(sys.argv[1], extractable))


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

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html

import sqlite3

class OutercrawlPipeline(object):
    def open_spider(self, spider):
        self.conn = sqlite3.connect('outerdata.sqlite')
        self.cur = self.conn.cursor()
        self.cur.execute('create table if not exists outerdata(store varchar(20), current_time datetime,\
         name varchar(100), price varchar(20), link varchar(100),fee varchar(20), sell varchar(20))')
        # pass

    def close_apider(self, spider):
        self.conn.commit()
        self.conn.close()
        # pass

    def process_item(self, item, spider):
        col = ','.join(item.keys())
        placeholders = ','.join(len(item) * '?')
        sql = 'insert into outerdata({}) values({})'
        self.cur.execute(sql.format(col, placeholders), item.values())
        return item


#!python3

from flask import Flask, render_template, request, session, redirect, url_for, escape

app = Flask(__name__)

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST' and 'wage' in request.form:
        session['wage'] = float(request.form.get('wage'))
        return redirect(url_for('pay_calc'))
    return render_template("index.html")

@app.route('/pay', methods=['GET', 'POST'])
def pay_calc():
    pay = ''
    if request.method == 'POST' and 'hours' in request.form and 'wage' in session:
        hours = float(request.form.get('hours'))
        pay = calc_wage(session['wage'], hours)
        #pay = (session['wage'] * hours)
    return render_template("pay_calc.html",
                            pay=pay)

def calc_wage(wage, hours):
    return (wage * hours)

app.secret_key = "Test_Secret_Key"
app.run()


# import the necessary packages
import numpy as np
import cv2

def detect_stop(image):

    boundaries = [([0, 0, 200], [200, 200, 255])] #orange

    im = cv2.imread(image)
    # hsv = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

    for (lower, upper) in boundaries:
        lower = np.array(lower,dtype = "uint8")
        upper = np.array(upper, dtype = "uint8")
        mask = cv2.inRange(im, lower, upper)
        output = cv2.bitwise_and(im, im, mask = mask)
        gray = cv2.cvtColor(output, cv2.COLOR_BGR2GRAY)

        ret,thresh1 = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)
        _, contours, hierarchy = cv2.findContours(thresh1, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        contour_list = []
        for contour in contours:
            area = cv2.contourArea(contour)
            if area > 500:
                contour_list.append(contour)

        maximum = 0
        biggest_contour = None
        for contour in contour_list:
            temp = cv2.contourArea(contour)
            if temp > maximum:
                maximum = temp
                biggest_contour = contour

        cnt = biggest_contour

        moments = cv2.moments(cnt)
        if (moments['m00'] >0):
            cx = int(moments['m10'] / moments['m00'])
            cy = int(moments['m01'] / moments['m00'])

            pos_y = cx
        else:
            pos_y = False
        return(pos_y)
        # cv2.drawContours(im, biggest_contour, -1, (255,0,0), 2)
        # cv2.imshow('Objects Detected', im)
        # cv2.waitKey(0)


class SQLs:
    list_tables = """
    SELECT
        name
    FROM
        sqlite_master
    WHERE
        type ='table' AND
        name NOT LIKE 'sqlite_%';
    """

    create_table = "CREATE TABLE IF NOT EXISTS {}({});"

    create_table__row_primary = "{} INTEGER PRIMARY KEY"

    create_table__row = "{} {} NOT NULL"

    select = "SELECT * FROM {} "

    where = "WHERE {} "

    order_by = "ORDER BY {} "

    limit = "LIMIT {} "

    offset = "OFFSET {} "

    insert = "INSERT INTO {} ({}) VALUES {}"

    insert_row = "({})"

    count = "SELECT COUNT(*) FROM {}"

    get_schema_version = 'SELECT version FROM schema WHERE name="{}"'

    drop = "DROP TABLE {}"

    insert_schema = 'INSERT OR REPLACE INTO schema(name,version) VALUES("{0}","{1}");'

    having = "HAVING {} "


def gameOfLife(board):
    print('Old board: {}'.format(board))

    rows = len(board)
    cols = len(board[0])
    travelX = [-1, -1, -1, 0, 1, 1, 1, 0]
    travelY = [-1, 0, 1, 1, 1, 0, -1, -1]
    total = 0
    deductibles = {
        0: [],
        1: []
    }

    for row in range(rows):
        for col in range(cols):
            total = 0
            for i in range(len(travelX)):
                neighbourX = row + travelX[i]
                neighbourY = col + travelY[i]
                if neighbourX < 0 or neighbourX > rows - 1 or neighbourY < 0 or neighbourY > cols - 1:
                    continue
                total += board[neighbourX][neighbourY]

            if total < 2:
                deductibles[0].append((row, col))
            if total == 3 and board[row][col] == 0:
                deductibles[1].append((row, col))
            if total >= 2 and total <= 3 and board[row][col] == 1:
                deductibles[1].append((row, col))
            if total > 3 and board[row][col] == 1:
                deductibles[0].append((row, col))

    for i in deductibles[0]:
        board[i[0]][i[1]] = 0

    for i in deductibles[1]:
        board[i[0]][i[1]] = 1

    print('New board: {}'.format(board))

    return

board = [[0, 1, 0], [0, 0, 1], [1, 1, 1], [0, 0, 0]]
print(gameOfLife(board))


import csv

def write_csv(records):

    with open("students.csv", "w", newline="") as file:
        writer = csv.DictWriter(file, fieldnames=["name", "age", "grade", "address"])
        writer.writeheader()
        writer.writerows(records)

def read_csv():

    try:
        with open("students.csv", "r", newline="") as file:
            reader = csv.DictReader(file)
            return [row for row in reader]
    except FileNotFoundError:
        return []

def add_record():

    name = input("Enter student name: ")
    age = input("Enter student age: ")
    grade = input("Enter student grade: ")
    address = input("Enter student address: ")
    records.append({"name": name, "age": age, "grade": grade, "address": address})
    print("Student record added successfully!")

def modify_record():

    name = input("Enter student name: ")
    for record in records:
        if record["name"] == name:
            record["age"] = input("Enter new age: ")
            record["grade"] = input("Enter new grade: ")
            record["address"] = input("Enter new address: ")
            print("Student record modified successfully!")
            return
    print("Student not found.")

def delete_record():

    name = input("Enter student name: ")
    for record in records:
        if record["name"] == name:
            records.remove(record)
            print("Student record deleted successfully!")
            return
    print("Student not found.")

records = read_csv()

while True:
    print("1. Add student record")
    print("2. Modify student record")
    print("3. Delete student record")
    print("4. View all student records")
    print("5. Exit")
    choice = input("Enter your choice: ")

    if choice == "1":
        add_record()
    elif choice == "2":
        modify_record()
    elif choice == "3":
        delete_record()
    elif choice == "4":
        for record in records:
            print(record)
    elif choice == "5":
        write_csv(records)
        break
    else:
        print("Invalid choice.")


from tkinter import *

color_win_bg='#483D8B'
color_btn_bg='#7B68EE'
color_light_text='#FFFFFF'
color_btn_active='#8A2BE2'

class Tl(Toplevel):
    def __init__(self,*arg, **kwarg):
        super().__init__(bg=color_win_bg,padx=7,pady=7,*arg, **kwarg)

class Fr(Frame):
    def __init__(self,*arg, **kwarg):
        super().__init__(bg=color_win_bg,padx=7,pady=7,*arg, **kwarg)

class Sc(Scale):
    def __init__(self,*arg, **kwarg):
        super().__init__(orient=HORIZONTAL,width=10,length=250,bg=color_win_bg,fg=color_light_text,
                         highlightbackground=color_win_bg,font=('Courier New',13),*arg, **kwarg)

class Butt(Button):
    def __init__(self,*arg, **kwarg):
        super().__init__(bg=color_btn_bg,fg=color_light_text,activebackground=color_btn_active,borderwidth=5,relief='ridge',
            font=('Courier New',12),*arg, **kwarg)

class Rb(Radiobutton):
    def __init__(self,*arg, **kwarg):
        super().__init__(indicatoron=0, bg=color_win_bg,fg=color_light_text,borderwidth=5,font=('Courier New',12),
                         selectcolor=color_btn_bg,activebackground=color_btn_active,*arg, **kwarg)

class Lbl (Label):
    def __init__(self, *arg, **kwarg):
        super().__init__(bg=color_win_bg,fg=color_light_text,font=('Courier New',13),pady=5,*arg, **kwarg)

info_img=[]
info_txt=['для начала нажмите левой кнопкой\nмыши на любую ячейку. ячейка\nс точкойв середине означает,\nчто вокруг неё мин точно нет',
          'открывайте ячейки до ячеек\nс цифрами. цифра показывает,\nсколько мин рядом с ячейкой в\nрадиусе одной клетки в 8 сторон',
          'если вам кажестся, что где-то мина,\nнажмите туда правой кнопкой мыши,\nлевой - на безопасные ячейки',
          'после окончания игры вам начислятся\nстолько монеток, сколько мин\nвы разминировали. вы молодец!']
for i in range (4):
    info_img.append('files\info_'+str(i)+'.gif')
page=1
def info():
    def pas():
        pass
    if 'info_win' in locals():
        info_win.destroy()
    global page
    page=1

    def page_turn(next=True):
        global page
        for widget in info_page.winfo_children():
            widget.destroy()
        page = page - 1 if next else page + 1
        if page==0:
            up.config(command = pas)
        else:
            up.config(command = lambda: page_turn(True))
        if page==3:
            down.config(command = info_win.destroy)
        else:
            down.config(command = lambda: page_turn(False))

        img=PhotoImage(file=info_img[page])
        lbl=Lbl(info_page,image=img)
        lbl.image=img
        lbl.grid()
        Lbl(info_page,text=info_txt[page]).grid()
        Butt(info_win,text=page+1).grid(row=1,column=1)

    info_win=Tl()
    info_win.resizable(False,False)
    info_page=Fr(info_win)
    info_page.grid(columnspan=3)
    up=Butt(info_win,text='пред.')
    up.grid(row=1,column=0,sticky='w')
    down=Butt(info_win,text='след.')
    down.grid(row=1,column=2,sticky='e')
    page_turn(True)
    info_win.mainloop()


#!/usr/bin/python3
def list_division(my_list_1, my_list_2, list_length):
    result = []
    for i in range(0, list_length):
        try:
            qt = my_list_1[i] / my_list_2[i]
        except ZeroDivisionError:
            qt = 0
            print("division by 0")
        except (TypeError, ValueError):
            qt = 0
            print("wrong type")
        except IndexError:
            qt = 0
            print("out of range")
        finally:
            result.append(qt)
    return result


# lsh.py (question 2)
# Implements both locality sensitive hashing (LSH) and a brute-force nearest neighbor
# approach on a dataset of 39,861 e-mails.
#---------------------------------------------------------------------------------------
# Il Shan Ng
# April 7, 2017

import numpy as np
import heapq as hq
from collections import defaultdict
import sys
import random
import math
import time
import argparse

#####################################################################################
# specify path to and name of data file
file_name = 'docword.enron.txt'
#####################################################################################

def character_matrix(D):
	"""
	Reads in the first D documents of the data and creates a character matrix,
	implemented as a set of words for each document.
	"""
	# start timer
	start_time = time.time()
	# initialize list of D empty sets
	chr_mat = [set() for _ in range(D)]
	# open file containing data
	with open(file_name) as file:
		# skip first three lines
		for _ in range(3):
			next(file)
		while True:
			# read and split line on white space, casting fragments into integers
			line = [int(i) for i in str.split(file.readline())]
			# if reached end of data set, return list of sets
			if not line:
				return chr_mat
			# if document ID is within first D documents
			if line[0] <= D:
				# add word ID to the set for the current document
				chr_mat[line[0]-1].add(line[1])
			# otherwise, return list of sets
			else:
				return (chr_mat, time.time()-start_time)

def jaccard(doc1, doc2):
	"""
	Takes in two documents, in the form of two sets, and returns the Jaccard
	similarity between them.
	"""
	return (len(doc1 & doc2)/len(doc1 | doc2))

def signature_matrix(chr_mat, N, D):
	"""
	Takes in a character matrix and creates a signature matrix with N rows using
	the min-hash algorithm.
	"""
	# start timer
	start_time = time.time()
	# set random seed for debugging purposes
	random.seed(1)
	# compute number of words in the character matrix
	words = set.union(*chr_mat)
	W = len(words)
	# initialize empty list to store N randomly generated hash functions
	hash_functions = []
	# for each hash function
	for n in range(N):
		# generate random b between 0 and W-1
		b = random.randint(0, W-1)
		# generate random a between 0 and W-1, which is coprime with W
		gcd = 2
		while gcd != 1:
			a = random.randint(0, W-1)
			gcd = math.gcd(a, W)
		# add (a,b) tuple to list of hash functions
		hash_functions.append((a,b))
	# initialize signature matrix with inf in all entries
	sig_mat = np.empty(shape=(N, len(chr_mat)), dtype=int)
	sig_mat.fill(99999999)
	# for each row of the character matrix
	for w in range(W):
		# compute hash values for row number
		hash_values = np.array([(coeff[0]*w + coeff[1])%W for coeff in hash_functions])
		# obtain word ID corresponding to row
		wordID = words.pop()
		# for each document
		for d in range(D):
			# if the word ID is in the document
			if wordID in chr_mat[d]:
				# compare the existing column for the document to the vector of
				# computed hash values, and choose the element-wise minimum
				sig_mat[:,d] = np.minimum(sig_mat[:,d], hash_values)
	# return signature matrix along with time taken
	return (sig_mat, time.time() - start_time)

def estimated_jaccard(doc1, doc2):
	"""
	Takes in two documents, in the form of two columns of the signature matrix, and
	returns the estimated Jaccard similarity between them.
	"""
	return sum(doc1 == doc2)/len(doc1)

def knn_brute_force(chr_mat, K, D):
	"""
	Takes in a character matrix, in the form of a list of sets, and finds the K closest
	neighbors to each document, measured by Jaccard similarity. Computes the average
	Jaccard similarities for those K neighbors with respect to each document, and returns
	the average over all documents.
	"""
	# start timer
	start_time = time.time()
	# initialize numpy array to store average Jaccard similarities
	avg_jaccard_sim = np.empty(D, dtype=float)
	# for each document
	for d in range(D):
		# initialize empty priority queue to store K closest neighbors
		queue = []
		# loop over all other documents
		for j in list(range(d)) + list(range(d+1, D)):
			# compute the Jaccard similarity between the current pair and add to queue
			hq.heappush(queue, (jaccard(chr_mat[d], chr_mat[j]), j))
			# if more than K items in queue
			if len(queue) > K:
				# remove document with lowest Jaccard similarity
				hq.heappop(queue)
		# initialize numpy array to store Jaccard similarities
		jaccard_sim = np.empty(K, dtype=float)
		# iterate through all K neighbors in queue
		for k in range(K):
			# obtain Jaccard similarity and add it to the array
			jaccard_sim[k] = hq.heappop(queue)[0]
		# compute the average Jaccard similarity and add to array at top
		avg_jaccard_sim[d] = np.mean(jaccard_sim)
		# print progress to screen
		if D >= 10:
			if (d+1) % (D//10) == 0:
				print('Average Jaccard similarity for document ', d+1, ': ',
					'%.4f' % avg_jaccard_sim[d], sep='')
				sys.stdout.flush()
	# return average of averages along with time taken
	return(np.mean(avg_jaccard_sim), time.time() - start_time)

def knn_lsh(sig_mat, K, D, R):
	"""
	Takes in a signature matrix, in the form of a numpy 2D array, and finds the K
	closest neighbors to each document using banding and locality sensitive hashing.
	Computes the average estimated Jaccard similarities for those K neighbors with
	respect to each document, and returns the average over all documents.
	"""
	# start timer
	start_time = time.time()
	# set random seed for debugging purposes
	random.seed(1)
	# determine number of bands (drop remainder rows that do not form a band)
	B = sig_mat.shape[0]//R
	# initialize empty list of dictionaries, one for each band
	dict_list = [defaultdict(set) for b in range(B)]
	# for each band
	for b in range(B):
		# iterate over all documents
		for d in range(D):
			# use the vector of R integers, converted to a tuple, as key
			key = tuple(sig_mat[b*R:(b+1)*R, d])
			# add key-documentID pair to corresponding dictionary
			dict_list[b][key].add(d)
	# initialize numpy array to store average estimated Jaccard similarities
	avg_jaccard_sim = np.empty(D, dtype=float)
	# initialize count for number of documents whose neighbors were padded at random
	num_padded = 0
	# for each document
	for d in range(D):
		# initialize empty set of candidates
		candidates = set()
		# iterate over all bands
		for b in range(B):
			# compute the key of the document for the current dictionary
			key = tuple(sig_mat[b*R:(b+1)*R, d])
			# add all document IDs in the corresponding bucket to set of candidates
			candidates = candidates.union(dict_list[b][key])
		# remove ID of current document from set of candidates
		candidates.remove(d)
		# initialize numpy array to store Jaccard similarities
		jaccard_sim = np.empty(K, dtype=float)
		# if number of candidates <= K for current document
		if len(candidates) < K:
			# sample randomly from the other non-candidate documents
			docs = random.sample((set(range(d))|set(range(d+1, D)))-candidates, K-len(candidates))
			# pad set of candidates with these document IDs and recast as list
			candidates = list(candidates.union(set(docs)))
			num_padded += 1
			# then iterate through all K neighbors
			for k in range(K):
				# and compute the estimated Jaccard similarity and add it to array
				neighbor = candidates[k]
				jaccard_sim[k] = estimated_jaccard(sig_mat[:,d], sig_mat[:,neighbor])
		# otherwise
		else:
			# initialize empty priority queue to store K closest neighbors
			queue = []
			# loop over all candidates
			for j in candidates:
				# compute the Jaccard similarity between the current pair and enqueue
				hq.heappush(queue, (estimated_jaccard(sig_mat[:,d], sig_mat[:,j]), j))
				# if more than K items in queue
				if len(queue) > K:
					# remove document with lowest Jaccard similarity
					hq.heappop(queue)
			# iterate through all K neighbors
			for k in range(K):
				# obtain Jaccard similarity and add it to the array
				jaccard_sim[k] = hq.heappop(queue)[0]
		# compute the average Jaccard similarity and add to array at top
		avg_jaccard_sim[d] = np.mean(jaccard_sim)
	 	# print progress to screen
		if D >= 10:
			if (d+1) % (D//10) == 0:
		 		print('Average estimated Jaccard similarity for document ', d+1, ': ',
		 			'%.4f' % avg_jaccard_sim[d], sep='')
		 		sys.stdout.flush()
	# return average of averages along with time taken and number of documents whose
	# neighbors were chosen randomly
	return(np.mean(avg_jaccard_sim), time.time() - start_time, num_padded)

def main():
	# # obtain command line arguments
	# parser = argparse.ArgumentParser()
	# parser.add_argument('--D', type=int,
	# 	help='Integer number of documents to read into program')
	# parser.add_argument('--doc1', type=int, default=1,
	# 	help='Document ID of first document')
	# parser.add_argument('--doc2', type=int, default=2,
	# 	help='Document ID of second document')
	# parser.add_argument('--N', type=int, default=1000,
	# 	help='Number of rows of signature matrix')
	# parser.add_argument('--K', type=int,
	# 	help='Number of closest neighbors for the knn algorithm')
	# parser.add_argument('--R', type=int,
	# 	help='Number of rows in each band')
	# flags, unparsed = parser.parse_known_args()

	# get user input for number of documents D
	D = int(input('Input number of documents to read: '))
	# create character matrix stored as a list of sets
	chr_mat, time_taken0 = character_matrix(D)
	print('Created character matrix (%.4f seconds).' % float(time_taken0))
	# get user input for two documents whose Jaccard similarity is to be computed
	doc1 = int(input('Input first document ID: '))
	doc2 = int(input('Input second document ID: '))
	# compute Jaccard similarity between requested documents
	print('Actual Jaccard similarity for documents %s and %s: %.4f' %
		(doc1, doc2, jaccard(chr_mat[doc1-1], chr_mat[doc2-1])))
	# get user input for number of rows of signature matrix N
	N = int(input('Input number of rows for the signature matrix: '))
	# create signature matrix stored as numpy 2D array
	sig_mat, time_taken1 = signature_matrix(chr_mat, N, D)
	print('Created signature matrix (%.4f seconds)' % float(time_taken1))
	# compute estimated Jaccard similarity between requested documents
	print('Estimated Jaccard similarity for documents %s and %s: %.4f' %
		(doc1, doc2, estimated_jaccard(sig_mat[:,doc1-1],
							sig_mat[:,doc2-1])))
	print('------------------------------------------------------------------------------------------------')
	# get user input for number of nearest neighbors K
	K = int(input('Input number of nearest neighbors: '))
	# compute average Jaccard similarity in data set using brute force
	avg_acc1, time_taken2 = knn_brute_force(chr_mat, K=K, D=D)
	print('Average Jaccard similarity across all documents using brute force: %.4f (%.4f seconds)' \
		% (avg_acc1, float(time_taken2)))
	# get user input for number of rows per band R
	R = int(input('Input number of rows in each band: '))
	# compute average estimated Jaccard similarity using LSH
	avg_acc2, time_taken3, num_random = knn_lsh(sig_mat, K=K, D=D, R=R)
	print('Average estimated Jaccard similarity across all documents using banding and LSH: %.4f (%.4f seconds)' \
		% (avg_acc2, float(time_taken3)))
	print('Number of documents whose neighbors were chosen at random:', num_random)

if __name__ == '__main__':
	main()


class Solution:
    def mySqrt(self, x: int) -> int:

        #binary search the numbers to find the int(floor(sqrt(x)))

        left = 0
        right = 46341
        middle = (left + right)//2

        while True:
            mid_val = middle * middle
            if mid_val < x:
                if (middle+1) * (middle+1) > x:
                    return middle
                left = middle + 1
                middle = (left + right)//2
            elif mid_val > x:
                right = middle - 1
                middle = (left + right)//2
            else: #mid_val == x:
                return middle

#runtime: O(1) (logarithmic, way faster than the brute force solution)


import sys
from io import StringIO
import unittest

class TestClass(unittest.TestCase):
    def assertIO(self, input, output):
        stdout, stdin = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(input)
        resolve()
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, stdin
        self.assertEqual(out, output)

    def test_Sample_Input_1(self):
        input = """5
2 2
3 1
1 3
4 2
5 3"""
        output = """12"""
        self.assertIO(input, output)

    def test_Sample_Input_2(self):
        input = """9
5 5
-4 4
4 3
6 3
-5 5
-3 2
2 2
3 3
1 4"""
        output = """38"""
        self.assertIO(input, output)

def resolve():
  inf = 10**18+1
  # 各色の min max を管理する
  from collections import defaultdict
  N = int(input())
  # BALLES = [list(map(int, input().split(" "))) for _ in range(N)]

  min_ = [inf]*(N+2)
  max_ = [-inf]*(N+2)
  C = set()
  min_[0] = min_[N+1] = max_[0] = max_[N+1] = 0
  C.add(0)
  C.add(N+1)
  for n in range(N):
    x, c = map(int, input().split(" "))
    min_[c] = min(min_[c], x)
    max_[c] = max(max_[c], x)
    C.add(c)
  C = sorted(list(C))

  last_min = last_max = 0
  min_ans = max_ans = 0
  for i in range(1, len(C)):
    min_ans, max_ans = min(min_ans + abs(min_[C[i-1]] - max_[C[i]]), max_ans + abs(max_[C[i-1]] - max_[C[i]])) + max_[C[i]]-min_[C[i]], min(min_ans + abs(min_[C[i-1]] - min_[C[i]]), max_ans + abs(max_[C[i-1]] - min_[C[i]])) + max_[C[i]]-min_[C[i]]
  print(min(min_ans, max_ans))

resolve()

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


"""
Example script of WaveBlocks framework.
This script uses a Fourier Light Field (FLF) microscope with a Microlens Array (MLA) and a phase mask (PM)

The aim of this experiment is to show a complete working example of simulation and reconstruction
Here, we define the microscope and forward project a volume of microspheres.
We then use torch optimizers to reconstruct the volume.

# Erik Riedel & Josef Kamysek
# erik.riedel@tum.de & josef@kamysek.com
# 15/10/2020, Munich, Germany
"""

# Third party libraries imports
import matplotlib.pyplot as plt
import numpy as np
import torch
import pathlib
import logging
import tables
import os
import math

# Waveblocks imports
import waveblocks
from waveblocks.microscopes.fourier_lightfield_mla_micro import Microscope, preset1
from waveblocks.utils import generate_phase_masks as pm
import waveblocks.evaluation.reconstruction_analysis as fwhm
import waveblocks.reconstruction.deconvolution.optimizer_reconstruction as recon
import waveblocks.evaluation.microspheres as ms
from waveblocks.blocks.optic_config import OpticConfig
from waveblocks.blocks.microlens_arrays import MLAType
import waveblocks.blocks.point_spread_function as psf
from waveblocks.utils.helper import get_free_gpu

# Set logging
logger = logging.getLogger("Waveblocks")
waveblocks.set_logging(debug_mla=False, debug_microscope=False, debug_richardson_lucy=False, debug_optimizer=True)
torch.set_num_threads(8)

pm_name = 'cubic'

work_dir = os.getcwd()
save_img_path = f"{work_dir}/outputs/{os.path.basename(__file__)[:-3]}/" + pm_name + "_pm_"
os.makedirs(save_img_path, exist_ok=True)

# Optical Parameters
depth_range = [-32, 32]
depth_step = 2
depths = np.arange(depth_range[0], depth_range[1] + depth_step, depth_step)
n_depths = len(depths)
# Change size of volume you are looking at
vol_xy_size = 151  # 17

# Configuration parameters
lr = 5e-2
max_volume = 1
n_epochs = 1
file_path = pathlib.Path(__file__).parent.absolute()
output_path = file_path.parent.joinpath("runs/LF_PM/")
data_path = file_path.parent.joinpath("data")
prefix = "_basic_example_"
# Fetch Device to use
device = torch.device("cuda:" + str(get_free_gpu()) if torch.cuda.is_available() else "cpu")
# device = torch.device("cpu")

if device == torch.device("cpu"):
    logger.warning("USING CPU")

# Load volume to use as our object in front of the microscope
vol_file = tables.open_file(data_path.joinpath("fish_phantom_251_251_51.h5"), "r", driver="H5FD_CORE")
gt_volume = torch.tensor(vol_file.root.fish_phantom).permute(2, 1, 0).unsqueeze(0).unsqueeze(0).to(device)
gt_volume = torch.nn.functional.interpolate(gt_volume, [vol_xy_size, vol_xy_size, n_depths])
gt_volume = gt_volume[:, 0, ...].permute(0, 3, 1, 2).contiguous()
gt_volume = torch.nn.functional.pad(gt_volume, [2, 2, 2, 2])
gt_volume /= gt_volume.max()
gt_volume *= max_volume

# Create opticalConfig object with the information from the microscope
optic_config = preset1()

# Lateral size of PSF in pixels
psf_size = 17 * 31  # 17 * 11

# Define PSF
psf = psf.PSF(optic_config=optic_config, members_to_learn=[])
_, psf_in = psf.forward(optic_config.sensor_pitch / optic_config.PSF_config.M, psf_size, depths)

# Enable Fourier convolutions
optic_config.use_fft_conv = True

# Create Microscope
# List of all coordinates in the MLA
mla_coordinates = [
    (100, 250),
    (250, 250),
    (400, 250),
    (100, 100),
    (250, 100),
    (400, 100),
    (100, 400),
    (250, 400),
    (400, 400),
]
mla_shape = [psf_size, psf_size]

# Define phase mask
optic_config.use_pm = True
# Number of pixels in phase mask
# compute pixel size at fourier plane of first lens
Fs = 1.0 / optic_config.sensor_pitch
cycles_perum = Fs / psf_in.shape[-2]
# incoherent resolution limit
resolution_limit = optic_config.PSF_config.wvl / (optic_config.PSF_config.NA * optic_config.PSF_config.M)
n_pix_in_fourier = resolution_limit / cycles_perum
# diameter of the objective back focal plane, which acts as the entrance pupil for our system
d_obj = optic_config.PSF_config.fobj * optic_config.PSF_config.NA
# sampling size on the fourier domain
fourier_metric_sampling = d_obj / n_pix_in_fourier

optic_config.pm_sampling = fourier_metric_sampling

# optic_config.pm_pixel_size = 8
optic_config.pm_pixel_size = 3.9

# optic_config.pm_shape = [
#     int(optic_config.pm_pixel_size / fourier_metric_sampling * 1080),
#     int(optic_config.pm_pixel_size / fourier_metric_sampling * 1920),
# ]
optic_config.pm_shape = [
    psf_size,
    psf_size,
]  # 512 [1054, 1054] # [187, 187] # [527,527]

optic_config.pm_max_phase_shift = 5.4 * math.pi
if pm_name == 'cubic':
    pm_image = pm.create_phasemask(
        pm.PhaseMaskType.cubic,
        pm.PhaseMaskShape.square,
        {
            "x": optic_config.pm_shape[0],
            "y": optic_config.pm_shape[1],
            "ratio": 0.4,  # 0.3,
            "offset": [0, 0],
        },
        information={"max_phase_shift": 5.4 * math.pi},
    ).unsqueeze(0).unsqueeze(0)

elif pm_name == 'zernikie':
    pm_image = pm.create_phasemask(
        pm.PhaseMaskType.zernkie,
        pm.PhaseMaskShape.square,
        {
            "x": optic_config.pm_shape[0],
            "y": optic_config.pm_shape[1],
            "ratio": 0.7,
            "offset": [0, 0],
        },
        information={"j": 3, "max_phase_shift": 2.5 * math.pi},
    )

pm_image_plot = pm_image
plt.imshow(pm_image_plot[0,0,:,:].detach().cpu().numpy())
plt.title("PM used")
plt.savefig(f'{save_img_path}/PM_used.png')
plt.clf()

wb_micro = Microscope(
    optic_config=optic_config,
    members_to_learn=["volume_pred"],
    psf_in=psf_in,
    mla_coordinates=mla_coordinates,
    mla_shape=mla_shape,
    pm_image=pm_image,
).to(device)
wb_micro.eval()

# Create observed FLF image
gt_flf_img = wb_micro(gt_volume.detach()).detach()
try:
    plt.title("GT simulated Image")
    plt.imshow(gt_flf_img[0, 0, :, :].detach().cpu().numpy())
    plt.savefig(f'{save_img_path}/GT_simulated_image.png')
    plt.clf()
except Exception as inst:
    print(inst)

reconstructor = recon.Optimizer_Reconstruction(wb_micro, gt_flf_img, gt_volume.shape, torch.optim.Adam, 0.02, torch.nn.L1Loss())
volume_pred,losses = reconstructor.train(200)

fig, axs = plt.subplots(1, 3)
axs[0].title.set_text("GT")
im = axs[0].imshow(gt_volume[0].amax(0).detach().cpu().numpy(), cmap="inferno", vmin=0, vmax=1)
fig.colorbar(im, ax=axs[0])
axs[1].title.set_text("reconstruction")
axs[1].imshow(volume_pred[0].amax(0).detach().cpu().numpy(), cmap="inferno", vmin=0, vmax=1)
fig.colorbar(im, ax=axs[1])
fig.tight_layout()
axs[2].title.set_text("losses")
axs[2].plot(losses)
fig.tight_layout()

plt.savefig(f'{save_img_path}/recon_result.png')
plt.clf()


import numpy as np
from liboptpy.simulator.bioprocess import bioprocess_simulator
from liboptpy.lib.util import comupute_cumulative_feed
import pandas as pd
from tqdm import tqdm

def compute_reward(cumulative_feed, state, horizon):
    titer = state[1]
    total_CA = state[1] * state[-1]
    oil_consumed = cumulative_feed * 917 - state[2] * state[-1]
    yield_CA = total_CA / oil_consumed
    pv = titer / horizon
    man_cost = (2 / pv + 1 / yield_CA) / 1000  # $/(g h)
    total_reward = - man_cost * horizon  # * state[-1] * state[1]
    return total_reward

def compute_avg_reward(bn, params, policy, time_measurement,  real_measurement, B, isMDP=True):
    reward = np.zeros(B)
    for b in tqdm(range(B)):
        x0 = bn.initial_state_full + np.abs(
            np.random.normal(0, np.array(bn.initial_state_full) / 10 + 0.01))
        # time_measurement = [4 * i for i in range(bn.n_time)]
        # time_measurement[-1] = 135.9
        simulator = bioprocess_simulator(bn, time_measurement, policy, real_measurement)
        states = simulator.g(time_measurement, x0, params)
        feed = pd.DataFrame(simulator.feed_every_second, columns=['time', 'feed_rate'],
                               dtype="float64").drop_duplicates().to_numpy() if isMDP else np.vstack([real_measurement, np.array(policy.measurement)]).T
        total_feed = comupute_cumulative_feed(feed)
        reward[b] = compute_reward(total_feed, states[-1,:], time_measurement[-1])
    return np.mean(reward)


import sys
from io import StringIO
import unittest

class TestClass(unittest.TestCase):
    maxDiff = None
    def assertIO(self, input, output):
        stdout, stdin = sys.stdout, sys.stdin
        sys.stdout, sys.stdin = StringIO(), StringIO(input)
        resolve()
        sys.stdout.seek(0)
        out = sys.stdout.read()[:-1]
        sys.stdout, sys.stdin = stdout, stdin
        self.assertEqual(out, output)

    def test_Sample_Input_1(self):
        input = """1"""
        output = """Aoki"""
        self.assertIO(input, output)

    def test_Sample_Input_2(self):
        input = """5"""
        output = """Takahashi"""
        self.assertIO(input, output)

    def test_Sample_Input_3(self):
        input = """7"""
        output = """Aoki"""
        self.assertIO(input, output)

    def test_Sample_Input_4(self):
        input = """10"""
        output = """Takahashi"""
        self.assertIO(input, output)

    def test_Sample_Input_5(self):
        input = """123456789123456789"""
        output = """Aoki"""
        self.assertIO(input, output)

def resolve():
  # DP っぽい
  # 一回の操作でパターン数は 2 倍に増える。
  # N <= 10**18 なので最大 60 回程度の操作しかしない。
  # i の時に手番をとったら負けるゾーンがある。
  # => 遷移先に i を選べる場合はそこに放り込めば勝ち。
  # => i に遷移できるならば勝ち
  # 遷移を考えるのが厄介。

  N = int(input())+1
  win = False
  while N > 1:
    win = not win
    N = (N+1)//2 if win else (N)//2

  print("Takahashi" if not win else "Aoki")

import sys
if sys.argv[-1] == './Main.py':
  resolve()

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


# Test d'un cache en utilisant un weakref.WeakValueDictionary
# 2021-02-26    PV

import weakref
import collections
import random
import matplotlib.pyplot as plt     # type: ignore
import math

# Classe objet arbitraire
class sprocket:
    def __init__(self, key: int) -> None:
        self.key = key

def test_cache(global_size:int, cache_size: int, rounds: int) -> float:
    # Les objects ne sont présents dans ce cache que s'ils existent dans cache_que.  Le test est rapide puisque c'est un dictionnaire
    cache_dic: weakref.WeakValueDictionary = weakref.WeakValueDictionary()
    # Simple queue de stockage des objets cachés, limitée à cache_size entrées
    cache_que: collections.deque = collections.deque(maxlen=cache_size)

    # Retourne le coût pour obtenir le sprocket de clé key, par convention la création de l'objet a un coût de 50 (ex: lecture BD) contre 1 s'il est dans le cache
    def build_item(key: int) -> int:
        if key in cache_dic:
            s = cache_dic[key]
            # On place l'objet en tête de cache, comme s'il venait d'être ajouté au cache pour la première fois
            cache_que.remove(s)
            cache_que.append(s)
            return 1
        s = sprocket(key)
        cache_que.append(s)
        cache_dic[key] = s
        return 50

    cost = 0
    for i in range(rounds):
        while True:
            # Deux modèle d'accès aléatoire aux clés, un modèle "loi normale" centrée en global_size/2, et un modèle uniforme
            k = math.floor(random.normalvariate(global_size/2,global_size/8))
            #k = random.randint(1, global_size)
            if 1<=k<=global_size: break
        cost += build_item(k)
    return cost/rounds

print(test_cache(10,10,100))

sizes = [5*i for i in range(0,20)]
costs = [test_cache(100,s,200) for s in sizes]

#print(sizes)
#print(costs)

"""
# Test d'une loi normale
b = 50
sizes = range(b+1)
costs = [0]*(b+1)
for i in range(100000):
    k = math.floor(random.normalvariate(b/2,b/8))
    if 0<=k<=b:
        costs[k]+=1
print(costs)
"""

plt.plot(sizes, costs)
plt.show()


import random
import re
import signal
from collections import defaultdict
from contextlib import contextmanager
from typing import Any, Dict, List, Optional, Set, Tuple

from llama_index.program.predefined.evaporate.prompts import (
    DEFAULT_EXPECTED_OUTPUT_PREFIX_TMPL,
    DEFAULT_FIELD_EXTRACT_QUERY_TMPL,
    FN_GENERATION_PROMPT,
    SCHEMA_ID_PROMPT,
    FnGeneratePrompt,
    SchemaIDPrompt,
)
from llama_index.schema import BaseNode, MetadataMode, NodeWithScore, QueryBundle
from llama_index.service_context import ServiceContext

class TimeoutException(Exception):
    pass

@contextmanager
def time_limit(seconds: int) -> Any:
    """Time limit context manager.

    NOTE: copied from https://github.com/HazyResearch/evaporate.

    """

    def signal_handler(signum: Any, frame: Any) -> Any:
        raise TimeoutException("Timed out!")

    signal.signal(signal.SIGALRM, signal_handler)
    signal.alarm(seconds)
    try:
        yield
    finally:
        signal.alarm(0)

def get_function_field_from_attribute(attribute: str) -> str:
    """Get function field from attribute.

    NOTE: copied from https://github.com/HazyResearch/evaporate.

    """
    return re.sub(r"[^A-Za-z0-9]", "_", attribute)

def extract_field_dicts(result: str, text_chunk: str) -> Set:
    """Extract field dictionaries."""
    existing_fields = set()
    result = result.split("---")[0].strip("\n")
    results = result.split("\n")
    results = [r.strip("-").strip() for r in results]
    results = [r[2:].strip() if len(r) > 2 and r[1] == "." else r for r in results]
    for result in results:
        try:
            field = result.split(": ")[0].strip(":")
            value = ": ".join(result.split(": ")[1:])
        except Exception:
            print(f"Skipped: {result}")
            continue
        field_versions = [
            field,
            field.replace(" ", ""),
            field.replace("-", ""),
            field.replace("_", ""),
        ]
        if not any(f.lower() in text_chunk.lower() for f in field_versions):
            continue
        if not value:
            continue
        field = field.lower().strip("-").strip("_").strip(" ").strip(":")
        if field in existing_fields:
            continue
        existing_fields.add(field)

    return existing_fields

# since we define globals below
class EvaporateExtractor:
    """Wrapper around Evaporate.

    Evaporate is an open-source project from Stanford's AI Lab:
    https://github.com/HazyResearch/evaporate.
    Offering techniques for structured datapoint extraction.

    In the current version, we use the function generator
    from a set of documents.

    Args:
        service_context (Optional[ServiceContext]): Service Context to use.
    """

    def __init__(
        self,
        service_context: Optional[ServiceContext] = None,
        schema_id_prompt: Optional[SchemaIDPrompt] = None,
        fn_generate_prompt: Optional[FnGeneratePrompt] = None,
        field_extract_query_tmpl: str = DEFAULT_FIELD_EXTRACT_QUERY_TMPL,
        expected_output_prefix_tmpl: str = DEFAULT_EXPECTED_OUTPUT_PREFIX_TMPL,
        verbose: bool = False,
    ) -> None:
        """Initialize params."""
        # TODO: take in an entire index instead of forming a response builder
        self._service_context = service_context or ServiceContext.from_defaults()
        self._schema_id_prompt = schema_id_prompt or SCHEMA_ID_PROMPT
        self._fn_generate_prompt = fn_generate_prompt or FN_GENERATION_PROMPT
        self._field_extract_query_tmpl = field_extract_query_tmpl
        self._expected_output_prefix_tmpl = expected_output_prefix_tmpl
        self._verbose = verbose

    def identify_fields(
        self, nodes: List[BaseNode], topic: str, fields_top_k: int = 5
    ) -> List:
        """Identify fields from nodes.

        Will extract fields independently per node, and then
        return the top k fields.

        Args:
            nodes (List[BaseNode]): List of nodes to extract fields from.
            topic (str): Topic to use for extraction.
            fields_top_k (int): Number of fields to return.

        """
        field2count: dict = defaultdict(int)
        for node in nodes:
            llm = self._service_context.llm
            result = llm.predict(
                self._schema_id_prompt,
                topic=topic,
                chunk=node.get_content(metadata_mode=MetadataMode.LLM),
            )

            existing_fields = extract_field_dicts(
                result, node.get_content(metadata_mode=MetadataMode.LLM)
            )

            for field in existing_fields:
                field2count[field] += 1

        sorted_tups: List[Tuple[str, int]] = sorted(
            field2count.items(), key=lambda x: x[1], reverse=True
        )
        sorted_fields = [f[0] for f in sorted_tups]
        return sorted_fields[:fields_top_k]

    def extract_fn_from_nodes(
        self, nodes: List[BaseNode], field: str, expected_output: Optional[Any] = None
    ) -> str:
        """Extract function from nodes."""
        # avoid circular import
        from llama_index.response_synthesizers import (
            ResponseMode,
            get_response_synthesizer,
        )

        function_field = get_function_field_from_attribute(field)
        # TODO: replace with new response synthesis module

        if expected_output is not None:
            expected_output_str = (
                f"{self._expected_output_prefix_tmpl}{expected_output!s}\n"
            )
        else:
            expected_output_str = ""

        qa_prompt = self._fn_generate_prompt.partial_format(
            attribute=field,
            function_field=function_field,
            expected_output_str=expected_output_str,
        )

        response_synthesizer = get_response_synthesizer(
            service_context=self._service_context,
            text_qa_template=qa_prompt,
            response_mode=ResponseMode.TREE_SUMMARIZE,
        )

        # ignore refine prompt for now
        query_str = self._field_extract_query_tmpl.format(field=function_field)
        query_bundle = QueryBundle(query_str=query_str)
        response = response_synthesizer.synthesize(
            query_bundle,
            [NodeWithScore(node=n, score=1.0) for n in nodes],
        )
        fn_str = f"""def get_{function_field}_field(text: str):
    \"""
    Function to extract {field}.
    \"""
    {response!s}
"""

        # format fn_str
        return_idx_list = [i for i, s in enumerate(fn_str.split("\n")) if "return" in s]
        if not return_idx_list:
            return ""

        return_idx = return_idx_list[0]
        fn_str = "\n".join(fn_str.split("\n")[: return_idx + 1])
        fn_str = "\n".join([s for s in fn_str.split("\n") if "print(" not in s])
        return "\n".join(
            [s for s in fn_str.split("\n") if s.startswith((" ", "\t", "def"))]
        )

    def run_fn_on_nodes(
        self, nodes: List[BaseNode], fn_str: str, field_name: str, num_timeouts: int = 1
    ) -> List:
        """Run function on nodes.

        Calls python exec().

        There are definitely security holes with this approach, use with caution.

        """
        function_field = get_function_field_from_attribute(field_name)
        results = []
        for node in nodes:
            global result
            global node_text
            node_text = node.get_content()  # type: ignore[name-defined]
            # this is temporary
            result = []  # type: ignore[name-defined]
            try:
                with time_limit(1):
                    exec(fn_str, globals())
                    exec(f"result = get_{function_field}_field(node_text)", globals())
            except TimeoutException:
                raise
            results.append(result)  # type: ignore[name-defined]
        return results

    def extract_datapoints_with_fn(
        self,
        nodes: List[BaseNode],
        topic: str,
        sample_k: int = 5,
        fields_top_k: int = 5,
    ) -> List[Dict]:
        """Extract datapoints from a list of nodes, given a topic."""
        idxs = list(range(len(nodes)))
        sample_k = min(sample_k, len(nodes))
        subset_idxs = random.sample(idxs, sample_k)
        subset_nodes = [nodes[si] for si in subset_idxs]

        # get existing fields
        existing_fields = self.identify_fields(
            subset_nodes, topic, fields_top_k=fields_top_k
        )

        # then, for each existing field, generate function
        function_dict = {}
        for field in existing_fields:
            fn = self.extract_fn_from_nodes(subset_nodes, field)
            function_dict[field] = fn

        # then, run function for all nodes
        result_dict = {}
        for field in existing_fields:
            result_list = self.run_fn_on_nodes(nodes, function_dict[field], field)
            result_dict[field] = result_list

        # convert into list of dictionaries
        result_list = []
        for i in range(len(nodes)):
            result_dict_i = {}
            for field in existing_fields:
                result_dict_i[field] = result_dict[field][i]
            result_list.append(result_dict_i)
        return result_list


import datetime
import random

from sklearn.model_selection import train_test_split
import pandas as pd
from svm.accuracy import *
from svm.linear import LinearSVM

start = datetime.datetime.now()
f = pd.read_csv('dataset_breastcancer.csv')
f.columns=["id", "diagnosis", "radius_2ean", "texture_2ean", "peri2eter_2ean", "area_2ean", "s2oothness_2ean", "co2pactness_2ean", "concavity_2ean", "concave points_2ean", "sy22etry_2ean", "fractal_di2ension_2ean", "radius_se, ", "texture_se, "	, "peri2eter_se, ", "	area_se, ", "	s2oothness_se, ", "	co2pactness_se, ", "	concavity_se, ", "	concave points_se, ", "	sy22etry_se, ", "	fractal_di2ension_se, ", "	radius_worst, ", "	texture_worst, ", "	peri2eter_worst, ", "	area_worst, ", "	s2oothness_worst, ", "	co2pactness_worst, ", "	concavity_worst, ", "	concave points_worst, ", "	sy22etry_worst, ", "	fractal_di2ension_worst"]
file = f[[ "radius_2ean", "texture_2ean", "peri2eter_2ean", "area_2ean", "s2oothness_2ean", "co2pactness_2ean", "concavity_2ean", "concave points_2ean", "sy22etry_2ean", "fractal_di2ension_2ean", "radius_se, ", "texture_se, "	, "peri2eter_se, ", "	area_se, ", "	s2oothness_se, ", "	co2pactness_se, ", "	concavity_se, ", "	concave points_se, ", "	sy22etry_se, ", "	fractal_di2ension_se, ", "	radius_worst, ", "	texture_worst, ", "	peri2eter_worst, ", "	area_worst, ", "	s2oothness_worst, ", "	co2pactness_worst, ", "	concavity_worst, ", "	concave points_worst, ", "	sy22etry_worst, ", "	fractal_di2ension_worst"]]
file = np.array(file)
y = f[["diagnosis"]]

''' 打亂column(Pi)
l1 = random.sample(range(0, 30), 30)
file = file[:, l1]
print(l1)
'''

X_train1, X_test1, y_train1, y_test1 = train_test_split(file, y, test_size=0.3)

y_train1 = np.array(y_train1)
y_test1 = np.array(y_test1)

for i in range(y_train1.shape[0]):
    if(y_train1[i] == 2):
        y_train1[i] = -1
    if(y_train1[i] == 4):
        y_train1[i] = 1
for i in range(y_test1.shape[0]):
    if (y_test1[i] == 2):
        y_test1[i] = -1
    if (y_test1[i] == 4):
        y_test1[i] = 1

k=0
x_train = np.zeros((15,X_train1.shape[0],2))
for j in range(15):
    for i in range(X_train1.shape[0]): #(0~499, 500)
        x_train[j][i] = X_train1[i][k:k+2]
    k+=2

k=0
x_test = np.zeros((15,X_test1.shape[0],2))  #ALL is 15 parties (2 featrues in each)
for j in range(15):
    for i in range(X_test1.shape[0]): #(500~558, 59)
        x_test[j][i] = X_test1[i][k:k+2]
    k+=2

Xtrain = x_train[0]   #(500,30)
for i in range(1, x_train.shape[0]):  #range(1, x_train.shape[0])
    Xtrain = np.hstack([Xtrain, x_train[i]])

Xtest = x_test[0]     #(59,30)
for i in range(1, 15):  #range(1, x_test.shape[0])
    Xtest = np.hstack([Xtest, x_test[i]])

#print(x_train[:3].shape)
print("Dataset: Breast cancer")

clf = LinearSVM()
clf.fit(X=x_train[:15], y=y_train1)

acc_test = accuracy(clf, X=Xtest, y=y_test1)
print("Accuracy (on test): "+str(acc_test))
end = datetime.datetime.now()
#print("All time： ", end - start)