import os
import json

# third party imports
import mock

# CubicWeb specific imports
from cubicweb.devtools import PostgresApptestConfiguration
from cubicweb.devtools.testlib import CubicWebTC

# library specific imports
from cubicweb_francearchives.views import STRING_SEP
from cubicweb_frarchives_edition.alignments import get_externaluri_data
from cubicweb_frarchives_edition.alignments.align import AgentAligner, AgentRecord
from cubicweb_frarchives_edition.alignments.databnf import DataBnfDatabase
from cubicweb_frarchives_edition.alignments.wikidata import WikidataDatabase

from cubicweb_frarchives_edition.alignments import DATABNF_RE, DATABNF_ARK_RE

from utils import FrACubicConfigMixIn
from pgfixtures import setup_module, teardown_module  # noqa

class AlignementUtilsTC(CubicWebTC):
    """Agent alignements utils tests class."""

    def test_databnf_re(self):
        uri = "https://data.bnf.fr/fr/11894985/albert_camus/"
        self.assertEqual("11894985", DATABNF_RE.search(uri).group(1))
        uri = "https://data.bnf.fr/11907966/victor_hugo"
        self.assertEqual("11907966", DATABNF_RE.search(uri).group(1))
        uri = "https://data.bnf.fr/11907966"
        self.assertFalse(DATABNF_RE.search(uri))
        uri = "https://data.bnf.fr/ark:/12148/cb13005429m"
        self.assertFalse(DATABNF_RE.search(uri))

    def test_databnf_ark_re(self):
        uri = "https://data.bnf.fr/fr/11894985/albert_camus/"
        self.assertFalse(DATABNF_ARK_RE.search(uri))
        uri = "https://data.bnf.fr/11907966/victor_hugo"
        self.assertFalse(DATABNF_ARK_RE.search(uri))
        uri = "https://data.bnf.fr/11907966"
        self.assertFalse(DATABNF_ARK_RE.search(uri))
        uri = "https://data.bnf.fr/ark:/12148/cb11909252t"
        self.assertEqual("11909252", DATABNF_ARK_RE.search(uri).group(1))
        uri = "https://data.bnf.fr/fr/ark:/12148/cb13005429m"
        self.assertEqual("13005429", DATABNF_ARK_RE.search(uri).group(1))

    def test_uri_source(self):
        for source, extid, uri in (
            ("databnf", "11907966", "https://data.bnf.fr/11907966/victor_hugo"),
            ("databnf", "11907966", "https://data.bnf.fr/en/11907966/victor_hugo"),
            ("databnf", "13005429", "https://data.bnf.fr/fr/ark:/12148/cb13005429m"),
            ("databnf", "11921467", "http://data.bnf.fr/ark:/12148/cb11921467w"),
            ("databnf", "13946072", "https://data.bnf.fr/ark:/12148/cb139460728"),
            ("databnf", "13926902", "https://data.bnf.fr/ark:/12148/cb139269025"),
            ("databnf", "39269025", "https://data.bnf.fr/ark:/12148/cb39269025q"),
            ("wikidata", "Q158768", "https://www.wikidata.org/wiki/Q158768"),
            ("wikidata", "Q131412", "http://www.wikidata.org/wiki/Q131412"),
            ("fr.wikipedia.org", None, "https://fr.wikipedia.org/wiki/Edmond_Maire"),
            ("geoname", "3033123", "https://www.geonames.org/3033123"),
            ("geoname", "2986302", "http://www.geonames.org/2986302"),
        ):
            got_source, got_extid = get_externaluri_data(uri)
            self.assertEqual(source, got_source)
            self.assertEqual(extid, got_extid)

class AlignmentTC(FrACubicConfigMixIn, CubicWebTC):
    """Manual alignment test cases base class."""

    configcls = PostgresApptestConfiguration

class WikidataTC(AlignmentTC):
    """Wikidata test cases."""

    def test_agentinfo_from_wikidata(self):
        """Retrieve some data from Wikidata.

        Trying: retrieve and process mock data
        Expecting: data is processed correctly
        """
        return_value = (
            (
                "Igor Stravinsky",
                "+1882-06-18T00:00:00Z",
                "+1971-04-06T00:00:00Z",
                "11",
                "11",
                "pianiste et compositeur",
            ),
        )
        with mock.patch.object(WikidataDatabase, "agent_query", return_value=return_value):
            wikidata = WikidataDatabase()
            data_infos = wikidata.agent_infos("Q7314")
            dates = json.loads(data_infos["dates"])
            birthdate = dates["birthdate"]
            self.assertEqual("1882-06-18", birthdate["timestamp"])
            self.assertEqual("d", birthdate["precision"])
            self.assertTrue(birthdate["isiso"])
            deathdate = dates["deathdate"]
            self.assertEqual("1971-04-06", deathdate["timestamp"])
            self.assertEqual("d", deathdate["precision"])
            self.assertTrue(deathdate["isiso"])
            self.assertEqual("Igor Stravinsky", data_infos["label"])
            self.assertEqual("pianiste et compositeur", data_infos["description"])

    def test_agentinfo_from_wikidata_bc(self):
        """Retrieve some data from Wikidata.

        Trying: birthdate and deathdate are BC
        Expecting: timestamp is unsigned and isbc flag is True
        """
        return_value = (
            (
                "Jules César",
                "-0099-07-01T00:00:00Z",
                "-0043-03-13T00:00:00Z",
                "10",
                "11",
                "homme politique et général romain du Ier siècle avant J-C.",
            ),
        )
        with mock.patch.object(WikidataDatabase, "agent_query", return_value=return_value):
            wikidata = WikidataDatabase()
            data_infos = wikidata.agent_infos("Q1048")
            dates = json.loads(data_infos["dates"])
            birthdate = dates["birthdate"]
            self.assertEqual("0099-07-01", birthdate["timestamp"])
            self.assertEqual("m", birthdate["precision"])
            self.assertTrue(birthdate["isiso"])
            self.assertTrue(birthdate["isbc"])
            deathdate = dates["deathdate"]
            self.assertEqual("0043-03-13", deathdate["timestamp"])
            self.assertEqual("d", deathdate["precision"])
            self.assertTrue(deathdate["isiso"])
            self.assertTrue(deathdate["isbc"])
            self.assertEqual("Jules César", data_infos["label"])
            self.assertEqual(
                "homme politique et général romain du Ier siècle avant J-C.",
                data_infos["description"],
            )

    def test_agentinfo_from_wikidata_year(self):
        """Retrieve some data from Wikidata.

        Trying: birthdate has precision '9'
        Expecting: birthdate has precision 'y'(ear)
        """
        return_value = (
            (
                "François Rabelais",
                "+1494-01-01T00:00:00Z",
                "+1553-04-19T00:00:00Z",
                "9",
                "11",
                "auteur français du 16e siècle",
            ),
        )
        with mock.patch.object(WikidataDatabase, "agent_query", return_value=return_value):
            wikidata = WikidataDatabase()
            data_infos = wikidata.agent_infos("Q131018")
            dates = json.loads(data_infos["dates"])
            birthdate = dates["birthdate"]
            self.assertEqual("1494-01-01", birthdate["timestamp"])
            self.assertEqual("y", birthdate["precision"])
            self.assertTrue(birthdate["isiso"])
            deathdate = dates["deathdate"]
            self.assertEqual("1553-04-19", deathdate["timestamp"])
            self.assertEqual("d", deathdate["precision"])
            self.assertTrue(deathdate["isiso"])
            self.assertEqual("François Rabelais", data_infos["label"])
            self.assertEqual("auteur français du 16e siècle", data_infos["description"])

class DataBnfTC(AlignmentTC):
    """Data.bnf.fr test cases."""

    def test_agentinfo_from_databnf_date(self):
        """
        Retrieve some data from data.bnf.fr
        Trying: add an same_as relation to a databnf ExternalUri
        Expecting: retrive dates (full date) and notes
        """
        return_value = (
            (
                "Igor Stravinsky (1882-1971)",
                None,
                "1882-06-17",
                None,
                "1971-04-06",
                "Compositeur. - Pianiste. - Chef d'orchestre",
            ),
        )
        with mock.patch.object(DataBnfDatabase, "author_query", return_value=return_value):
            databnf = DataBnfDatabase()
            data_infos = databnf.agent_infos("12405560")
            dates = json.loads(data_infos["dates"])
            birthdate = dates["birthdate"]
            self.assertEqual("1882-06-17", birthdate["timestamp"])
            self.assertEqual("d", birthdate["precision"])
            self.assertFalse(birthdate["isiso"])
            deathdate = dates["deathdate"]
            self.assertEqual("1971-04-06", deathdate["timestamp"])
            self.assertEqual("d", deathdate["precision"])
            self.assertFalse(deathdate["isiso"])
            self.assertEqual("Igor Stravinsky (1882-1971)", data_infos["label"])
            self.assertEqual(
                "Compositeur. - Pianiste. - Chef d'orchestre", data_infos["description"]
            )

    def test_agentinfo_description_from_databnf_date(self):
        """
        Retrieve some data from data.bnf.fr
        Trying: add an same_as relation to a databnf ExternalUri
        Expecting: retrive dates all notes
        """
        descriptions = (
            "A utilisé le pseudonyme de Morland dans la Résistance",
            "Avocat et homme politique. - Quatrième président de la Ve République (1981-1995)",
        )
        return_value = (
            (
                "François Mitterrand (1916-1996)",
                None,
                "1916-10-26",
                None,
                "1996-01-08",
                descriptions[0],
            ),
            (
                "François Mitterrand (1916-1996)",
                None,
                "1916-10-26",
                None,
                "1996-01-08",
                descriptions[1],
            ),
        )
        with mock.patch.object(DataBnfDatabase, "author_query", return_value=return_value):
            databnf = DataBnfDatabase()
            data_infos = databnf.agent_infos("11916320")
            self.assertCountEqual(descriptions, data_infos["description"].split(STRING_SEP))

    def test_agentinfo_from_databnf_year(self):
        """
        Retrieve some data from data.bnf.fr
        Trying: add an same_as relation to a databnf ExternalUri
        Expecting: retrive year and notes
        """
        return_value = (
            (
                "Hervé (saint, 05..-0575?)",
                "05..",
                None,
                "0575",
                None,
                "Barde d'origine galloise. - Fonda un ermitage en Bretagne",
            ),
        )
        with mock.patch.object(DataBnfDatabase, "author_query", return_value=return_value):
            databnf = DataBnfDatabase()
            data_infos = databnf.agent_infos("14978856")
            dates = json.loads(data_infos["dates"])
            birthdate = dates["birthdate"]
            self.assertEqual(birthdate["timestamp"], "05..")
            self.assertFalse(birthdate["isdate"])
            self.assertFalse(birthdate["isiso"])
            deathdate = dates["deathdate"]
            self.assertEqual(deathdate["timestamp"], "0575-01-01")
            self.assertTrue(deathdate["isdate"])
            self.assertFalse(deathdate["isiso"])
            self.assertEqual(deathdate["precision"], "y")

    def test_agentinfo_from_databnf_bc(self):
        """Test processing BCE dates.

        Trying: retrieve BCE dates from data.bnf.fr
        Expecting: valid date as timestamp and marked as BCE
        """
        return_value = (
            (
                "Sénèque (0004 av. J.-C.-0065)",
                None,
                "- 4",
                None,
                "65",
                (
                    "Philosophe stoïcien. - Auteur de tragédies. - Fils de : "
                    "Sénèque le rhéteur (0060 av. J.-C.?-0039?)"
                ),
            ),
        )
        with mock.patch.object(DataBnfDatabase, "author_query", return_value=return_value):
            databnf = DataBnfDatabase()
            data_infos = databnf.agent_infos("11887555")
            dates = json.loads(data_infos["dates"])
            birthdate = dates["birthdate"]
            self.assertEqual(birthdate["timestamp"], "0004-01-01")
            self.assertTrue(birthdate["isdate"])
            self.assertTrue(birthdate["isbc"])
            self.assertFalse(birthdate["isiso"])
            self.assertEqual(birthdate["precision"], "y")
            deathdate = dates["deathdate"]
            self.assertEqual(deathdate["timestamp"], "0065-01-01")
            self.assertFalse(deathdate["isbc"])
            self.assertFalse(deathdate["isiso"])

    def test_agentinfo_one_date_from_databnf_date(self):
        """
        Retrieve some data from data.bnf.fr
        Trying: add an same_as relation to a databnf ExternalUri
        Expecting: only the start date exist
        """
        return_value = (("Alain Jupp\xe9", 1945, None, None, None, "Inspecteur des finances"),)
        with mock.patch.object(DataBnfDatabase, "author_query", return_value=return_value):
            databnf = DataBnfDatabase()
            data_infos = databnf.agent_infos("11909252")
            dates = json.loads(data_infos["dates"])
            birthdate = dates["birthdate"]
            self.assertEqual("1945-01-01", birthdate["timestamp"])
            self.assertEqual("y", birthdate["precision"])
            self.assertFalse(birthdate["isiso"])
            self.assertIsNone(dates.get("deathdate"))
            self.assertEqual("Alain Juppé", data_infos["label"])
            self.assertEqual("Inspecteur des finances", data_infos["description"])

    def test_agentinfo_cast(self):
        """Test retrieving information from data.bnf.fr.

        Trying: using int
        Expecting: no birthdate is returned and deathdate is of the proper type (str)
        despite failing date evaluation (no dates > 9999 allowed in datetime)
        """
        return_value = (("Max Mustermann", None, None, 10000, None, ""),)
        with mock.patch.object(DataBnfDatabase, "author_query", return_value=return_value):
            databnf = DataBnfDatabase()
            data_infos = databnf.agent_infos("1234567890")
            dates = json.loads(data_infos["dates"])
            self.assertIsNone(dates.get("birthdate"))
            self.assertEqual("10000", dates["deathdate"]["timestamp"])

