import asyncio
import json
from abc import abstractmethod, ABC
from datetime import datetime
from typing import Union, List, Dict, Any, Optional, cast, Tuple

from aiohttp import ClientSession

from helix_fhir_client_sdk.dictionary_parser import DictionaryParser
from helix_fhir_client_sdk.fhir_bundle import BundleEntry, Bundle
from helix_fhir_client_sdk.fhir_bundle_appender import FhirBundleAppender
from helix_fhir_client_sdk.function_types import HandleStreamingChunkFunction
from helix_fhir_client_sdk.graph.graph_definition import (
    GraphDefinition,
    GraphDefinitionLink,
    GraphDefinitionTarget,
)
from helix_fhir_client_sdk.loggers.fhir_logger import FhirLogger
from helix_fhir_client_sdk.responses.fhir_get_response import FhirGetResponse
from helix_fhir_client_sdk.responses.paging_result import PagingResult
from helix_fhir_client_sdk.utilities.fhir_json_encoder import FhirJSONEncoder
from helix_fhir_client_sdk.utilities.request_cache import RequestCache

class SimulatedGraphProcessorMixin(ABC):
    # noinspection PyPep8Naming,PyUnusedLocal
    async def process_simulate_graph_async(
        self,
        *,
        id_: Union[List[str], str],
        graph_json: Dict[str, Any],
        contained: bool,
        concurrent_requests: int = 1,
        separate_bundle_resources: bool = False,
        restrict_to_scope: Optional[str] = None,
        restrict_to_resources: Optional[List[str]] = None,
        restrict_to_capability_statement: Optional[str] = None,
        retrieve_and_restrict_to_capability_statement: Optional[bool] = None,
        ifModifiedSince: Optional[datetime] = None,
        eTag: Optional[str] = None,
        logger: Optional[FhirLogger],
        url: Optional[str],
        expand_fhir_bundle: Optional[bool],
    ) -> FhirGetResponse:
        """
        Simulates the $graph query on the FHIR server

        :param separate_bundle_resources:
        :param id_: single id or list of ids (ids can be comma separated too)
        :param concurrent_requests:
        :param graph_json: definition of a graph to execute
        :param contained: whether we should return the related resources as top level list or nest them inside their
                            parent resources in a contained property
        :param restrict_to_scope: Optional scope to restrict to
        :param restrict_to_resources: Optional list of resources to restrict to
        :param restrict_to_capability_statement: Optional capability statement to restrict to
        :param retrieve_and_restrict_to_capability_statement: Optional capability statement to retrieve and restrict to
        :param ifModifiedSince: Optional datetime to use for If-Modified-Since header
        :param eTag: Optional ETag to use for If-None-Match header
        :param logger: Optional logger to use
        :param url: Optional url to use
        :param expand_fhir_bundle: Optional flag to expand the FHIR bundle
        :return: FhirGetResponse
        """
        assert graph_json
        graph_definition: GraphDefinition = GraphDefinition.from_dict(graph_json)
        assert isinstance(graph_definition, GraphDefinition)
        assert graph_definition.start

        # we handle separate resources differently below
        self.separate_bundle_resources(False)

        if logger:
            logger.info(
                f"FhirClient.simulate_graph_async() id_=${id_}, contained={contained}, "
                + f"separate_bundle_resources={separate_bundle_resources}"
            )

        if not isinstance(id_, list):
            id_ = id_.split(",")

        cache: RequestCache
        with RequestCache() as cache:
            output_queue: asyncio.Queue[PagingResult] = asyncio.Queue()
            async with self.create_http_session() as session:
                # first load the start resource
                start: str = graph_definition.start
                response: FhirGetResponse
                cache_hits: int
                response, cache_hits = await self._get_resources_by_parameters_async(
                    session=session,
                    resource_type=start,
                    id_=id_,
                    cache=cache,
                )
                if not response.responses:
                    return response
                parent_bundle_entries: List[BundleEntry] = response.get_bundle_entries()

                if logger:
                    logger.info(
                        f"FhirClient.simulate_graph_async() got parent resources: {len(response.get_resources())} "
                        + f"cached:{cache_hits}"
                    )
                # turn into a bundle if not already a bundle
                bundle = Bundle(entry=parent_bundle_entries)

                # now process the graph links
                responses: List[FhirGetResponse] = []
                if graph_definition.link and len(graph_definition.link) > 0:
                    link: GraphDefinitionLink
                    for link in graph_definition.link:
                        parent_bundle_entry: BundleEntry
                        for parent_bundle_entry in parent_bundle_entries:
                            responses.extend(
                                await self._process_link_async(
                                    session=session,
                                    link=link,
                                    parent_bundle_entry=parent_bundle_entry,
                                    logger=logger,
                                    cache=cache,
                                )
                            )
                FhirBundleAppender.append_responses(responses=responses, bundle=bundle)

                bundle = FhirBundleAppender.remove_duplicate_resources(bundle=bundle)

                # token, url, service_slug
                if separate_bundle_resources:
                    resources: Dict[str, Union[str, List[Dict[str, Any]]]] = {}
                    if bundle.entry:
                        entry: BundleEntry
                        for entry in bundle.entry:
                            resource: Optional[Dict[str, Any]] = entry.resource
                            if resource:
                                resource_type = resource.get("resourceType")
                                assert (
                                    resource_type
                                ), f"No resourceType in {json.dumps(resource)}"
                                if resource_type not in resources:
                                    resources[resource_type] = []
                                if isinstance(resources[resource_type], list):
                                    resources[resource_type].append(resource)  # type: ignore
                    response.responses = json.dumps(resources, cls=FhirJSONEncoder)
                elif expand_fhir_bundle:
                    if bundle.entry:
                        response.responses = json.dumps(
                            [e.resource for e in bundle.entry], cls=FhirJSONEncoder
                        )
                    else:
                        response.responses = ""
                else:
                    bundle_dict: Dict[str, Any] = bundle.to_dict()
                    response.responses = json.dumps(bundle_dict, cls=FhirJSONEncoder)

                response.url = url or response.url  # set url to top level url
                if logger:
                    logger.info(
                        f"Request Cache hits: {cache.cache_hits}, misses: {cache.cache_misses}"
                    )
                return response

    async def _process_link_async(
        self,
        *,
        session: ClientSession,
        link: GraphDefinitionLink,
        parent_bundle_entry: Optional[BundleEntry],
        logger: Optional[FhirLogger],
        cache: RequestCache,
    ) -> List[FhirGetResponse]:
        """
        Process a GraphDefinition link object

        :param session: aiohttp session
        :param link: link to process
        :param parent_bundle_entry: parent bundle entry
        :param logger: logger to use
        :return: list of FhirGetResponse objects
        """
        assert session
        assert link
        responses: List[FhirGetResponse] = []
        targets: List[GraphDefinitionTarget] = link.target
        target: GraphDefinitionTarget
        for target in targets:
            responses.extend(
                await self._process_target_async(
                    session=session,
                    target=target,
                    path=link.path,
                    parent_bundle_entry=parent_bundle_entry,
                    logger=logger,
                    cache=cache,
                )
            )
        return responses

    async def _process_target_async(
        self,
        *,
        session: ClientSession,
        target: GraphDefinitionTarget,
        path: Optional[str],
        parent_bundle_entry: Optional[BundleEntry],
        logger: Optional[FhirLogger],
        cache: RequestCache,
    ) -> List[FhirGetResponse]:
        """
        Process a GraphDefinition target

        :param session: aiohttp session
        :param target: target to process
        :param path: path to process
        :param parent_bundle_entry: parent bundle entry
        :param logger: logger to use
        :return: list of FhirGetResponse objects
        """
        responses: List[FhirGetResponse] = []
        children: List[BundleEntry] = []
        child_response: FhirGetResponse
        child_response_resources: Union[Dict[str, Any], List[Dict[str, Any]]]
        target_type: Optional[str] = target.type_
        parent_resource: Optional[Dict[str, Any]] = (
            parent_bundle_entry.resource if parent_bundle_entry else None
        )
        if path:  # forward link
            if path.endswith("[x]"):  # a list
                path = path.replace("[x]", "")
                # find references
                references: Union[List[Dict[str, Any]], Dict[str, Any], str, None] = (
                    DictionaryParser.get_nested_property(parent_resource, path)
                    if parent_resource and path
                    else None
                )
                # remove null references
                if references and isinstance(references, list):
                    references = [r for r in references if r is not None]
                # iterate through all references
                if parent_resource and references and target_type:
                    reference_ids: List[str] = [
                        cast(str, r.get("reference"))
                        for r in references
                        if "reference" in r and isinstance(r, dict)
                    ]
                    for reference_id in reference_ids:
                        reference_parts = reference_id.split("/")
                        if reference_parts[0] == target_type:
                            child_id = reference_parts[1]
                            (
                                child_response,
                                cache_hits,
                            ) = await self._get_resources_by_parameters_async(
                                session=session,
                                resource_type=target_type,
                                id_=child_id,
                                cache=cache,
                            )
                            responses.append(child_response)
                            children = child_response.get_bundle_entries()
                            if logger:
                                logger.info(
                                    f"FhirClient.simulate_graph_async() got child resources with path:{path} "
                                    + f"from parent {target_type}/{child_id}: "
                                    + f"{len(children)} cached:{cache_hits}"
                                )
            else:  # single reference
                if parent_resource and parent_resource.get(path) and target_type:
                    reference = parent_resource.get(path)
                    if reference and "reference" in reference:
                        reference_id = reference["reference"]
                        reference_parts = reference_id.split("/")
                        if reference_parts[0] == target_type:
                            child_id = reference_parts[1]
                            (
                                child_response,
                                cache_hits,
                            ) = await self._get_resources_by_parameters_async(
                                session=session,
                                resource_type=target_type,
                                id_=child_id,
                                cache=cache,
                            )
                            responses.append(child_response)
                            children = child_response.get_bundle_entries()
                            if logger:
                                logger.info(
                                    f"FhirClient.simulate_graph_async() got child resources with path:{path} "
                                    + f"from parent {target_type}/{child_id}: "
                                    + f"{len(children)}. cached:{cache_hits}"
                                )
        elif target.params:  # reverse path
            # for a reverse link, get the ids of the current resource, put in a view and
            # add a stage to get that
            param_list: List[str] = target.params.split("&")
            ref_param = [p for p in param_list if p.endswith("{ref}")][0]
            additional_parameters = [p for p in param_list if not p.endswith("{ref}")]
            property_name: str = ref_param.split("=")[0]
            if (
                parent_resource
                and property_name
                and parent_resource.get("id")
                and target_type
            ):
                parent_id = parent_resource.get("id")
                (
                    child_response,
                    cache_hits,
                ) = await self._get_resources_by_parameters_async(
                    session=session,
                    resource_type=target_type,
                    parameters=[f"{property_name}={parent_id}"] + additional_parameters,
                    cache=cache,
                )
                responses.append(child_response)
                if logger:
                    logger.debug(
                        f"FhirClient.simulate_graph_async() got child resources with params:{target.params} "
                        + f"from parent {target_type} with {property_name}={parent_id}: "
                        + f"{child_response.responses}.  cached:{cache_hits}"
                    )
                children = child_response.get_bundle_entries()

        if target.link:
            child_link: GraphDefinitionLink
            for child_link in target.link:
                child: BundleEntry
                for child in children:
                    responses.extend(
                        await self._process_link_async(
                            session=session,
                            link=child_link,
                            parent_bundle_entry=child,
                            logger=logger,
                            cache=cache,
                        )
                    )
        return responses

    async def _get_resources_by_parameters_async(
        self,
        *,
        id_: Optional[Union[List[str], str]] = None,
        session: ClientSession,
        resource_type: str,
        parameters: Optional[List[str]] = None,
        cache: RequestCache,
    ) -> Tuple[FhirGetResponse, int]:
        assert session
        assert resource_type
        self.resource(resource=resource_type)

        id_list: Optional[List[str]]
        if id_ and not isinstance(id_, list):
            id_list = [id_]
        else:
            id_list = cast(Optional[List[str]], id_)

        non_cached_id_list: List[str] = []
        # get any cached resources
        cached_bundle_entries: List[BundleEntry] = []
        cached_response: Optional[FhirGetResponse] = None
        cache_hits: int = 0
        if id_list:
            for resource_id in id_list:
                cached_bundle_entry: Optional[BundleEntry] = cache.get(
                    resource_type=resource_type, resource_id=resource_id
                )
                if cached_bundle_entry:
                    cached_bundle_entries.append(cached_bundle_entry)
                    cache_hits += 1
                else:
                    non_cached_id_list.append(resource_id)

        if cached_bundle_entries and len(cached_bundle_entries) > 0:
            cached_bundle: Bundle = Bundle(entry=cached_bundle_entries)
            cached_response = FhirGetResponse(
                request_id=None,
                url=cached_bundle_entries[0].request.url
                if cached_bundle_entries[0].request
                else "",
                id_=None,
                resource_type=resource_type,
                responses=json.dumps(cached_bundle.to_dict(), cls=FhirJSONEncoder),
                response_headers=None,
                status=200,
                access_token=None,
                next_url=None,
                total_count=len(cached_bundle_entries),
                extra_context_to_return=None,
                error=None,
            )

        result: Optional[FhirGetResponse] = None
        # either we have non-cached ids or this is a query without id but has other parameters
        if len(non_cached_id_list) > 0 or not id_:
            result = await self._get_with_session_async(
                session=session,
                ids=non_cached_id_list,
                additional_parameters=parameters,
            )
            non_cached_bundle_entry: BundleEntry
            for non_cached_bundle_entry in result.get_bundle_entries():
                if non_cached_bundle_entry.resource:
                    non_cached_resource: Dict[
                        str, Any
                    ] = non_cached_bundle_entry.resource
                    non_cached_resource_id: Optional[str] = non_cached_resource.get(
                        "id"
                    )
                    if non_cached_resource_id:
                        cache.add(
                            resource_type=resource_type,
                            resource_id=non_cached_resource_id,
                            bundle_entry=non_cached_bundle_entry,
                        )

            if cached_response:
                result.append([cached_response])
        elif cached_response:
            result = cached_response
        assert result
        return result, cache_hits

    @abstractmethod
    def separate_bundle_resources(self, separate_bundle_resources: bool):  # type: ignore[no-untyped-def]
        pass

    @abstractmethod
    def create_http_session(self) -> ClientSession:
        pass

    @abstractmethod
    async def _get_with_session_async(
        self,
        *,
        session: Optional[ClientSession],
        page_number: Optional[int] = None,
        ids: Optional[List[str]] = None,
        id_above: Optional[str] = None,
        fn_handle_streaming_chunk: Optional[HandleStreamingChunkFunction] = None,
        additional_parameters: Optional[List[str]] = None,
    ) -> FhirGetResponse:
        pass

    @abstractmethod
    def resource(self, resource: str):  # type: ignore[no-untyped-def]
        pass


