#!/usr/bin/env python

import argcomplete
import argparse
import atexit
import coloredlogs
import functools
import gc
import json
import katcp
import logging
import os
import ipaddress
import socket
import sys
import time
import threading

from collections import OrderedDict
from itertools import izip_longest
from ast import literal_eval as evaluate
from pprint import PrettyPrinter

def retry(func, count=20, wait_time=300):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        retExc = TypeError
        for _ in xrange(count):
            while True:
                try:
                    return func(*args, **kwargs)
                except Exception as exc:
                    retExc = exc
                    time.sleep(wait_time)
                    continue
                break
        raise retExc
    return wrapper

def combined_Dict_List(*args):
    """
    Combining two/more dictionaries into one with the same keys

    Params
    =======
    args: list
        list of dicts to combine

    Return
    =======
    result: dict
        combined dictionaries
    """
    result = {}
    for _dict in args:
        for key in result.viewkeys() | _dict.keys():
            if key in _dict:
                result.setdefault(key, []).extend([_dict[key]])
    return result

# This class could be imported from a utility module
class LoggingClass(object):
    @property
    def logger(self):
        log_format = "%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(pathname)s : %(lineno)d - %(message)s"
        name = ".".join([os.path.basename(sys.argv[0]), self.__class__.__name__])
        logging.basicConfig(format=log_format)
        coloredlogs.install(fmt=log_format)
        return logging.getLogger(name)

class SensorPoll(LoggingClass):
    def __init__(self, katcp_ip=None, katcp_port=7147):
        """
        Parameters
        =========
        katcp_ip: str
            IP to connect to!
        katcp_port: int
            Port to connect to! [Defaults: 7147]
        """

        try:
            assert katcp_ip
            self.katcp_ip = katcp_ip
            ipaddress.ip_address(u"{}".format(self.katcp_ip))
            self.hostname = ''.join(socket.gethostbyaddr(katcp_ip)[1])
        except Exception:
            self.logger.exception("Invalid KATCP_IP!")
            raise
        self.katcp_port = katcp_port
        self._kcp_connect()

    @retry
    def _kcp_connect(self):
        try:
            self._started = False
            self.primary_client = self.katcp_request(which_port=self.katcp_port)
            atexit.register(self.cleanup, self.primary_client)
            assert isinstance(self.primary_client, katcp.client.BlockingClient)
            reply, informs = self.sensor_request(self.primary_client)
            assert reply.reply_ok()
            katcp_array_list = informs[0].arguments
            assert isinstance(katcp_array_list, list)
            self.katcp_array_port, self.katcp_sensor_port = [
                int(i) for i in katcp_array_list[1].split(",")
            ]
            self.array_name = katcp_array_list[0]
            assert isinstance(self.katcp_array_port, int)
            assert isinstance(self.katcp_sensor_port, int)
        except Exception:
            self.logger.error(
                "No running array on {}:{}!!!!".format(self.katcp_ip, self.katcp_port),
                #exc_info=True
            )
            if self.primary_client.is_connected():
                self.cleanup(self.primary_client)
            raise
        else:
            if self._started:
                self._started = False
                self.sec_client = self.katcp_request(which_port=self.katcp_array_port)
                atexit.register(self.cleanup, self.sec_client)

            if self._started:
                self._started = False
                self.sec_sensors_katcp_con = self.katcp_request(
                    which_port=self.katcp_sensor_port
                )
                atexit.register(self.cleanup, self.sec_sensors_katcp_con)

            self.logger.info(
                "Katcp connection established: IP {}, Primary Port: {}, Array Port: {}, "
                "Sensor Port: {}".format(
                    self.katcp_ip,
                    self.katcp_port,
                    self.katcp_array_port,
                    self.katcp_sensor_port,
                )
            )
            time.sleep(1)
            try:
                self.input_mapping, self.hostname_mapping = self.do_mapping()
            except Exception:
                self.cleanup(self.sec_client)
                self.cleanup(self.sec_sensors_katcp_con)
                self.logger.error(
                    "Ayeyeyeye! it broke cannot do mappings",
                             # exc_info=True
                    )
                raise

    def katcp_request(
        self, which_port, katcprequest="array-list", katcprequestArg=None, timeout=10
    ):
        """
        Katcp requests

        Parameters
        =========
        which_port: str
            Katcp port to connect to!
        katcprequest: str
            Katcp requests messages [Defaults: 'array-list']
        katcprequestArg: str
            katcp requests messages arguments eg. array-list array0 [Defaults: None]
        timeout: int
            katcp timeout [Defaults :10]

        Return
        ======
        reply, informs : tuple
            katcp request messages
        """
        # self._started = False
        if not self._started:
            self._started = True
            self.logger.info(
                "Establishing katcp connection on {}:{}".format(
                    self.katcp_ip, which_port
                )
            )
            client = katcp.BlockingClient(self.katcp_ip, which_port)
            client.setDaemon(True)
            client.start()
            time.sleep(0.1)
            try:
                is_connected = client.wait_running(timeout)
                assert is_connected
                self.logger.info(
                    "Katcp client connected to {}:{}\n".format(
                        self.katcp_ip, which_port
                    )
                )
                return client
            except Exception:
                client.stop()
                self.logger.error("Could not connect to katcp, timed out.")

    def sensor_request(
        self, client, katcprequest="array-list", katcprequestArg=None, timeout=10
    ):
        """
        Katcp requests

        Parameters
        =========
        client: katcp.client.BlockingClient
            katcp running client
        katcprequest: str
            Katcp requests messages [Defaults: 'array-list']
        katcprequestArg: str
            katcp requests messages arguments eg. array-list array0 [Defaults: None]
        timeout: int
            katcp timeout [Defaults :10]

        Return
        ======
        reply, informs : tuple
            katcp request messages
        """
        try:
            if katcprequestArg:
                reply, informs = client.blocking_request(
                    katcp.Message.request(katcprequest, katcprequestArg),
                    timeout=timeout,
                )
            else:
                reply, informs = client.blocking_request(
                    katcp.Message.request(katcprequest), timeout=timeout
                )
            assert reply.reply_ok()
        except Exception:
            self.logger.error("Failed to execute katcp command")
            # time.sleep(20)
            raise
        else:
            return reply, informs

    def cleanup(self, client):
        if self._started:
            self.logger.debug("Some Cleaning Up!!!")
            client.stop()
            time.sleep(0.1)
            if client.is_connected():
                self.logger.error("Did not clean up client properly, %s" % client.bind_address)

    @property
    def get_sensor_values(self):
        try:
            assert self.katcp_sensor_port
            reply, informs = self.sensor_request(
                self.sec_sensors_katcp_con, katcprequest="sensor-value")
            assert reply.reply_ok()
            assert int(reply.arguments[-1])
            yield [inform.arguments for inform in informs]
        except AssertionError:
            self.logger.error("No Sensors!!! Exiting!!!")
            raise

    @property
    def get_hostmapping(self):
        try:
            assert self.katcp_sensor_port
            reply, informs = self.sensor_request(
                self.sec_sensors_katcp_con,
                katcprequest="sensor-value",
                katcprequestArg="hostname-functional-mapping",
            )
            assert reply.reply_ok()
            assert int(reply.arguments[-1])
            yield [inform.arguments for inform in informs]
        except AssertionError:
            self.cleanup(self.sec_sensors_katcp_con)
            self.logger.error("No Sensors!!! Exiting!!!")
            raise

    @property
    def get_inputlabel(self, i=1):
        try:
            assert self.katcp_array_port
            for i in xrange(i):
                reply, informs = self.sensor_request(
                    self.sec_client,
                    katcprequest="sensor-value",
                    katcprequestArg="input-labelling",
                )
                assert reply.reply_ok()
            assert int(reply.arguments[-1])
            yield [inform.arguments for inform in informs]
        except AssertionError:
            self.cleanup(self.sec_client)
            self.logger.error("No Sensors!!! Exiting!!!")
            raise

    @property
    def get_sensor_dict(self):
        sensor_value_informs = next(self.get_sensor_values)
        self.logger.debug("Converting sensor list to dict!!!")
        # sensors name + status + value
        self.original_sensors = dict(
            (x[0], x[1:]) for x in [i[2:] for i in sensor_value_informs]
        )
        # sensors name and status
        simplified_sensors = dict(
            (x[0], x[1]) for x in [i[2:] for i in sensor_value_informs]
        )
        simplified_ordered_sensors = OrderedDict(sorted(simplified_sensors.items()))
        try:
            return simplified_ordered_sensors
        except Exception as exc:
            raise exc

    def do_mapping(self):
        try:
            self.logger.debug("Mapping input labels and hostnames")
            hostname_mapping = next(self.get_hostmapping)[-1][-1]
            input_mapping = next(self.get_inputlabel)[-1][-1]
        except Exception:
            self.logger.error(
                "Serious error occurred, cannot continue!!! Missing sensors"
            )
            raise
        else:
            input_mapping = dict(list(i)[0:3:2] for i in evaluate(input_mapping))
            input_mapping = dict((v, k) for k, v in input_mapping.iteritems())
            update_maps = []
            for i in input_mapping.values():
                if "_y" in i:
                    i = i.replace("_y", "_xy")
                elif "_x" in i:
                    i = i.replace("_x", "_xy")
                elif "v" in i:
                    i = i.replace("v", "_vh")
                elif "h" in i:
                    i = i.replace("h", "_vh")

                update_maps.append(i)

            update_maps = sorted(update_maps)
            input_mapping = dict(zip(sorted(input_mapping.keys()), update_maps))
            hostname_mapping = dict(
                (v, k) for k, v in evaluate(hostname_mapping).iteritems()
            )
            return [input_mapping, hostname_mapping]

    def get_list_index(self, String, List):
        """
        Find the index of a string in a list

        Params
        =======
        String: str
            String to search in list
        List: list
            List to be searched!

        Return
        =======
        list
        """
        try:
            return [_c for _c, i in enumerate(List) if any(String in x for x in i)][0]
        except Exception:
            self.logger.error("Failed to find the index of string in list")

    def new_mapping(self, _host):
        try:
            self.logger.debug("Sorting ordered sensor dict by %ss!!!" % _host)
            ordered_sensor_dict = self.get_sensor_dict
            assert isinstance(ordered_sensor_dict, OrderedDict)
        except Exception:
            self.logger.error("Failed to retrieve sensor dict", exc_info=True)
        else:
            mapping = []
            for key, value in ordered_sensor_dict.iteritems():
                key_s = key.split(".")
                host = key_s[0].lower()
                if host.startswith(_host) and ("device-status" in key_s):
                    new_value = [x.replace("device-status", value) for x in key_s[1:]]
                    if "network-reorder" in new_value:
                        # rename such that, it fits on html/button
                        _indices = new_value.index("network-reorder")
                        new_value[_indices] = new_value[_indices].replace(
                            "network-reorder", "Net-ReOrd"
                        )
                    if "missing-pkts" in new_value:
                        # rename such that, it fits on html/button
                        _indices = new_value.index("missing-pkts")
                        new_value[_indices] = new_value[_indices].replace(
                            "missing-pkts", "hmcReOrd"
                        )
                    if "bram-reorder" in new_value:
                        # rename such that, it fits on html/button
                        _indices = new_value.index("bram-reorder")
                        new_value[_indices] = new_value[_indices].replace(
                            "bram-reorder", "bramReOrd"
                        )

                    new_dict = dict(
                        izip_longest(*[iter([host, new_value])] * 2, fillvalue="")
                    )
                    mapping.append(new_dict)

            new_mapping = combined_Dict_List(*mapping)
            for host, _list in new_mapping.iteritems():
                if host in self.hostname_mapping:
                    new_hostname = host.replace(_host, "") + self.hostname_mapping[
                        host
                    ].replace("skarab", "-").replace("-01", "")
                _ = [value.insert(0, new_hostname)
                    for value in _list if len(value) == 1]

            return new_mapping

    @property
    def map_xhost_sensors(self):
        """
        Needs to be in this format:
            'host03': [
                    ['03-020308', 'warn'],
                    ['network', 'warn'],
                    ['spead-rx', 'nominal'],
                    ['Net-ReOrd', 'nominal'],
                    ['hmcReOrd', 'warn'],
                    ['bram-reorder', 'error'],
                    ['vacc', 'error'],
                    ['spead-tx', 'nominal']
                ]
            }

        """
        xhost_sig_chain = [
            "-02",
            "network",
            "spead-rx",
            "Net-ReOrd",
            "hmcReOrd",
            "bramReOrd",
            "vacc",
            "spead-tx",
        ]
        try:
            new_mapping = self.new_mapping("xhost")
            assert isinstance(new_mapping, dict)
        except Exception:
            self.logger.error("Failed to map xhosts", exc_info=True)
        else:
            new_dict_mapping = {}
            for keys, values in new_mapping.iteritems():
                keys_ = keys[1:]
                new_dict_mapping[keys_] = []
                for value in values:
                    if (len(value) <= 2) and (not value[0].startswith("xeng")):
                        new_dict_mapping[keys_].append(value)
                    if (
                        value[0].startswith("xeng")
                        and value not in new_dict_mapping.values()
                    ):
                        if "vacc" in value:
                            new_dict_mapping[keys_].append(value[1:])
                        if "spead-tx" in value:
                            new_dict_mapping[keys_].append(value[1:])
                        if "bramReOrd" in value:
                            new_dict_mapping[keys_].append(value[1:])

            # _ = [listA.insert(_index, listA.pop(self.get_list_index(_sig, listA)))
            #      for _, listA in new_dict_mapping.iteritems() for _index, _sig in enumerate(xhost_sig_chain)]
            # return new_dict_mapping
            fixed_dict_mapping = {}
            for host_, listA in new_dict_mapping.iteritems():
                listA = listA[: len(xhost_sig_chain)]
                for _index, _sig in enumerate(xhost_sig_chain):
                    listA.insert(_index, listA.pop(self.get_list_index(_sig, listA)))
                fixed_dict_mapping[host_] = listA
            return fixed_dict_mapping

    @property
    def map_fhost_sensors(self):
        """
        {
             'fhost03': [
                            ['SKA-020709', 'warn'],
                            ['fhost00', 'skarab020709-01'],
                            ['ant0_y', 'inputlabel'],
                            ['network', 'nominal'],
                            ['spead-rx', 'failure'],
                            ['Net-ReOrd', 'nominal'],
                            ['cd', 'warn'],
                            ['pfb', 'warn'],
                            ['ct', 'nominal'],
                            ['spead-tx', 'nominal'],
                            ['->XEngine', 'xhost']
                        ]
        }

        """

        # Abbreviated signal chain
        # F_LRU -> Host -> input_label -> network-trx -> spead-rx -> network-reorder -> cd -> pfb -->>
        #    -->> ct -> spead-tx -> network-trx : [To Xengine ]
        # issue reading cmc3 input labels
        # fhost_sig_chain = ['SKA', 'fhost', 'network', 'spead-rx', 'Net-ReOrd', 'cd', 'pfb',
        fhost_sig_chain = [
            "-02",
            "input",
            "network",
            "spead-rx",
            "Net-ReOrd",
            "cd",
            "pfb",
            "ct",
            "spead-tx",
        ]
        try:
            new_mapping = self.new_mapping("fhost")
            assert isinstance(new_mapping, dict)
        except Exception:
            self.logger.error("Failed to map fhosts", exc_info=True)
        else:
            for host, values in new_mapping.iteritems():
                if host in self.hostname_mapping:
                    values.insert(
                        2, [self.input_mapping[self.hostname_mapping[host]], "inputlabel"]
                    )
                    # values.append(['->XEngine', 'xhost'])

            new_dict_mapping = {}
            for host, values in new_mapping.iteritems():
                host_ = host[1:]
                new_dict_mapping[host_] = values
            # Update mappings
            _ = [listA.insert(_index, listA.pop(self.get_list_index(_sig, listA)))
                for _, listA in new_dict_mapping.iteritems()
                for _index, _sig in enumerate(fhost_sig_chain)
                ]

            return new_dict_mapping

    @property
    def get_original_mapped_sensors(self):
        mapping = []
        for key, value in self.original_sensors.iteritems():
            host = key.split(".")[0].lower()
            if host[1:].startswith("host"):
                if value[0] != "nominal":
                    value.insert(0, key)
                    new_dict = dict(
                        izip_longest(*[iter([host, value])] * 2, fillvalue="")
                    )
                    mapping.append(new_dict)

        new_mapping = combined_Dict_List(*mapping)
        return new_mapping

    @staticmethod
    def merged_sensors_dict(dict1, dict2):
        """
        merge two dictionaries
        https://stackoverflow.com/questions/38987/how-to-merge-two-dictionaries-in-a-single-expression#26853961
        """
        for key, value in dict2.iteritems():
            dict1.setdefault(key, []).extend(value)
        return dict1
        # merged_sensors = f_sensors.copy()
        # merged_sensors.update(x_sensors)
        # return merged_sensors

    def create_dumps_dir(self):
        """
        Create json dumps directory
        """
        # Conflicted: To store in /tmp or not to store in , that is the question
        try:
            _dir, _name = os.path.split(os.path.dirname(os.path.realpath(__file__)))
        except Exception:
            _dir, _name = os.path.split(os.path.dirname(os.path.realpath(__name__)))
        path = _dir + "/json_dumps"
        if not os.path.exists(path):
            self.logger.info("Created %s for storing json dumps." % path)
            os.makedirs(path)

    def write_sorted_sensors_to_file(self):
        try:
            sensors = self.merged_sensors_dict(
                self.map_fhost_sensors, self.map_xhost_sensors
            )
        except Exception:
            self.logger.error(
                "Failed to map the host sensors",
                exc_info=True
                )
            raise
        else:
            self.create_dumps_dir()
            try:
                cur_path = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0]
            except Exception:
                cur_path = os.path.split(os.path.dirname(os.path.abspath(__name__)))[0]
            else:
                _filename = "{}/json_dumps/{}.{}.sensor_values.json".format(
                    cur_path, self.hostname, self.array_name)
                _sensor_filename = "{}/json_dumps/{}.{}.ordered_sensor_values.json".format(
                    cur_path, self.hostname, self.array_name)
                self.logger.info("Updating file: %s" % _filename)
                with open(_filename, "w") as outfile:
                    json.dump(sensors, outfile, indent=4, sort_keys=True)
                with open(_sensor_filename, "w") as outfile:
                    json.dump(
                        self.get_original_mapped_sensors,
                        outfile,
                        indent=4,
                        sort_keys=True,
                    )
                self.logger.info("Updated: %s" % _filename)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Receive data from a CBF and play.")
    parser.add_argument(
        "--hostip",
        dest="katcp_host_ip",
        action="store",
        help="IP address of primary interface [eg: 10.103.254.6]",
        required=True,
    )
    parser.add_argument(
        "--port",
        dest="katcp_host_port",
        action="store",
        default=7147,
        help="Primary Port to connect to. [Default: 7147]",
    )
    parser.add_argument(
        "--poll-time",
        dest="poll",
        action="store",
        default=10,
        type=int,
        help="Poll the sensors every x seconds [Default: 10]",
    )
    parser.add_argument(
        "--loglevel",
        dest="log_level",
        action="store",
        default="INFO",
        help="log level to use, default INFO, options INFO, DEBUG, ERROR",
    )

    argcomplete.autocomplete(parser)
    args = vars(parser.parse_args())
    pp = PrettyPrinter(indent=4)
    log_level = None
    log_format = "%(asctime)s - %(name)s - %(levelname)s - %(module)s - %(pathname)s : %(lineno)d - %(message)s"
    if args.get("log_level", "INFO"):
        log_level = args.get("log_level", "INFO").upper()
        try:
            logging.basicConfig(level=getattr(logging, log_level), format=log_format)
        except AttributeError:
            raise RuntimeError("No such log level: %s" % log_level)
        else:
            if log_level == "DEBUG":
                coloredlogs.install(level=log_level, fmt=log_format)
            else:
                coloredlogs.install(level=log_level)

    katcp_ip = args.get("katcp_host_ip")
    katcp_port = args.get("katcp_host_port")

    sensor_poll = SensorPoll(katcp_ip, katcp_port)
    main_logger = LoggingClass()
    try:
        poll_time = args.get("poll")
        main_logger.logger.info("Begin sensor polling every %s seconds!!!" % poll_time)
        while True:
            sensor_poll.write_sorted_sensors_to_file()
            main_logger.logger.debug("Updating sensor on dashboard!!!")
            main_logger.logger.info("---------------------RELOADING SENSORS---------------------")
            time.sleep(poll_time)
    except Exception:
        main_logger.logger.error("Error occurred now breaking...")