class AgentAlignerTC(AlignmentTC):
    """Wikidata and data.bnf.fr test cases (automatic)."""

    configcls = PostgresApptestConfiguration
    # TODO remove test_isdate and test_isbc as soon as
    # manual alignment and automatic alignment behaviour is
    # the same and test compute_dates function instead of
    # process_alignment (Wikidata)

    def test_process_csv(self):
        """Test processing CSV file.

        Trying: processing CSV file
        Expecting: corresponding alignments
        """
        with self.admin_access.cnx() as cnx:
            file_name = os.path.join(self.datapath(), "agent-alignments.csv")
            aligner = AgentAligner(cnx)
            with open(file_name) as fp:
                expected = AgentRecord(
                    {
                        "eid": "19034398",
                        "date naissance": "+1600-01-01T00:00:00Z",
                        "precision date naissance": "9",
                        "date mort": "+1674-01-01T00:00:00Z",
                        "precision date mort": "9",
                        "description": "Marin",
                        "uri": "https://www.wikidata.org/wiki/Q646986",
                        "source": "wikidata",
                        "confidence": "0.9",
                        "extlabel": "Marin le Roy de Gomberville",
                    }
                )
                alignments = aligner.process_csv(fp)
                self.assertEqual(1, len(alignments))
                actual = alignments[("19034398", "https://www.wikidata.org/wiki/Q646986")]
                self.assertEqual(actual.autheid, expected.autheid)
                self.assertEqual(actual.date_birth, expected.date_birth)
                self.assertEqual(actual.date_death, expected.date_death)
                self.assertEqual(actual.description, expected.description)
                self.assertEqual(actual.exturi, expected.exturi),
                self.assertEqual(actual.source, expected.source)
                self.assertEqual(actual.confidence, expected.confidence)
                self.assertEqual(actual.extlabel, expected.extlabel)

    def test_process_alignments_existing_externaluris(self):
        """Test updating database.

        Trying: existing ExternalUris
        Expecting: ExternalUri is kept
        """
        with self.admin_access.cnx() as cnx:
            external_uri = cnx.create_entity(
                "ExternalUri",
                source="wikidata",
                uri="https://www.wikidata.org/wiki/Q646986",
                label="Marin le Roy de Gomberville",
            )
            cnx.commit()
            agent_authority = cnx.create_entity("AgentAuthority")
            cnx.commit()
            record = AgentRecord(
                {
                    "eid": str(agent_authority.eid),
                    "date naissance": "+1600-01-01T00:00:00Z",
                    "precision date naissance": "9",
                    "date mort": "+1674-01-01T00:00:00Z",
                    "precision date mort": "9",
                    "description": "Marin",
                    "uri": "https://www.wikidata.org/wiki/Q646986",
                    "source": "wikidata",
                    "confidence": "0.9",
                    "external label": "Marin le Roy de Gomberville",
                }
            )
            alignments = {(agent_authority.eid, "https://www.wikidata.org/wiki/Q646986"): record}
            dates = {
                "birthdate": {
                    "timestamp": "1600-01-01",
                    "isbc": False,
                    "isdate": True,
                    "precision": "y",
                    "isiso": True,
                },
                "deathdate": {
                    "timestamp": "1674-01-01",
                    "isbc": False,
                    "isdate": True,
                    "precision": "y",
                    "isiso": True,
                },
            }
            aligner = AgentAligner(cnx)
            aligner.process_alignments(alignments)
            agent_info = cnx.execute(
                "Any X WHERE X is AgentInfo, X agent_info_of %(eid)s", {"eid": external_uri.eid}
            ).one()
            self.assertEqual(agent_info.dates, dates)
            self.assertEqual(agent_info.description, record.description)
            self.assertEqual(external_uri.label, record.extlabel)

    def test_process_alignments_nonexisting_externaluris(self):
        """Test updating database.

        Trying: nonexisting ExternalUris
        Expecting: new ExternalUris and AgentInfos are created
        """
        with self.admin_access.cnx() as cnx:
            self.assertFalse(cnx.find("ExternalUri"))
            agent_authority = cnx.create_entity("AgentAuthority")
            cnx.commit()
            record = AgentRecord(
                {
                    "eid": str(agent_authority.eid),
                    "date naissance": "+1600-01-01T00:00:00Z",
                    "precision date naissance": "9",
                    "date mort": "+1674-01-01T00:00:00Z",
                    "precision date mort": "9",
                    "description": "Marin",
                    "uri": "https://www.wikidata.org/wiki/Q646986",
                    "source": "wikidata",
                    "confidence": "0.9",
                    "external label": "Marin le Roy de Gomberville",
                }
            )
            alignments = {(agent_authority.eid, "https://www.wikidata.org/wiki/Q646986"): record}
            dates = {
                "birthdate": {
                    "timestamp": "1600-01-01",
                    "isbc": False,
                    "isdate": True,
                    "precision": "y",
                    "isiso": True,
                },
                "deathdate": {
                    "timestamp": "1674-01-01",
                    "isbc": False,
                    "isdate": True,
                    "precision": "y",
                    "isiso": True,
                },
            }
            aligner = AgentAligner(cnx)
            aligner.process_alignments(alignments)
            agent_info = cnx.find("AgentInfo").one()
            self.assertEqual(agent_info.dates, dates)
            self.assertEqual(agent_info.description, record.description)
            external_uri = cnx.find("ExternalUri").one()
            self.assertEqual(external_uri.label, record.extlabel)

    def test_process_date_wikidata(self):
        """Test processing date.

        Trying: source is Wikidata
        Expecting: is successfully processed
        """
        with self.admin_access.cnx() as cnx:
            aligner = AgentAligner(cnx)
            self.assertEqual(
                aligner._process_date("+1600-01-01T00:00:00Z", "9", "wikidata"),
                {
                    "timestamp": "1600-01-01",
                    "isbc": False,
                    "isdate": True,
                    "precision": "y",
                    "isiso": True,
                },
            )

    def test_process_date_databnf(self):
        """Test processing date.

        Trying: source is data.bnf.fr
        Expecting: is successfully processed
        """
        with self.admin_access.cnx() as cnx:
            aligner = AgentAligner(cnx)
            self.assertEqual(
                aligner._process_date("05..", "", "databnf"),
                {
                    "timestamp": "05..",
                    "isbc": False,
                    "isdate": False,
                    "precision": "d",
                    "isiso": False,
                },
            )

    def test_isbc(self):
        """Test updating database.

        Trying: date is Before Christ
        Expecting: timestamp is formatted date and it is flagged as Before Christ
        """
        with self.admin_access.cnx() as cnx:
            agent_authority = cnx.create_entity("AgentAuthority")
            cnx.commit()
            record = AgentRecord(
                {
                    "eid": str(agent_authority.eid),
                    "date naissance": "-0400-01-01T00:00:00Z",
                    "precision date naissance": "9",
                    "date mort": "+0065-04-12T00:00:00Z",
                    "precision date mort": "11",
                    "description": "philosophe stoïcien, dramaturge et homme d'État romain",
                    "uri": "https://www.wikidata.org/wiki/Q2054",
                    "source": "wikidata",
                    "confidence": "1.0",
                }
            )
            alignments = {(agent_authority.eid, "https://www.wikidata.org/wiki/Q2054"): record}
            dates = {
                "birthdate": {
                    "timestamp": "0400-01-01",
                    "isbc": True,
                    "isdate": True,
                    "precision": "y",
                    "isiso": True,
                },
                "deathdate": {
                    "timestamp": "0065-04-12",
                    "isbc": False,
                    "isdate": True,
                    "precision": "d",
                    "isiso": True,
                },
            }
            aligner = AgentAligner(cnx)
            aligner.process_alignments(alignments)
            agent_info = cnx.find("AgentInfo").one()
            self.assertEqual(agent_info.dates, dates)

    def test_isdate(self):
        """Test updating database.

        Trying: date is not valid date format
        Expecting: date is not retrieved
        """
        with self.admin_access.cnx() as cnx:
            agent_authority = cnx.create_entity("AgentAuthority")
            cnx.commit()
            record = AgentRecord(
                {
                    "eid": str(agent_authority.eid),
                    "date naissance": "0061",
                    "precision date naissance": "11",
                    "date mort": "0114",
                    "precision date mort": "11",
                    "description": "orateur et homme politique romain",
                    "uri": "https://www.wikidata.org/wiki/Q168707",
                    "source": "wikidata",
                    "confidence": "1.0",
                }
            )
            alignments = {(agent_authority.eid, "https://www.wikidata.org/wiki/Q168707"): record}
            aligner = AgentAligner(cnx)
            aligner.process_alignments(alignments)
            agent_info = cnx.find("AgentInfo").one()
            self.assertEqual(agent_info.dates, {})


import math
import rclpy
from rclpy.action import ActionServer
from rclpy.callback_groups import MutuallyExclusiveCallbackGroup
from rclpy.executors import MultiThreadedExecutor
from rclpy.node import Node
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose

from action_turtle_commands.action import MessageTurtleCommands