from tensorflow.python.data.util import structure
from tensorflow.python.ops import gen_experimental_dataset_ops as ged_ops

def compress(element):
  """Compress a dataset element.

  Args:
    element: A nested structure of types supported by Tensorflow.

  Returns:
    A variant tensor representing the compressed element. This variant can be
    passed to `uncompress` to get back the original element.
  """
  element_spec = structure.type_spec_from_value(element)
  tensor_list = structure.to_tensor_list(element_spec, element)
  return ged_ops.compress_element(tensor_list)

def uncompress(element, output_spec):
  """Uncompress a compressed dataset element.

  Args:
    element: A scalar variant tensor to uncompress. The element should have been
      created by calling `compress`.
    output_spec: A nested structure of `tf.TypeSpec` representing the type(s) of
      the uncompressed element.

  Returns:
    The uncompressed element.
  """
  flat_types = structure.get_flat_tensor_types(output_spec)
  flat_shapes = structure.get_flat_tensor_shapes(output_spec)
  tensor_list = ged_ops.uncompress_element(
      element, output_types=flat_types, output_shapes=flat_shapes)
  return structure.from_tensor_list(output_spec, tensor_list)


# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import re

df = pd.read_csv("astronauts.csv")

df['Group'] = df['Group'].astype(object)
sns.boxplot(df['Year'],)

df.describe()
len(df['Group'].unique())

df.head()

sns.factorplot('Military Rank',kind='count',data= df)
plt.xticks(rotation=90)

sns.factorplot('Status', kind='count', data=df)
plt.xticks(rotation=45)

sns.factorplot('Military Branch', kind='count', data=df, size=8)
plt.xticks(rotation=90)

df2 = df.copy()
df2['Military Branch'].apply(lambda x:replace(x," (Retired)"))

Temp_df = df[["Space Flights","Space Flight (hr)"]]
Temp_df.head()
Temp_df[["Space Flights","Space Flight (hr)"]].head(2).apply(lambda x:x[1]/x[0], axis=1)

8. Kaggle/11. NASA Astronauts(1959-NOW)/astronauts.py


from datetime import datetime

def sample_responses(input_text):
    user_text = str(input_text).lower()

    if user_text in ("hello","hey","hi","sup"):
        return "hey! How's it going?"

    if user_text in ("who are you","who are you?"):
        return "I am a bot"

    if user_text in("time", "time?"):
        now= datetime.now()
        date_time=now.strftime("%d/%m/%y, %H:%M: %S")

        return str(date_time)
    else:
        return "I don't understand you"


#!/usr/bin/python
#
# -*- coding: utf-8 -*-
# vim: set ts=2 sw=2 et sts=2 ai:

from __future__ import print_function

import getpass

from helpers import Namespace
from objects import (
  Snapshot,
  SnapshotName,
  Instance,
  Disk,
)
from tasklets import (
  CreateInstance,
  CreateDiskFromSnapshot,
  CreateDiskFromContentSnapshot,
  MountDisksInInstance,
  CancelledByOtherTask,
  AttachDiskToInstance,
  WaitOnOtherTasks,
  RunCommandsOnInstance,
  UnmountDisksInInstance,
  DetachDiskFromInstance,
  CreateSnapshotFromDisk,
)

class Stage(object):
  @property
  def stage_id(self):
    return '-'.join([
      Namespace(),
      'linux',
      self.current_commit,
      self.name,
    ])

  @staticmethod
  def extract_stage_id(tid):
    components = tid.split('-')
    return ('-'.join(components[:4]), '-'.join(components[4:]))

  @staticmethod
  def extract_commit(sid):
    return sid.split('-')[2]

  @staticmethod
  def extract_name(sid):
    return sid.split('-')[3]

  def __init__(self, previous_commit, current_commit):
    self.current_commit = current_commit
    self.previous_commit = previous_commit
    self._inputs = []
    self._outputs = []
    self._objects = []
    self.tasklets = self._tasklets()

  @property
  def name(self):
    return self.__class__.__name__.replace('Stage', '').lower()

  def _tasklets(self):
    raise NotImplementedError()

  def inputs(self):
    return self._inputs

  def outputs(self):
    return self._outputs

  def objects(self):
    return self._objects

  def cleanup(self, driver):
    for o in self.objects():
        if o.exists():
            o.destroy(driver)

  def needs_cleanup(self):
    if self.is_finished():
      for o in self.objects():
        if o.exists():
          return True
    else:
      for o in self.objects():
        if o.status == "TERMINATED":
          return True
    return False

  def is_startable(self):
    return all(i.ready() for i in self.inputs())

  def is_finished(self):
    return all(o.ready() for o in self.outputs())

class SyncStage(Stage):

  def _tasklets(self):
    sid = self.stage_id

    previous_snap_src = Snapshot.load(SnapshotName(self.previous_commit, "src"))
    self._inputs.append(previous_snap_src)

    instance = Instance.load("%s-instance" % sid)
    self._objects.append(instance)
    disk_src = Disk.load("%s-disk-src" % sid)
    self._objects.append(disk_src)

    snap_src = Snapshot.load(SnapshotName(self.current_commit, "src"))
    self._outputs.append(snap_src)

    tasks = []
    tasks.append(CreateInstance(self, sid + "-instance-create", instance, 'n1-standard-2', required_snapshots=[previous_snap_src]))
    tasks.append(CreateDiskFromSnapshot(self, sid + "-disk-src-create", previous_snap_src, disk_src))
    mount_task = MountDisksInInstance(self, sid + "-disk-mount", instance, [(disk_src, "/mnt/chromium")])
    attach_task = CancelledByOtherTask(
        AttachDiskToInstance(self, sid + "-disk-src-attach", instance, disk_src, 'READ_WRITE'),
        mount_task)
    tasks.append(attach_task)
    tasks.append(mount_task)

    run_task = WaitOnOtherTasks(
        RunCommandsOnInstance(self, sid + "-run", instance, [
            'export PATH=$PATH:/mnt/chromium/depot_tools',
            'cd /mnt/chromium/src',
            'time gclient sync -r %s' % self.current_commit,
        ]),
        [mount_task])
    tasks.append(run_task)

    umount_task = WaitOnOtherTasks(
        UnmountDisksInInstance(self, sid + "-disk-umount", instance, [(disk_src, '/mnt/chromium')]),
        [run_task])
    tasks.append(umount_task)

    detach_task = WaitOnOtherTasks(
        DetachDiskFromInstance(self, sid + "-disk-src-detach", instance, disk_src),
        [umount_task])
    tasks.append(detach_task)

    snapshot_task = WaitOnOtherTasks(
        CreateSnapshotFromDisk(self, sid + "-disk-src-snapshot", disk_src, snap_src),
        [detach_task])
    tasks.append(snapshot_task)

    return tasks

class BuildStage(Stage):
  def _tasklets(self):
    sid = self.stage_id

    current_snap_src = Snapshot.load(SnapshotName(self.current_commit, "src"))

    instance = Instance.load("%s-instance" % sid)
    disk_src = Disk.load("%s-disk-src" % sid)
    disk_out = Disk.load("%s-disk-out" % sid)
    snap_out = Snapshot.load(SnapshotName(self.current_commit, "out"))

    self._inputs.append(current_snap_src)
    self._objects.append(instance)
    self._objects.append(disk_src)
    self._objects.append(disk_out)
    self._outputs.append(snap_out)

    tasks = []
    tasks.append(CreateInstance(self, sid + "-instance-create", instance, 'n1-standard-16', required_snapshots=[current_snap_src]))
    create_src_disk = CreateDiskFromSnapshot(self, sid + "-disk-src-create", current_snap_src, disk_src)
    tasks.append(create_src_disk)
    tasks.append(WaitOnOtherTasks(
      CreateDiskFromContentSnapshot(self, sid + "-disk-out-create", self.current_commit, 'out', disk_out),
      [create_src_disk]))

    mount_task = MountDisksInInstance(self, sid + "-disk-mount", instance, [(disk_src, "/mnt/chromium"), (disk_out, "/mnt/chromium/src/out")])
    tasks.append(CancelledByOtherTask(
      AttachDiskToInstance(self, sid + "-disk-src-attach", instance, disk_src, 'READ_ONLY'),
      mount_task))
    tasks.append(CancelledByOtherTask(
      AttachDiskToInstance(self, sid + "-disk-out-attach", instance, disk_out, 'READ_WRITE'),
      mount_task))
    tasks.append(mount_task)

    run_task = WaitOnOtherTasks(
      RunCommandsOnInstance(self, sid + "-run", instance, [
        'export PATH=$PATH:/mnt/chromium/depot_tools',
        'cd /mnt/chromium/src',
        'time build/gyp_chromium',
        'time ninja -C out/Debug',
      ]),
      [mount_task])
    tasks.append(run_task)

    umount_task = WaitOnOtherTasks(
      UnmountDisksInInstance(self, sid + "-disk-umount", instance, [(disk_out, "/mnt/chromium/src/out"), (disk_src, "/mnt/chromium")]),
      [run_task])
    tasks.append(umount_task)

    detach_src_task = WaitOnOtherTasks(
      DetachDiskFromInstance(self, sid + "-disk-src-detach", instance, disk_src),
      [umount_task])
    tasks.append(detach_src_task)

    detach_out_task = WaitOnOtherTasks(
      DetachDiskFromInstance(self, sid + "-disk-out-detach", instance, disk_out),
      [umount_task])
    tasks.append(detach_out_task)

    snapshot_out_task = WaitOnOtherTasks(
      CreateSnapshotFromDisk(self, sid + "-disk-out-snapshot", disk_out, snap_out),
      [detach_out_task])
    tasks.append(snapshot_out_task)

    return tasks