# uzd. 1.a
print("Input numbers to calculate average")
count = 1
total = 0.0
average = 0
number = 1
stopg = ""
while stopg != "q":
    number = float(input("Please enter number: "))
    total += number
    count += 1
    average = total/(count-1)
    print(round(average,2))
    stopg = input("To exit enter q  ")

#1c
# number_list = [45.0, 34.2, 10.3, 80.2]
number_list = []
while True:
    # print(number_list)
    query = input("Enter number or q to quit: ")
    if query == "q":
        print("Done with with work")
        break
    number_list.append(float(query))
    number_list.sort() #almost sorted list will be easy to sort
    print("Calculate their sum:")
    number_sum = sum(number_list)
    print(number_sum)
    print("Determine the length of the list:")
    number_len = len(number_list)
    print(number_len)
    print("Calculate their average:")
    avg = round(number_sum/number_len, 2)
    print(number_list[:3],avg,number_list[-3:])


from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
from rest_framework import serializers, status
from visionoflaborapi.models import User, Household, Chore, ChoreCategory

class HouseholdViewSet(ViewSet):

    def retrieve(self, request, pk):
        """GET request for a single household"""

        household = Household.objects.get(pk=pk)
        users = User.objects.all()
        chores = Chore.objects.all()
        chorecategories = ChoreCategory.objects.all()
        household.users = users.filter(household=pk)
        household.users.update()
        household.chores = chores.filter(household=pk)
        household.chores.update()
        for chore in household.chores:
            chore.category = chorecategories.filter(chore=chore.id)
            chore.category.update()

        serializer = HouseholdSerializer(household)
        return Response(serializer.data)

    def list(self, request):
        """GET request for All Households"""
        household = Household.objects.all()

        serializer = HouseholdSerializer(household, many=True)
        return Response(serializer.data)

    def create(self, request):
        """POST for household

        Pass in JSON object
        Can pass in Users to be associated with given household
        """

        household_users = request.data['users']
        user = User.objects.get(uid=request.data['uid'])
        if user.household is not None:
            return Response(None, status=status.HTTP_403_FORBIDDEN)

        household = Household.objects.create(
            name=request.data['name']
        )
        user.household = household
        user.save()

        if household_users is not None:
            for user in household_users:
                user = User.objects.get(pk=user['value'])
                user.household = household
                user.save(update_fields=['household'])
        serializer = HouseholdSerializer(household)
        return Response(serializer.data)

    def update(self, request, pk):
        """PUT for household"""

        household = Household.objects.get(pk=pk)
        household_users = request.data['users']

        household.name = request.data['name']

        if household_users is not None:
            household_user = User.objects.all()
            household_user = User.objects.filter(household=household)
            for user in household_user:
                user.household = None
                user.save()

        if household_users is not None:
            for user in household_users:
                user = User.objects.get(pk=user['value'])
                user.household = household
                user.save(update_fields=['household'])

        household.save()

        return Response(None, status=status.HTTP_204_NO_CONTENT)

class ChoreCategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = ChoreCategory
        fields = ('id', 'category')
        depth = 1

class ChoreSerializer(serializers.ModelSerializer):
    category = ChoreCategorySerializer(many=True, read_only=True)
    class Meta:
        model = Chore
        fields = ('id', 'name', 'description',
                  'frequency', 'priority', 'owner', 'photo_url', 'household', 'category', 'status')
        depth = 1

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ('id', 'uid', 'first_name', 'last_name',
                  'full_name', 'household', 'photo_url', 'admin')

class HouseholdSerializer(serializers.ModelSerializer):
    chores = ChoreSerializer(many=True, read_only=True)
    users = UserSerializer(many=True, read_only=True)

    class Meta:
        model = Household
        fields = ('id', 'name', 'users', 'chores')


#!/usr/bin/env python3

# pylint:disable=C0111,C0103

from sys import argv as sys_argv, exit as sys_exit, stderr as sys_stderr
from os import environ as os_environ
from re import match as re_match
from pathlib import Path
from glob import glob

class Err(Exception):
    pass

def usage():
    stderr('')
    stderr('{} <src_dir> <dst_file> [<black_files>]'.format(sys_argv[0]))
    stderr('')
    stderr('  src_dir     = Source directory with shell files')
    stderr('  dst_file    = Destination (markdown) file')
    stderr('  black_files = Skip these comma separated src files')
    stderr('')
    stderr('  export $SHMD_PAT to match other source files than *.sh')
    stderr('')
    stderr('  Examples:')
    stderr('    {} ~/foo ~/api.md'.format(sys_argv[0]))
    stderr('    {} ~/foo ~/api.md cfg.sh,main.sh'.format(sys_argv[0]))
    stderr('    SHMD_PAT=\'*_*.sh\' {} ~/foo ~/api.md'.format(sys_argv[0]))
    stderr('')
    sys_exit(2)

def stderr(msg):
    print(msg, file=sys_stderr)

def get_arg(ix, optional=False):
    if len(sys_argv) < (ix + 1):
        if optional:
            return None
        usage()
    return sys_argv[ix]

def get_file_paths(dp, pat, blackFns):
    fps = []
    for fp in glob('{}/{}'.format(dp, pat)):
        fp = Path(fp)
        if fp.name not in blackFns:
            fps.append(fp)
    return sorted(fps)

def read_file(fp):
    fp = Path(fp)
    try:
        with open(fp, 'rt', encoding='utf-8') as f:
            return f.read().split('\n')
    except (OSError, IOError, PermissionError, FileNotFoundError) as e:
        raise Err('Reading {} failed: {}'.format(fp, e))

def write_file(fp, data):
    fp = Path(fp)
    try:
        with open(fp, 'wt', encoding='utf-8') as f:
            f.write(data)
    except (OSError, IOError, PermissionError, FileNotFoundError) as e:
        raise Err('Writing {} failed: {}'.format(fp, e))

def san(d, mode='full'):
    if mode == 'full':
        d = ' '.join(d.split()).strip()
    d.lstrip()
    d.rstrip()
    return d

def extract(fp):
    fcs = {}
    name = None
    for line in read_file(fp):
        if re_match(r'^\s*#', line) and not re_match(r'^\s*##[ACDE]\s+', line):
            continue
        if name:
            if re_match(r'^\s*}\s*$', line):
                fcs[name]['C'] = san(fcs[name].get('C', name))
                name = None
                continue
            mtch = re_match(r'^\s*##C\s+(.+)$', line)
            if mtch:
                fcs[name]['C'] = '{} {}'.format(name, mtch.group(1))
                continue
            mtch = re_match(r'^\s*##(A|D|E)\s+(.+)$', line)
            if mtch:
                typ = mtch.group(1)
                msg = mtch.group(2)
                if typ == 'A':
                    mtch = re_match(r'^(.+?)=(.+)$', msg)
                    arg = san(mtch.group(1))
                    msg = san(mtch.group(2))
                    fcs[name].setdefault(typ, {})[arg] = msg
                elif typ == 'D':
                    fcs[name].setdefault(typ, []).append(san(msg))
                else:  # E
                    fcs[name].setdefault(typ, []).append(san(msg, 'simple'))
                continue
        else:
            mtch = re_match(r'^(\w+)\(\)\s+{\s*$', line)
            if mtch:
                name = mtch.group(1)
                fcs[name] = {}
    return fcs

def write_markdown(fcs, fp):
    lines = []
    for name in sorted(fcs):
        lines.append(f'- [`{name}`](#{name})')
    lines.append('\n***\n')
    for name in sorted(fcs):
        fc = fcs[name]
        lines.append('#### `{}`\n'.format(name))
        if fc.get('D'):
            lines.append('{}\n'.format(san(' '.join(fc['D']))))
        lines.append('**Usage**\n')
        lines.append('```shell\n{}\n```\n'.format(fc['C']))
        if fc.get('A'):
            lines.append('**Arguments**\n')
            for arg in fc['A']:
                lines.append('- {}\n    - {}'.format(arg, fc['A'][arg]))
            lines.append('')
        if fc.get('E'):
            lines.append('**Examples**\n')
            lines.append('```shell\n{}\n```\n'.format('\n'.join(fc['E'])))
    write_file(fp, '\n'.join(lines))

def main():
    srcDp = Path(get_arg(1))
    srcPat = os_environ.get('SHMD_PAT', '*.sh')
    dstFp = Path(get_arg(2))
    blackFns = get_arg(3, True)
    blackFns = blackFns.split(',') if blackFns else []
    fps = get_file_paths(srcDp, srcPat, blackFns)
    if not fps:
        raise Err('No "{}" files found in {}'.format(srcPat, srcDp))
    fcs = {}
    for fp in fps:
        stderr('Processing {}'.format(fp))
        fcs_ = extract(fp)
        stderr('{} functions found'.format(len(fcs_)))
        fcs.update(fcs_)
    stderr('Writing {} with {} functions'.format(dstFp, len(fcs)))
    write_markdown(fcs, dstFp)

try:
    main()
except Err as e:
    stderr('ERROR: {}'.format(e))
    sys_exit(1)


import sys
input = sys.stdin.readline

def solution():
    n = int(input())
    board = [input().strip() for _ in range(n)]
    open_board = [list(input().strip()) for _ in range(n)]

    # 체크된 곳의 좌표와 근처 지뢰 수를 저장하는 구조
    count_loc = dict()
    # 지뢰의 좌표와 폭발 여부를 저장하는 구조
    bomb_loc = dict()

    # 체크된 곳과 지뢰의 좌표를 저장
    for x in range(n):
        for y in range(n):
            if board[x][y] == '*':
                bomb_loc[(x, y)] = False
            if open_board[x][y] == 'x':
                count_loc[(x, y)] = 0

    # 주변 칸의 좌표를 반환
    def get_around(num):
        _list = []
        if num-1 >= 0:
            _list.append(num-1)
        _list.append(num)
        if num+1 < n:
            _list.append(num+1)
        return _list

    # 탐색
    for x, y in bomb_loc.keys():
        for _x in get_around(x):
            for _y in get_around(y):
                if open_board[_x][_y] == 'x':
                    if board[_x][_y] == '*':
                        bomb_loc[(x, y)] = True
                    count_loc[(_x, _y)] += 1

    # 폭발한 지뢰가 존재하면 표시
    if True in list(bomb_loc.values()):
        for x, y in bomb_loc.keys():
            open_board[x][y] = '*'
    # 지뢰가 있는 곳을 제외하고 근처 지뢰 수를 기록
    for x, y in count_loc.keys():
        if open_board[x][y] != '*':
            open_board[x][y] = count_loc[(x, y)]

    open_board = [''.join(map(str, row)) for row in open_board]
    print('\n'.join(open_board))

solution()


import problem
import math
from utility import *

class Problem(problem.Problem):
	def __init__(self):
		number = 37
		question = 'Find the sum of all eleven primes that are both truncatable from left to right and right to left.'
		problem.Problem.__init__(self, number, question)

	def getAnswer(self):
		def isTruncatablePrime(n, primes):
			s = str(n)
			l = len(s)
			for i in xrange(1, l):
				if not isPrime(int(s[i:]), primes):
					return False
				if not isPrime(int(s[:-1*i]), primes):
					return False
			return True

		limit = 10
		primes = getPrimes(limit)
		ret = 0
		numberOfTruncatablePrimes = 0
		while True:
			limit *= 10
			primes = getPrimesFrom(limit, primes)
			for p in primes:
				if p >= limit / 10 and isTruncatablePrime(p, primes):
					ret += p
					numberOfTruncatablePrimes += 1
				if numberOfTruncatablePrimes == 11:
					break
			if numberOfTruncatablePrimes == 11:
				break

		return ret


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 28 20:17:37 2020

@author: Jonas