class CommandActionServer(Node):

    def __init__(self):
        super().__init__('action_turtle_server')
        # кземпляр сообщения Twist спользуется для представления скоростей движения и угловых скоростей в трехмерном пространстве
        self.twist = Twist()
        self.flag = 0
        # используется для хранения информации о текущем положении и ориентации объекта в трехмерном пространстве.
        self.after_pose = Pose()
        self.before_pose = Pose()
        self.publisher_ = self.create_publisher(Twist, '/turtle1/cmd_vel', 10)
        #с оздаем экземпляр нового сервера действий
        self._action_server = ActionServer(
            self,
            MessageTurtleCommands,
            'execute_turtle_commands',
            self.execute_callback)
        # тот фрагмент кода создает подписку на тему /turtle1/pose, которая предоставляет сообщения типа Pose. Позволяет узлу получать информацию о положении черепахи
        self.subscription = self.create_subscription(Pose, '/turtle1/pose', self.callback, 10)
        self.subscription # prevent unused variable warn

    def callback(self, msg):
        self.after_pose = msg
        if self.flag == 1:
            self.before_pose = msg
            self.flag = 0
            self.get_logger().info('send flag {0}'.format(self.flag))

    def execute_callback(self, goal_handle):
        self.get_logger().info('Executing goal...')
        self.flag = 1
        if goal_handle.request.command == 'forward':
            self.twist.linear.x = float(goal_handle.request.s)
            self.twist.angular.z = float(goal_handle.request.angle*3.14159/180)
        elif goal_handle.request.command == 'turn_left':
            self.twist.linear.x = float(goal_handle.request.s)
            self.twist.angular.z = float(goal_handle.request.angle*3.14159/180)
        elif goal_handle.request.command == 'turn_right':
            self.twist.linear.x = float(goal_handle.request.s)
            self.twist.angular.z = -float(goal_handle.request.angle*3.14159/180)
        self.publisher_.publish(self.twist)
        self.get_logger().info('Publishing: "%s"' % self.twist)

        feedback_msg = MessageTurtleCommands.Feedback()
        feedback_msg.odom = 0
        while self.flag == 1 and (self.after_pose.linear_velocity==0 or self.after_pose.angular_velocity==0):
            pass
        self.get_logger().info('flag: {0}'.format(self.flag))
        while self.after_pose.linear_velocity != 0 or self.after_pose.angular_velocity != 0:
            feedback_msg.odom = int(math.sqrt((self.after_pose.x - self.before_pose.x)**2+(self.after_pose.y - self.before_pose.y)**2))
            self.get_logger().info('Feedback: {0}'.format(feedback_msg.odom))
            goal_handle.publish_feedback(feedback_msg)
        goal_handle.succeed()
        result = MessageTurtleCommands.Result()
        result.result = True
        return result

def main(args=None):
    rclpy.init(args=args)
    action_turtle_server = CommandActionServer()
    executor = MultiThreadedExecutor(num_threads=2)
    executor.add_node(action_turtle_server)
    executor.spin()

if __name__ == '__main__':
    main()


"""

A magic index in an array A[1...n-1] is defined to be an index such that A[i] = i.
Given a sorted array of distinct integers, write a method to find a magic index, if one exists, in an array A.

FOLLOW UP: What if the values are not distinct?

QUESTIONS YOU SHOULD ASK:
+ Can I use custom classes?
+ Will the input always valid? (aka an array)
+ Are the integers always positive? No
+ Do the indexes such that A[i] = i start from 0? Yes

"""

"""

Initial algorithm

Basically binary search.

Some clarifications on complexity:

The performance of binary search can be analyzed by reducing the procedure to a binary comparison tree.
The root node of the tree is the middle element of the array. The middle element of the lower half is
the left child node of the root and the middle element of the upper half is the right child node of the root.

The rest of the tree is built in a similar fashion. This model represents binary search. Starting from
the root node, the left or right subtrees are traversed depending on whether the target value is less or more than
the node under consideration. This represents the successive elimination of elements, making it a complexity of
worst case O(log(n)+1) in the end.

"""

def _find_magic_index_in(numbers, start, end):
    middle_point = int((start + end) / 2)
    middle_array_value = numbers[middle_point]
    if start > end:
        return None
    if middle_array_value == middle_point:
        return middle_point
    if middle_array_value > middle_point:
        return _find_magic_index_in(numbers, start, middle_point - 1)
    if middle_array_value < middle_point:
        return _find_magic_index_in(numbers, middle_point + 1, end)

def find_magic_index_in(numbers):
    if not numbers or len(numbers) == 0:
        raise ValueError("No array found or empty array.")
    return _find_magic_index_in(numbers=numbers, start=0, end=len(numbers) - 1)

"""

Final note: When calling _find_magic_index_in for the first time, passing len in place of len-1 won't change much.
If len is odd then len-1 will be even and both will give same mid value.
If len is even then you have two elements in mid position. Passing len-1 will give us the first mid point, while
passing len will give the second one.

"""

"""

Follow-up algorithm

The idea is to do the same as above, but try to skip the repeated values.
Since there can be many repeated values, I need to search both sides all the time. For example with
[0, 2, 2, 2, 2, 2, 2, 2, 99, 100], the answer is on the left but the normal algorithm tells me to go right.

However, how do I know which parts to search for? We should use 2 facts
A) The array is sorted.
B) There may be (multiple) repeats.

For the left, I want to start from the index that's min between middle_point-1 and middle_array_value.
EXAMPLE 1:
[0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 99, 100]
A[mid] = A[6] = 2
If I do the recursion between indexes 0 and 6, it's pointless from the indexes 3-6 since I already know they will be
of value 2 or lower. I need the recursion between indexes 0 and 2, which guarantees me that there may be a magic index
hiding in any of those indexes (because A[2] can be 2 or lower, for example).

EXAMPLE 2:
[0, 1, 6, 6, 6, 7, 8, 9, 99]
A[mid] = A[4] = 6
If I do the recursion between indexes 0 and 6, it's pointless from the indexes 4 to 6 since I will be searching those
in the right part of the recursion (because since A[4]=6, A[6] could be 6 too!). Doing it from indexes 0 to 4 allows me
to find a magic index that's below 6. A[5] is always pointless since it will be 6 or more, therefore not a magic index.

For the right, it's the same logic but using max(middle_point+1, middle_array_value).

"""

def _find_follow_up_magic_index_in(numbers, start, end):
    if not numbers:
        return None
    if end < start:
        return False
    middle_point = int((start + end) / 2)
    middle_array_value = numbers[middle_point]
    if middle_array_value == middle_point:
        return middle_point

    # Search left
    left_index = min(middle_point - 1, middle_array_value)
    left = _find_follow_up_magic_index_in(numbers, start, left_index)
    if left:
        return left

    # Search right
    right_index = max(middle_point + 1, middle_array_value)
    right = _find_follow_up_magic_index_in(numbers, right_index, end)
    if right:
        return right

def find_follow_up_magic_index_in(numbers):
    if not numbers or len(numbers) == 0:
        raise ValueError("No array found or empty array.")
    return _find_follow_up_magic_index_in(numbers=numbers, start=0, end=len(numbers) - 1)


"""
------ NOT USED IN THE MAIN SCRIPT ------
Stitching with OpenCV stitcher.
"""

import argparse
import logging

import cv2
from imutils import paths

parser = argparse.ArgumentParser()
parser.add_argument(
    "-i", "--images", type=str, required=True, help="path to input directory of images to stitch"
)
parser.add_argument("-o", "--output", type=str, required=True, help="path to the output image")
parser.add_argument("-v", "--verbose", action="store_true", help="increase output verbosity")
args = vars(parser.parse_args())

if args["verbose"]:
    logging.basicConfig(level=logging.INFO)

logging.info("Loading images...")
images = []
imagePaths = paths.list_images(args["images"])
for imagePath in imagePaths:
    image = cv2.imread(imagePath)
    images.append(image)

logging.info("Stitching images...")
stitcher = cv2.Stitcher_create()
(status, stitched) = stitcher.stitch(images)

if status == 0:
    logging.info("Stiching successful, saving result...")
    cv2.imwrite(args["output"], stitched)
else:
    logging.info(f"Image stitching failed ({status})")


"""
Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

Example:

Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

Source from: LeetCode
"""
import time

# class Solution:
#     """08/01/2020 00:56"""
#     def twoSum(self, nums, target):
#         res = []
#         if len(nums) >= 2:
#             a = len(nums)
#             for i in range(a):
#                 for j in range(i+1,a):
#                     sum_number = nums[i] + nums[j]
#                     if sum_number == target:
#                         return [i,j]

# class Solution:
#     """09/02/2022 21:39"""
#     def twoSum(self, nums, target):
#         """
#         Runtime: 7103 ms, faster than 7.82% of Python3 online submissions for Two Sum.
#         Memory Usage: 15 MB, less than 76.35% of Python3 online submissions for Two Sum.
#         """
#         for i in range(len(nums)):
#             if nums[i] == 0:
#                 pass
#             for j in range(i+1, len(nums)):
#                 sum = nums[i] + nums[j]
#                 if sum > target: continue
#                 elif sum < target: continue
#                 else:
#                     return [i, j]

# class Solution:
#     """09/02/2022 21:39"""
#     def twoSum(self, nums, target):
#         """
#         Runtime: 792 ms, faster than 34.85% of Python3 online submissions for Two Sum.
#         Memory Usage: 14.8 MB, less than 99.57% of Python3 online submissions for Two Sum.
#         """
#         for i in range(len(nums)):
#             b = target - nums[i]
#             remain = nums[i+1:]
#             if b in remain:
#                 return [i, remain.index(b)+i+1]

class Solution(object):
    """09/03/2022 13:32"""
    def twoSum(self, nums, target):
        """
        Runtime: 133 ms, faster than 40.45% of Python3 online submissions for Two Sum.
        Memory Usage: 15.2 MB, less than 49.63% of Python3 online submissions for Two Sum.
        """
        record = {}
        for a in range(len(nums)):
            b = target - nums[a]
            if b in record:
                return [record[b], a]
            else:
                record[nums[a]] = a

class Solution(object):
    """24/03/2023 23:58"""
    def twoSum(self, nums, target):
        """
        Runtime: 64 ms, faster than 69.98% of Python3 online submissions for Two Sum.
        Memory Usage: 15.2 MB, less than 16.37% of Python3 online submissions for Two Sum.
        """
        seen = {}
        for i in range(len(nums)):
            res = target - nums[i]
            if res not in seen:
                seen[nums[i]] = i
            else:
                return [seen[res], i]

start = time.time()
Solution = Solution()