try:
  from db_objects import TestResults
except ImportError:
  TestResults = None

class TestResultsUploadedObject:
  def __init__(self, path):
    self._path = path

  def ready(self):
    return TestResults.get_by_key_name(self._path) != None

class TestStage(Stage):
  TEST_BINARY = 'unit_tests'
  TOTAL_SHARDS = 1
  SHARD_INDEX = 0

  def _tasklets(self):
    sid = self.stage_id

    self._inputs = []
    self._outputs = [TestResultsUploadedObject(sid)]
    self._objects = []

    current_snap_src = Snapshot.load(SnapshotName(self.current_commit, "src"))
    self._inputs.append(current_snap_src)
    current_snap_out = Snapshot.load(SnapshotName(self.current_commit, "out"))
    self._inputs.append(current_snap_out)

    instance = Instance.load("%s-instance" % sid)
    self._objects.append(instance)
    disk_src = Disk.load("%s-disk-src" % sid)
    self._objects.append(disk_src)
    disk_out = Disk.load("%s-disk-out" % sid)
    self._objects.append(disk_out)

    tasks = []
    tasks.append(CreateInstance(self, sid + "-instance-create", instance, 'n1-standard-16', required_snapshots=[current_snap_src, current_snap_out]))
    tasks.append(CreateDiskFromSnapshot(self, sid + "-disk-src-create", current_snap_src, disk_src))
    tasks.append(AttachDiskToInstance(self, sid + "-disk-src-attach", instance, disk_src, 'READ_ONLY'))
    tasks.append(CreateDiskFromSnapshot(self, sid + "-disk-out-create", current_snap_out, disk_out))
    tasks.append(AttachDiskToInstance(self, sid + "-disk-out-attach", instance, disk_out, 'READ_ONLY'))

    mount_task = MountDisksInInstance(self, sid + "-disk-mount", instance, [(disk_src, "/mnt/chromium"), (disk_out, "/mnt/chromium/src/out")])
    tasks.append(mount_task)

    shard_variables = ('GTEST_TOTAL_SHARDS=%(total)d GTEST_SHARD_INDEX=%(index)d '
                       % {'total': self.TOTAL_SHARDS, 'index': self.SHARD_INDEX})
    xvfb_command = 'xvfb-run --server-args=\'-screen 0, 1024x768x24\' '
    command = (shard_variables + xvfb_command +
       ('out/Debug/%(test_binary)s --gtest_output="xml:/tmp/%(test_binary)s.xml"'
        % {'test_binary': self.TEST_BINARY}))

    run_task = WaitOnOtherTasks(
      RunCommandsOnInstance(self, sid + "-run", instance, [
        'export PATH=$PATH:/mnt/chromium/depot_tools',
        'cd /mnt/chromium/src',
        'sudo apt-get install xvfb -y',
        'chromium/src/build/update-linux-sandbox.sh',
        'export CHROME_DEVEL_SANDBOX=/usr/local/sbin/chrome-devel-sandbox',
        'time %s' % command,
      ]),
      [mount_task])
    tasks.append(run_task)

    upload_results_task = WaitOnOtherTasks(
      RunCommandsOnInstance(self, sid + "-upload-results", instance, [
        'curl -d @/tmp/%(test_binary)s.xml -X POST http://delta-trees-830.appspot.com/test_results/%(test_run_id)s' % {
          'test_binary': self.TEST_BINARY,
          'test_run_id': sid,
        },
      ]),
      [run_task])
    tasks.append(upload_results_task)

    umount_task = WaitOnOtherTasks(
      UnmountDisksInInstance(self, sid + "-disk-umount", instance, [(disk_src, "/mnt/chromium"), (disk_out, "/mnt/chromium/src/out")]),
      [run_task])
    tasks.append(umount_task)

    detach_src_task = WaitOnOtherTasks(
      DetachDiskFromInstance(self, sid + "-disk-src-detach", instance, disk_src),
      [umount_task])
    tasks.append(detach_src_task)

    detach_out_task = WaitOnOtherTasks(
      DetachDiskFromInstance(self, sid + "-disk-out-detach", instance, disk_out),
      [umount_task])
    tasks.append(detach_out_task)

    return tasks


import subprocess
import struct
import os
import sys
import hashlib
import json

import argparse

parser = argparse.ArgumentParser(description='Process some integers.')

parser.add_argument('asm', help='Assembly code to test (semicolon separated string)')

parser.add_argument('--init', help='Initialization assembly code (semicolon separated string)')
parser.add_argument('--icestorm', action='store_true', help='Test Icestorm instead of the default Firestorm')
parser.add_argument('--arm64e', action='store_true', help='Test on arm64e (requires bootarg)')

parser.add_argument('--unroll', type=int, default=100, help='Number of copies of the asm in the loop.')
parser.add_argument('--iters', type=int, default=100, help='Number of iterations to run.')
parser.add_argument('--divide', type=int, default=1, help='Number to divide results by (typically the number of times the instruction being tested is repeated in asm)')
parser.add_argument('--counters', default='default', choices=['default', 'all', 'fast', 'cycles'])
parser.add_argument('--zeroes', action='store_true', help='Show zero counters')

args = parser.parse_args()

DEFAULT_CONFIG = [
  0x54535202, 0x57560155,
  0x5b5a5958, 0x7e7d7c78,
  0xe981807f, 0x00efeeed,
]

if args.counters == 'fast':
	config = [
	  0x54535202, 0x78000155
	]
elif args.counters == 'cycles':
	config = [
		2 * 0x01010101, 2 * 0x01010101
	]
elif args.counters == 'all':
	config = []
	for i in range(1, 256):
		config.append(i * 0x01010101)
		config.append(i * 0x01010101)
else:
	config = DEFAULT_CONFIG

all_counters = set()
for i in config:
	for j in range(0, 32, 8):
		all_counters.add((i >> j) & 0xFF)

if 0 in all_counters:
	all_counters.remove(0)
all_counters = ['%02x' % i for i in sorted(all_counters)]
CYCLES = '02'
INST_ISSUE = '52'

if args.icestorm:
	SUFFIX = '-icestorm'
else:
	SUFFIX = '-firestorm'

if args.arm64e:
	SUFFIX += '-arm64e'

def assemble(code):
	if not code:
		return b''
	with open('tmp1.s', 'w') as f:
		f.write(code.replace(';', '\n'))
	if subprocess.call(['clang', '-c', 'tmp1.s', '-march=armv8.5-a+sha3+fp16fml']):
		exit(1)

	txt = subprocess.check_output(['otool', '-t', 'tmp1.o']).decode('ascii')
	u32s = []
	for line in txt.strip().split('\n')[2:]:
		for u32 in line.split()[1:]:
			u32s.append(struct.pack('<I', int(u32, 16)))
	os.unlink('tmp1.s')
	os.unlink('tmp1.o')
	return b''.join(u32s)

COUNTER_NAMES = {
	0x02: 'CYCLE',
	0x0d: 'MMU_MISS',
	0x52: 'INST_ISSUE',
	0x6c: 'INTERRUPT_PENDING',
	0x70: 'DISPATCH_STALL',
	0x75: 'SCHEDULER_REWIND',
	0x76: 'SCHEDULER_STALL',
	0x84: 'PIPELINE_REDIRECT',
	0x8c: 'INST_ALL',
	0x8d: 'INST_BRANCH',
	0x8e: 'INST_FUNCTION_CALLS',
	0x8f: 'INST_FUNCTION_RETURNS',
	0x97: 'INST_INTEGER',
	0x9a: 'INST_NEON_OR_FP',
	0x9b: 'INST_LDST',
	0x9c: 'INST_BARRIER',
	0xb3: 'ATOMIC_OR_EXCLUSIVE_SUCCESS',
	0xb4: 'ATOMIC_OR_EXCLUSIVE_FAIL',
	0xbf: 'DCACHE_LOAD_MISS',
	0xc0: 'DCACHE_STORE_MISS',
	0xc1: 'DTLB_MISS',
	0xc4: 'MEMORY_ORDER_VIOLATION',
	0xcb: 'BRANCH_MISPREDICT',
	0xd3: 'ICACHE_MISS',
	0xd4: 'ITLB_MISS',
	0xde: 'INST_FETCH_RESTART',

	0x01: 'uops_that_retire',

	0x53: 'int_unit_uops',
	0x54: 'fp_unit_uops',
	0x55: 'ldst_unit_uops',

	0x56: 'int_unk1_uops',
	0x57: 'fp_unk1_uops',
	0x58: 'ldst_unk1_uops',

	0x78: 'unk2_fused_uops',

	0x7C: 'int_unk3_unfused_uops',
	0x7E: 'fp_unk3_unfused_uops',
	0x7D: 'ldst_unk3_unfused_uops',

	0x7F: 'int_unk4_deps',
	0x81: 'fp_unk4_deps',
	0x80: 'ldst_unk4_deps',

	0xe9: 'int_unk5',
	0xee: 'fp_unk6',
	0xed: 'ldst_unk7',
	0xef: 'int_writes_unk8',

	0x59: 'unk9_int_count',
    0x5A: 'unk9_ldst_count',
    0x5B: 'unk9_fp_count',

    0x4C: 'opt_shift_ext',

    0x90: 'inst_branch_taken',
    0x94: 'inst_bcc',
    0x95: 'inst_int_load',
    0x96: 'inst_int_store',
    0x98: 'inst_fp_load',
    0x99: 'inst_fp_store',
}

def experiment(code, init_code='', unroll_count=100, iter_count=100, config=DEFAULT_CONFIG):
	key = repr((code, init_code, unroll_count, iter_count))

	with open('tmp.code.bin', 'wb') as f:
		f.write(assemble(code))

	with open('tmp.init_code.bin', 'wb') as f:
		f.write(assemble(init_code))

	with open('tmp.config.bin', 'wb') as f:
		for i in config:
			f.write(struct.pack('<I', i))

	suffix = ''
	suffix += SUFFIX
	cmd = "./timer%s tmp.code.bin tmp.init_code.bin %d %d tmp.config.bin" % (suffix, unroll_count, iter_count)

	for retry in range(20):
		#print(cmd)
		r = subprocess.check_output(cmd, shell=True).decode('utf-8')

		r = r.replace('SIGILL', '')
		r = r.replace('context switch', '')

		if 'SIGILL' in r and r.count('SIGILL') < 9:
			r = r.replace('SIGILL', '')

		try:
			j = json.loads(r)
		except json.decoder.JSONDecodeError:
			continue

		return j

	print(r)
	exit(1)