source: https://towardsdatascience.com/how-to-get-stock-data-using-python-c0de1df17e75
"""
#%%

import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import yfinance as yf

colors = {'text': '#eeeeee', 'background': '#eeeeee'}
app = dash.Dash()
app.layout = html.Div([
    html.H1('Financial Dashboard', style={'background-color': colors['text']}),
    html.Div([
        html.Div([
            dcc.Dropdown(id='company_selection1',options=[
            {'label': 'Tesla', 'value': 'TSLA'},
            {'label': 'Apple', 'value': 'AAPL'},
            {'label': 'Google', 'value': 'GOOG'}],
            value = 'TSLA')], style={'background-color': colors['background']}),
        dcc.Graph(id ='figure1', style={'background-color': colors['background'], 'padding': 10}),

        html.Div([
            dcc.Dropdown(id='company_selection2',options=[
            {'label': 'Tesla', 'value': 'TSLA'},
            {'label': 'Apple', 'value': 'AAPL'},
            {'label': 'Google', 'value': 'GOOG'}],
            value = 'AAPL')]),
        dcc.Graph(id ='figure2', style={'background-color': colors['background'], 'padding': 10}),
        ], style={'background-color': colors['background']})
    ],style= {'background-color': colors['background']})

    #html.H3(id='text'),

#import seaborn as sns
#sns.set()

tickerSymbol = 'KINV-B.ST'

#get data on this ticker

#%%
#sns.lineplot(data = df, x = df.index, y = 'Close')

@app.callback(Output(component_id = 'figure1', component_property = 'figure'),
                [Input('company_selection1','value')])
def plot_financial_data(company):
    tickerData = yf.Ticker(company)
    #get the historical prices for this ticker
    df = tickerData.history(period = '1d', start = '2010-1-1', end = '2020-4-28')
    df.describe()

    datapoints = {'data': [go.Line(x=df.index, y=df.Close.values,
            marker_color='lightsalmon',
            name='Net Income')], 'layout': dict(xaxis={'title':'Date'},
            yaxis={'title':'Close'}, paper_bgcolor = colors['background'], plot_bgcolor = colors['background'])}

    return datapoints

@app.callback(Output(component_id = 'figure2', component_property = 'figure'),
                [Input('company_selection2','value')])
def plot_financial_data(company):
    tickerData = yf.Ticker(company)
    #get the historical prices for this ticker
    df = tickerData.history(period = '1d', start = '2010-1-1', end = '2020-4-28')
    df.describe()

    datapoints = {'data': [go.Line(x=df.index, y=df.Close.values,
            marker_color='lightsalmon',
            name='Net Income')], 'layout': dict(xaxis={'title':'Date'},
            yaxis={'title':'Close'}, paper_bgcolor = colors['background'], plot_bgcolor = colors['background'] )}

    return datapoints
# %%
if __name__ == '__main__': app.run_server(debug=True)


from __future__ import absolute_import, print_function
from math import isnan, isinf
from itertools import combinations

import rdkit
from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem.rdchem import BondType
import sys

METALS = (3, 4, 11, 12, 13, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
          37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 55, 56, 57,
          58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
          75, 76, 77, 78, 79, 80, 81, 82, 83, 87, 88, 89, 90, 91, 92, 93, 94,
          95, 96, 97, 98, 99, 100, 101, 102, 103)

def PathFromAtomList(mol, amap):
    out = []
    for i, j in combinations(amap, 2):
        bond = mol.GetBondBetweenAtoms(i, j)
        if bond:
            out.append(bond.GetIdx())
    return out

def AtomListToSubMol(mol, amap, includeConformer=False):
    """
    Parameters
    ----------
        mol: rdkit.Chem.rdchem.Mol
            Molecule
        amap: array-like
            List of atom indices (zero-based)
        includeConformer: bool (default=True)
            Toogle to include atoms coordinates in submolecule.

    Returns
    -------
        submol: rdkit.Chem.rdchem.RWMol
            Submol determined by specified atom list
    """
    if not isinstance(amap, list):
        amap = list(amap)
    submol = Chem.RWMol(Chem.Mol())
    for aix in amap:
        submol.AddAtom(mol.GetAtomWithIdx(aix))
    for i, j in combinations(amap, 2):
        bond = mol.GetBondBetweenAtoms(i, j)
        if bond:
            submol.AddBond(amap.index(i),
                           amap.index(j),
                           bond.GetBondType())
    if includeConformer:
        for conf in mol.GetConformers():
            new_conf = Chem.Conformer(len(amap))
            for i in range(len(amap)):
                new_conf.SetAtomPosition(i, conf.GetAtomPosition(amap[i]))
                new_conf.SetId(conf.GetId())
                new_conf.Set3D(conf.Is3D())
            submol.AddConformer(new_conf)
    return submol

def MolFromPDBBlock(molBlock,
                    sanitize=True,
                    removeHs=True,
                    flavor=0):
    # before 2019.03 pre-sanitization is required
    pre_sanitize = False
    if sanitize and rdkit.__version__ <= '2018.09':
        pre_sanitize = True

    mol = Chem.MolFromPDBBlock(molBlock,
                               sanitize=pre_sanitize,
                               removeHs=removeHs,
                               flavor=flavor)
    if mol is None:
        return None
    # Adjust connectivity
    for atom in mol.GetAtoms():
        res = atom.GetPDBResidueInfo()
        if res is None:
            continue
        res_name = res.GetResidueName()
        atom_name = res.GetName().strip()

        # Fix missing double bonds in RDKit - double bonds
        if atom_name == 'O' and not res.GetIsHeteroAtom() and atom.GetDegree() == 1:
            atom.SetNoImplicit(True)
            atom.GetBonds()[0].SetBondType(Chem.BondType.DOUBLE)

        # Double bonds in sidechains
        if res_name in ['HID', 'HIE', 'HIP']:
            if atom_name == 'CD2':
                for bond in atom.GetBonds():
                    if bond.GetOtherAtom(atom).GetPDBResidueInfo().GetName().strip() == 'CG':
                        bond.SetBondType(Chem.BondType.DOUBLE)
                        break
            if res_name == 'HID':
                if atom_name == 'CE1':
                    for bond in atom.GetBonds():
                        if bond.GetOtherAtom(atom).GetPDBResidueInfo().GetName().strip() == 'ND1':
                            bond.SetBondType(Chem.BondType.DOUBLE)
                            break
            elif res_name in ['HIE', 'HIP']:
                if atom_name == 'CE1':
                    for bond in atom.GetBonds():
                        if bond.GetOtherAtom(atom).GetPDBResidueInfo().GetName().strip() == 'NE2':
                            bond.SetBondType(Chem.BondType.DOUBLE)
                            break
    mol.UpdatePropertyCache(strict=sanitize)

    # Set metal coordination (zero order) bond orders to single to prevent adding Hs
    if rdkit.__version__ >= '2018.03':
        for bond in mol.GetBonds():
            if bond.GetBondType() == Chem.BondType.ZERO:
                a1 = bond.GetBeginAtom()
                a2 = bond.GetEndAtom()
                # single bonds only if there are enough electrons
                if ((a1.GetAtomicNum() in METALS and
                     a2.GetNumImplicitHs() + a2.GetNumExplicitHs() > 0) or
                    (a2.GetAtomicNum() in METALS and
                     a1.GetNumImplicitHs() + a1.GetNumExplicitHs() > 0)):
                    bond.SetBondType(Chem.BondType.SINGLE)

    if sanitize:
        result = Chem.SanitizeMol(mol)
        if result != 0:
            return None

    # Debug
    # for atom in mol.GetAtoms():
    #     res = atom.GetPDBResidueInfo()
    #     if res is None:
    #         continue
    #     res_name = res.GetResidueName()
    #     atom_name = res.GetName().strip()
    #     if atom_name in ['NE2', 'ND1'] and res_name in ['HID', 'HIE', 'HIS']:
    #         print(res_name,
    #               atom_name,
    #               atom.GetDegree(),
    #               atom.GetTotalValence(),
    #               atom.GetNumExplicitHs(),
    #               atom.GetNumImplicitHs(),
    #               sum(n.GetAtomicNum() == 1 for n in atom.GetNeighbors()),
    #               sep='\t')

    return mol

# Mol2 Atom typing
def _sybyl_atom_type(atom):
    """ Asign sybyl atom type
    Reference #1: http://www.tripos.com/mol2/atom_types.html
    Reference #2: http://chemyang.ccnu.edu.cn/ccb/server/AIMMS/mol2.pdf
    """
    sybyl = None
    atom_symbol = atom.GetSymbol()
    atomic_num = atom.GetAtomicNum()
    hyb = atom.GetHybridization()-1  # -1 since 1 = sp, 2 = sp1 etc
    hyb = min(hyb, 3)
    degree = atom.GetDegree()
    aromtic = atom.GetIsAromatic()

    # define groups for atom types
    guanidine = '[NX3,NX2]([!O,!S])!@C(!@[NX3,NX2]([!O,!S]))!@[NX3,NX2]([!O,!S])'  # strict
    # guanidine = '[NX3]([!O])([!O])!:C!:[NX3]([!O])([!O])' # corina compatible
    # guanidine = '[NX3]!@C(!@[NX3])!@[NX3,NX2]'
    # guanidine = '[NX3]C([NX3])=[NX2]'
    # guanidine = '[NX3H1,NX2,NX3H2]C(=[NH1])[NH2]' # previous
    #

    if atomic_num == 6:
        if aromtic:
            sybyl = 'C.ar'
        elif degree == 3 and _atom_matches_smarts(atom, guanidine):
            sybyl = 'C.cat'
        else:
            sybyl = '%s.%i' % (atom_symbol, hyb)
    elif atomic_num == 7:
        if aromtic:
            sybyl = 'N.ar'
        elif _atom_matches_smarts(atom, 'C(=[O,S])-N'):
            sybyl = 'N.am'
        elif degree == 3 and _atom_matches_smarts(atom, '[$(N!-*),$([NX3H1]-*!-*)]'):
            sybyl = 'N.pl3'
        elif _atom_matches_smarts(atom, guanidine):  # guanidine has N.pl3
            sybyl = 'N.pl3'
        elif degree == 4 or hyb == 3 and atom.GetFormalCharge():
            sybyl = 'N.4'
        else:
            sybyl = '%s.%i' % (atom_symbol, hyb)
    elif atomic_num == 8:
        # http://www.daylight.com/dayhtml_tutorials/languages/smarts/smarts_examples.html
        if degree == 1 and _atom_matches_smarts(atom, '[CX3](=O)[OX1H0-]'):
            sybyl = 'O.co2'
        elif degree == 2 and not aromtic:  # Aromatic Os are sp2
            sybyl = 'O.3'
        else:
            sybyl = 'O.2'
    elif atomic_num == 16:
        # http://www.daylight.com/dayhtml_tutorials/languages/smarts/smarts_examples.html
        if degree == 3 and _atom_matches_smarts(atom, '[$([#16X3]=[OX1]),$([#16X3+][OX1-])]'):
            sybyl = 'S.O'
        # https://github.com/rdkit/rdkit/blob/master/Data/FragmentDescriptors.csv
        elif _atom_matches_smarts(atom, 'S(=,-[OX1;+0,-1])(=,-[OX1;+0,-1])(-[#6])-[#6]'):
            sybyl = 'S.o2'
        else:
            sybyl = '%s.%i' % (atom_symbol, hyb)
    elif atomic_num == 15 and hyb == 3:
        sybyl = '%s.%i' % (atom_symbol, hyb)

    if not sybyl:
        sybyl = atom_symbol
    return sybyl

def _atom_matches_smarts(atom, smarts):
    idx = atom.GetIdx()
    patt = Chem.MolFromSmarts(smarts)
    for m in atom.GetOwningMol().GetSubstructMatches(patt):
        if idx in m:
            return True
    return False

def _amide_bond(bond):
    a1 = bond.GetBeginAtom()
    a2 = bond.GetEndAtom()
    if (a1.GetAtomicNum() == 6 and a2.GetAtomicNum() == 7 or
            a2.GetAtomicNum() == 6 and a1.GetAtomicNum() == 7):
        # https://github.com/rdkit/rdkit/blob/master/Data/FragmentDescriptors.csv
        patt = Chem.MolFromSmarts('C(=O)-N')
        for m in bond.GetOwningMol().GetSubstructMatches(patt):
            if a1.GetIdx() in m and a2.GetIdx() in m:
                return True
    return False

def MolFromPDBQTBlock(block, sanitize=True, removeHs=True):
    """Read PDBQT block to a RDKit Molecule

    Parameters
    ----------
        block: string
            Residue name which explicitly pint to a ligand(s).
        sanitize: bool (default=True)
            Should the sanitization be performed
        removeHs: bool (default=True)
            Should hydrogens be removed when reading molecule.

    Returns
    -------
        mol: rdkit.Chem.rdchem.Mol
            Molecule read from PDBQT
    """
    pdb_lines = []
    name = ''
    data = {}
    for line in block.split('\n'):
        # Get all know data from REMARK section
        if line[:12] == 'REMARK  Name':
            name = line[15:].strip()
        elif line[:18] == 'REMARK VINA RESULT':
            tmp = line[19:].split()
            data['vina_affinity'] = tmp[0]
            data['vina_rmsd_lb'] = tmp[1]
            data['vina_rmsd_ub'] = tmp[2]

        # no more data to collect
        if line[:4] != 'ATOM':
            continue

        pdb_line = line[:56]
        pdb_line += '1.00  0.00           '

        # Do proper atom type lookup
        atom_type = line[71:].split()[1]
        if atom_type == 'A':
            atom_type = 'C'
        elif atom_type[:1] == 'O':
            atom_type = 'O'
        elif atom_type[:1] == 'H':
            atom_type = 'H'
            if removeHs:
                continue
        elif atom_type == 'NA':
            atom_type = 'N'
        elif atom_type == 'SA':
            atom_type = 'S'

        pdb_lines.append(pdb_line + atom_type)
    mol = Chem.MolFromPDBBlock('\n'.join(pdb_lines), sanitize=False)
    if sanitize:
        Chem.SanitizeMol(mol)
    else:
        Chem.GetSSSR(mol)
    # reorder atoms using serial
    new_order = sorted(range(mol.GetNumAtoms()),
                       key=lambda i: (mol.GetAtomWithIdx(i)
                                      .GetPDBResidueInfo()
                                      .GetSerialNumber()))
    mol = Chem.RenumberAtoms(mol, new_order)

    # properties must be set on final copy of Mol, RenumberAtoms purges data
    mol.SetProp('_Name', name)
    for k, v in data.items():
        mol.SetProp(str(k), str(v))

    return mol

def PDBQTAtomLines(mol, donors, acceptors):
    """Create a list with PDBQT atom lines for each atom in molecule. Donors
    and acceptors are given as a list of atom indices.
    """

    atom_lines = [line.replace('HETATM', 'ATOM  ')
                  for line in Chem.MolToPDBBlock(mol).split('\n')
                  if line.startswith('HETATM') or line.startswith('ATOM')]

    pdbqt_lines = []
    for idx, atom in enumerate(mol.GetAtoms()):
        pdbqt_line = atom_lines[idx][:56]

        pdbqt_line += '0.00  0.00    '  # append empty vdW and ele
        # Get charge
        charge = 0.
        fields = ['_MMFF94Charge', '_GasteigerCharge', '_TriposPartialCharge']
        for f in fields:
            if atom.HasProp(f):
                charge = atom.GetDoubleProp(f)
                break
        # FIXME: this should not happen, blame RDKit
        if isnan(charge) or isinf(charge):
            charge = 0.
        pdbqt_line += ('%.3f' % charge).rjust(6)

        # Get atom type
        pdbqt_line += ' '
        atomicnum = atom.GetAtomicNum()
        atomhybridization = atom.GetHybridization()
        atombondsnum = atom.GetDegree()
        if atomicnum == 6 and atom.GetIsAromatic():
            pdbqt_line += 'A '
        elif atomicnum == 7 and ((idx in acceptors) or (atomhybridization == Chem.HybridizationType.SP3 and atombondsnum == 3) ):
            pdbqt_line += 'NA'
        elif atomicnum == 8 and idx in acceptors:
            pdbqt_line += 'OA'
        elif atomicnum == 1 and atom.GetNeighbors()[0].GetIdx() in donors:
            pdbqt_line += 'HD'
        elif atomicnum == 1 and atom.GetNeighbors()[0].GetIdx() not in donors:
            pdbqt_line += 'H '
        elif atomicnum == 16 and ( (atomhybridization == Chem.HybridizationType.SP3 and atombondsnum != 4) or atomhybridization == Chem.HybridizationType.SP2 ):
            pdbqt_line += 'SA'
        else:
            if len(atom.GetSymbol()) >1:
                pdbqt_line += atom.GetSymbol()
            else:
                pdbqt_line += (atom.GetSymbol() + ' ')
        pdbqt_lines.append(pdbqt_line)
    return pdbqt_lines

def MolToPDBQTBlock(mol, flexible=True, addHs=False, computeCharges=False):
    """Write RDKit Molecule to a PDBQT block

    Parameters
    ----------
        mol: rdkit.Chem.rdchem.Mol
            Molecule with a protein ligand complex
        flexible: bool (default=True)
            Should the molecule encode torsions. Ligands should be flexible,
            proteins in turn can be rigid.
        addHs: bool (default=False)
            The PDBQT format requires at least polar Hs on donors. By default Hs
            are added.
        computeCharges: bool (default=False)
            Should the partial charges be automatically computed. If the Hs are
            added the charges must and will be recomputed. If there are no
            partial charge information, they are set to 0.0.

    Returns
    -------
        block: str
            String wit PDBQT encoded molecule
    """
    # make a copy of molecule
    mol = Chem.Mol(mol)

    # if flexible molecule contains multiple fragments write them separately
    if flexible and len(Chem.GetMolFrags(mol)) > 1:
        return ''.join(MolToPDBQTBlock(frag, flexible=flexible, addHs=addHs, computeCharges=computeCharges)
                       for frag in Chem.GetMolFrags(mol, asMols=True))

    # Identify donors and acceptors for atom typing
    # Acceptors
    patt = Chem.MolFromSmarts('[$([O;H1;v2]),'
                              '$([O;H0;v2;!$(O=N-*),'
                              '$([O;-;!$(*-N=O)]),'
                              '$([o;+0])]),'
                              '$([n;+0;!X3;!$([n;H1](cc)cc),'
                              '$([$([N;H0]#[C&v4])]),'
                              '$([N&v3;H0;$(Nc)])]),'
                              '$([F;$(F-[#6]);!$(FC[F,Cl,Br,I])])]')
    acceptors = list(map(lambda x: x[0], mol.GetSubstructMatches(patt, maxMatches=mol.GetNumAtoms())))
    # Donors
    patt = Chem.MolFromSmarts('[$([N&!H0&v3,N&!H0&+1&v4,n&H1&+0,$([$([Nv3](-C)(-C)-C)]),'
                              '$([$(n[n;H1]),'
                              '$(nc[n;H1])])]),'
                              # Guanidine can be tautormeic - e.g. Arginine
                              '$([NX3,NX2]([!O,!S])!@C(!@[NX3,NX2]([!O,!S]))!@[NX3,NX2]([!O,!S])),'
                              '$([O,S;H1;+0])]')
    donors = list(map(lambda x: x[0], mol.GetSubstructMatches(patt, maxMatches=mol.GetNumAtoms())))
    if addHs:
        mol = Chem.AddHs(mol, addCoords=True, onlyOnAtoms=donors, )
    if addHs or computeCharges:
        AllChem.ComputeGasteigerCharges(mol)

    atom_lines = PDBQTAtomLines(mol, donors, acceptors)
    assert len(atom_lines) == mol.GetNumAtoms()

    pdbqt_lines = []

    # vina scores
    if (mol.HasProp('vina_affinity') and mol.HasProp('vina_rmsd_lb') and mol.HasProp('vina_rmsd_lb')):
        pdbqt_lines.append('REMARK VINA RESULT:  ' +
                           ('%.1f' % float(mol.GetProp('vina_affinity'))).rjust(8) +
                           ('%.3f' % float(mol.GetProp('vina_rmsd_lb'))).rjust(11) +
                           ('%.3f' % float(mol.GetProp('vina_rmsd_ub'))).rjust(11))

    pdbqt_lines.append('REMARK  Name = ' + (mol.GetProp('_Name') if mol.HasProp('_Name') else ''))
    if flexible:
        # Find rotatable bonds
        '''
        rot_bond = Chem.MolFromSmarts('[!$(*#*)&!D1&!$(C(F)(F)F)&'
                                      '!$(C(Cl)(Cl)Cl)&'
                                      '!$(C(Br)(Br)Br)&'
                                      '!$(C([CH3])([CH3])[CH3])&'
                                      '!$([CD3](=[N,O,S])-!@[#7,O,S!D1])&'
                                      '!$([#7,O,S!D1]-!@[CD3]=[N,O,S])&'
                                      '!$([CD3](=[N+])-!@[#7!D1])&'
                                      '!$([#7!D1]-!@[CD3]=[N+])]-!@[!$(*#*)&'
                                      '!D1&!$(C(F)(F)F)&'
                                      '!$(C(Cl)(Cl)Cl)&'
                                      '!$(C(Br)(Br)Br)&'
                                      '!$(C([CH3])([CH3])[CH3])]')
        '''

        #rot_bond = Chem.MolFromSmarts('[!$([NH]!@C(=O))&!D1&!$(*#*)]-&!@[!$([NH]!@C(=O))&!D1&!$(*#*)]') # From Chemaxon
        rot_bond  = Chem.MolFromSmarts('[!$(*#*)&!D1]-&!@[!$(*#*)&!D1]') #single and not ring, really not in ring?

        exclude_list = ['[NX3]-[CX3]=[O,N]','C(=[O;!R])N']
        #, '[!#1]-[C;H3,Cl3,F3,Br3]']
        excluded_atoms = []
        for excluded_smarts in exclude_list:
            excluded_bond = Chem.MolFromSmarts(excluded_smarts)
            excluded_atoms += [(x[0],x[1]) for x in list(mol.GetSubstructMatches(excluded_bond))]

        tertiary_amide_bonds = Chem.MolFromSmarts('[NX3]([!#1])([!#1])-[CX3]=[O,N]')

        bond_atoms = list(mol.GetSubstructMatches(rot_bond))

        tertiary_amide_bond_atoms=[(x[0],x[3]) for x in list(mol.GetSubstructMatches(tertiary_amide_bonds))]
        for excld_atom in excluded_atoms:
            #bond_atoms.remove(amide_bond_atom)
            excld_atom_reverse=(excld_atom[1],excld_atom[0])
            if excld_atom in bond_atoms:
                bond_atoms.remove(excld_atom)
            elif excld_atom_reverse in bond_atoms:
                bond_atoms.remove(excld_atom_reverse)

        if len(tertiary_amide_bond_atoms) > 0:
            for tertiary_amide_bond_atom in tertiary_amide_bond_atoms:
                bond_atoms.append(tertiary_amide_bond_atom)

        # Fragment molecule on bonds to ge rigid fragments
        bond_ids = [mol.GetBondBetweenAtoms(a1, a2).GetIdx()
                    for a1, a2 in bond_atoms]
        if bond_ids:
            for i, b_index in enumerate(bond_ids):
                tmp_frags= Chem.FragmentOnBonds(mol, [b_index], addDummies=False)
                tmp_frags_list=list(Chem.GetMolFrags(tmp_frags))
                #tmp_bigger=0
                if len(tmp_frags_list) == 1:
                    del bond_ids[i]
                    del bond_atoms[i]
                #else:
                #    tmp_bigger= max(len(tmp_frags_list[0]), len(tmp_frags_list[1]))
                #mol.GetBonds()[b_index].SetProp("large_part", str(tmp_bigger))
            mol_rigid_frags = Chem.FragmentOnBonds(mol, bond_ids, addDummies=False)
        else:
            mol_rigid_frags = mol

        num_torsions = len(bond_atoms)
        # Active torsions header
        pdbqt_lines.append('REMARK  %i active torsions:' % num_torsions)
        pdbqt_lines.append('REMARK  status: (\'A\' for Active; \'I\' for Inactive)')
        for i, (a1, a2) in enumerate(bond_atoms):
            pdbqt_lines.append('REMARK%5.0i  A    between atoms: _%i  and  _%i'
                               % (i + 1, a1 + 1, a2 + 1))

        frags = list(Chem.GetMolFrags(mol_rigid_frags))
        #list frag  from which bonds ?
        fg_bonds=[]
        fg_num_rotbonds={}
        for fg in frags:
            tmp_bonds=[]
            for a1,a2 in bond_atoms:
                if a1 in fg or a2 in fg:
                    tmp_bonds.append(mol.GetBondBetweenAtoms(a1, a2).GetIdx())
            if tmp_bonds:
                fg_bonds.append(tmp_bonds)
            else:
                fg_bonds.append(None)
            fg_num_rotbonds[fg] = len(tmp_bonds)

        # frag with long branch ?
        fg_bigbranch={}
        for i, fg_bond in enumerate(fg_bonds):
            tmp_bigger=0
            frag_i_mol=frags[i]
            if fg_bond != None: # for rigid mol
                tmp_frags= Chem.FragmentOnBonds(mol, fg_bond, addDummies=False)
                tmp_frags_list=list(Chem.GetMolFrags(tmp_frags))
                for tmp_frag_j in tmp_frags_list:
                    len_tmp_fg_j=len(tmp_frag_j)
                    if frag_i_mol == tmp_frag_j:
                        pass
                    else:
                        if len_tmp_fg_j > tmp_bigger:
                            tmp_bigger=len_tmp_fg_j
                #print(f'REMARK FRAG: {i} : {len(frags[i])} : {tmp_bigger} ')
            fg_bigbranch[frags[i]] = tmp_bigger

        #def weigh_frags(frag):
            """sort by the fragment size and the number of bonds (secondary)"""
            #num_bonds = 0
            # bond_weight = 0
            #big_frag_size=0
            #for a1, a2 in bond_atoms:
            #    if a1 in frag or a2 in frag:
            #        num_bonds += 1
                    #big_frag_size = max(big_frag_size, int(mol.GetBondBetweenAtoms(a1, a2).GetProp("large_part")))
            # changed signs are fixing mixed sorting type (ascending/descending)
            #return -num_bonds, -len(frag),  # bond_weight
        def weigh_frags(frag):
            return fg_bigbranch[frag], -fg_num_rotbonds[frag],   # bond_weight
        frags = sorted(frags, key=weigh_frags)

        # Start writting the lines with ROOT
        pdbqt_lines.append('ROOT')
        frag = frags.pop(0)
        for idx in frag:
            pdbqt_lines.append(atom_lines[idx])
        pdbqt_lines.append('ENDROOT')

        # Now build the tree of torsions usign DFS algorithm. Keep track of last
        # route with following variables to move down the tree and close branches
        branch_queue = []
        current_root = frag
        old_roots = [frag]

        visited_frags = []
        visited_bonds = []
        while len(frags) > len(visited_frags):
            end_branch = True
            for frag_num, frag in enumerate(frags):
                for bond_num, (a1, a2) in enumerate(bond_atoms):
                    if (frag_num not in visited_frags and
                        bond_num not in visited_bonds and
                        (a1 in current_root and a2 in frag or
                         a2 in current_root and a1 in frag)):
                        # direction of bonds is important
                        if a1 in current_root:
                            bond_dir = '%i %i' % (a1 + 1, a2 + 1)
                        else:
                            bond_dir = '%i %i' % (a2 + 1, a1 + 1)
                        pdbqt_lines.append('BRANCH %s' % bond_dir)
                        for idx in frag:
                            pdbqt_lines.append(atom_lines[idx])
                        branch_queue.append('ENDBRANCH %s' % bond_dir)

                        # Overwrite current root and stash previous one in queue
                        old_roots.append(current_root)
                        current_root = frag

                        # remove used elements from stack
                        visited_frags.append(frag_num)
                        visited_bonds.append(bond_num)

                        # mark that we dont want to end branch yet
                        end_branch = False
                        break
                    else:
                        continue
                    break  # break the outer loop as well

            if end_branch:
                pdbqt_lines.append(branch_queue.pop())
                if old_roots:
                    current_root = old_roots.pop()
        # close opened branches if any is open
        while len(branch_queue):
            pdbqt_lines.append(branch_queue.pop())
        pdbqt_lines.append('TORSDOF %i' % num_torsions)
    else:
        pdbqt_lines.extend(atom_lines)

    return '\n'.join(pdbqt_lines)

def HelpAndExit():
    print("USAGE: rdkit2pdbqt.py -r protein.pdb")
    print("USAGE: rdkit2pdbqt.py -l ligand.sdf")
    exit()

if __name__ == "__main__":
    #parsing the command
    if len(sys.argv) != 3:
        HelpAndExit()

    if sys.argv[1] == '-r':
        try:
            receptor_mol=Chem.MolFromPDBFile(sys.argv[2], removeHs=False)
            #AllChem.AssignBondOrdersFromTemplate(receptor_mol,receptor_mol)
            # detect aromaticity
            #AllChem.AssignAtomChiralTagsFromStructure(receptor_mol)
            #AllChem.AssignBondOrdersFromTemplate(Chem.MolFromSmarts('[a]'), receptor_mol)
            #Chem.AssignStereochemistry(receptor_mol)

            receptor_lines=MolToPDBQTBlock(receptor_mol, False, False, True)
            print(receptor_lines)
        except:
            raise TypeError('Protein is not readable by rdkit.')

    elif sys.argv[1] == '-l':
        mol=Chem.MolFromMolFile(sys.argv[2],removeHs=False, sanitize=False)
        mol_problems = Chem.DetectChemistryProblems(mol)
        if len(mol_problems) > 0:
            for problem in mol_problems:
                if "N, 4" in problem.Message():
                    at_idx = problem.GetAtomIdx()
                    atom = mol.GetAtomWithIdx(at_idx)
                    chg = atom.GetFormalCharge()
                    print(f'REMARK    N {at_idx} with formal charge {chg}')
                    atom.SetFormalCharge(1)
                    atom.UpdatePropertyCache()
                else:
                    print(problem.Message())
                    exit()
        Chem.SanitizeMol(mol)
        pdbqtlines=MolToPDBQTBlock(mol, True, False, True)
        print(pdbqtlines)
        exit()

    else:
        HelpAndExit()


#
# @lc app=leetcode id=221 lang=python3
#
# [221] Maximal Square
#
# https://leetcode.com/problems/maximal-square/description/
#
# algorithms
# Medium (33.80%)
# Total Accepted:    162.8K
# Total Submissions: 471.1K
# Testcase Example:  '[["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]]'
#
# Given a 2D binary matrix filled with 0's and 1's, find the largest square
# containing only 1's and return its area.
#
# Example:
#
#
# Input:
#
# 1 0 1 0 0
# 1 0 1 1 1
# 1 1 1 1 1
# 1 0 0 1 0
#
# Output: 4
#
#
class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        """
        Time Complexity = O(m*n)
        Space Complexity = O(m)
        """
        if len(matrix) == 0:
            return 0
        dp = [0]*len(matrix[0])
        maxi = 0
        for i in range(len(matrix)):
            curr = [0]*len(matrix[0])
            for j in range(len(matrix[0])):
                if matrix[i][j] != "1":
                    continue
                curr[j] = min(min(dp[j], curr[j-1]), dp[j-1]) + 1
                maxi = max(maxi, curr[j]**2)
            dp = curr
        return maxi


import requests
from rest_framework.serializers import (
    ModelSerializer,
    SerializerMethodField,
    CharField,
    ValidationError,
)

from pokeapi.settings import POKEMON_API_URL

from pokemons.models import Pokemon

class PokemonSerializer(ModelSerializer):
    """Basic Pokemon serializer."""
    class Meta:
        model = Pokemon
        fields = [
            'uuid',
            'name',
        ]

class PokemonDetailSerializer(ModelSerializer):
    """Pokemon serializer with details from external API."""

    name = CharField()
    info = SerializerMethodField()

    class Meta:
        model = Pokemon
        fields = [
            'uuid',
            'name',
            'info',
        ]

    def get_pokemon(self, name):
        """
        Get pokemon info from external API
        """
        response = requests.get(POKEMON_API_URL + name)
        if response.status_code == 404:
            raise ValidationError('Pokemon not found')
        if response.status_code != 200:
            raise ValidationError('Pokemon API is down')
        return response.json()

    def get_info(self, obj):
        pokemon = self.get_pokemon(obj.name)
        return pokemon

    def validate(self, attrs):
        self.get_pokemon(attrs['name'].lower())
        attrs['trainer'] = self.context['request'].user.trainer
        return attrs


import os

# ID OF TRY
ID = 1

# VALIDATION SIZE
validation_size = 0.2  # change for split.py

# ROOT
root_folder = f'data/try_no_{ID}'

# FOLDERS
# FOLDERS AND FILES OF DATA AFTER OCR PIPELINE
after_ocr_folder = r"/home/nca/Projects/vzd/FINAL_DATA_RENAMED/"  # CHANGE THIS <============
images_after_ocr = os.path.join(after_ocr_folder, 'images')
json_after_ocr = os.path.join(after_ocr_folder, 'json')
coords_after_ocr = os.path.join(after_ocr_folder, 'coords')

# UTILITY FOLDER/
valid_folder = 'Valid'
boxes_and_transcripts_folder = 'boxes_and_transcripts'
helper_csv_folder = 'helper_csv_files'
boxes_and_transcripts_for_testing_folder = 'boxes_and_transcripts_for_testing'

# MODEL ALL INPUT DATA (NO SPLIT)
model_all_data = 'initial_bt_ent'  # Change this path to specify where you want
# to generate the initial boxes and transcripts and entities files

# MODEL INPUT FOLDER
model_input_folder = 'model_input'

# MODEL OUTPUT FOLDER
model_output_folder = 'model_output'

# REPORT FILES/FOLDERS
report_output_folder = 'report_output'

# SIMILARITY FILES/FOLDERS
similarity_output_folder = 'similarity_output'

# AGGREGATION FOLDERS
document_level_aggregated_folder = 'document_level_output_aggregated'
label_document_level_folder = 'label_document_level_aggregated'

# TESTING
boxes_and_transcripts_for_testing = boxes_and_transcripts_for_testing_folder

# ADD FOLDERS TO ROOT FOLDER
helper_csv_folder = os.path.join(root_folder, helper_csv_folder)
model_input_folder = os.path.join(root_folder, model_input_folder)
model_output_folder = os.path.join(root_folder, model_output_folder)
document_level_aggregated_folder = os.path.join(root_folder, document_level_aggregated_folder)
label_document_level_folder = os.path.join(root_folder, label_document_level_folder)
similarity_output_folder = os.path.join(root_folder, similarity_output_folder)
report_output_folder = os.path.join(root_folder, report_output_folder)
boxes_and_transcripts_for_testing = os.path.join(root_folder, boxes_and_transcripts_for_testing)

# FIELDS
fields = ["insuranceCompany", "policyNumber", "policyEnd", "insuranceType", "fee", "insuranceSum"]

# UTILITY FOLDERS/FILES

image_doc_csv = os.path.join(helper_csv_folder, 'image_doc.csv')
doc_bin_csv = os.path.join(helper_csv_folder, 'doc_bin.csv')

# MODEL INPUT SAMPLES
valid_samples_list = os.path.join(model_input_folder, valid_folder) + '/valid_samples_list.csv'
document_valid_samples_list = os.path.join(model_input_folder, valid_folder) + '/valid_samples_list_doc.csv'
model_input_boxes_and_transcripts = os.path.join(os.path.join(model_input_folder, valid_folder),
                                                 boxes_and_transcripts_folder)

# SIMILARITY FILE
similarity_output_file = similarity_output_folder + '/similarity_output.csv'

# REPORT FILE
report_document_level_output_file = report_output_folder + "/report_document_level.txt"
report_time_per_function = report_output_folder + 'report_time.txt'

# POPPLER PATH
poppler_path = r'C:\Users\mbogoevs\Release-20.12.1\poppler-20.12.1\bin'  # Change for pdf_to_image.py script

# OCR
pre_ocr_all_images = r'C:\Users\mbogoevs\Output_testing_folder\Collected_data_renamed\images'  # Change for image_to_coords.py script(ocr)
after_ocr_path = r'C:\Users\mbogoevs\Output_testing_folder\OCRd_3'  # Change for image_to_coords.py script(ocr)

def create_folders():
    os.makedirs(root_folder, exist_ok=True)
    os.makedirs(helper_csv_folder, exist_ok=True)
    os.makedirs(model_input_folder, exist_ok=True)
    os.makedirs(model_output_folder, exist_ok=True)
    os.makedirs(document_level_aggregated_folder, exist_ok=True)
    os.makedirs(label_document_level_folder, exist_ok=True)
    os.makedirs(similarity_output_folder, exist_ok=True)
    os.makedirs(report_output_folder, exist_ok=True)
    os.makedirs(boxes_and_transcripts_for_testing, exist_ok=True)

    file = open(report_time_per_function, "w")
    file.write("Generated report for time spent per function\n")
    file.close()

if __name__ == '__main__':
    create_folders()


import tkinter as tk
from PIL import ImageTk, Image
from tkinter import filedialog
import pytesseract

class Convert:

    def tesseract(request):
        root = tk.Tk()
        #root.withdraw()         #  '#' 제외하면 위젯 안보임 : new
        root.title('waiting...')
        root.geometry('250x50')

        #tkinter label
        label = tk.Label(root, text="이미지를 선택한 후, 기다려 주세요", bg='white')
        label.pack(padx=10, pady=15)

        # root.filename : type / str
        root.filename = filedialog.askopenfilename(initialdir='./png', title='파일선택', filetypes=(
            ('png files', '*.png'), ('jpg files', '*.jpg')))

        # 이미지 불러서 나타내기
        img=Image.open(root.filename)
        img.show()
        root.destroy()  # true - 자동닫김 / mainloop는 오류 떠서 바꿈

        # tesseract 한글변환
        pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract'

        convert = pytesseract.image_to_string(img, lang="kor+eng")
        convert=convert.replace("\n","<br>")

        context={'convert':convert, 'filename':root.filename}
        #1.특수문자 인식
        #2.이미지 출력하기
        #3.출력할때 줄바꿈하기

        # 딕셔너리로 반환
        return context

'''
#성공
t=Convert()
str=t.tesseract()
print(str.replace('\n',''))
'''


# Aqui iremos receber / unir os dataframes, fazer copias para front
# normalizar dados, tirar medias e classificar os quartil's

from os import sep
import numpy as np
import pandas as pd
from computer.funcomputer import *

# Recebendo os dataframes dados

## Tabela de conteudos
t_conteudos=pd.read_csv("./csvs/tab_conteudos.csv")
del t_conteudos['Unnamed: 0']
t_conteudos=t_conteudos.replace(np.inf, 0)

## Tabela de relátorios
t_relas=pd.read_csv("./csvs/tab_rela23.csv")
del t_relas['Unnamed: 0']
t_relas=t_relas.replace(np.inf, 0)

# Tabela de questoes
t_quest=pd.read_csv("./csvs/tab_quest.csv")
del t_quest['Unnamed: 0']
t_quest=t_quest.replace(np.inf, 0)

# Tabela de engajamento
t_engaj=pd.read_csv("./csvs/tab_engaja.csv")
del t_engaj['Unnamed: 0']
t_engaj=t_engaj.replace(np.inf, 0)

# Tabela de Produto/Dealowner (separar)
t_prod=pd.read_csv("./csvs/produto_deal_licen_receita.csv")
del t_prod['Unnamed: 0']

# Vamos agora separar as tabelas por produto e licenças
tab_prod=reorder_columns(t_prod,"licenças",2).iloc[:,:3]

# unindo e inserindo a tabela de produto no restando das tabelas

# conteudos
tab_unida_prod = pd.merge(t_conteudos, t_relas, on="namespace", how='outer')
tab_unida_prod = pd.merge(tab_unida_prod, t_quest, on="namespace", how='outer')
tab_unida_prod = pd.merge(tab_unida_prod, t_engaj, on="namespace", how='outer')
tab_unida_prod = pd.merge(tab_unida_prod, t_prod, on="namespace", how='outer')
tab_unida_prod = tab_unida_prod.replace(np.nan, 0)

# Separando por produto e licenças

# Váriavel de tamanho para retirar a tabela produto para normalização e avg
vsize=tab_unida_prod.shape[1]

###################   Pedagogico ####################
# 0 - 30
prod_pedago_030 = split_dataframe(tab_unida_prod,"Produto","Pedagógico","licenças", "0 - 30").iloc[:,:vsize-6]
norm_pedago_030 = norm_dataframe(prod_pedago_030)
avg_pedago_030 = media_das_colunas(norm_pedago_030)
pont_pedago_030 = avg_ratio(norm_pedago_030, avg_pedago_030)
quartil_pegado_030 = quartiles_classification(sumx_arranging(norm_pedago_030))

# 30 - 400
prod_pedago_34 = split_dataframe(tab_unida_prod,"Produto","Pedagógico","licenças", "30 - 400").iloc[:,:vsize-6]
norm_pedago_34 = norm_dataframe(prod_pedago_34)
avg_pedago_34 = media_das_colunas(norm_pedago_34)
pont_pedago_34 = avg_ratio(norm_pedago_34, avg_pedago_34)
quartil_pegado_34 = quartiles_classification(sumx_arranging(norm_pedago_34))

# 400 - 800
prod_pedago_48 = split_dataframe(tab_unida_prod,"Produto","Pedagógico","licenças","400 - 800").iloc[:,:vsize-6]
norm_pedago_48 = norm_dataframe(prod_pedago_48)
avg_pedago_48 = media_das_colunas(norm_pedago_48)
pont_pedago_48 = avg_ratio(norm_pedago_48, avg_pedago_48)
quartil_pegado_48 = quartiles_classification(sumx_arranging(norm_pedago_48))

# 800 - 1200
prod_pedago_812 = split_dataframe(tab_unida_prod,"Produto","Pedagógico","licenças","800 - 1200").iloc[:,:vsize-6]
norm_pedago_812 = norm_dataframe(prod_pedago_812)
avg_pedago_812 = media_das_colunas(norm_pedago_812)
pont_pedago_812= avg_ratio(norm_pedago_812, avg_pedago_812)
quartil_pegado_812 = quartiles_classification(sumx_arranging(norm_pedago_812))

# 1200 - x
prod_pedago_12x = split_dataframe(tab_unida_prod,"Produto","Pedagógico","licenças","1200 - x").iloc[:,:vsize-6]
norm_pedago_12x = norm_dataframe(prod_pedago_12x)
avg_pedago_12x = media_das_colunas(norm_pedago_12x)
pont_pedago_12x = avg_ratio(norm_pedago_12x, avg_pedago_12x)
quartil_pegado_12x = quartiles_classification(sumx_arranging(norm_pedago_12x))

###################   Diagnístico ####################

# 0 - 30 -> DEU VAZIO
proddia03 = split_dataframe(tab_unida_prod,"Produto","Diagnóstico","licenças","0 - 30").iloc[:,:vsize-6]
normdia03 = norm_dataframe(proddia03)
avgdia03 = media_das_colunas(normdia03)
pontdia03 = avg_ratio(normdia03, avgdia03)
quartildia03 = quartiles_classification(sumx_arranging(normdia03))

# 30 - 400
proddia34 = split_dataframe(tab_unida_prod,"Produto","Diagnóstico","licenças","30 - 400").iloc[:,:vsize-6]
normdia34 = norm_dataframe(proddia34)
avgdia34 = media_das_colunas(normdia34)
pontdia34 = avg_ratio(normdia34, avgdia34)
quartildia34 = quartiles_classification(sumx_arranging(normdia34))

# 400 - 800
proddia48 = split_dataframe(tab_unida_prod,"Produto","Diagnóstico","licenças","400 - 800").iloc[:,:vsize-6]
normdia48 = norm_dataframe(proddia48)
avgdia48 = media_das_colunas(normdia48)
pontdia48 = avg_ratio(normdia48, avgdia48)
quartildia48 = quartiles_classification(sumx_arranging(normdia48))

# 800 - 1200 -> Deu vazio
proddia812 = split_dataframe(tab_unida_prod,"Produto","Diagnóstico","licenças","800 - 1200").iloc[:,:vsize-6]
normdia812 = norm_dataframe(proddia812)
avgdia812 = media_das_colunas(normdia812)
pontdia812 = avg_ratio(normdia812, avgdia812)
quartildia812 = quartiles_classification(sumx_arranging(normdia812))

# 1200 - x
proddia12x = split_dataframe(tab_unida_prod,"Produto","Diagnóstico","licenças","1200 - x").iloc[:,:vsize-6]
normdia12x = norm_dataframe(proddia12x)
avgdia12x = media_das_colunas(normdia12x)
pontdia12x = avg_ratio(normdia12x, avgdia12x)
quartildia12x = quartiles_classification(sumx_arranging(normdia12x))

###################   Banco   ####################

# 0 - 30 -> DEU VAZIO
prodbc03 = split_dataframe(tab_unida_prod,"Produto","Banco","licenças","0 - 30").iloc[:,:vsize-6]
normbc03 = norm_dataframe(prodbc03)
avgbc03 = media_das_colunas(normbc03)
pontbc03 = avg_ratio(normbc03, avgbc03)
quartilbc03 = quartiles_classification(sumx_arranging(normbc03))

# 30 - 400
prodbc34 = split_dataframe(tab_unida_prod,"Produto","Banco","licenças","30 - 400").iloc[:,:vsize-6]
normbc34 = norm_dataframe(prodbc34)
avgbc34 = media_das_colunas(normbc34)
pontbc34 = avg_ratio(normbc34, avgbc34)
quartilbc34 = quartiles_classification(sumx_arranging(normbc34))

# 400 - 800
prodbc48 = split_dataframe(tab_unida_prod,"Produto","Banco","licenças","400 - 800").iloc[:,:vsize-6]
normbc48 = norm_dataframe(prodbc48)
avgbc48 = media_das_colunas(normbc48)
pontbc48 = avg_ratio(normbc48, avgbc48)
quartilbc48 = quartiles_classification(sumx_arranging(normbc48))

# 800 - 1200 -> Deu vazio
prodbc812 = split_dataframe(tab_unida_prod,"Produto","Banco","licenças","800 - 1200").iloc[:,:vsize-6]
normbc812 = norm_dataframe(prodbc812)
avgbc812 = media_das_colunas(normbc812)
pontbc812 = avg_ratio(normbc812, avgbc812)
quartilbc812 = quartiles_classification(sumx_arranging(normbc812))

# 1200 - x
prodbc12x = split_dataframe(tab_unida_prod,"Produto","Banco","licenças","1200 - x").iloc[:,:vsize-6]
normbc12x = norm_dataframe(prodbc12x)
avgbc12x = media_das_colunas(normbc12x)
pontbc12x = avg_ratio(normbc12x, avgbc12x)
quartilbc12x = quartiles_classification(sumx_arranging(normbc12x))

# joining the pieces

# total quartile dataframe
lista_quartil = [quartil_pegado_030, quartil_pegado_34, quartil_pegado_48, quartil_pegado_812, quartil_pegado_12x, quartildia03, quartildia34, quartildia48, quartildia812, quartildia12x, quartilbc03, quartilbc34, quartilbc48, quartilbc812, quartilbc12x]
total_quartil = append_dataframes(lista_quartil).sort_values(by=['quartil','soma'], ascending=[False,True]).reset_index(drop=True)
total_quartil = pd.merge(total_quartil, t_prod, on="namespace", how='left')

# total points dataframe
lista_pontos = [pont_pedago_030, pont_pedago_34, pont_pedago_48, pont_pedago_812, pont_pedago_12x, pontdia03, pontdia34, pontdia48, pontdia812, pontdia12x, pontbc03, pontbc34, pontbc48, pontbc812, pontbc12x]
total_pontos = append_dataframes(lista_pontos).reset_index(drop=True)
total_pontos = pd.merge(t_prod, total_pontos, on="namespace", how='left')

# total norm dataframe
lista_norm = [norm_pedago_030, norm_pedago_34, norm_pedago_48, norm_pedago_812, norm_pedago_12x, normdia03, normdia34, normdia48, normdia812, normdia12x]
total_norm = append_dataframes(lista_norm).sort_values(by=['namespace'], ascending=[True]).reset_index(drop=True)

# points with riick
point_risk = pd.merge(total_quartil, total_pontos, on="namespace", how='outer')


#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Project      : aizoo.
# @File         : utils
# @Time         : 2022/7/14 下午3:32
# @Author       : yuanjie
# @WeChat       : meutils
# @Software     : PyCharm
# @Description  :

from meutils.pipe import *

from LAC import LAC

def get_nouns(texts):
    lac = LAC()
    dic = {'NOUN': [], 'PER': [], 'LOC': [], 'ORG': [], 'TIME': []}
    for words, flags in lac.run(texts):
        for i, flag in enumerate(flags):
            if 'n' in flag:
                dic['NOUN'].append(words[i])
            elif flag in dic:
                dic[flag].append(words[i])

    return dic

import rocketqa


# 14890
import sys
input = sys.stdin.readline

size, length = map(int, input().split())
road = [list(map(int, input().split())) for _ in range(size)]
answer = 0

# 가로, 1차 검사
def check(i):
    tmp_road = [0] * size
    for j in range(size-1):

        # 도로 높이차 2이상
        if abs(road[i][j] - road[i][j+1]) > 1:
            return 0

        # 내리막
        if road[i][j] - road[i][j+1] == 1:

            if max(road[i][j+1: j+length+1]) != min(road[i][j+1: j+length+1]):
                return 0

            elif len(road[i][j+1: j+length+1]) < length:
                return 0

            for k in range(j+1, j+length+1):
                tmp_road[k] = 1

        # 오르막
        if road[i][j] - road[i][j+1] == -1:

            if j-length+1 < 0:
                return 0

            elif max(road[i][j-length+1: j+1]) != min(road[i][j-length+1: j+1]):
                return 0

            elif sum(tmp_road[j-length+1:j+1]) != 0:
                return 0

    return 1

for i in range(size):
    answer += check(i)

road = list(map(list, zip(*road)))

for i in range(size):
    answer += check(i)

print(answer)


"""Test file for secp192r1"""
import math
import sys
import random
import matplotlib.pyplot as plt
import base64
from Point import Point
from KoblitzAlgorithm import KoblitzAlgorithm
from ECC import ECC

class Test192r1(object):

    def main():
        print("-------------------Elliptic curve cryptography-------------------")
        print("-----encryption and decryption of an image using secp256-r1------")
        print("-------------developed in Python from Nicola Venturi-------------")
        print("-----------------------------------------------------------------")
        print("\n")

        """I'm reading an image and trasfom it into a string"""
        with open("./python-1-226045.png", "rb") as image:
            b64string = base64.b64encode(image.read())

        """Decode the string into ascii and trasform this string in a ascii character array"""
        message=b64string.decode('ascii')
        #message='ciao'
        msg=[]
        for c in message:
            msg.append(ord(c))

        """Curve on p-256r1"""

        p=int('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF', 16)
        a=int('FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC', 16)
        b=int('5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B', 16)
        gx=int('6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296',16)
        gy=int('4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5',16)
        G=Point(gx, gy)
        n=int('FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551',16)
        h=int('01',16)
        seed=int('C49D360886E704936A6678E1139D26B7819F7E90',16)

        print("-------------------Curve parameters------------------------------")
        print("-----------------------------------------------------------------")
        print("Odd prime p is ", p,"\n")
        print("Value of a is ", a, "\n")
        print("Value of b is ", b, "\n")
        print("Generator point G is ", G.getCoordinate(), "\n")
        print("Point order is ", n, "\n")
        print("Starting value of h is ", h, "\n")
        print("Seed for random value is ", seed, "\n")

        #Curve setting and keys generation
        encryptor=ECC(a,b,p, G,n,h,seed)
        random.seed(seed)

        print("-------------------Keys generation-----------------------------")
        print("---------------------------------------------------------------")
        (kprvM,kpubM)=encryptor.keys_generator()
        print("Mitt keys are: ")
        print("Private key ", kprvM)
        print("Public key ", kpubM.getCoordinate())
        print("---------------------------------------------------------------")
        (kprvD,kpubD)=encryptor.keys_generator()
        print("Dest keys are: ")
        print("Private key ", kprvD)
        print("Public key ", kpubD.getCoordinate())
        print("---------------------------------------------------------------")
        print("\n")

        transformer=KoblitzAlgorithm(a,b,p)
        trovato=False
        ErrPoint=Point(-1,-1)
        #Trasform every characters of the message in curve point if it is possible
        while not trovato:
            p_message=[]
            for i in msg:
                Pm=transformer.trasform_message(i,h)
                plt.plot(Pm.X,Pm.Y, marker='.')
                #If Pm is (-1,-1), it's not a curve point and it can't be added to the array
                if Pm.equals(ErrPoint):
                    break
                p_message.append(Pm)
            if p_message.__len__()!=msg.__len__():
                print("It's impossible to generate a point for this value of h ", h)
                h+=1
            else:
                trovato=True
                print("Right value of h is ", h)

        """Plot settings and show"""
        plt.title("Message points generated with Koblitz algorithm")
        plt.show()

        #Message encryption simulation
        print("Now encrypt the message")
        encrypted_message=[]
        print(p_message.__len__())
        count=0
        for cr in p_message:
            #for every point i'll use a different r to have different pair on same points
            r=random.randint(2,n-1)
            (V,W)=encryptor.encrypt(r, kpubD, cr)
            plt.plot(V.X,V.Y, marker='.')
            plt.plot(W.X,W.Y, marker='.')
            encrypted_message.append((V,W))
            count+=1

        plt.title("Points pair generated by the encryption method")
        plt.show()

        #Message decryption simulation
        print("Now you have to decrypt message")
        decrypt_message=[]
        for couple in encrypted_message:
            c=encryptor.decrypt(couple,kprvD)
            decrypt_message.append(c)

        msgrcv=[]
        for p in decrypt_message:
            msgrcv.append(math.floor(p.X//h))

        s=""
        for i in msgrcv:
            s+=chr(i)

        print(s==message)
        imagedata=base64.b64decode(s)
        image='new_image.png'
        with open(image, 'wb') as f:
            f.write(imagedata)

    if __name__=="__main__":
        main()


#iterative function traverses through a string's length,
#concatinating every last element to the front in order to reverse string
def reverse(string):
   ctr = len(string)
   newString = ""
   for c in string:
      newString = c + newString
      ctr = ctr - 1
   return newString

def main() :
   # Demonstrate the reverse function.
   r = reverse("Hello!")
   print(r)
   print("Expected: !olleH")

# Call the main function.
main()


from shutil import copyfile
import os

def replaceUnion(path):

    In = open(path, "r")
    text = str(In.read())
    In.close()

    text = text.replace('union', 'struct')

    Out = open(path, "w")
    Out.write(text)
    Out.close()

include_str = '#include "VarStor.h"\n'
cpp_file = 'parse.cpp'
cpp_file_h = 'parse.cpp.h'

f = open(cpp_file_h, 'r')
s = str(f.read())
f.close()

f = open(cpp_file_h, 'w')

if (False == s.startswith(include_str)):
    s = include_str + s

f.write(s)
f.close()

replaceUnion(cpp_file)
replaceUnion(cpp_file_h)

upper_dir = os.path.dirname(os.getcwd())

copyfile(cpp_file, upper_dir + '\\' + cpp_file)
copyfile(cpp_file_h, upper_dir + '\\' + cpp_file_h)

os.remove(cpp_file)
os.remove(cpp_file_h)


'''
There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

You may assume nums1 and nums2 cannot be both empty.
'''

class Solution(object):
    def findMedianSortedArrays(self, nums1, nums2):
        """
        :type nums1: List[int]
        :type nums2: List[int]
        :rtype: float
        """
        nums1.extend(nums2)
        nums1.sort()
        n = len(nums1)
        if n % 2 == 0:
            first = nums1[n//2]
            second = nums1[n//2 - 1]
            res = (first+second)/2.0
            return res
        else :
            return nums1[int(n/2)]


from django.shortcuts import render
import requests

def boredAPIView(request):
    url ="https://www.boredapi.com/api/activity"
    response = requests.get(url)
    data = response.json()
    activity =  data['activity']
    return render(request, 'home.html', {'activity':activity})


# Written by Mingkai Ma for COMP9021

from binary_tree import *
from math import log

class PriorityQueue(BinaryTree):
    def __init__(self):
        super().__init__()
        self.data = [None]
        self.nb_of_elements = 0

    def insert(self, value):
        self.nb_of_elements += 1
        self.data.append(value)
        self._bubble_up(self.nb_of_elements)
        self._transfer_to_tree()

    def _bubble_up(self, position):
        if position == 1:
            return
        elif self.data[position] < self.data[position // 2]:
            self.data[position], self.data[position // 2] = self.data[position // 2], self.data[position]
            self._bubble_up(position // 2)

    def _transfer_to_tree(self):

        L = self.data[1:]
        tree_L = []
        for i in L:
            tree_L.append(BinaryTree(i))

        max_value = len(L)

        for i in range(len(L)):
            if 2 * i + 1 < max_value:
                left_tree = tree_L[2 * i + 1]
                tree_L[i].left_node = left_tree
            if 2 * i + 2 < max_value:
                right_tree = tree_L[2 * i + 2]
                tree_L[i].right_node = right_tree

        self.value = tree_L[0].value
        self.left_node = tree_L[0].left_node
        self.right_node = tree_L[0].right_node


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models
import django.db.models.deletion

class Migration(migrations.Migration):

    dependencies = [
        ('productions', '0001_initial'),
        ('people', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='person',
            name='production',
            field=models.ForeignKey(null=True, blank=True, help_text='Leave blank for AIR/Localore staff.', on_delete=django.db.models.deletion.SET_NULL, to='productions.ProductionPage', related_name='+', verbose_name='associated production'),
        ),
    ]


from dbConnection import MySql
from sql.dashBoardSql import *
import pandas as pd

class ChartMaker():
    def __init__(self):
        self.db = MySql()

    async def getChartData(self, idx, term):
        value = []
        rawChartData = await self.db.oneSelect(getChartDataSql(idx))
        chartData = pd.DataFrame(rawChartData)
        chartData = chartData.groupby(chartData.index // term).mean().round().astype(int)
        chartData = chartData.values.tolist()
        for data in chartData:
            value.append(data[0])
        return value


s = input()

def get_b(s:str) -> int:
    l =[]
    for i in range(len(s)):
        if i+2 == len(s):
            break
        int_s = int(s[i]+s[i+1]+s[i+2])
        ans = abs(753 - int_s)
        l.append(ans)
    return min(l)

print(get_b(s))


import csv
import googlemaps

def request_result(search_key):
    gmaps = googlemaps.Client(key="{api_key}")
    return gmaps.geocode(search_key)

def extract_geo_point(response):
    return response[0]["geometry"]["location"]

def extract_formatted_address(response):
    return response[0]["formatted_address"]

def write_csv(row):
    with open("./point_geo_info.csv", "a") as f:
        writer = csv.writer(f)
        writer.writerow(row)

ct = 0
with open("longlati_gmap/results-20191223-180631.csv") as f:
    reader = csv.reader(f)

    header = next(reader)
    header.append("lat")
    header.append("lng")
    write_csv(header)

    for row in reader:
        try:
            search_key = ",".join(row)
            response = request_result(search_key)

            row.append(extract_geo_point(response)["lat"])
            row.append(extract_geo_point(response)["lng"])

            write_csv(row)
        except Exception as e:
            print(e)
        finally:
            ct += 1
            if ct % 5 == 0:
                print("prgress: {}".format(ct))