## 1
inputs = [1, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
target = 18

result = Solution.twoSum(inputs, target)
print(result) # Answer: [2,7]

print("Time :", time.time() - start)

## 2
inputs = [2, 7, 11, 15]
target = 9

result = Solution.twoSum(inputs, target)
print(result)  # Answer: [0,1]

## 3
inputs = [3, 2, 4]
target = 6

result = Solution.twoSum(inputs, target)
print(result) # Answer: [1,2]

## 4
inputs = [2, 7, 11, 15]
target = 18

result = Solution.twoSum(inputs, target)
print(result)  # Answer: [1,2]

## 5
inputs = [3, 3]
target = 6

result = Solution.twoSum(inputs, target)
print(result)  # Answer: [0,1]

## 6
inputs = [0, 4, 3, 0]
target = 0
result = Solution.twoSum(inputs, target)
print(result)  # Answer: [0,3]

## 7
inputs = [-1, -2, -3, -4, -5]
target = -8
result = Solution.twoSum(inputs, target)
print(result)  # Answer: [2,4]


# coding: utf-8
from PIL import Image
import numpy as np
import dicom

for i in range(1, 50):
    #tif画像読み込み
    img = Image.open('C:\Python27\matsuzawa\Cube\Cube_post\\3mm\cube3mm_{}.tif'.format(i))
    width, height = img.size
    img_pixels = []

    for y in range(height):
        row = []
        for x in range(width):
            row.append(img.getpixel((x, y)))
        img_pixels.append(row)

    img_pixels = np.array(img_pixels)

    #dicom画像読み込み
    ds = dicom.read_file("C:\Python27\matsuzawa\Cube\Cube_pre\\3mm\cube3mm_{}.dcm".format(i))

    for y in range(height):
        for x in range(width):
            ds.pixel_array[y][x] = img_pixels[y][x]

    ds.PixelData = ds.pixel_array.tostring()
    ds.save_as("C:\Python27\matsuzawa\cube\\add_noise\\3mm\cube3mm_noise_{}.dcm".format(i))


import torch, torchvision
import detectron2
from detectron2.utils.logger import setup_logger
import numpy as np
import os, json, cv2, random
import scipy.sparse
import pyamg
from sys import exit as e
from torch.nn import functional as F
from torch import nn
from skimage import exposure
from skimage.exposure import match_histograms
from tqdm import tqdm

from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.data import MetadataCatalog, DatasetCatalog
setup_logger()
from modules.util import imshow, show
from modules.poisson import solve_poisson

# https://github.com/fbessho/PyPoi
def blend(img_target, img_source, img_mask, offset=(0, 0)):
  new_mask= 1 - img_mask
  copy_img = cv2.bitwise_and(img_source, img_source, mask = img_mask.astype(np.uint8) * 255)
  cat_img = copy_img + cv2.bitwise_and(img_target, img_target, mask=new_mask.astype(np.uint8) * 255)
  # compute regions to be blended
  region_source = (
      max(-offset[0], 0),
      max(-offset[1], 0),
      min(img_target.shape[0] - offset[0], img_source.shape[0]),
      min(img_target.shape[1] - offset[1], img_source.shape[1]))
  region_target = (
      max(offset[0], 0),
      max(offset[1], 0),
      min(img_target.shape[0], img_source.shape[0] + offset[0]),
      min(img_target.shape[1], img_source.shape[1] + offset[1]))
  region_size = (region_source[2] - region_source[0], region_source[3] - region_source[1])

  # clip and normalize mask image
  img_mask = img_mask[region_source[0]:region_source[2], region_source[1]:region_source[3]]
  img_mask[img_mask == 0] = False
  img_mask[img_mask != False] = True

  # determines the diagonals on the coefficient matrix
  positions = np.where(img_mask)
  # setting the positions to be in a flatted manner
  positions = (positions[0] * region_size[1]) + positions[1]

  # row and col size of coefficient matrix
  n = np.prod(region_size)

  main_diagonal = np.ones(n)
  main_diagonal[positions] = 4
  diagonals = [main_diagonal]
  diagonals_positions = [0]

  # creating the diagonals of the coefficient matrix
  for diagonal_pos in [-1, 1, -region_size[1], region_size[1]]:
      in_bounds_indices = None
      if np.any(positions + diagonal_pos > n):
          in_bounds_indices = np.where(positions + diagonal_pos < n)[0]
      elif np.any(positions + diagonal_pos < 0):
          in_bounds_indices = np.where(positions + diagonal_pos >= 0)[0]
      in_bounds_positions = positions[in_bounds_indices]

      diagonal = np.zeros(n)
      diagonal[in_bounds_positions + diagonal_pos] = -1
      diagonals.append(diagonal)
      diagonals_positions.append(diagonal_pos)
  A = scipy.sparse.spdiags(diagonals, diagonals_positions, n, n, 'csr')

  # create poisson matrix for b
  P = pyamg.gallery.poisson(img_mask.shape)

  # get positions in mask that should be taken from the target
  inverted_img_mask = np.invert(img_mask.astype(np.bool)).flatten()
  positions_from_target = np.where(inverted_img_mask)[0]

  # for each layer (ex. RGB)
  for num_layer in range(img_target.shape[2]):
      # get subimages
      t = img_target[region_target[0]:region_target[2], region_target[1]:region_target[3], num_layer]
      s = img_source[region_source[0]:region_source[2], region_source[1]:region_source[3], num_layer]
      t = t.flatten()
      s = s.flatten()

      # create b
      b = P * s
      b[positions_from_target] = t[positions_from_target]

      # solve Ax = b
      x = scipy.sparse.linalg.spsolve(A, b)

      # assign x to target image
      x = np.reshape(x, region_size)
      x = np.clip(x, 0, 255)
      x = np.array(x, img_target.dtype)
      # print(num_layer)
      # imshow(x)
      # imshow(img_source[:, :, num_layer])
      # x = match_histograms(x, img_source[:, :, num_layer], multichannel=True)
      # imshow(x)
      # e()
      img_target[region_target[0]:region_target[2], region_target[1]:region_target[3], num_layer] = x
      # img_target[region_target[1]:region_target[3], region_target[0]:region_target[2], num_layer] = x
  return img_target

def extend_boundary(mask, src, inc):
  mask_orig = np.copy(mask)
  mask = torch.from_numpy(mask).unsqueeze(0).unsqueeze(0)
  weight = torch.Tensor([
    [0, 1, 0],
    [1, 0, 1],
    [0, 1, 0]
  ]).type(mask.dtype)
  mask = F.conv2d(F.pad(mask, (1, 1, 1, 1)), weight.unsqueeze(0).unsqueeze(0)).squeeze().detach().numpy()
  src_2 = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
  src_2 = cv2.normalize(src_2, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  # imshow(mask * 255)
  n_mask = cv2.resize(mask, (int(mask.shape[0] * 1.1), int(mask.shape[1] * 1.1)), interpolation=cv2.INTER_CUBIC)
  # imshow(n_mask * 255)
  diff_r = n_mask.shape[0] - mask.shape[0]
  diff_c = n_mask.shape[1] - mask.shape[1]
  new_mask = n_mask[diff_r//2:n_mask.shape[0] - diff_r//2, diff_c//2:n_mask.shape[1] - diff_c//2]
  new_mask = cv2.resize(new_mask, (mask.shape[0], mask.shape[1]))
  boundary_mask = np.where(new_mask==4, 0, new_mask)
  new_mask = cv2.normalize(new_mask, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  boundary_mask = np.where(mask==4, 0, mask)
  new_mask = cv2.normalize(mask, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  boundary_mask = cv2.normalize(boundary_mask, None, alpha=0, beta=1, norm_type=cv2.NORM_MINMAX, dtype=cv2.CV_32F)
  return new_mask, boundary_mask

def get_masks(im):
  cfg = get_cfg()
  cfg.MODEL.DEVICE='cpu'
  cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml"))
  cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5
  cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml")
  predictor = DefaultPredictor(cfg)
  outputs = predictor(im)
  segments = np.asarray(outputs["instances"].pred_masks)
  boxes = outputs["instances"].pred_boxes
  return segments

def combine_img(configs):
  source_path = configs["args"]["source"]
  target_path = configs["args"]["target"]
  output_path = configs["args"]["output"]
  img_size = configs["args"]["img_size"]

  i = 0
  for tgt in tqdm(os.listdir(target_path)):
    target = os.path.join(target_path, tgt)
    for src in os.listdir(source_path):
      source = os.path.join(source_path, src)
      im = cv2.imread(source)
      tgt = cv2.imread(target)
      rs, cs, _ = im.shape
      rd, cd, _ = tgt.shape
      im  = cv2.resize(im, (img_size, img_size))
      tgt  = cv2.resize(tgt, (img_size, img_size))
      segments = get_masks(im)
      for mask in (segments.astype(np.uint8)):
        mask, boundary_mask = extend_boundary(mask, im, 30)
        if np.count_nonzero(mask==1) < configs["args"]["threshold"]:
          print(np.count_nonzero(mask==1))
          continue
        if configs["args"]["blend_type"] == "copy_paste":
          new_mask = 1 - mask
          cat_img = cv2.bitwise_and(im, im, mask = mask) + cv2.bitwise_and(tgt, tgt, mask = new_mask)
        elif configs["args"]["blend_type"] == "poisson":
          cv2.imwrite("./input/mask_plane.png", mask * 255)
          # new_mask= 1 - mask
          # cat_img = cv2.bitwise_and(im, im, mask = mask.astype(np.uint8) * 255) + cv2.bitwise_and(tgt, tgt, mask = new_mask.astype(np.uint8) * 255)
          # cat_img = blend(np.copy(cat_img), np.copy(im), np.copy(boundary_mask))
          # cat_img = solve_poisson(np.copy(tgt), np.copy(im), np.copy(mask), boundary_mask)
          cat_img = blend(np.copy(tgt), np.copy(im), np.copy(mask))
          # imshow(cat_img)
          # print(im.shape, tgt.shape, mask.shape)
          # cat_img = cv2.seamlessClone(im, tgt, mask * 255, (rd//2, cd//2), cv2.MIXED_CLONE)
        cv2.imwrite(f"{output_path}/{i}.png", cat_img)
        i+=1


import csv
from datetime import date

from django.contrib import admin
from django.db.models.query import QuerySet
from django.db.models.fields.files import FieldFile
from django.http import HttpResponse

from .models import UserProfile
from .models import Query
from .models import Invitation
from .models import Verification

def prep_field(request, obj, field, manyToManySep=';'):
    """ Returns the field as a unicode string. If the field is a callable, it
    attempts to call it first, without arguments.
    """
    if '__' in field:
        bits = field.split('__')
        field = bits.pop()

        for bit in bits:
            obj = getattr(obj, bit, None)

            if obj is None:
                return ""

    attr = getattr(obj, field)

    if isinstance(attr, (FieldFile,)):
        attr = request.build_absolute_uri(attr.url)

    output = attr() if callable(attr) else attr

    if isinstance(output, (list, tuple, QuerySet)):
        output = manyToManySep.join([str(item) for item in output])
    return str(output) if output else ""

def export_csv_action(description="Export as CSV", fields=None, exclude=None,
                      header=True, manyToManySep=';'):
    """ This function returns an export csv action. """

    def export_as_csv(modeladmin, request, queryset):
        """ Generic csv export admin action.
        Based on http://djangosnippets.org/snippets/2712/
        """

        opts = modeladmin.model._meta
        field_names = [field.name for field in opts.fields]
        labels = []

        if exclude:
            field_names = [f for f in field_names if f not in exclude]

        elif fields:
            field_names = [field for field, _ in fields]
            labels = [label for _, label in fields]

        response = HttpResponse(content_type='text/csv')
        namefile = "rec_invitations_%s" % (date.today(), )
        response['Content-Disposition'] = 'attachment; filename=%s.csv' % (
            namefile, )

        writer = csv.writer(response)

        if header:
            writer.writerow(labels if labels else field_names)

        for obj in queryset:
            writer.writerow(
                [prep_field(request, obj, field, manyToManySep)
                 for field in field_names])
        return response
    export_as_csv.short_description = description
    export_as_csv.acts_on_all = True
    return export_as_csv

@admin.register(UserProfile)
class UserAdmin(admin.ModelAdmin):
    list_display = ('firstname', 'lastname', 'email', 'acceptance', 'created',
                    'modified', )
    list_filter = ('created', 'acceptance', )
    search_fields = ('email', )

@admin.register(Query)
class QueryAdmin(admin.ModelAdmin):
    list_display = ('description', 'user', 'created', 'modified', 'raw_data', )
    search_fields = ('user', )

@admin.register(Invitation)
class InvitationAdmin(admin.ModelAdmin):
    list_display = (
        'inviter', 'email', 'count', 'state', 'created', 'modified', )
    search_fields = ['email', 'inviter__email']
    list_filter = ('state', 'count', 'created', 'modified', )
    actions = (
        export_csv_action("Export Invitations Report",
                          fields=[
                              ('email', 'Invitado'),
                              ('inviter__email', 'Invitante'),
                              ('count', 'Reiteraciones'),
                              ('created', 'Fecha de Invitacion',),
                              ('modified', 'ambio Estado-Reiteracion'), ],
                          header=True,
                          manyToManySep=';'
                          ),)

@admin.register(Verification)
class VerificationAdmin(admin.ModelAdmin):
    list_display = ('user', 'token', )
    search_fields = ('user__email', )


#!/usr/bin/env python3
import sys

if len(sys.argv) > 1:
    filename = sys.argv[1]
else:
    filename = "input.txt"

def group_by(iter, sep):
    current_group = []
    for i in iter:
        if i == sep:
            yield current_group
            current_group = []
        else:
            current_group.append(i)
    yield current_group

groups = [i for i in group_by(open(filename).read().splitlines(), "") if i]

# star 1
total = 0
for group in groups:
    questions = set()
    for i in group:
        questions |= set(i)
    total += len(questions)
print(total)

# star 2
total = 0
for group in groups:
    questions = set(group[0])
    for i in group[1:]:
        questions &= set(i)
    total += len(questions)
print(total)


# import requests
# from lxml import etree
# url='https://www.78gk.net/440/'
# headers={
#
# "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
# "accept-encoding":"gzip,deflate,br",
# "accept-language":"zh-CN,zh;q=0.9",
# "cache-control":"no-cache",
# "cookie":"Hm_lvt_e0355b37aacebb0e9b79c5ba05d6678f=1612319315; jweu__cityid=2; Hm_lpvt_e0355b37aacebb0e9b79c5ba05d6678f=1612410123",
# "pragma":"no-cache",
# "sec-fetch-mode":"navigate",
# "sec-fetch-site":"none",
# "sec-fetch-user":"?1",
# "upgrade-insecure-requests":"1",
# "user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.97 Safari/537.36",
# }
#
# html = requests.get(url=url,headers=headers)
# # res= etree.HTML(html.text)
# print(html.text)

import re
a = "setbg('查看完整电话',420,520,'https://www.78gk.net/box.php?part=seecontact_tel&id=381022&tel_base64=MTM2NDM4NTM3MjA=')"
par=re.compile("https:.*?\)")
res=re.findall(par,a)[0].split("')")[0]
print(res)


import requests
import re
from requests.exceptions import RequestException

def get_one_page(url):
	try:
		response=requests.get(url)
		response.encoding='utf-8'
		if response.status_code==200:
			return response.text
		return None
	except RequestsException:
		return None

def parse_one_page(html):
	pattern=re.compile('<div id="lg">.*?<img.*?class="index-logo-src" src="(.*?)".*?usemap="#mp">',re.S)
	item=re.findall(pattern, html)
	return item

def main():
	url='https://www.baidu.com/'
	html=get_one_page(url)
	item=parse_one_page(html)
	print(item)

if __name__=='__main__':
	main()


import pickle
import gzip
import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import interp1d

import os
os.chdir('/home/lab_abel/Heatwaves/Data/compact')

def analyse_direct(block):

    with gzip.open('long_series', 'rb') as f:
        T=pickle.load(f)

    anomaly=T-np.mean(T)
    print('mean = ',np.mean(T))

    def running_mean(x, N):
        cumsum = np.cumsum(np.insert(x, 0, 0))
        return (cumsum[N:] - cumsum[:-N]) / float(N)

    T90=running_mean(anomaly,24*90)

    A_max=[]
    T_block=block
    M=int(len(T90)/(24*T_block))
    for i in range(M):
        A_max.append((T90[i*24*T_block:i*24*T_block+24*T_block]).max())

    A_max=np.sort(A_max)
    A_hot=A_max[A_max>0.01]

    m=len(A_hot)

    Ret=[]
    prob=[]
    for i in range(m):
        t=-T_block/(np.log((1-(m-i)/M)))
        Ret.append(t/365)
        prob.append(1-np.exp(-T_block/t))

    plt.scatter((Ret),A_hot[:],s=10, alpha=0.5, facecolors='none', edgecolors='black',
    label='1000 year direct run')
    # plt.plot((Ret),A_hot[:],
    # label='1000 year direct run')

def analyse_GKTL(exp):

    with open('prob_'+str(exp), 'rb') as f:
        p=pickle.load(f)

    with open('T_'+str(exp), 'rb') as f:
        T=pickle.load(f)

    # with open('link_'+str(exp), 'rb') as f:
    #     link=pickle.load(f)

    def running_mean(x, N):
        cumsum = np.cumsum(np.insert(x, 0, 0))
        return (cumsum[N:] - cumsum[:-N]) / float(N)

    A_max=[]
    for e in T:
        A_max.append(np.max(running_mean((np.array(e)-298.3797386241071)[:], 3*24*90)))

    a, p = zip(*sorted(zip(A_max, p)))

    # print(np.sum(p))

    # index=0
    # for i in range(len(a)):
    #     if a[i]>0.01:
    #         break
    #     index+=1

    # a=a[index:];p=p[index:]

    r=[]
    for i in range(len(a)):
        T=-(128-90)/np.log(1-np.sum(p[i:]))
        # T=(128-90)/np.sum(p[i:])
        r.append((T)/365)

    # plt.plot(r,a, label='GKTL k=10', color='red', linewidth='0.8')

    # r_interpol_range=np.linspace(0,1000000,10000001, endpoint=True)
    r_interpol_range=np.power(10, np.linspace(-1,8,1000000, endpoint=True))
    f = interp1d(r, a)
    r_interpol=r_interpol_range[np.logical_and(r_interpol_range>np.min(r), r_interpol_range<np.max(r))]
    a_interpol=f(r_interpol)

    mean=np.mean(a_interpol); std=np.std(a_interpol)
    front=0;rear=len(a_interpol)
    for i in range(len(a_interpol)):
        if a_interpol[i]<mean-1.0*std:
            front=i+1
        if a_interpol[i]<mean+1.0*std:
            rear= i+1

    a_interpol=a_interpol[front:rear];r_interpol=r_interpol[front:rear]

    # plt.plot(r_interpol,a_interpol, label=exp)
    return r_interpol,a_interpol

analyse_direct(38)

r=np.power(10, np.linspace(-1,8,1000000, endpoint=True))
print(r.min(), r.max())
c=np.zeros(len(r))
val=np.zeros(len(r))
val2=np.zeros(len(r))

for exp in  ['10b', '20', '20b', '30', '40', '40b', '50' ]:
    r_temp, a_temp=analyse_GKTL(exp)
    mask=np.logical_and(r>=r_temp.min(), r<=r_temp.max())
    val[mask]=val[mask]+a_temp
    val2[mask]=val2[mask]+a_temp*a_temp
    c[mask]=c[mask]+1

a_avg=val/c
std=np.sqrt(val2/c-(val*val)/(c*c))
print(std.min(),std.max())

plt.plot(r,a_avg, label='GKTL run',color='red',linewidth=1.5)
# plt.fill_between(r,a_avg-std,a_avg+std,color="grey",alpha=0.3)
plt.grid()
plt.xscale('log')
plt.xlabel('Return time (years)')
plt.ylabel('Anomaly of 90 day avg temperature (K)')
plt.legend()
# plt.xlim([0,70000000])
plt.xticks([1/10,1,10,100,1000,10000,100000,1000000,1000000])
plt.ylim([0,3])
plt.show()

analyse_direct(38)

front=0;rear=len(c)
stop=0
for i in range(len(c)):
    if c[i]>=1 and stop==0:
        front=i+1
        stop=1
    if c[i]>=3:
        rear= i+1

a_avg=a_avg[front:rear];r=r[front:rear];std=std[front:rear]

z = np.polyfit(np.log10(r), a_avg, 5)
P=np.polyval(z,np.log10(r))
print(z)
plt.plot(r,P, label='GKTL run',color='red',linewidth=1.5)
plt.fill_between(r,P-std,P+std,color='grey',alpha=0.2)

plt.grid()
plt.xscale('log')
plt.xlabel('Return time (years)')
plt.ylabel('Anomaly of 90 day avg temperature (K)')
plt.legend()
# plt.xlim([0,70000000])
plt.xticks([1/10,1,10,100,1000,10000,100000,1000000,1000000])
plt.ylim([0,3])
plt.show()


CTB_TAG             = 128

CTB_PKE             = 1
CTB_SIGNATURE       = 2
CTB_MESSAGE_DIGETS  = 3
CTB_PRIVATE_KEY     = 5
CTB_PUBLIC_KEY      = 6
CTB_COMPRESSED_DATA = 8
CTB_CKE             = 9
CTB_LITERAL_DATA    = 11
CTB_TRUST           = 12
CTB_USERID          = 13
CTB_COMMENT         = 14


import os

from django.http import JsonResponse
from django.core.cache import cache

from common import keys
from common import stat
from user import logics
from user.models import User
from user.models import Profile
from user.forms import UserForm
from user.forms import ProfileForm

def get_vcode(request):
    '''用户获取验证码接口'''
    phonenum = request.GET.get('phonenum')
    result = logics.send_vcode(phonenum)
    if result:
        return JsonResponse({'code': stat.OK, 'data': None})
    else:
        return JsonResponse({'code': stat.SMS_ERR, 'data': None})

def submit_vcode(request):
    '''用户提交验证码接口，并执行登陆注册'''
    # 获取参数
    phonenum = request.POST.get('phonenum')
    vcode = request.POST.get('vcode')
    # print(vcode)
    # print(phonenum)

    cached_vcode = cache.get(keys.VCODE % phonenum)
    # print(cached_vcode)

    # 检查验证码
    if vcode and cached_vcode and vcode == cached_vcode:
        try:
            user = User.objects.get(phonenum=phonenum)
        except User.DoesNotExist:
            user = User.objects.create(phonenum=phonenum, nickname=phonenum)

        # 将用户状态记录到Session
        request.session['uid'] = user.id

        return JsonResponse({'code': stat.OK, 'data': user.to_dict()})

    else:
        return JsonResponse({'code': stat.VCODE_ERR, 'data': None})

def get_profile(request):
    '''获取个人交友资料'''
    uid = request.session['uid']
    # try:
    #     profile = Profile.objects.get(id=uid)
    # except Profile.DoesNotExist:
    #     profile = Profile.objects.create(id=uid)
    profile, _ = Profile.objects.get_or_create(id=uid)
    return JsonResponse({'code':stat.OK, 'data':profile.to_dict()})

def set_profile(request):
    '''修改个人、交友资料'''

    # 验证用户表的数据
    user_form = UserForm(request.POST)
    if not user_form.is_valid():
        return JsonResponse({'code': stat.USER_FORM_ERR, 'data': user_form.errors})

    # 验证个人资料表的数据
    profile_form = ProfileForm(request.POST)
    if not profile_form.is_valid():
        return JsonResponse({'code': stat.PROFILE_FORM_ERR, 'data': profile_form.errors})

    # 更新user数据
    uid = request.session['uid']
    user = User.objects.get(id=uid)
    user.__dict__.update(user_form.cleaned_data)

    # 更新Profile数据
    profile, _ = Profile.objects.get_or_create(id=uid)
    profile.__dict__.update(profile_form.cleaned_data)

    user.save()
    profile.save()
    return JsonResponse({'code': stat.OK, 'data': None})

def upload_avatar(request):
    '''上传个人头像接口'''

    # 取出文件对象
    uid = request.session.get('uid')
    avatar_file = request.FILES.get('avatar')

    logics.upload_avatar.delay(uid, avatar_file)

    return JsonResponse({'code': stat.OK, 'data': None})


import sys
import random

class Node:

    edges = []
    head = None
    neighbors = 0

    def __init__(self, head):
        self.head = head
        self.edges = []
        self.neighbors = 0

    def add_edge(self, edge):
        self.edges.append(edge)

    def contains_edge(self, edge):
        if self.edges.__contains__(edge):
            return True
        return False

def print_graph(graph):
    for i in range(0, len(graph)):
        print("{}, {}: {}".format(graph[i].head, graph[i].neighbors, graph[i].edges))

run = True
print("Welcome")
print("Graph Generator 3000")
print("Choose an option:")
print("For generating random oriented graph enter: g")
print("For entering your own oriented graph enter: e")
print('For help enter: h')
print("For quiting enter: q")
while(run):
    option = input("ENTER OPTION: ")
    if option=='g':
        #generuoti:
        try:
            point_number = int(input("Enter amount of points you want: "))
            min_edges = int(input("Enter minimum amount of edges: "))
            max_edges  = int(input("Enter maximum amount of edges: "))

            if point_number < max_edges:
                max_edges = point_number
            graph = []
            for i in range(0, point_number):
                point = Node(i)
                graph.append(point)
            for i in range(0, point_number):
                #if(graph[i].neighbors == max_edges):
                 #   break
                edge_count = random.randint(min_edges, max_edges)
                if min_edges == max_edges:
                    edge_count = min_edges
                for j in range(0, edge_count):
                    add = True
                    while add:
                        edge = random.randint(0, point_number-1)
                        if not graph[i].contains_edge(edge):
                            if not graph[edge].contains_edge(i) and edge is not i:
                                graph[i].neighbors = graph[i].neighbors + 1
                                #graph[edge].neighbors = graph[edge].neighbors + 1
                                graph[i].add_edge(edge)
                                add = False
            print_graph(graph)
            print("END")
        except:
            print("That is not a valid input. Try again")
    elif option=='e':
        user_answ = input("Enter your oriented graph in form n.m n1.m2 eg: 1.2 1.3 3.2 : ")
        try:
            edges = user_answ.strip().split(' ')
            graph = []
            points = edges[0].split('.')
            node=Node(points[0])
            node.add_edge(points[1])
            graph.append(node)
            for i in range(1, len(edges)):
                points = edges[i].split('.')
                node = Node(points[0])
                peak_exists = False
                edge_exists = False
                for j in range(0, len(graph)):
                    if graph[j].head == points[0]:
                        if not graph[j].contains_edge(points[1]):
                            graph[j].add_edge(points[1])
                        peak_exists = True
                    if graph[j].head == points[1]:
                        edge_exists = True
                if not peak_exists:
                    node.add_edge(points[1])
                    graph.append(node)
                if not edge_exists:
                    node = Node(points[1])
                    graph.append(node)
            print_graph(graph)
        except:
            print("Not a valid input. Try again.")
    elif option=='q':
        run = False
    elif option=='f':
        print("Coming soon.")
    elif option=='h':
        print("Welcome")
        print("Graph Generator 3000")
        print("Availabale options:")
        print("For generating random oriented graph enter: g")
        print("For entering your own oriented graph enter: e")
        print('For help enter: h')
        print("For quiting enter: q")
    else:
        print("Not an option try again.")


from endpoints.crud import AuthUser, Token
from flask import Blueprint, make_response, request

auth = Blueprint(
    "authentication",
    __name__,
)

@auth.route("/registration", methods=["POST"])
async def registration():
    user = AuthUser()
    registration_res = await user.create_new_user(request.get_json())
    return make_response(registration_res)

@auth.route("/login", methods=["POST"])
async def login():
    user = AuthUser()
    login_res = await user.login_user(request.get_json())
    return make_response(login_res)

@auth.route("/token/refresh", methods=["POST"])
async def refresh_access_token():
    token = Token()
    new_access_token = await token.update_access_token(request.get_json())
    return make_response(new_access_token)


# !python3
# -*- coding: utf-8 -*-

"""
Create on 2018 08 29 10:29
@author: wuyu
"""

import os
import cv2
import numpy as np
from matplotlib import pyplot as plt

def test_opencv_1():
    img_path = "D:/project/py_test/test_open_cv_image/rose_1.jpg"

    # 彩色图像 cv2.IMREAD_COLOR
    # img = cv2.imread(img_path, cv2.IMREAD_COLOR)

    # 灰度图 cv2.IMREAD_GRAYSCALE
    # img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)

    # 带alpha通道  cv2.IMREAD_UNCHANGED     测试和cv2.IMREAD_COLOR效果相同
    img = cv2.imread(img_path, cv2.IMREAD_UNCHANGED)

    # print(img)

    if img is not None:
        # cv2.WINDOW_NORMAL 可调整图框尺寸   默认: cv2.WINDOW_AUTOSIZE
        cv2.namedWindow('image', cv2.WINDOW_NORMAL)
        cv2.imshow("image", img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    else:
        print("img is None, img_path={}, exists={}.".format(img_path, os.path.exists(img_path)))

def test_2():
    img_path = "D:/project/py_test/test_open_cv_image/rose_1.jpg"
    img = cv2.imread(img_path, 0)
    cv2.imshow('image', img)
    # k = cv2.waitKey(0)
    # 64位机器
    k = cv2.waitKey(0) & 0xff

    # wait for ESC key to exit
    if k == 27:
        cv2.destroyAllWindows()
    # wait for 's' key to save and exit
    elif k == ord('s'):
        cv2.imwrite('D:/project/py_test/test_open_cv_image/save_rose_1.jpg', img)
        cv2.destroyAllWindows()

def test_3():
    img_path = "D:/project/py_test/test_open_cv_image/rose_1.jpg"
    img = cv2.imread(img_path, 0)
    plt.imshow(img, cmap='gray', interpolation='bicubic')
    plt.xticks([]), plt.yticks([])
    plt.show()

def test_4():
    """
    使用 matplotlib 正确显示彩色图片  BGR -> RGB
    """

    img_path = "D:/project/py_test/test_open_cv_image/rose_1.jpg"
    img = cv2.imread(img_path, 1)
    # print(img)
    # b, g, r = cv2.split(img)
    # img2 = cv2.merge([r, g, b])
    img2 = img[:, :, ::-1]
    plt.subplot(121)
    plt.imshow(img)  # expects distorted color
    plt.subplot(122)
    plt.imshow(img2)  # expect true color
    plt.show()

    cv2.imshow('bgr image', img)  # expects true color
    cv2.imshow('rgb image', img2)  # expects distorted color
    cv2.waitKey(0)
    cv2.destroyAllWindows()

def test_video():
    # path = "rtsp://admin:1234qwer@192.168.16.202/h264/ch1/main"
    # path = 0
    path = "output.avi"

    cap = cv2.VideoCapture(path)
    print("cap.isOpened() = ", cap.isOpened())
    if not cap.isOpened():
        """检查摄像头是否成功初始化"""
        cap.open()

    for i in range(18):
        print("cap.get({}) = {}".format(i, cap.get(i)))

    # not use ???
    cap.set(3, 640)
    cap.set(4, 480)
    print("cap.get(3) = {}, cap.get(4) = {}".format(cap.get(3), cap.get(4)))

    while True:
        try:
            ret, frame = cap.read()
        except Exception as e:
            print(str(e))
        if ret:
            cv2.namedWindow('gray Video', cv2.WINDOW_NORMAL)
            cv2.namedWindow('Oto Video', cv2.WINDOW_NORMAL)
            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            cv2.imshow("gray Video", gray)
            cv2.imshow("Oto Video", frame)
        else:
            print("camera catch image error!")
            break
        key = cv2.waitKey(1) & 0xFF
        if key == ord("q"):
            break
    cap.release()
    cv2.destroyAllWindows()

def test_5():
    path = "rtsp://admin:1234qwer@192.168.16.202/h264/ch1/main"
    cap = cv2.VideoCapture(path)

    print(cap.get(3), cap.get(4))

    # Define the codec and create VideoWriter object
    fourcc = cv2.VideoWriter_fourcc(*'XVID')
    out = cv2.VideoWriter('output.avi', fourcc, 20.0, (1920, 1080), True)

    while cap.isOpened():
        ret, frame = cap.read()

        if ret:
            # > 0 : L/R turn    0:Top/down turn    <0:L/R and Top/down turn
            frame = cv2.flip(frame, -1)
            # write the flipped frame
            out.write(frame)
            cv2.imshow('frame', frame)

            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
        else:
            break

    # Release everything if job is finished
    cap.release()
    out.release()
    cv2.destroyAllWindows()

def test_draw():
    img = np.zeros((512, 512, 3), np.uint8)
    cv2.line(img, (0, 0), (511, 511), (255, 0, 0), 5)
    cv2.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)
    cv2.circle(img, (447, 63), 63, (0, 0, 255), -1, cv2.LINE_AA)
    cv2.ellipse(img, (256, 256), (100, 50), 0, 0, 180, (125, 125, 125), -1, cv2.LINE_AA)

    pts = np.array([[10, 5], [20, 30], [70, 20], [50, 10]], np.int32)
    pts = pts.reshape((-1, 1, 2))
    cv2.polylines(img, [pts], True, (0, 0, 255), 3, lineType=cv2.LINE_AA)

    font = cv2.FONT_HERSHEY_SIMPLEX
    cv2.putText(img, 'OpenCV', (10, 450), font, 4, (255, 255, 255), 2, lineType=cv2.LINE_AA, bottomLeftOrigin=False)

    winname = "test_draw"
    cv2.namedWindow(winname, cv2.WINDOW_NORMAL)
    cv2.imshow(winname, img)

    k = cv2.waitKey(0) & 0xff

    if ord('q') == k:
        cv2.destroyAllWindows()

def test_mouse():
    # events = [i for i in dir(cv2) if 'EVENT' in i]
    # print(events)
    """['EVENT_FLAG_ALTKEY', 'EVENT_FLAG_CTRLKEY', 'EVENT_FLAG_LBUTTON', 'EVENT_FLAG_MBUTTON', 'EVENT_FLAG_RBUTTON',
     'EVENT_FLAG_SHIFTKEY', 'EVENT_LBUTTONDBLCLK', 'EVENT_LBUTTONDOWN', 'EVENT_LBUTTONUP', 'EVENT_MBUTTONDBLCLK',
     'EVENT_MBUTTONDOWN', 'EVENT_MBUTTONUP', 'EVENT_MOUSEHWHEEL', 'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL',
     'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']"""

    drawing = False
    mode = True
    ix, iy = -1, -1

    def draw_circle(event, x, y, flags, param):
        nonlocal drawing, mode, ix, iy

        if event == cv2.EVENT_LBUTTONDBLCLK:
            cv2.circle(img, (x, y), 20, (255, 0, 0), 3)

        if event == cv2.EVENT_LBUTTONDOWN:
            drawing = True
            ix, iy = x, y
        # 当鼠标左键按下并移动是绘制图形。 event可以查看移动， flag查看是否按下
        elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
            if drawing is True:
                if mode is True:
                    cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
                else:
                    # 绘制圆圈，小圆点连在一起就成了线， 3 代表了笔画的粗细
                    cv2.circle(img, (x, y), 3, (0, 0, 255), -1)
                    # 下面注释掉的代码是起始点为圆心，起点到终点为半径的
                    #  r=int(np.sqrt((x-ix)**2+(y-iy)**2))
                    #  cv2.circle(img,(x,y),r,(0,0,255),-1)
        # 当鼠标松开停止绘画。
        elif event == cv2.EVENT_LBUTTONUP:
            drawing = False
            mode = not mode
            # if mode==True:
            #     cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            # else:
            #     cv2.circle(img,(x,y),5,(0,0,255),-1)

    # 创建图像与窗口并将窗口与回调函数绑定
    img = np.zeros((512, 512, 3), np.uint8)
    cv2.namedWindow('image')
    cv2.setMouseCallback('image', draw_circle)

    while True:
        cv2.imshow('image', img)

        if cv2.waitKey(20) & 0xFF == ord('q'):
            break

    cv2.destroyAllWindows()

def test_progressbar():
    def nothing(x):
        pass

    # 创建一副黑色图像
    img = np.zeros((300, 512, 3), np.uint8)
    cv2.namedWindow('image')
    cv2.createTrackbar('R', 'image', 0, 255, nothing)
    cv2.createTrackbar('G', 'image', 0, 255, nothing)
    cv2.createTrackbar('B', 'image', 0, 255, nothing)

    switch = "0:OFF\n1:ON"
    cv2.createTrackbar(switch, 'image', 0, 1, nothing)

    while True:
        cv2.imshow('image', img)
        k = cv2.waitKey(1) & 0xFF

        if k == 27:
            break

        r = cv2.getTrackbarPos('R', 'image')
        g = cv2.getTrackbarPos('G', 'image')
        b = cv2.getTrackbarPos('B', 'image')
        s = cv2.getTrackbarPos(switch, 'image')

        if s == 0:
            img[:] = 0
        else:
            img[:] = [b, g, r]

    cv2.destroyAllWindows()

def test_6():
    img = cv2.imread("D:/project/py_test/test_open_cv_image/rose_1.jpg")
    bgr_100_100 = img[100, 100]
    b_100_100 = img[100, 100, 0]
    # print(img, type(img))
    print(bgr_100_100)     # (100, 100)像素点的bgr值
    print(b_100_100)       # (100, 100)像素点的blue值

    # 修改像素点的值
    # img[100, 100] = [255, 255, 255]
    # print(">>>", img[100, 100])
    print(img.item(100, 100, 0))
    img.itemset((100, 100, 0), 100)
    print(img.item(100, 100, 0))

    print("(高度，宽度，通道数) = ", img.shape)
    print("像素数：", img.size, 768*1366*3)
    print("数据类型: ", img.dtype)
    log = img[50:140, 1120:1300]
    cv2.imshow('log', log)

    img[300:390, 1120:1300] = log
    cv2.imshow('image', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # cv2.split()是一个比较耗时的操作，尽量不要用
    # b, g , r = cv2.split(img)
    b, g, r = img[:, :, 0], img[:, :, 1], img[:, :, 2]
    print(b, g, r)

def test_border():
    """给图片添加边框"""

    BLUE = [0, 0, 255]
    img = cv2.imread('../test_open_cv_image/rose_3.jpg')
    img2 = img[:, :, ::-1]

    replicate = cv2.copyMakeBorder(img2, 50, 50, 50, 50, cv2.BORDER_REPLICATE)
    reflect = cv2.copyMakeBorder(img2, 50, 50, 50, 50, cv2.BORDER_REFLECT)
    reflect101 = cv2.copyMakeBorder(img2, 50, 50, 50, 50, cv2.BORDER_REFLECT_101)
    wrap = cv2.copyMakeBorder(img2, 50, 50, 50, 50, cv2.BORDER_WRAP)
    constant = cv2.copyMakeBorder(img2, 50, 50, 50, 50, cv2.BORDER_CONSTANT, value=BLUE)
    plt.subplot(231), plt.imshow(img2, 'gray'), plt.title('ORIGINAL')
    plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
    plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
    plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
    plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
    plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
    plt.show()

def test_cv_add():
    """openCvd的加法是一种饱和操作，Numpy的加法是一种模操作"""
    x = np.uint8([250])       # 250+10 = 260 => 255         [[255]]
    y = np.uint8([10])        # 250+10 = 260 % 256 = 4      [4]
    print("cv2.add(x, y) = {}, x + y = {}".format(cv2.add(x, y), x + y))

    img1 = cv2.imread('../test_open_cv_image/rose_1920_1080_1.jpg')
    img2 = cv2.imread('../test_open_cv_image/rose_1920_1080_2.jpg')

    # 图片大小、类型必须一致
    dst = cv2.addWeighted(img1, 0.7, img2, 0.3, 0)
    cv2.imshow('dst', dst)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

if __name__ == "__main__":
    # test_opencv_1()
    # test_2()
    # test_3()
    # test_4()
    # test_video()
    # test_5()
    # test_draw()
    # test_mouse()
    # test_progressbar()
    # test_6()
    # test_border()
    test_cv_add()


import sys

target=list(map(str,sys.stdin.readline().strip("\n"))) # abcd 커서가 존재할 수 있는 위치는 5곳
target2=[]

n=int(sys.stdin.readline())

for i in range(n):
    command=list(map(str,sys.stdin.readline().strip("\n")))

    if command[0]=='L': # 왼쪽으로 1칸 이동
        if len(target)==0:
            continue
        target2.append(target.pop()) # target2에 target의 마지막 원소 삽입

    elif command[0]=='D': # 오른쪽으로 1칸 이동
        if len(target2)==0:
            continue
        target.append(target2.pop()) # target에 target2의 마지막 원소 삽입

    elif command[0]=='B': # 커서 왼쪽의 문자 삭제
        if len(target)==0:
            continue
        target.pop()

    else: # 삽입
        target.append(command[2])

target.extend(reversed(target2))

print(''.join(target))

#----------------------------------------------------------------------------------------

from collections import deque

dequeue=deque(input())
queue=deque([])

n=int(input())

for i in range(n):
    command=list(input().split())

    if command[0]=='P': # 추가
        dequeue.append(command[1])

    elif command[0]=='B': # 삭제
        if dequeue:
            dequeue.pop()

    elif command[0]=='L': # << 이동
        if dequeue:
            queue.appendleft(dequeue.pop())

    elif command[0]=='D':
        if queue:
            dequeue.append(queue.popleft())

result=dequeue+queue

print(''.join(result))


"""Example of Cross Validation and Grid Search for Model Hyperparameters"""
import pyspark
import numpy as np
import argparse

from pyspark.ml.regression import RandomForestRegressor
from pyspark.ml.evaluation import RegressionEvaluator
from pyspark.ml.tuning import ParamGridBuilder, TrainValidationSplit, CrossValidator

from pyspark.sql import SparkSession
from pyspark.sql.functions import udf
from pyspark.sql.types import *

#initialize spark session
spark = SparkSession\
        .builder\
        .appName("Test")\
        .config('spark.sql.warehouse.dir', 'file:///C:/')\
        .getOrCreate()

sc = spark.sparkContext

def main():
    parser = argparse.ArgumentParser(description='Pyspark Training')
    parser.add_argument('--data', type=str,
        default="../../../data/sample_linear_regression_data.txt",
        help='Data location.')
    parser.add_argument('--cross_val', type=bool, default=False, help='whether to use cross_validation')
    args = parser.parse_args()

    data = spark.read.format("libsvm").load(args.data)

    # Split the data into training and test sets (30% held out for testing)
    (train, test) = data.randomSplit([0.7, 0.3])

    # Train a RandomForest model.
    rf = RandomForestRegressor()

    # Create a grid of hyperparameters. Each combination will be tested.
    paramGrid = ParamGridBuilder()\
        .addGrid(rf.numTrees, [2, 25]) \
        .addGrid(rf.maxDepth, [2, 6])\
        .addGrid(rf.maxBins, [15, 30])\
        .build()

    if args.cross_val:
        # Run five-fold cross validation to find best hyperparamters.
        crossval = CrossValidator(estimator=rf,
                          estimatorParamMaps=paramGrid,
                          evaluator=RegressionEvaluator(labelCol="label", predictionCol="prediction", metricName="rmse"),
                          numFolds=5)  # use 3+ folds in practice

        model = crossval.fit(train)
    else:
        # Grid search for best hyperparameters with a single validation set.
        tvs = TrainValidationSplit(estimator=rf,
                                   estimatorParamMaps=paramGrid,
                                   evaluator=RegressionEvaluator(labelCol="label", predictionCol="prediction", metricName="rmse"),
                                   # 80% of the data will be used for training, 20% for validation.
                                   trainRatio=0.8)

        # Run TrainValidationSplit, and choose the best set of parameters.
        model = tvs.fit(train)

    # Make predictions.
    predictions = model.transform(test)

    # Select (prediction, true label) and compute test error
    evaluator = RegressionEvaluator(
        labelCol="label", predictionCol="prediction", metricName="rmse"
    )

    rmse = evaluator.evaluate(predictions)
    print("Root Mean Squared Error (RMSE) on test data = %g" % rmse)

if __name__=="__main__":
    main()


import os

from app.utils.env_utils import load_environment

ENVIRONMENT = load_environment()

def get(key: str) -> str:
    value = os.getenv(key)

    if value is None:
        raise Exception(f"{key} environment variable is undefined")

    return value

# Root of the repo
ROOT = os.path.dirname(os.path.dirname(__file__))

DB_FILE = os.path.join(ROOT, get("DB_FILE"))


#Step 4

import random

#Life stages of the hangman
stages = ['''
  +---+
  |   |
  O   |
 /|\  |
 / \  |
      |
=========
''', '''
  +---+
  |   |
  O   |
 /|\  |
 /    |
      |
=========
''', '''
  +---+
  |   |
  O   |
 /|\  |
      |
      |
=========
''', '''
  +---+
  |   |
  O   |
 /|   |
      |
      |
=========''', '''
  +---+
  |   |
  O   |
  |   |
      |
      |
=========
''', '''
  +---+
  |   |
  O   |
      |
      |
      |
=========
''', '''
  +---+
  |   |
      |
      |
      |
      |
=========
''']

endgame = False
word_list = ["ardvark", "baboon", "camel"]
chosen_word = random.choice(word_list)
word_length = len(chosen_word)

#TODO-1: - Create a variable called 'lives' to keep track of the number of lives left.
#Set 'lives' to equal 6.
lives = 6

#Testing code
print(f'Pssst, the solution is {chosen_word}.')

#Create blanks
display = []
for _ in range(word_length):
    display += "_"

while not endgame:
    guess = input("Guess a letter: ").lower()

    #Check guessed letter
    for position in range(word_length):
        letter = chosen_word[position]
        # print(f"Current position: {position}\n Current letter: {letter}\n Guessed letter: {guess}")
        if letter == guess:
            display[position] = letter

    #TODO-2: - If guess is not a letter in the chosen_word,
    #Then reduce 'lives' by 1.
    #If lives goes down to 0 then the game should stop and it should print "You lose."
    if guess not in chosen_word:
        lives -= 1
        print("The letter is not in chosen word, you lose a life!")
        if lives == 0:
            endgame = True
            print("You lose")

    #Joins all the elements in the list and turn it into a String.
    print(f"{' '.join(display)}")

    #Check if user has got all letters.
    if "_" not in display:
        endgame = True
        print("You win.")

    #TODO-3: - print the ASCII art from 'stages' that corresponds to the current number of 'lives' the user has remaining.
    print(stages[lives])

    #Test it here: https://replit.com/@terrykirungo/4-hangman#main.py


from tkinter import *

def Login(windows,width, height):
    page_login = Canvas(windows,height=height, width=width)

    # titre de la page
    Label(page_login,text="Login",font=('arial',20,'bold')).place(x=50,y=50)

    page_login.place(x=0,y=0)


# Find different ways to partition N into a sum of at least 2 positive integers

# Return the number of ways to partition N as the sum of
#   a1 + a2 + ... + ak
# where a1 >= a2 >= ... >= ak >= 1
#
# Methodology: Use dynamic programming
#   1) Define f(n, m, k) = the number of ways to partition n into k parts when
#                               the largest summand is m <= n.
#   2) Recurrence relation:
#           f(n, m, k) = sum{ f(n - i, i, k - 1) } for i = m downto 1
#   3) Base cases
#           f(0, m, 0) = 1
#           f(0, m, k) = 0 for k >= 1
#           f(n, m, 0) = 0 for n >= 1
#
# Tim complexity: O(N^3 * K)

numPartition = []

def countPartition(N):
    numWay = 0

    initializeMemoTable(N, N)
    for numPartition in range(2, N + 1):
        numWay += partitionFixPart(N, N, numPartition)

    return numWay

def initializeMemoTable(N, K):
    global numPartition
    numPartition = [[[-1] * (K + 1) for i in range(N + 1)] for j in range(N + 1)]

def partitionFixPart(N, M, K):
    global numPartition

    if N == 0 and K == 0:
        return 1
    if N == 0 and K >= 1:
        return 0
    if N > 0 and K == 0:
        return 0

    if numPartition[N][M][K] != -1:
        return numPartition[N][M][K]

    numWay = 0
    for i in range(M, 0, -1):
        numWay += partitionFixPart(N - i, min(i, N - i), K - 1)
    numPartition[N][M][K] = numWay

    return numWay


class BridgeManager:
    def __init__(self, bridge_length, bridge_weight_limit):
        self.bridge_length = bridge_length
        self.bridge_weight_limit = bridge_weight_limit
        self.wait_list = []
        self.trucks_on_bridge = [0] * bridge_length
        self.current_bridge_weight = 0
        self.working_time = 0

    def set_wait_list(self, waiting_trucks):
        self.wait_list = waiting_trucks

    def begin_entrance(self):
        while True:  # 차량 출입 시작
            self.current_bridge_weight -= self.trucks_on_bridge.pop(0)

            if len(self.wait_list) > 0:
                if self.current_bridge_weight + self.wait_list[0] > self.bridge_weight_limit:
                    # 대기 중인 첫 번째 트럭이 들어오면 다리의 최대 하중을 넘어서는 경우
                    self.trucks_on_bridge.append(0)
                else:
                    # 대기 중인 첫 번째 트력이 들어와도 다리의 최대 하중을 넘지 않는 경우
                    self.current_bridge_weight += self.wait_list[0]
                    self.trucks_on_bridge.append(self.wait_list.pop(0))
            else:
                self.trucks_on_bridge.append(0)

            self.working_time += 1

            if self.current_bridge_weight == 0:  # 모든 트럭이 다리를 건넜을 경우 종료
                break

in_trucks_count, in_bridge_length, in_bridge_weight_limit = map(int, input().split(' '))
in_waiting_trucks = list(map(int, input().split(' ')))

bridge_manager = BridgeManager(in_bridge_length, in_bridge_weight_limit)
bridge_manager.set_wait_list(in_waiting_trucks)
bridge_manager.begin_entrance()

print(bridge_manager.working_time)


import numpy as np

from sklearn.metrics import accuracy_score, f1_score
from sklearn.model_selection import train_test_split
from load_datasets import load_dataset, import_amazon_dataset
from classic_methods.clustering.clust_classifier import get_community_based_pred
from classic_methods.node_features.feat_classifier import (
    FeatureExtractor,
    feature_prediction,
)
from classic_methods.node2vec.node2vec import (
    get_node2vec_embeddings,
    node2vec_prediction,
)

if __name__ == "__main__":
    # Uncomment one of the following line in order to load to load either Pubmed, Citeseer or Cora or the Amazon dataset using BERT embedding or TFI-IDF.
    g = load_dataset("Citeseer", to_netx=True)  # "Pubmed", "Cora", "Citeseer"
    # g = import_amazon_dataset('amazon_dataset/edges.csv', 'amazon_dataset/BERT_embeddings2.csv', embedding='BERT')
    # g = import_amazon_dataset('amazon_dataset/edges.csv', 'amazon_dataset/TF_IDF_embeddings.csv', embedding='TF_IDF')

    node_list = list(g.nodes)
    label_list = [g.nodes[i]["y"] for i in range(len(node_list))]

    extractor = FeatureExtractor()
    features = extractor.global_feature_extract(g, node_list)
    train_features, test_features, train_labels, test_labels = train_test_split(
        features, label_list, shuffle=False
    )
    comm_pred = feature_prediction(train_features, train_labels, test_features)
    print(
        "\n\nglobal features based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\nglobal features based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    del features
    del train_features
    del test_features
    del train_labels
    del test_labels

    features = extractor.node_feature_extract(g, node_list)
    features = np.array(features, dtype=np.float16)
    train_features, test_features, train_labels, test_labels = train_test_split(
        features, label_list, shuffle=False
    )
    comm_pred = feature_prediction(train_features, train_labels, test_features)
    print(
        "\n\nnode features based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\nnode features based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    features = extractor.full_feature_extract(g, node_list)
    train_features, test_features, train_labels, test_labels = train_test_split(
        features, label_list, shuffle=False
    )
    comm_pred = feature_prediction(train_features, train_labels, test_features)
    print(
        "\n\nnode and global features based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\nnode and global features based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    train_nodes, test_nodes, train_labels, test_labels = train_test_split(
        node_list, label_list, shuffle=False
    )
    comm_pred = get_community_based_pred(g, train_nodes, train_labels, test_nodes)
    print(
        "\n\ncommunity based classifier accuracy =",
        accuracy_score(test_labels, comm_pred),
        "\n\n",
    )
    print(
        "\n\ncommunity based classifier F1-score =",
        f1_score(test_labels, comm_pred, average="weighted"),
        "\n\n",
    )

    embeddings = get_node2vec_embeddings(g)
    train_embeddings, test_embeddings, train_labels, test_labels = train_test_split(
        embeddings, label_list, shuffle=False
    )
    node2pred = node2vec_prediction(train_embeddings, train_labels, test_embeddings)
    print(
        "\n\nnode2vec embeddings based classifier accuracy =",
        accuracy_score(test_labels, node2pred),
        "\n\n",
    )
    print(
        "\n\nnode2vec embeddings based classifier F1-score =",
        f1_score(test_labels, node2pred, average="weighted"),
        "\n\n",
    )


import numpy as np
import cv2

# multiple cascades: https://github.com/Itseez/opencv/tree/master/data/haarcascades

face_cascade = cv2.CascadeClassifier('C:/Users/My Pc/AppData/Local/Programs/Python/Python37-32/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')

img = cv2.imread('faces2.png')
scale_factor = 1.3
while 1:
    faces = face_cascade.detectMultiScale(img, scale_factor  , 5)

    for (x, y, w, h) in faces:
        cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)

    print("number of faces found {} " .format(len(faces)))

    cv2.imshow('img', img)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cv2.destroyAllWindows()


n, k = map(int, input().split())
d = [[[[False] * 436 for _ in range(31)] for _ in range(31)] for _ in range(31)]
answer = ""

def go(i, a, b, p):
    if i == n:
        return p == k

    if d[i][a][b][p]:
        return False

    d[i][a][b][p] = True
    global answer
    temp = answer

    answer = temp + "A"
    if go(i + 1, a + 1, b, p):
        return True

    answer = temp + "B"
    if go(i + 1, a, b + 1, p + a):
        return True

    answer = temp + "C"
    if go(i + 1, a, b, p + a + b):
        return True

    return False

if go(0, 0, 0, 0):
    print(answer)
else:
    print(-1)


class Solution:
    def findMedianSortedArrays(self, nums1: List[int], nums2: List[int]) -> float:
        if len(nums1) > len(nums2):
            return self.findMedianSortedArrays(nums2, nums1)

        m, n = len(nums1), len(nums2)
        left, right = 0, m
        halfLen = (m+n+1)//2
        while left<=right:
            i=(left+right)//2
            j=halfLen-i
            if (i<right) and (nums1[i] < nums2[j-1]):
                left=i+1
            elif (i>left) and (nums1[i-1] > nums2[j]):
                right=i-1
            else:
                maxLeft = 0
                if i==0:
                    maxLeft=nums2[j-1]
                elif j==0:
                    maxLeft=nums1[i-1]
                else:
                    maxLeft=max(nums1[i-1],nums2[j-1])
                if (m+n)%2 == 1:
                    return maxLeft

                minRight = 0
                if i==m:
                    minRight=nums2[j]
                elif j==n:
                    minRight=nums1[i]
                else:
                    minRight=min(nums1[i],nums2[j])

                return (maxLeft+minRight)/2

        return 0.0

LeetCode/4. Median of Two Sorted Arrays/Solution.py


import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats

#Read provided data as dataframe
data=pd.read_csv("srajend2.csv",header=-1)
#print(data.head(3))
#print(data[5][0])

for i in range(data.shape[1]-1):
    mean = np.mean(data[i])
    print("mean X"+str(i)+": "+ str(mean))

    var = np.var(data[i])
    print("Variance of X"+str(i)+": "+ str(var))

    plt.figure()
    plt.hist(data[i], bins='auto')
    plt.title("Histogram for X"+str(i))
    plt.show()

    plt.figure(2)
    plt.boxplot(data[i])
    plt.title("BoxPlot for X" + str(i))
    plt.show()
correlation=data.corr()
print("Correlation Matrix: \n", correlation)

#Remove outliers
data=data[(np.abs(stats.zscore(data)) < 2.5).all(axis=1)]
#Box plot after removing outliers
for i in range(0,data.shape[1]-1,1):
    plt.figure()
    plt.boxplot(data[i])
    plt.title("BoxPlot for X" + str(i))
    plt.show()

correlation=data.corr()
print("Correlation Matrix after removing outliers: \n", correlation)


"""Decorator utils."""
# Standard Python Libraries
from functools import wraps
import hashlib
from http import HTTPStatus

# Third-Party Libraries
import cognitojwt
from flask import abort, g, request

# cisagov Libraries
from api.config import (
    AWS_REGION,
    COGNITO_CLIENT_ID,
    COGNITO_DEFAULT_ADMIN,
    COGNTIO_ENABLED,
    COGNTIO_USER_POOL_ID,
    logger,
)
from api.manager import DomainManager, UserManager
from utils.users import user_can_access_domain

domain_manager = DomainManager()
user_manager = UserManager()

class RequestAuth:
    """Authorization class for requests."""

    def __init__(self, request):
        """Initialize class with cognito settings and associated request."""
        self.request = request
        self.username = ""
        self.groups = []

    def validate(self):
        """Validate request."""
        if self.check_api_key(request):
            g.is_admin = True
            return True
        if not COGNTIO_ENABLED:
            g.is_admin = True
            return True
        if self.check_cognito_jwt(request):
            return True

        return False

    def check_api_key(self, request):
        """Check if API Key is valid."""
        if "api_key" in request.headers:
            hash_val = hashlib.sha256(
                str.encode(request.headers.get("api_key"))
            ).hexdigest()
            user = user_manager.all(params={"HashedAPI": hash_val})
            if not user:
                return False
            if len(user) > 1:
                logger.info(f"Hash Key collision - {hash_val}")
                return False

            matched_user = user[0]
            self.username = matched_user["Username"]
            return True
        return False

    def get_authorization_header(self, request):
        """Get auth header."""
        auth_header = request.headers.get("Authorization", "")
        return auth_header

    def get_jwt_token(self, request):
        """Get JWT Token."""
        auth = self.get_authorization_header(request).split()
        if not auth or str(auth[0].lower()) != "bearer":
            return None
        if len(auth) != 2:
            return None
        return auth[1]

    def check_cognito_jwt(self, request):
        """Check if valid cognito jwt."""
        jwt = self.get_jwt_token(request)
        if not jwt:
            return False
        try:
            resp = cognitojwt.decode(
                jwt,
                AWS_REGION,
                COGNTIO_USER_POOL_ID,
                app_client_id=COGNITO_CLIENT_ID,
            )
            self.username = resp["cognito:username"]
            self.groups = resp.get("cognito:groups", [])
            return self.username
        except Exception as e:
            if str(e) != "Token is expired":
                logger.exception(e)
            else:
                print("Token is expired")
            return False

    def check_admin_status(self):
        """Check if user is in the admin cognito group."""
        if not COGNTIO_ENABLED:
            return True
        if COGNITO_DEFAULT_ADMIN:
            return True
        if "admin" in self.groups:
            return True
        return False

def auth_required(view):
    """Authorize requests."""

    @wraps(view)
    def decorated(*args, **kwargs):
        """Decorate."""
        auth = RequestAuth(request)
        if auth.validate():
            g.username = auth.username
            if auth.check_admin_status():
                g.is_admin = True
            else:
                g.is_admin = False
            return view(*args, **kwargs)
        else:
            abort(HTTPStatus.UNAUTHORIZED.value)

    return decorated

def auth_admin_required(view):
    """Authorize requests."""

    @wraps(view)
    def decorated(*args, **kwargs):
        """Decorate."""
        if not g.is_admin:
            abort(HTTPStatus.FORBIDDEN.value)
        return view(*args, **kwargs)

    return decorated

def can_access_domain(view):
    """Check if user can access domain."""

    @wraps(view)
    def decorated(*args, **kwargs):
        """Decorate."""
        if kwargs.get("domain_id"):
            domain = domain_manager.get(
                document_id=kwargs.get("domain_id"), fields=["application_id"]
            )
            if user_can_access_domain(domain):
                return view(*args, **kwargs)
            else:
                return (
                    "User does not have permission to domain.",
                    HTTPStatus.BAD_REQUEST.value,
                )
        else:
            return (
                "URL Path configured improperly.",
                HTTPStatus.INTERNAL_SERVER_ERROR.value,
            )

    return decorated

def can_access_user(view):
    """Check if user can access user."""

    @wraps(view)
    def decorated(*args, **kwargs):
        """Decorate."""
        if kwargs.get("username"):
            if g.is_admin or g.username == kwargs.get("username"):
                return view(*args, **kwargs)
            else:
                return (
                    "User does not have permission to user.",
                    HTTPStatus.BAD_REQUEST.value,
                )
        else:
            return (
                "URL Path configured improperly.",
                HTTPStatus.INTERNAL_SERVER_ERROR.value,
            )

    return decorated