def median(j, counter):
	counter = counter.lower()
	if counter in j:
		values = j[counter][:]
		values.sort()
		return values[len(values) // 2]
	return 0

counters = experiment(args.asm, unroll_count=args.unroll, iter_count=args.iters, init_code=args.init or '', config=config)

for i in all_counters:
	value = median(counters, i)
	if not args.zeroes and value == 0:
		continue
	value = value / float(args.unroll * args.iters * args.divide)

	l = len(str(args.unroll * args.iters * args.divide - 1))
	fmt = '%' + str(l+6) + '.' + str(l) + 'f'

	print(i, COUNTER_NAMES.get(int(i, 16), '').ljust(27), (fmt % value).rstrip('0').rstrip('.'))


import requests
from collections import deque
import pandas as pd
import plotly.graph_objects as go

class Protein(object):
    def __init__(self, protein_id):
        """
        Args:
            protein_id: String of the protein id
        """
        self.protein_id = protein_id

    def get_data(self):
        """
        Downloads the fasta-file of a given protein id, extracts the amino-acid sequence and puts it into a list
        Returns:
            list containing the one letter code of the amino acids in the given sequence

        """
        website = 'https://www.uniprot.org/uniprot/' + self.protein_id + '.fasta?fil=reviewed:yes'
        r = requests.get(website)
        fasta_file = self.protein_id + '.fasta'

        with open(fasta_file, 'wb') as file:
            file.write(r.content)
        with open(fasta_file, 'r') as file:
            read_data = file.read()
            read_data_split = read_data.split('\n')

            protein_list = ""
            for line in read_data_split:
                if not line.startswith('>'):
                    protein_list += line
        protein_list = list(protein_list)
        return protein_list

    def map(self, lookup: dict, aa_property: str, window_len=1):
        """
        returns a list that contains the corresponding property values of the amino acids in the given sequence.
        Args:
            lookup: nested dictionary containing different amino acid properties and the corresponding values assigned
            to the 1-letter amino acid code
            aa_property: amino acid property that has to be examined
            window_len: length of the sliding window

        Returns:
            list containing the corresponding property of the amino-acid sequence (averaged in the given sliding window)

        """
        protein = self.get_data()
        dictionary = lookup[aa_property]
        property_list = [dictionary[aa] for aa in protein]

        window = deque([], window_len)
        average_list = []
        for specific_property in property_list:
            window.append(specific_property)
            average = sum(window) / len(window)
            average_list.append(average)
        return average_list

def get_lookup_dict(csv):
    """
    Makes a nested dictionary out of a given csv-file
    Args:
        csv: csv-file

    Returns:
        nested dictionary containing different amino acid properties and the corresponding values assigned to the
        1-letter amino acid code

    """
    aa_properties_dict = pd.read_csv(csv)
    # return pd.Series(data = data['hydropathy index (Kyte-Doolittle method)'].values, index = data['1-letter code'])
    aa_properties_dict = aa_properties_dict.to_dict()

    list_1lettercode = aa_properties_dict['1-letter code'].values()
    lookup_dict = {}
    for pos, aa_property in enumerate(aa_properties_dict.keys()):
        if pos > 2:
            property_dict_list = aa_properties_dict[aa_property].values()
            property_dict = dict(zip(list_1lettercode, property_dict_list))
            lookup_dict[aa_property] = property_dict

    return lookup_dict

def plot_bar_chart(x_values, y_values, title: str):
    """
    Plots a bar chart with the position of the amino acid on the x-axis and the corresponding hydropathy on the y-axis
    and a given title
    Args:
        x_values: list of the position of the amino acids
        y_values: list of the hydropathy values a the specific positions
        title: Title of the plot

    Returns:
        Bar Chart

    """
    data_fig = [go.Bar(x=x_values, y=y_values, marker_color="white")]
    fig = go.Figure(data=data_fig)
    fig.update_layout(template='plotly_dark', title=title, yaxis=dict(title='hydropathy'),
                      xaxis=dict(title='position in the sequence'), font=dict(size=22))
    fig.show()

if __name__ == '__main__':
    p1 = Protein('P32249')
    sequence = p1.get_data()
    lookup_dictionary = get_lookup_dict('amino_acid_properties.csv')
    print(lookup_dictionary)
    result_list = p1.map(lookup_dictionary, 'hydropathy index (Kyte-Doolittle method)')
    position_list = list(range(len(result_list)))
    print(result_list)
    plot_bar_chart(position_list, result_list, "Hydropathy plot of P32249 with a sliding window of 10")


# Q1
# Given an array of integers, return indices of the two numbers such that they add up to a specific target.
# You may assume that each input would have exactly one solution, and you may not use the same element twice.

# One pass hash table
# Time: O(n)
# Space: O(n)

def twoSum(nums, target):
    """
    :type nums: List[int]
    :type target: int
    :rtype: List[int]
    """
    num_ind_dict = {}
    for i in range(len(nums)):
        # check before adding to the dict can prevent conflicting keys
        # e.g. nums = [3. 3], target = 6
        if target - nums[i] in num_ind_dict:
            return [num_ind_dict[target - nums[i]], i]
        else:
            num_ind_dict[nums[i]] = i


from onyx.core import Interpolate, CalcTerm
from onyx.core import Archivable, GraphNodeDescriptor
from onyx.core import ReferenceField, CurveField
from onyx.core import MktIndirectionFactory, EnforceArchivableEntitlements

import math

__all__ = ["Currency"]

###############################################################################
@EnforceArchivableEntitlements("Database", "ArchivedOverwritable")
class Currency(Archivable):
    """
    Class used to represent a currency and its discount curve.
    """
    HolidayCalendar = ReferenceField(obj_type="HolidayCalendar")

    # -------------------------------------------------------------------------
    @MktIndirectionFactory(CurveField)
    def ZeroCurve(self, graph):
        pass

    # -------------------------------------------------------------------------
    @GraphNodeDescriptor("Callable")
    def DiscountFactor(self, graph, from_date, to_date):
        zero_crv = graph(self, "ZeroCurve")
        ref_date = graph("Database", "MktDataDate")
        rate_from = Interpolate(zero_crv, from_date, method="Linear")
        term_from = CalcTerm(ref_date, from_date)
        rate_to = Interpolate(zero_crv, to_date, method="Linear")
        term_to = CalcTerm(ref_date, to_date)
        return math.exp(-term_from*rate_from)*math.exp(term_to*rate_to)

# -----------------------------------------------------------------------------
def prepare_for_test():
    from onyx.core import Curve, Date, AddIfMissing, EvalBlock
    from . import ufo_database
    from . import ufo_holiday_calendar

    ufo_database.prepare_for_test()
    ufo_holiday_calendar.prepare_for_test()

    ccys = []
    ccys.append(AddIfMissing(Currency(Name="USD", HolidayCalendar="USD_CAL")))
    ccys.append(AddIfMissing(Currency(Name="EUR", HolidayCalendar="EUR_CAL")))
    ccys.append(AddIfMissing(Currency(Name="GBP", HolidayCalendar="GBP_CAL")))

    zero_curve = Curve([Date.low_date()], [0.0])

    with EvalBlock() as eb:
        eb.change_value("Database", "ArchivedOverwritable", True)
        for ccy in ccys:
            ccy.set_dated("ZeroCurve", Date.today(), zero_curve)


a = int(input('Primeiro bimestre: '))
if a > 10:
    a = int(input('Você digitou errado. Primeiro bimestre: '))
b = int(input('Segundo bimestre: '))
if b > 10:
    b = int(input('Você digitou errado. Segundo bimestre: '))
c = int(input('Terceiro bimestre: '))
if c > 10:
    c = int(input('Você digitou errado. Terceiro bimestre: '))
d = int(input('Quarto bimestre: '))
if d > 10:
    d = int(input('Você digitou errado. Quarto bimestre: '))
media = ( a + b + c + d) / 4
print('media: {}' .format(media))

# if a <= 10 and b <= 10 and c <= 10 and d <= 10:
#     print('media: {}' .format(media))
# else:
#     print('alguma nota foi digitada errada')

# a = int(input('Primeiro valor: '))
# b = int(input('Segundo valor: '))
# c = int(input('Terceiro valor: '))
#
# if a > b and a > c:
#     print('o maior numero é {}' .format(a))
# elif b > a and b > c:
#     print('o maior numero é {}' .format(b))
# else:
#     print('o maior numero é {}' .format(c))
# print('final do programa')


COMMAND_ADD = '1'
COMMAND_DELETE = '2'
COMMAND_GET = '3'
COMMAND_UNDO = '4'
COMMAND_REDO = '5'

history = ['']
pointer = 0
undo_state = False

def current_string():
    return history[pointer]

def parse_command(command):
    n_chars = []
    param_chars = []

    separator_appeared = False
    for i in range(len(command)):
        if separator_appeared:
            param_chars.append(command[i])
        elif command[i] == ' ':
            separator_appeared = True
            continue
        else:
            n_chars.append(command[i])

    n = ''.join(n_chars)
    param = ''.join(param_chars)

    return [n, param]

def add(part_str):
    global history, pointer, undo_state

    cur_str = current_string()

    if len(part_str):
        new_str = cur_str + part_str

        if undo_state:
            history = [cur_str, new_str]
            pointer = 1
        else:
            history.append(new_str)
            pointer += 1

        undo_state = False
        cur_str = current_string()

    return cur_str

def delete(n):
    global history, pointer, undo_state

    cur_str = current_string()

    if n > 0 and len(cur_str) > 0:
        new_str_chars = []
        for i in range(len(cur_str) - n):
            new_str_chars.append(cur_str[i])
        new_str = ''.join(new_str_chars)

        if undo_state:
            history = [cur_str, new_str]
            pointer = 1
        else:
            history.append(new_str)
            pointer += 1

        undo_state = False
        cur_str = current_string()

    return cur_str

def get_char(n):
    global history, pointer

    cur_str = current_string()

    try:
        pos_char = cur_str[n]
    except Exception:
        pos_char = ''

    return pos_char

def undo():
    global history, pointer, undo_state

    if pointer > 0:
        pointer -= 1
        undo_state = True

    cur_str = current_string()
    return cur_str

def redo():
    global history, pointer, undo_state

    if pointer < len(history) - 1:
        pointer += 1

    cur_str = current_string()
    return cur_str

def BastShoe(command):
    parsed_command = parse_command(command)
    n = parsed_command[0]
    param = parsed_command[1]

    if n == COMMAND_ADD:
        new_str = add(param)
        return new_str

    if n == COMMAND_DELETE:
        try:
            del_count = int(param)
        except Exception:
            del_count = 0

        new_str = delete(del_count)
        return new_str

    if n == COMMAND_GET:
        try:
            pos = int(param)
            if pos >= 0:
                pos_char = get_char(pos)
            else:
                pos_char = ''
        except Exception:
            pos_char = ''

        return pos_char

    if n == COMMAND_UNDO:
        new_str = undo()
        return new_str

    if n == COMMAND_REDO:
        new_str = redo()
        return new_str

    cur_str = current_string()
    return cur_str


"""
169. Majority Element
Given an array nums of size n, return the majority element.

The majority element is the element that appears more than [n / 2] times. You may assume that the majority element always exists in the array.

Example1:
Input: nums = [3,2,3]
Output: 3

Example2:
Input: nums = [2,2,1,1,1,2,2]
Output: 2

Constraints:
n == nums.length
1 <= n <= 5 * 10^4
-2^31 <= nums[i] <= 2^31 - 1

Follow up: Cound you solve the problem in linear time and in O(1) space?
"""

"""
Notes:
1. Hash Table: O(n) time | O(n) space
2. Boyer Moore's Algorithm: O(n) time | O(1) space
"""
from typing import List
class Solution(object):
    def majorityElement(self, nums: List[int]) -> int:
        numCount = {} # <num, count>
        for num in nums:
            numCount[num] = numCount.get(num, 0) + 1
        for num in numCount:
            if numCount[num] >= len(nums) / 2:
                return num

    def majorityElement2(self, nums: List[int]) -> int:
        candidate, count = nums[0], 0
        for num in nums:
            if num == candidate:
                count += 1
            elif count == 0:
                candidate, count = num, 1
            else:
                count -= 1
        return candidate

# Unit Tests
import unittest
funcs = [Solution().majorityElement, Solution().majorityElement2]

class TestMajorityElement(unittest.TestCase):
    def testMajorityElement1(self):
        for func in funcs:
            nums = [3,2,3]
            self.assertEqual(func(nums=nums), 3)

    def testMajorityElement2(self):
        for func in funcs:
            nums = [2,2,1,1,1,2,2]
            self.assertEqual(func(nums=nums), 2)

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


from collections import deque

#入力：グラフgと、探索の始点s
#出力：sからの各頂点への最短路長を表す配列
def bfs(g, s):
    n = len(g) #頂点数
    dist = [-1] * n #全頂点を未訪問に初期化
    que = deque([])

    #初期条件(頂点sを初期頂点とする)
    dist[s] = 0
    que.append(s) #sをqueにpush

    #BFS開始(キューが空になるまで探索を行う)
    while len(que) > 0:
        v = que[0]
        que.popleft()

        #vから辿れる頂点を全て調べる
        for x in g[v]:
            #すでに探索済の頂点は探索しない
            if dist[x] != -1:
                continue
            #新たに辿れる頂点xについて距離情報を更新してキューに挿入
            dist[x] = dist[v] + 1
            que.append(x)
    return dist

n = int(input())
g = [[] for _ in range(n)]
for i in range(n):
    lis = list(map(int, input().split()))
    for j in range(2, len(lis)):
        g[lis[0] - 1].append(lis[j] - 1)

dist = bfs(g, 0)
for v in range(n):
    print(str(v + 1) + " " + str(dist[v]))


import pygame
import numpy as np

class Piece:
    x = 0
    y = 1
    grid = [[True, True, True], [False, False, True]]
    color = pygame.Color(0, 0, 0)

    def __init__(self, x=0, y=0, grid=[[True, True, True], [False, False, True]], color=pygame.Color(50, 50, 50)):
        self.x = x
        self.y = y
        self.grid = grid
        self.color = color

    def paint(self, tile_size, marge, screen):
        piece_height = len(self.grid)
        for i in range(len(self.grid)):
            for j in range(len(self.grid[i])):
                if self.grid[i][j]:
                    rect = pygame.Rect(marge[0] + (self.x + j) * tile_size,
                                       marge[1] + (self.y - piece_height + i+1) * tile_size, tile_size, tile_size)
                    pygame.draw.rect(screen, self.color, rect)

    def rotate(self):
        pass

class Grid:
    x = 12
    y = 22
    pieces = [Piece(0, 0, [[True, True, True, True]], pygame.Color(255, 0, 0)), Piece()]
    pieces2 = [Piece(0, 0, [[False, True, True, True]], pygame.Color(255, 0, 0)), Piece()]
    gridBorderWidth = 4

    grid_bool = []
    grid_color = []

    def __init__(self):
        self.grid_bool = [[False for i in range(self.x + 1)] for j in range(self.y + 1)]
        self.grid_color = [[pygame.Color(155, 155, 155) for i in range(self.x + 1)] for j in range(self.y + 1)]
        pass

    def save_piece(self):
        piece = self.pieces[1]
        for x in range(len([piece.grid])):
            for y in range(len(piece.grid[0])):
                if piece.grid[x][y]:
                    self.grid_bool[int(piece.y - len(piece.grid) + y)][int(x + piece.x)] = True
                    self.grid_color[int(piece.y - len(piece.grid) + y)][int(x + piece.x)] = piece.color
                y += 1
            x += 1

    def generate_piece(self):
        self.pieces.pop()
        self.pieces.append(Piece())

    def check_collision(self, piece):
        if piece.y >= self.y:
            self.save_piece()
            self.generate_piece()
            return True

        x = 0
        for line in piece.grid:
            y = -len(piece.grid)
            for bool in line:
                if bool:
                    if self.grid_bool[y + 1 + int(piece.y)][x + int(piece.x)]:
                        self.save_piece()
                        self.generate_piece()
                        return True
                y += 1
            x += 1

    def paint(self, screen, tile_size):
        pos_x = (screen.get_width() - tile_size * self.x) / 2
        pos_y = (screen.get_height() - tile_size * self.y) / 2

        pygame.draw.rect(screen, pygame.Color(0, 0, 0),
                         pygame.Rect(pos_x - self.gridBorderWidth, pos_y - self.gridBorderWidth,
                                     self.x * tile_size + self.gridBorderWidth * 2,
                                     self.y * tile_size + self.gridBorderWidth * 2))
        pygame.draw.rect(screen, pygame.Color(255, 255, 255),
                         pygame.Rect(pos_x, pos_y, self.x * tile_size, self.y * tile_size))

        self.pieces[-1].paint(tile_size, [pos_x, pos_y], screen)
        self.check_collision(self.pieces[1])

        for y in range(len(self.grid_bool)):
            for x in range(len(self.grid_bool[0])):
                if (self.grid_bool[y][x]):
                    pygame.draw.rect(screen, self.grid_color[y][x], pygame.Rect(
                        pos_x + (x) * tile_size, (y-1) * tile_size + pos_y, tile_size, tile_size
                    ))

    def move_left(self):
        piece = self.pieces[1]
        if piece.x > 0:
            piece.x -= 1

    def move_right(self):
        piece = self.pieces[1]
        if piece.x + len(piece.grid[0]) < self.x:
            piece.x += 1

    def move_down(self):
        piece = self.pieces[1]
        if piece.y > 0:
            piece.y += 0.25

    def move_instant(self):
        piece = self.pieces[1]
        while not self.check_collision(self.pieces[1]):
            piece.y += 0.1

    def rotate(self):
        grid = self.pieces[1].grid
        array = np.array([grid[i]for i in range(len(grid))])
        self.pieces[1].grid = array.T

    def update(self, screen, tile_size):
        if self.pieces[1].y < self.y:
            self.pieces[1].y += 0.1
        self.paint(screen, tile_size)


import pandas as pd
import json

def get_maximum_values(event, context):
    data = pd.read_csv('s3://therealgraphs.com/representative.csv')
    maximum_encoded_day = data['EncodedDay'].max()
    maximum_active_cases = data['Active'].max()
    return {
        "statusCode": 200,
        "headers": {
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Credentials': 'true',
        },
        'body': json.dumps({
                                "maximum_encoded_day": str(maximum_encoded_day),
                                "maximum_active_cases": str(maximum_active_cases)
                           })
    }

if __name__ == "__main__":
    get_maximum_values('', '')


import argparse
import imap

def main():
    args = parsearg()
    args.subcommand(args)

def parsearg():
    parser = argparse.ArgumentParser(description='imofs - IMAP Based Online File Storage')
    sub = parser.add_subparsers(title='commands', help='Remote path format is user:password@host:port')

    cp = sub.add_parser('cp', help="copy a file in whatever direction")
    cp.add_argument('source', metavar='SOURCE', type=str, help='Source file path')
    cp.add_argument('dest', metavar='DEST', type=str, help='Destination path')
    cp.set_defaults(subcommand = lambda args: imap.cp(args))

    rm = sub.add_parser('rm', help='remove an online file')
    rm.add_argument('file', metavar='FILE', type=str, help='Full file path to remove')
    rm.set_defaults(subcommand = lambda args: imap.rm(args))

    mkdir = sub.add_parser('mkdir', help='create an online folder')
    mkdir.add_argument('file', metavar='FILE', type=str, help='Folder name')
    mkdir.set_defaults(subcommand = lambda args: imap.mkdir(args))

    parser.add_argument('-v', '--version', action='version',
                        version='imofs 0.0.1', help="prints the current program version")

    return parser.parse_args()

if __name__ == "__main__":
    main()


# import main Flask class and request object
from flask import Flask, request, jsonify

import json
import finalNftGenerator

app = Flask(__name__)

@app.route("/", methods=["GET"])
def test_get():
    discord_account_name = request.args.get("discord_account_name")
    discord_event_name = request.args.get("discord_event_name")
    discord_account_address = request.args.get("discord_account_address")
    jsonData = jsonify(
        {
            "discord_account_name": discord_account_name,
            "discord_event_name": discord_event_name,
            "discord_account_address": discord_account_address,
        }
    )
    print(jsonData)
    return jsonData

if __name__ == "__main__":
    # run app in debug mode on port 5000
    app.run(debug=True, port=5000)

# @app.route("/")
# def App():
#     response_hyon = "hyon"
#     return response_hyon

# @app.route("/safeMint", methods=["POST"])
# def proceed_mint():
# finalNftGenerator.nftImageGenerator(
#     discord_event_name,
#     discord_account_name,

#     safeMint()


import time
import unittest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains

# Так как мы часто логинимся создадим метод
def login(name, password, driver):
    driver.get('https://ruswizard.su/test/wp-login.php')
    for i in range(20):
        driver.find_element(By.ID, "user_login").send_keys(Keys.BACK_SPACE)
    WebDriverWait(driver, 100).until(EC.visibility_of_element_located((By.ID, 'user_login'))) \
        .send_keys(name)
    driver.find_element(By.ID, 'user_pass').send_keys(password)
    driver.find_element(By.ID, 'wp-submit').click()
    WebDriverWait(driver, 100).until(EC.visibility_of_element_located((By.CSS_SELECTOR, 'h1:nth-child(1)')))

def change_post_privacy(driver):
    driver.get("https://ruswizard.su/test/wp-admin/edit.php")
    WebDriverWait(driver, 100).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".wp-heading-inline")))

    post = driver.find_element(By.CLASS_NAME, "title.column-title.has-row-actions.column-primary.page-title")
    ActionChains(driver).move_to_element(post).perform()

    driver.find_element(By.CLASS_NAME, "button-link.editinline").click()
    driver.find_element(By.NAME, "keep_private").click()
    driver.find_element(By.CLASS_NAME, "button.button-primary.save.alignright").click()

def create_post(driver, text):
    driver.get(url='https://ruswizard.su/test/wp-admin/post-new.php')
    post = WebDriverWait(driver, 60).until(
        EC.presence_of_element_located((By.ID, 'post-title-0'))
    )

    post.send_keys(text)
    driver.find_element(By.XPATH, "//div[@id='editor']/div/div/div/div/div[2]/button[2]").click()
    WebDriverWait(driver, 100).until(
        EC.visibility_of_element_located((
            By.XPATH, "//div[@id='editor']/div/div/div[2]/div[4]/div[2]/div/div/div/div/button")))
    driver.find_element(By.XPATH, "//div[@id='editor']/div/div/div[2]/div[4]/div[2]/div/div/div/div/button").click()
    WebDriverWait(driver, 100).until(
        EC.visibility_of_element_located((
            By.CLASS_NAME, "post-publish-panel__postpublish")))

    return driver.find_element(By.ID, 'inspector-text-control-0').get_attribute("value")

def create_post_on_hold(driver, text):
    # create new post
    driver.get(url='https://ruswizard.su/test/wp-admin/post-new.php')
    post = WebDriverWait(driver, 100).until(
        EC.presence_of_element_located((By.ID, 'post-title-0'))
    )
    post.send_keys(text)

    driver.find_element(By.CLASS_NAME, "components-button.edit-post-post-schedule__toggle.is-tertiary").click()
    WebDriverWait(driver, 100).until(
        EC.visibility_of_element_located((By.CLASS_NAME, "components-datetime__time-field-hours-input")))
    h_field = driver.find_element(By.CLASS_NAME, "components-datetime__time-field-hours-input")
    m_field = driver.find_element(By.CLASS_NAME, "components-datetime__time-field-minutes-input")

    hours = int(h_field.get_attribute("value"))
    minutes = int(m_field.get_attribute("value"))

    #hours = int(h_field.get_attribute("value")) + 1
    if minutes + 2 > 59:
        hours += 1
        minutes = minutes + 1 - 59
    else:
        minutes += 2

    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-hours-input").click()
    time.sleep(0.5)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-hours-input").send_keys(Keys.ARROW_RIGHT)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-hours-input").send_keys(Keys.BACK_SPACE)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-hours-input").send_keys(Keys.BACK_SPACE)
    time.sleep(0.5)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-hours-input").send_keys(str(hours))
    time.sleep(0.5)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-minutes-input").click()
    time.sleep(0.5)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-minutes-input").send_keys(Keys.ARROW_RIGHT)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-minutes-input").send_keys(Keys.BACK_SPACE)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-minutes-input").send_keys(Keys.BACK_SPACE)
    time.sleep(0.5)
    driver.find_element(By.CLASS_NAME, "components-datetime__time-field-minutes-input").send_keys(str(minutes))
    time.sleep(0.5)

    # чтобы поле ввода закрылось и значения сохранились
    driver.find_element(By.CLASS_NAME, "components-button.components-panel__body-toggle").click()

    driver.find_element(By.XPATH,
                        "//div[@id='editor']/div/div/div/div/div[2]/button[2]").click()
    driver.find_element(By.XPATH,
                        "//div[@id='editor']/div/div/div[2]/div[4]/div[2]/div/div/div/div/button").click()

    WebDriverWait(driver, 100).until(
        EC.visibility_of_element_located((
            By.CLASS_NAME, "post-publish-panel__postpublish")))

    return driver.find_element(By.ID, 'inspector-text-control-0').get_attribute("value")

def delete_post(driver, text, additional_click=False):
    driver.get("https://ruswizard.su/test/wp-admin/edit.php")
    WebDriverWait(driver, 100).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".wp-heading-inline")))
    driver.find_element(By.LINK_TEXT, text).click()
    if additional_click:
        WebDriverWait(driver, 100).until(
            EC.visibility_of_element_located(
                (By.CLASS_NAME, "components-button.components-panel__body-toggle")))
        driver.find_element(By.CLASS_NAME, "components-button.components-panel__body-toggle").click()
    WebDriverWait(driver, 100).until(
        EC.visibility_of_element_located(
            (By.CLASS_NAME, "components-button.editor-post-trash.is-tertiary.is-destructive")))
    driver.find_element(By.CLASS_NAME, "components-button.editor-post-trash.is-tertiary.is-destructive").click()
    WebDriverWait(driver, 100).until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".wp-heading-inline")))

def add_comment(driver, link, bad=False, logged=False):
    text = "geek" if bad else "sosi nogi"
    driver.get(link)
    driver.find_element(By.ID, "comment").send_keys(text)

    if not logged:
        author = "KenKaneki"
        driver.find_element(By.ID, "author").send_keys(author)
        driver.find_element(By.ID, "email").send_keys(author + "@yandex.ru")

    driver.find_element(By.ID, "submit").send_keys(Keys.ENTER)
    return text

def check_page_text(driver, link, text):
    driver.get(link)
    WebDriverWait(driver, 100).until(EC.visibility_of_element_located((By.CLASS_NAME, "entry-title")))
    assert driver.find_element(By.CLASS_NAME, "entry-title").text == text

class WebTest(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")

    # Сценарий:
    # Пользователь создает запись, происходит попытка найти запись
    # в списке всех записей, при успехе запись удаляется.
    # После удаления происходит проверка, что запись больше недоступна
    def test_create_and_delete_record(self):
        driver = self.driver
        driver.implicitly_wait(100)

        # Логинимся и создаем запись
        login('dead_inside', '123', driver)
        text = "986 - 7"
        link = create_post(driver, text)

        # Удаляем запись и проверяем что она больше недоступна
        delete_post(driver, "986 — 7")
        driver.get(link)
        assert "Страница не найдена" == driver.find_element(By.CSS_SELECTOR, ".entry-title").text

    # Сценарий:
    # Пользователь создает запись, ставит задержку в две минуты
    # происходит попытка просмотреть запись без аккаунта, записи быть не должно.
    # Далее с аккаунта, создавшего запись, происходит вход на страницу со списком всех его записей,
    # проверяется, что в этом списке у записи появился соответствующий статус - "Запланировано"
    # Далее ставится таймаут на 120 секунд, после которого проверяется, что запись все же опубликовалась.
    # После всех проверок запись удаляется
    def test_create_post_on_hold(self):
        driver = self.driver
        text = "Задержка в развитии"

        login('dead_inside', '123', driver)
        link = create_post_on_hold(driver, text)

        second_driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")
        check_page_text(second_driver, link, "Страница не найдена")
        second_driver.close()

        driver.get("https://ruswizard.su/test/wp-admin/edit.php")
        assert driver.find_element(By.CLASS_NAME, "post-state").text == "Запланировано"

        time.sleep(120)
        second_driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")
        check_page_text(second_driver, link, "Задержка в развитии")
        second_driver.close()

        delete_post(driver, "Задержка в развитии", True)

    # Сценарий:
    # Пользователь создает запись
    # Происходит попытка просмотреть запись с другого аккаунта, запись должна быть видима.
    # Происходит попытка просмотреть запись без аккаунта аккаунта, запись должна быть видима.
    # После прохождения всех проверок пользователь удаляет запись
    def test_record_from_another_account(self):
        driver = self.driver
        driver.implicitly_wait(100)

        login('dead_inside', '123', driver)
        text = "1000 - 7"
        link = create_post(driver, text)

        second_driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")
        login('BigDickIsBackInTown', '12345678', second_driver)
        # Проверяем запись с чужого аккаунта
        check_page_text(second_driver, link, "1000 — 7")
        second_driver.close()

        # Проверяем без аккаунта
        third_driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")
        check_page_text(third_driver, link, "1000 — 7")
        third_driver.close()

        delete_post(driver, "1000 — 7")

    # Сценарий:
    # Пользователь создает запись,
    # изменяет настройки приватности, чтобы запись стала личной, и сохраняет настройки.
    # Происходит попытка просмотреть запись с другого аккаунта, записи по ссылке быть не должно.
    # Происходит попытка просмотреть запись без аккаунта аккаунта, записи по ссылке быть не должно.
    # Настройки приватность возвращаются назад и проверяется просмотр той же записи (после рефреша страницы)
    # Происходит попытка просмотреть запись с другого аккаунта, запись должна быть видима.
    # Происходит попытка просмотреть запись без аккаунта аккаунта, запись должна быть видима.
    # После всех проверок запись удаляется
    def test_private_record_from_another_account(self):
        driver = self.driver
        driver.implicitly_wait(100)

        login('dead_inside', '123', driver)
        text = "1000 - 7"
        link = create_post(driver, text)
        change_post_privacy(driver)

        second_driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")
        login('BigDickIsBackInTown', '12345678', second_driver)
        # Проверяем запись с чужого аккаунта
        check_page_text(second_driver, link, "Страница не найдена")

        # Проверяем без аккаунта
        third_driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")
        check_page_text(third_driver, link, "Страница не найдена")

        change_post_privacy(driver)

        # Проверяем запись с чужого аккаунта
        second_driver.refresh()
        check_page_text(second_driver, link, "1000 — 7")
        second_driver.close()

        # Проверяем без аккаунта
        third_driver.refresh()
        check_page_text(third_driver, link, "1000 — 7")
        third_driver.close()
        delete_post(driver, "1000 — 7")

    # Сценарий:
    # Пользователь создает запись и оставляет на ней комментарий с модерируемым словом - "geek",
    # модерации произойти не должно, так как комментарий происходит с аккаунта.
    # Также комментарий должен быть сразу апрувнут, так как его оставляет владелец записи.
    # Проверяется наличие комментария и его текст.
    # После всех проверок запись удаляется
    def test_add_comment_from_logged_user(self):
        driver = self.driver
        text = "I am ghoul"

        login('dead_inside', '123', driver)
        link = create_post(driver, text)
        comment = add_comment(driver, link, True, True)

        # Проверяем, что комментарий сразу апрувнут
        driver.get("https://ruswizard.su/test/wp-admin/edit.php")
        driver.find_element(By.CLASS_NAME, "comment-count-approved").click()

        assert driver.find_element(By.CLASS_NAME,
                                   "comment.column-comment.has-row-actions.column-primary").text == comment
        delete_post(driver, text)

    # Сценарий:
    # Пользователь создает запись
    # Пользователь без аккаунта оставляет на ней 2 комментария - с и без модерируемого слова.
    # Комментарий отправляется на подтверждение, так как пользователь не имеет отношения к записи.
    # Проверяется наличие одного комментария (с модерируемым словом был забанен) и его текст.
    # После всех проверок запись удаляется
    def test_add_comment_from_unlogged_user(self):
        driver = self.driver
        text = "I am ghoul"
        login('dead_inside', '123', driver)
        link = create_post(driver, text)

        second_driver = webdriver.Chrome("/Users/rinokus/Downloads/chromedriver")
        good_comment = add_comment(second_driver, link, False, False)
        time.sleep(15)  # таймаут, а то ругается на два комментария подряд
        _ = add_comment(second_driver, link, True, False)
        second_driver.close()

        driver.get("https://ruswizard.su/test/wp-admin/edit.php")

        # Проверяем, что всего один комментарий отправился (С гиком забанен)
        assert driver.find_element(By.CLASS_NAME, "comment-count-pending").text == '1'
        driver.find_element(By.CLASS_NAME, "post-com-count.post-com-count-pending").click()
        # И проверяем, что там верный текст
        assert driver.find_element(By.CLASS_NAME,
                                   "comment.column-comment.has-row-actions.column-primary").text == good_comment
        delete_post(driver, text)

    def tearDown(self):
        self.driver.close()

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


import sys

k, n = map(int, input().split())
lan_line = [int(sys.stdin.readline()) for _ in range(k)]
min_val = 1
max_val = max(lan_line)

while(min_val<=max_val):
    mid_val = (min_val+max_val)//2
    count = 0
    for i in lan_line:
        count += i//mid_val
    if count >= n:
        min_val = mid_val+1
    else:
        max_val = mid_val-1
print(max_val)


import cv2
import torch
import time
from torch import nn
import logging
import numpy as np
from PIL import Image, ImageFont, ImageDraw
import sophon.sail as sail
import colorsys
from datetime import datetime

class PreProcessor:
  """ Preprocessing class.
  """
  def __init__(self, bmcv, size_w, size_h, scale):
    """ Constructor.
    """
    self.bmcv = bmcv
    self.size_w = size_w
    self.size_h = size_h
    # self.ab = [x * scale for x in [1, -123, 1, -117, 1, -104]]
    self.ab = [x * scale for x in [1, 0, 1, 0, 1, 0]]

  def process(self, input, output):
    """ Execution function of preprocessing.
    Args:
      cv_input: sail.BMImage, input image
      bmcv_output: sail.BMImage, output data

    Returns:
      None
    """
    tmp = self.bmcv.vpp_resize(input, self.size_w, self.size_h)
    self.bmcv.convert_to(tmp, output, ((self.ab[0], self.ab[1]), \
                                       (self.ab[2], self.ab[3]), \
                                       (self.ab[4], self.ab[5])))

class Detector(object):
    """
    This is CenterNet detector class
    """
    _defaults = {
        # bmodel模型文件
        "bmodel_path"       : '/workspace/examples/centernet_test/ctdet_coco_dlav0_1x_fp32.bmodel',
        # 类标文件
        "classes_path"      : '/workspace/examples/centernet_test/CenterNet_object/data/coco_classes.txt',
        # 字体文件
        "font_path"         : '/workspace/examples/centernet_test/CenterNet_object/data/simhei.ttf',
        #--------------------------------------------------------------------------#
        #   只有得分大于置信度的预测框会被保留下来
        #--------------------------------------------------------------------------#
        "confidence"        : 0.35,
        #---------------------------------------------------------------------#
        #   非极大抑制所用到的nms_iou大小
        #---------------------------------------------------------------------#
        "nms_iou"           : 0.3,
        #--------------------------------------------------------------------------#
        #   是否进行非极大抑制，可以根据检测效果自行选择
        #   backbone为resnet50时建议设置为True、backbone为hourglass时建议设置为False
        #--------------------------------------------------------------------------#
        "nms"               : False,
        #---------------------------------------------------------------------#
        #   该变量用于控制是否使用letterbox_image对输入图像进行不失真的resize，
        #   在多次测试后，发现关闭letterbox_image直接resize的效果更好
        #---------------------------------------------------------------------#
        "letterbox_image"   : False,
    }
    def __init__(self, tpu_id):
        # 加载默认属性值
        self.__dict__.update(self._defaults)
        #---------------------------------------------------#
        #   计算总的类的数量
        #---------------------------------------------------#
        self.class_names, self.num_classes  = self.get_classes()

        #---------------------------------------------------#
        #   画框设置不同的颜色
        #---------------------------------------------------#
        hsv_tuples = [(x / self.num_classes, 1., 1.) for x in range(self.num_classes)]
        self.colors = list(map(lambda x: colorsys.hsv_to_rgb(*x), hsv_tuples))
        self.colors = list(map(lambda x: (int(x[0] * 255), int(x[1] * 255), int(x[2] * 255)), self.colors))

        # 加载bmodel
        self.engine         = sail.Engine(self.bmodel_path, tpu_id, sail.IOMode.SYSIO)
        self.graph_name     = self.engine.get_graph_names()[0]
        self.input_name     = self.engine.get_input_names(self.graph_name)[0]
        self.output_name    = self.engine.get_output_names(self.graph_name)[0]
        self.input_dtype    = self.engine.get_input_dtype(self.graph_name, self.input_name)
        self.output_dtype   = self.engine.get_output_dtype(self.graph_name, self.output_name)
        self.input_shape    = self.engine.get_input_shape(self.graph_name, self.input_name)
        self.input_w        = int(self.input_shape[-1])
        self.input_h        = int(self.input_shape[-2])
        self.output_shape   = self.engine.get_output_shape(self.graph_name, self.output_name)
        logging.info("\n" + "*" * 50 + "\n"
                     "graph_name:   {}\n"
                     "input_name:   {}\n"
                     "output_name:  {}\n"
                     "input_dtype:  {}\n"
                     "output_dtype: {}\n"
                     "input_shape:  {}\n"
                     "output_shape: {}\n".format(self.graph_name, self.input_name, self.output_name,
                                                 self.input_dtype, self.output_dtype, self.input_shape, self.output_shape)
                                                 + "*" * 50)
        # self.handle         = self.engine.get_handle()
        # self.input          = sail.Tensor(self.handle, self.input_shape, self.input_dtype,
        #                                   False, False)
        # self.output         = sail.Tensor(self.handle, self.output_shape, self.output_dtype,
        #                                   True, True)
        # self.input_tensors  = { self.input_name  : self.input }
        # self.output_tensors = { self.output_name : self.output}

        # self.bmcv = sail.Bmcv(self.handle)
        # self.img_dtype = self.bmcv.get_bm_image_data_format(self.input_dtype)
        # self.scale = self.engine.get_input_scale(self.graph_name, self.input_name)

        # logging.info("self.img_dtype: {}".format(self.img_dtype))
        # self.input_bmimage = sail.BMImage(self.handle,
        #                                   self.input_w, self.input_h,
        #                                   sail.Format.FORMAT_BGR_PLANAR,
        #                                   self.img_dtype)

        # self.preprocessor = PreProcessor(self.bmcv, self.input_w, self.input_h, self.scale)

    #---------------------------------------------------#
    #   获得类
    #---------------------------------------------------#
    def get_classes(self):
        with open(self.classes_path, encoding='utf-8') as f:
            class_names = f.readlines()
        class_names = [c.strip() for c in class_names]
        return class_names, len(class_names)

    def predict(self, cv_img):
        #---------------------------------------------------#
        #   计算输入图片的高和宽 HxW
        #---------------------------------------------------#
        image_shape = np.array(np.shape(cv_img)[0:2])
        #---------------------------------------------------------#
        #   在这里将图像转换成RGB图像，防止灰度图在预测时报错。
        #   代码仅仅支持RGB图像的预测，所有其它类型的图像都会转化成RGB
        #---------------------------------------------------------#
        cv_img      = self.cvt_color(cv_img)
        #---------------------------------------------------------#
        #   给图像增加灰条，实现不失真的resize
        #   也可以直接resize进行识别
        #---------------------------------------------------------#
        image_data  = self.resize_image(cv_img, (self.input_w, self.input_h))
        #-----------------------------------------------------------#
        #   图片预处理，归一化。获得的photo的shape为[1, 512, 512, 3]
        #-----------------------------------------------------------#
        image_data  = np.expand_dims(
            np.transpose(self.preprocess(np.array(image_data, dtype='float32')), (2, 0, 1)),
            axis=0
        )
        # Convert the image to row-major order, also known as "C order":
        image_data  = np.ascontiguousarray(image_data)

        input_data  = { self.input_name : np.array(image_data, dtype=np.float32)}
        logging.info('debug input {}'.format(input_data[self.input_name][0][0]))

        # 推理
        start       = time.time()
        output      = self.engine.process(self.graph_name, input_data)
        logging.info('inference time {}ms'.format((time.time() - start) * 1000))

        dets        = output[self.output_name]
        logging.info('inference finish. dets shape -> {}'.format(dets.shape))
        pred_hms = dets[:,:80,...]
        pred_whs = dets[:,80:82,...]
        pred_off = dets[:,82:84,...]
        logging.info('debug  dets -> {}'.format(dets[0][0]))

        # 解码
        outputs = self.decode_bbox(torch.from_numpy(pred_hms).sigmoid(),
                                   torch.from_numpy(pred_whs),
                                   torch.from_numpy(pred_off))

        #-------------------------------------------------------#
        #   对于centernet网络来讲，确立中心非常重要。
        #   对于大目标而言，会存在许多的局部信息。
        #   此时对于同一个大目标，中心点比较难以确定。
        #   使用最大池化的非极大抑制方法无法去除局部框
        #   所以我还是写了另外一段对框进行非极大抑制的代码
        #   实际测试中，hourglass为主干网络时有无额外的nms相差不大，resnet相差较大
        results = self.postprocess(outputs, image_shape)

        #--------------------------------------#
        #   如果没有检测到物体，则返回原图
        #--------------------------------------#
        if results[0] is None:
            return cv_img

        top_label   = np.array(results[0][:, 5], dtype='int32')
        top_conf    = results[0][:, 4]
        top_boxes   = results[0][:, :4]

        #---------------------------------------------------------#
        #   设置字体与边框厚度
        #---------------------------------------------------------#
        font = ImageFont.truetype(font=self.font_path,
                                  size=np.floor(3e-2 * np.shape(cv_img)[1] + 0.5).astype('int32'))
        logging.info('np.shape(cv_img) {}, self.input_shape {}'.format(np.shape(cv_img), self.input_shape))
        thickness = max((np.shape(cv_img)[0] + np.shape(cv_img)[1]) // self.input_shape[-1], 1)

        #---------------------------------------------------------#
        #   图像绘制
        #---------------------------------------------------------#
        for i, c in list(enumerate(top_label)):
            predicted_class = self.class_names[int(c)]
            box             = top_boxes[i]
            score           = top_conf[i]

            top, left, bottom, right = box

            top     = max(0, np.floor(top).astype('int32'))
            left    = max(0, np.floor(left).astype('int32'))
            bottom  = min(cv_img.size[1], np.floor(bottom).astype('int32'))
            right   = min(cv_img.size[0], np.floor(right).astype('int32'))
            label = '{} {:.2f}'.format(predicted_class, score)
            draw = ImageDraw.Draw(cv_img)

            label_size = draw.textsize(label, font)
            label = label.encode('utf-8')
            logging.info(
              '[object] -> label {}, top {}, left {}, bottom {}, right {}'.format(label, top, left, bottom, right)
            )

            if top - label_size[1] >= 0:
                text_origin = np.array([left, top - label_size[1]])
            else:
                text_origin = np.array([left, top + 1])
            for i in range(thickness):
                draw.rectangle([left + i, top + i, right - i, bottom - i], outline=self.colors[c])
            #draw.rectangle([tuple(text_origin), tuple(text_origin + label_size)], fill=self.colors[c])
            #draw.text(text_origin, str(label,'UTF-8'), fill=(0, 0, 0), font=font)
            del draw

        return cv_img

    def preprocess(self, image):
        image   = np.array(image, dtype = np.float32)[:, :, ::-1]
        mean    = [0.40789655, 0.44719303, 0.47026116]
        std     = [0.2886383, 0.27408165, 0.27809834]
        return (image / 255. - mean) / std

    def centernet_correct_boxes(self, box_xy, box_wh, image_shape):
        #-----------------------------------------------------------------#
        #   把y轴放前面是因为方便预测框和图像的宽高进行相乘
        #-----------------------------------------------------------------#
        box_yx = box_xy[..., ::-1]
        box_hw = box_wh[..., ::-1]
        input_shape = np.array(self.input_shape[-2:])
        image_shape = np.array(image_shape)

        if self.letterbox_image:
            #-----------------------------------------------------------------#
            #   这里求出来的offset是图像有效区域相对于图像左上角的偏移情况
            #   new_shape指的是宽高缩放情况
            #-----------------------------------------------------------------#
            new_shape = np.round(image_shape * np.min(input_shape/image_shape))
            offset  = (input_shape - new_shape)/2./input_shape
            scale   = input_shape/new_shape

            box_yx  = (box_yx - offset) * scale
            box_hw *= scale

        box_mins    = box_yx - (box_hw / 2.)
        box_maxes   = box_yx + (box_hw / 2.)
        boxes  = np.concatenate([box_mins[..., 0:1], box_mins[..., 1:2], box_maxes[..., 0:1], box_maxes[..., 1:2]], axis=-1)
        boxes *= np.concatenate([image_shape, image_shape], axis=-1)
        return boxes

    def pool_nms(self, heat, kernel = 3):
        pad = (kernel - 1) // 2
        hmax = nn.functional.max_pool2d(heat, (kernel, kernel), stride=1, padding=pad)
        keep = (hmax == heat).float()
        return heat * keep

    def postprocess(self, prediction, image_shape):
        output = [None for _ in range(len(prediction))]

        #----------------------------------------------------------#
        #   预测只用一张图片，只会进行一次
        #----------------------------------------------------------#
        for i, image_pred in enumerate(prediction):
            detections      = prediction[i]
            if len(detections) == 0:
                logging.info(detections)
                continue
            #------------------------------------------#
            #   获得预测结果中包含的所有种类
            #------------------------------------------#
            unique_labels   = detections[:, -1].cpu().unique()
            logging.info(unique_labels)
            for c in unique_labels:
                #------------------------------------------#
                #   获得某一类得分筛选后全部的预测结果
                #------------------------------------------#
                detections_class = detections[detections[:, -1] == c]
                if self.nms:
                    #------------------------------------------#
                    #   使用官方自带的非极大抑制会速度更快一些！
                    #------------------------------------------#
                    keep = nms(
                        detections_class[:, :4],
                        detections_class[:, 4],
                        self.nms_iou
                    )
                    max_detections = detections_class[keep]

                    # #------------------------------------------#
                    # #   按照存在物体的置信度排序
                    # #------------------------------------------#
                    # _, conf_sort_index = torch.sort(detections_class[:, 4], descending=True)
                    # detections_class = detections_class[conf_sort_index]
                    # #------------------------------------------#
                    # #   进行非极大抑制
                    # #------------------------------------------#
                    # max_detections = []
                    # while detections_class.size(0):
                    #     #---------------------------------------------------#
                    #     #   取出这一类置信度最高的，一步一步往下判断。
                    #     #   判断重合程度是否大于nms_thres，如果是则去除掉
                    #     #---------------------------------------------------#
                    #     max_detections.append(detections_class[0].unsqueeze(0))
                    #     if len(detections_class) == 1:
                    #         break
                    #     ious = bbox_iou(max_detections[-1], detections_class[1:])
                    #     detections_class = detections_class[1:][ious < nms_thres]
                    # #------------------------------------------#
                    # #   堆叠
                    # #------------------------------------------#
                    # max_detections = torch.cat(max_detections).data
                else:
                    max_detections  = detections_class

                output[i] = max_detections if output[i] is None else torch.cat((output[i], max_detections))

            if output[i] is not None:
                output[i]           = output[i].cpu().numpy()
                box_xy, box_wh      = (output[i][:, 0:2] + output[i][:, 2:4])/2, output[i][:, 2:4] - output[i][:, 0:2]
                output[i][:, :4]    = self.centernet_correct_boxes(box_xy, box_wh, image_shape)
        return output

    def decode_bbox(self, pred_hms, pred_whs, pred_offsets):
        #-------------------------------------------------------------------------#
        #   当利用512x512x3图片进行coco数据集预测的时候
        #   h = w = 128 num_classes = 80
        #   Hot map热力图 -> b, 80, 128, 128,
        #   进行热力图的非极大抑制，利用3x3的卷积对热力图进行最大值筛选
        #   找出一定区域内，得分最大的特征点。
        #-------------------------------------------------------------------------#
        logging.info('debug pred_hms {}'.format(pred_hms[0][0]))
        pred_hms = self.pool_nms(pred_hms)

        b, c, output_h, output_w = pred_hms.shape
        logging.info('pred_hms shape {}'.format(pred_hms.shape))
        detects = []
        #-------------------------------------------------------------------------#
        #   只传入一张图片，循环只进行一次
        #-------------------------------------------------------------------------#
        for batch in range(b):
            #-------------------------------------------------------------------------#
            #   heat_map        128*128, num_classes    热力图
            #   pred_wh         128*128, 2              特征点的预测宽高
            #   pred_offset     128*128, 2              特征点的xy轴偏移情况
            #-------------------------------------------------------------------------#
            heat_map    = pred_hms[batch].permute(1, 2, 0).view([-1, c])
            pred_wh     = pred_whs[batch].permute(1, 2, 0).view([-1, 2])
            pred_offset = pred_offsets[batch].permute(1, 2, 0).view([-1, 2])

            logging.info('heat_map shape {}, {}'.format(heat_map.shape, heat_map[0]))
            logging.info('pred_wh shape {}, {}'.format(pred_wh.shape, pred_wh[0]))
            logging.info('pred_offset shape {}, {}'.format(pred_offset.shape, pred_offset[0]))
            #exit(0)

            yv, xv      = torch.meshgrid(torch.arange(0, output_h), torch.arange(0, output_w))
            #-------------------------------------------------------------------------#
            #   xv              128*128,    特征点的x轴坐标
            #   yv              128*128,    特征点的y轴坐标
            #-------------------------------------------------------------------------#
            xv, yv      = xv.flatten().float(), yv.flatten().float()
            #-------------------------------------------------------------------------#
            #   class_conf      128*128,    特征点的种类置信度
            #   class_pred      128*128,    特征点的种类
            #-------------------------------------------------------------------------#
            class_conf, class_pred  = torch.max(heat_map, dim = -1)
            logging.info('class_conf shape {}, {}'.format(class_conf.shape, class_conf))
            logging.info('class_pred shape {}, {}'.format(class_pred.shape, class_pred))
            mask                    = class_conf > self.confidence

            #-----------------------------------------#
            #   取出得分筛选后对应的结果
            #-----------------------------------------#
            pred_wh_mask        = pred_wh[mask]
            pred_offset_mask    = pred_offset[mask]
            if len(pred_wh_mask) == 0:
                detects.append([])
                continue

            #----------------------------------------#
            #   计算调整后预测框的中心
            #----------------------------------------#
            logging.info(xv)
            logging.info(pred_offset_mask)
            logging.info(pred_wh_mask)
            xv_mask = torch.unsqueeze(xv[mask] + pred_offset_mask[..., 0], -1)
            yv_mask = torch.unsqueeze(yv[mask] + pred_offset_mask[..., 1], -1)
            #----------------------------------------#
            #   计算预测框的宽高
            #----------------------------------------#
            half_w, half_h = pred_wh_mask[..., 0:1] / 2, pred_wh_mask[..., 1:2] / 2
            #----------------------------------------#
            #   获得预测框的左上角和右下角
            #----------------------------------------#
            bboxes = torch.cat([xv_mask - half_w, yv_mask - half_h, xv_mask + half_w, yv_mask + half_h], dim=1)
            bboxes[:, [0, 2]] /= output_w
            bboxes[:, [1, 3]] /= output_h
            detect = torch.cat([bboxes, torch.unsqueeze(class_conf[mask],-1), torch.unsqueeze(class_pred[mask],-1).float()], dim=-1)
            detects.append(detect)
        return detects

    #---------------------------------------------------------#
    #   将图像转换成RGB图像，防止灰度图在预测时报错。
    #   代码仅仅支持RGB图像的预测，所有其它类型的图像都会转化成RGB
    #---------------------------------------------------------#
    def cvt_color(self, image):
        if len(np.shape(image)) == 3 and np.shape(image)[2] == 3:
            return image
        else:
            image = image.convert('RGB')
            return image

    #---------------------------------------------------#
    #   对输入图像进行resize
    #---------------------------------------------------#
    def resize_image(self, image, size):
        iw, ih  = image.size
        w, h    = size
        if self.letterbox_image:
            scale   = min(w/iw, h/ih)
            nw      = int(iw*scale)
            nh      = int(ih*scale)

            image   = image.resize((nw,nh), Image.BICUBIC)
            new_image = Image.new('RGB', size, (128,128,128))
            new_image.paste(image, ((w-nw)//2, (h-nh)//2))
        else:
            new_image = image.resize((w, h), Image.BICUBIC)
        return new_image

if __name__ == '__main__':
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s[%(levelname)s][%(module)s:%(lineno)s] - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    logging.info('start centernet detector sail demo')

    # Initialize centernet detector instance
    cet_detector = Detector(tpu_id=0)

    # open an image to predict
    image = Image.open('/workspace/examples/centernet_test/CenterNet_object/data/ctdet_test.jpg')

    # do prediction
    det_image = cet_detector.predict(image)

    # draw result
    det_filename = 'ctdet_result_{}.jpg'.format(datetime.now().strftime('%Y-%m-%d-%H-%M-%S'))
    det_image.save(det_filename, quality=95)
    logging.info('prediction result: {}'.format(det_filename))

    # exit
    logging.info('demo exit..')


# coding=utf-8
# ------------ 腾讯 ---------------
# input
# 2      2组测试
# 4      第一组：4对关系
# 1 2    编号1和编号2在一个圈子
# 3 4
# 5 6
# 1 6
# 4      第二组：4对关系
# 1 2
# 3 4
# 5 6
# 7 8
# output
# 4     第一组：最大的朋友圈有4人
# 2     第二组：最大的朋友圈有2人

import sys

class UnionFind:  # 并查集
    def __init__(self, n):
        self.n = n  # 总人数，用于计算largestNum
        self.parent = list(range(n))  # 索引为i的节点，它的直接父节点为parent[i]
        self.weight = [1] * n  # 并查树的深度， 优化合并
        self.maxDeep = 1  # 并查树的最大深度，用于寻找maxParent
        self.maxParent = 1  # 最大朋友圈的leader

    # 由于parent[i] 仅表示自己的直接父节点，查询两个节点是否相交需要比较它们的根节点是否相同。因此要封装一个查询自己根节点的方法。
    # def get_root(self, i):
    #     while i != self.parent[i]:
    #         i = self.parent[i]
    #     return i

    # 当前每次执行get_root时，需要一层一层的找到自己的父节点，很费时。
    # 由于根节点没有父节点，并且文章开始处提到过如果一个节点没有父节点，那么它的父节点就是自己，因此可以说只有根节点的父节点是自己本身。
    # 现在我们加上一个判断，判断当前节点的父节点是否为根节点，如果不为根节点，就递归地将自己的父节点设置为根节点，最后返回自己的根节点。
    def get_root(self, i):
        if self.parent[i] != i:
            self.parent[i] = self.get_root(self.parent[i])
        return self.parent[i]

    # 通过来比较根节点是否相同来判断两节点是否连通。
    def is_connected(self, i, j):
        return self.get_root(i) == self.get_root(j)

    # 连通两个节点时，我们要将其中一个节点的根节点的parent，设置为另一个节点的根节点。
    # 注意，连通两个节点并非仅仅让两节点自身相连，实际上是让它们所属的集合实现合并。
    # def union(self, i, j):
    #     i_root = self.get_root(i)
    #     j_root = self.get_root(j)
    #     self.parent[i_root] = j_root

    # 由于调用get_root时需要通过不断找自己的直接父节点，来寻找根节点，如果这棵树的层级过深，会导致性能受到严重影响。
    # 因此我们需要在union时，尽可能的减小合并后的树的高度。
    # 在构造函数中新建一个数组weight，weight[i] 表示节点i所在的集合的树的高度。
    def union(self, i, j):
        i_root = self.get_root(i)
        j_root = self.get_root(j)

        if self.weight[i_root] == self.weight[j_root]:
            self.parent[i_root] = j_root
            self.weight[j_root] += 1
            if self.weight[j_root] > self.maxDeep:
                self.maxDeep = self.weight[j_root]
                self.maxParent = j_root
        elif self.weight[i_root] > self.weight[j_root]:
            self.parent[j_root] = i_root
            if self.weight[i_root] > self.maxDeep:
                self.maxDeep = self.weight[i_root]
                self.maxParent = i_root
        else:
            self.parent[i_root] = j_root
            if self.weight[j_root] > self.maxDeep:
                self.maxDeep = self.weight[j_root]
                self.maxParent = j_root

    def largestNum(self):
        res = 0
        for i in range(self.n):  # i 的leader是最大朋友圈的leader，则i在这个最大的朋友圈中，朋友圈人数+1
            if self.get_root(i) == self.maxParent:
                res += 1
        return res

if __name__ == "__main__":
    # 读取第一行的n
    n = int(sys.stdin.readline().strip())
    ans = [2] * n  # 结果
    for i in range(n):  # n test
        m = int(sys.stdin.readline().strip())
        relation = [0, 0] * m  # 总关系数
        totalPerson = 0  # 总人数
        for j in range(m):
            relation[j] = list(map(int, sys.stdin.readline().strip().split(' ')))
            if relation[j][0] > relation[j][1] and relation[j][0] > totalPerson:
                totalPerson = relation[j][0]
            if relation[j][1] > relation[j][0] and relation[j][1] > totalPerson:
                totalPerson = relation[j][1]
        s = UnionFind(1 + totalPerson)  # 初始化：第一位0，因为人的index从1开始
        for j in range(m):
            for k in range(m):
                if j == k:
                    s.union(relation[j][0], relation[k][1])  # 直接朋友
                else:
                    if s.is_connected(relation[j][0], relation[k][0]):  # 间接朋友
                        s.union(relation[j][0], relation[k][0])
        ans[i] = s.largestNum()  # 最大朋友圈的人数
    for i in range(n):
        print(ans[i])