import copy
import io
import os
import zipfile

import obspy
import numpy as np
import pytest
from .tornado_testing_fixtures import *  # NOQA
from .tornado_testing_fixtures import _assemble_url

import instaseis

# Conditionally import mock either from the stdlib or as a separate library.
import sys

if sys.version_info[0] == 2:  # pragma: no cover
    import mock
else:  # pragma: no cover
    import unittest.mock as mock

DATA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
USGS_PARAM_FILE_1 = os.path.join(DATA, "nepal.param")
USGS_PARAM_FILE_2 = os.path.join(DATA, "chile.param")
USGS_PARAM_FILE_EMPTY = os.path.join(DATA, "empty.param")
USGS_PARAM_FILE_DEEP = os.path.join(DATA, "deep.param")
USGS_PARAM_FILE_AIR = os.path.join(DATA, "airquakes.param")
USGS_PARAM_FILE_LONG = os.path.join(DATA, "long_source.param")

def fetch_sync(client, url, **kwargs):
    """
    Helper function to call an async test client in a sync test case.
    """

    async def f():
        try:
            response = await client.fetch(
                f"http://localhost:{client.port}{url}", **kwargs
            )
        except Exception as e:
            response = e.response
        return response

    return client.io_loop.run_sync(f)

def _parse_finite_source(filename):
    """
    Helper function parsing a finite source exactly how it is parsed in the
    finite source server route.
    """
    fs = instaseis.FiniteSource.from_usgs_param_file(
        filename, npts=10000, dt=0.1, trise_min=1.0
    )

    # All test databases are the same.
    dominant_period = 100.0
    dt = 24.724845445855724
    npts = 73

    # Things are now on purpose a bit different than in the actual
    # implementation to actually test something....
    shift = fs.time_shift
    for src in fs.pointsources:
        src.sliprate = np.concatenate(
            [np.zeros(10), src.sliprate, np.zeros(10)]
        )
        src.time_shift += 10 * dt - shift

    fs.lp_sliprate(freq=1.0 / dominant_period, zerophase=True)
    fs.resample_sliprate(dt=dt, nsamp=npts + 20)

    return fs

def test_triggering_random_error_during_parsing(reciprocal_clients):
    """
    Tests triggering a random error during the USGS param file parsing.
    """
    client = reciprocal_clients

    with io.open(__file__) as fh:
        body = fh.read()

    # default parameters
    params = {"receiverlongitude": 11, "receiverlatitude": 22}

    with mock.patch(
        "instaseis.source.FiniteSource" ".from_usgs_param_file"
    ) as p:
        p.side_effect = ValueError("random crash")
        request = fetch_sync(
            client,
            _assemble_url("finite_source", **params),
            method="POST",
            body=body,
        )

    assert request.code == 400
    assert request.reason == (
        "Could not parse the body contents. " "Incorrect USGS param file?"
    )

def test_sending_non_usgs_file(reciprocal_clients):
    """
    Tests error if a non-USGS file is sent.
    """
    client = reciprocal_clients

    with io.open(__file__) as fh:
        body = fh.read()

    # default parameters
    params = {"receiverlongitude": 11, "receiverlatitude": 22}
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The body contents could not be parsed as an "
        "USGS param file due to: "
        "Not a valid USGS param file."
    )

@pytest.mark.parametrize("usgs_param", [USGS_PARAM_FILE_1, USGS_PARAM_FILE_2])
def test_finite_source_retrieval(reciprocal_clients, usgs_param):
    """
    Tests if the finite sources requested from the server are identical to
    the one requested with the local instaseis client with some required
    tweaks.
    """
    client = reciprocal_clients

    db = instaseis.open_db(client.filepath)

    basic_parameters = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "receiverdepthinmeters": 0,
        "format": "miniseed",
    }

    with io.open(usgs_param, "rb") as fh:
        body = fh.read()

    # default parameters
    params = copy.deepcopy(basic_parameters)
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_server = obspy.read(request.buffer)
    for tr in st_server:
        assert tr.stats._format == "MSEED"

    # Parse the finite source.
    fs = _parse_finite_source(usgs_param)
    rec = instaseis.Receiver(
        latitude=22, longitude=11, network="XX", station="SYN", location="SE"
    )

    st_db = db.get_seismograms_finite_source(sources=fs, receiver=rec)
    # The origin time is the time of the first sample in the route.
    for tr in st_db:
        # Cut away the first ten samples as they have been previously added.
        tr.data = tr.data[10:]
        tr.stats.starttime = obspy.UTCDateTime(1900, 1, 1)

    for tr_db, tr_server in zip(st_db, st_server):
        # Sample spacing is very similar but not equal due to floating point
        # accuracy.
        np.testing.assert_allclose(tr_server.stats.delta, tr_db.stats.delta)
        tr_server.stats.delta = tr_db.stats.delta
        del tr_server.stats._format
        del tr_server.stats.mseed

        assert tr_db.stats == tr_server.stats
        np.testing.assert_allclose(tr_db.data, tr_server.data)

    # Once again but this time request a SAC file.
    params = copy.deepcopy(basic_parameters)
    params["format"] = "saczip"
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_server = obspy.Stream()
    zip_obj = zipfile.ZipFile(request.buffer)
    for name in zip_obj.namelist():
        st_server += obspy.read(io.BytesIO(zip_obj.read(name)))
    for tr in st_server:
        assert tr.stats._format == "SAC"

    for tr_db, tr_server in zip(st_db, st_server):
        # Sample spacing is very similar but not equal due to floating point
        # accuracy.
        np.testing.assert_allclose(tr_server.stats.delta, tr_db.stats.delta)
        tr_server.stats.delta = tr_db.stats.delta
        del tr_server.stats._format
        del tr_server.stats.sac

        assert tr_db.stats == tr_server.stats
        np.testing.assert_allclose(tr_db.data, tr_server.data)

    # One with a label.
    params = copy.deepcopy(basic_parameters)
    params["label"] = "random_things"
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200

    cd = request.headers["Content-Disposition"]
    assert cd.startswith("attachment; filename=random_things_")
    assert cd.endswith(".mseed")

    # One simulating a crash in the underlying function.
    params = copy.deepcopy(basic_parameters)

    with mock.patch(
        "instaseis.database_interfaces.base_instaseis_db"
        ".BaseInstaseisDB.get_seismograms_finite_source"
    ) as p:
        p.side_effect = ValueError("random crash")
        request = fetch_sync(
            client,
            _assemble_url("finite_source", **params),
            method="POST",
            body=body,
        )

    assert request.code == 400
    assert request.reason == (
        "Could not extract finite source seismograms. "
        "Make sure, the parameters are valid, and the "
        "depth settings are correct."
    )

    # Simulating a logic error that should not be able to happen.
    params = copy.deepcopy(basic_parameters)
    with mock.patch(
        "instaseis.database_interfaces.base_instaseis_db"
        ".BaseInstaseisDB.get_seismograms_finite_source"
    ) as p:
        # Longer than the database returned stream thus the endtime is out
        # of bounds.
        st = obspy.read()

        p.return_value = st
        request = fetch_sync(
            client,
            _assemble_url("finite_source", **params),
            method="POST",
            body=body,
        )

    assert request.code == 500
    assert request.reason.startswith(
        "Endtime larger than the extracted " "endtime"
    )

    # One more with resampling parameters and different units.
    params = copy.deepcopy(basic_parameters)
    # We must have a sampling rate that cleanly fits in the existing one,
    # otherwise we cannot fake the cutting.
    dt_new = 24.724845445855724 / 10
    params["dt"] = dt_new
    params["kernelwidth"] = 2
    params["units"] = "acceleration"

    st_db = db.get_seismograms_finite_source(
        sources=fs, receiver=rec, dt=dt_new, kernelwidth=2, kind="acceleration"
    )
    # The origin time is the time of the first sample in the route.
    for tr in st_db:
        # Cut away the first ten samples as they have been previously added.
        tr.data = tr.data[100:]
        tr.stats.starttime = obspy.UTCDateTime(1900, 1, 1)

    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_server = obspy.read(request.buffer)

    # Cut some parts in the middle to avoid any potential boundary effects.
    st_db.trim(
        obspy.UTCDateTime(1900, 1, 1, 0, 4),
        obspy.UTCDateTime(1900, 1, 1, 0, 14),
    )
    st_server.trim(
        obspy.UTCDateTime(1900, 1, 1, 0, 4),
        obspy.UTCDateTime(1900, 1, 1, 0, 14),
    )

    for tr_db, tr_server in zip(st_db, st_server):
        # Sample spacing and times are very similar but not identical due to
        # floating point inaccuracies in the arithmetics.
        np.testing.assert_allclose(tr_server.stats.delta, tr_db.stats.delta)
        np.testing.assert_allclose(
            tr_server.stats.starttime.timestamp,
            tr_db.stats.starttime.timestamp,
        )
        tr_server.stats.delta = tr_db.stats.delta
        tr_server.stats.starttime = tr_db.stats.starttime
        del tr_server.stats._format
        del tr_server.stats.mseed
        del tr_server.stats.processing
        del tr_db.stats.processing

        np.testing.assert_allclose(tr_server.stats.delta, tr_db.stats.delta)

        assert tr_db.stats == tr_server.stats
        np.testing.assert_allclose(
            tr_db.data, tr_server.data, rtol=1e-7, atol=tr_db.data.ptp() * 1e-7
        )

    # Testing network and station code parameters.
    # Default values.
    params = copy.deepcopy(basic_parameters)
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_server = obspy.read(request.buffer)
    for tr in st_server:
        assert tr.stats.network == "XX"
        assert tr.stats.station == "SYN"
        assert tr.stats.location == "SE"

    # Setting all three.
    params = copy.deepcopy(basic_parameters)
    params["networkcode"] = "AA"
    params["stationcode"] = "BB"
    params["locationcode"] = "CC"
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_server = obspy.read(request.buffer)
    for tr in st_server:
        assert tr.stats.network == "AA"
        assert tr.stats.station == "BB"
        assert tr.stats.location == "CC"

    # Setting only the location code.
    params = copy.deepcopy(basic_parameters)
    params["locationcode"] = "AA"
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_server = obspy.read(request.buffer)
    for tr in st_server:
        assert tr.stats.network == "XX"
        assert tr.stats.station == "SYN"
        assert tr.stats.location == "AA"

    # Test the scale parameter.
    params = copy.deepcopy(basic_parameters)
    params["scale"] = 33.33
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_server = obspy.read(request.buffer)
    for tr in st_server:
        assert tr.stats._format == "MSEED"

    # Parse the finite source.
    fs = _parse_finite_source(usgs_param)
    rec = instaseis.Receiver(
        latitude=22, longitude=11, network="XX", station="SYN", location="SE"
    )

    st_db = db.get_seismograms_finite_source(sources=fs, receiver=rec)
    # The origin time is the time of the first sample in the route.
    for tr in st_db:
        # Multiply with scale parameter.
        tr.data *= 33.33
        # Cut away the first ten samples as they have been previously added.
        tr.data = tr.data[10:]
        tr.stats.starttime = obspy.UTCDateTime(1900, 1, 1)

    for tr_db, tr_server in zip(st_db, st_server):
        # Sample spacing is very similar but not equal due to floating point
        # accuracy.
        np.testing.assert_allclose(tr_server.stats.delta, tr_db.stats.delta)
        tr_server.stats.delta = tr_db.stats.delta
        del tr_server.stats._format
        del tr_server.stats.mseed

        assert tr_db.stats == tr_server.stats
        np.testing.assert_allclose(
            tr_db.data, tr_server.data, atol=1e-6 * tr_db.data.ptp()
        )

@pytest.mark.parametrize("usgs_param", [USGS_PARAM_FILE_1, USGS_PARAM_FILE_2])
def test_more_complex_queries(reciprocal_clients_all_callbacks, usgs_param):
    """
    These are not exhaustive tests but test that the queries do something.
    Elsewhere they are tested in more details.

    Test phase relative offsets.

    + must be encoded with %2B
    - must be encoded with %2D
    """
    client = reciprocal_clients_all_callbacks
    db = instaseis.open_db(client.filepath)

    basic_parameters = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "components": "".join(db.available_components),
        "format": "miniseed",
    }

    with io.open(usgs_param, "rb") as fh:
        body = fh.read()

    # default parameters
    params = copy.deepcopy(basic_parameters)
    params["dt"] = 2
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st = obspy.read(request.buffer)

    # Now request one starting ten seconds later.
    params = copy.deepcopy(basic_parameters)
    params["starttime"] = 10
    params["dt"] = 2
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_2 = obspy.read(request.buffer)

    assert st[0].stats.starttime + 10 == st_2[0].stats.starttime

    # The rest of data should still be identical.
    np.testing.assert_allclose(st.slice(starttime=10)[0].data, st_2[0].data)

    # Try with the endtime.
    params = copy.deepcopy(basic_parameters)
    params["endtime"] = 20
    params["dt"] = 2
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_2 = obspy.read(request.buffer)

    assert st_2[0].stats.endtime == st[0].stats.starttime + 18

    # The rest of data should still be identical.
    np.testing.assert_allclose(
        st.slice(endtime=st[0].stats.starttime + 18)[0].data, st_2[0].data
    )

    # Phase relative start and endtimes.
    params = copy.deepcopy(basic_parameters)
    params["starttime"] = "P%2D5"
    params["endtime"] = "P%2B5"
    params["dt"] = 2
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_2 = obspy.read(request.buffer)

    # Just make sure they actually do something.
    assert st_2[0].stats.starttime > st[0].stats.starttime
    assert st_2[0].stats.endtime < st[0].stats.endtime

    # Mixing things
    params = copy.deepcopy(basic_parameters)
    params["starttime"] = "P%2D5"
    params["endtime"] = "50"
    params["dt"] = 2
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_2 = obspy.read(request.buffer)

    # Just make sure they actually do something.
    assert st_2[0].stats.starttime > st[0].stats.starttime
    assert st_2[0].stats.endtime < st[0].stats.endtime

    if "Z" not in db.available_components:
        return

    # Network and station searches.
    params = {
        "network": "IU,B*",
        "station": "ANT*,ANM?",
        "components": "Z",
        "format": "miniseed",
    }
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 200
    st_2 = obspy.read(request.buffer)

    assert sorted(tr.id for tr in st_2) == ["IU.ANMO..LXZ", "IU.ANTO..LXZ"]

@pytest.mark.parametrize("usgs_param", [USGS_PARAM_FILE_1, USGS_PARAM_FILE_2])
def test_various_failure_conditions(
    reciprocal_clients_all_callbacks, usgs_param
):
    """
    Tests some failure conditions.
    """
    client = reciprocal_clients_all_callbacks

    basic_parameters = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "components": "Z",
        "format": "miniseed",
    }

    with io.open(usgs_param, "rb") as fh:
        body = fh.read()

    # Starttime too large.
    params = copy.deepcopy(basic_parameters)
    params["starttime"] = 200000
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The `starttime` must be before the seismogram " "ends."
    )

    # Starttime too early.
    params = copy.deepcopy(basic_parameters)
    params["starttime"] = -10000
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The seismogram can start at the maximum one "
        "hour before the origin time."
    )

    # Endtime too small.
    params = copy.deepcopy(basic_parameters)
    params["endtime"] = -200000
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The end time of the seismograms lies outside " "the allowed range."
    )

    # Useless phase relative times. pdiff does not exist at the epicentral
    # range of the example files.
    params = copy.deepcopy(basic_parameters)
    params["starttime"] = "Pdiff%2D5"
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "No seismograms found for the given phase "
        "relative offsets. This could either be due to "
        "the chosen phase not existing for the specific "
        "source-receiver geometry or arriving too "
        "late/with too large offsets if the database is "
        "not long enough."
    )

    # Scale of zero.
    params = copy.deepcopy(basic_parameters)
    params["scale"] = 0.0
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason.startswith("A scale of zero means")

    # Invalid receiver coordinates.
    params = copy.deepcopy(basic_parameters)
    params["receiverlatitude"] = 1e9
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "Could not construct receiver with passed "
        "parameters. Check parameters for sanity."
    )

    # Invalid receiver coordinates based on a station coordinates query.
    params = copy.deepcopy(basic_parameters)
    del params["receiverlatitude"]
    del params["receiverlongitude"]
    params["network"] = "XX"
    params["station"] = "DUMMY"
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "Station coordinate query returned invalid " "coordinates."
    )

    # Coordinates not found
    params = copy.deepcopy(basic_parameters)
    del params["receiverlatitude"]
    del params["receiverlongitude"]
    params["network"] = "UN"
    params["station"] = "KNOWN"
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 404
    assert request.reason == "No coordinates found satisfying the query."

def test_uploading_empty_usgs_file(reciprocal_clients):
    """
    Tests uploading an empty usgs file.
    """
    client = reciprocal_clients

    params = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "components": "Z",
        "format": "miniseed",
    }

    with io.open(USGS_PARAM_FILE_EMPTY, "rb") as fh:
        body = fh.read()

    # Starttime too large.
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The body contents could not be parsed as an USGS param file due to: "
        "No point sources found in the file."
    )

def test_uploading_deep_usgs_file(reciprocal_clients):
    """
    Tests uploading a usgs file that has sources that are too deep for the
    database.
    """
    client = reciprocal_clients

    params = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "components": "Z",
        "format": "miniseed",
    }

    with io.open(USGS_PARAM_FILE_DEEP, "rb") as fh:
        body = fh.read()

    # Starttime too large.
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The deepest point source in the given finite "
        "source is 1000.9 km deep. The database only "
        "has a depth range from 0.0 km to 371.0 km."
    )

def test_uploading_usgs_file_with_airquakes(reciprocal_clients):
    """
    Tests uploading a usgs file that has sources that are above the planet
    radius.
    """
    client = reciprocal_clients

    params = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "components": "Z",
        "format": "miniseed",
    }

    with io.open(USGS_PARAM_FILE_AIR, "rb") as fh:
        body = fh.read()

    # Starttime too large.
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The shallowest point source in the given "
        "finite source is -0.9 km deep. The database "
        "only has a depth range from 0.0 km to "
        "371.0 km."
    )

def test_uploading_usgs_file_with_long_rise_or_fall_times(reciprocal_clients):
    """
    Tests uploading a usgs file that has too long rise or fall times.
    radius.
    """
    client = reciprocal_clients

    params = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "components": "Z",
        "format": "miniseed",
    }

    with io.open(USGS_PARAM_FILE_LONG, "rb") as fh:
        body = fh.read()

    # Starttime too large.
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The body contents could not be parsed as an "
        "USGS param file due to: Rise + fall time are "
        "longer than the total length of calculated "
        "slip. Please use more samples."
    )

def test_uploading_file_with_too_many_sources(reciprocal_clients):
    """
    Tests uploading a file with too many point sources.
    """
    client = reciprocal_clients

    # Artificially limit the number of allowed sources.
    client.application.max_size_of_finite_sources = 17

    params = {
        "receiverlongitude": 11,
        "receiverlatitude": 22,
        "components": "Z",
        "format": "miniseed",
    }

    with io.open(USGS_PARAM_FILE_1, "rb") as fh:
        body = fh.read()

    # Starttime too large.
    request = fetch_sync(
        client,
        _assemble_url("finite_source", **params),
        method="POST",
        body=body,
    )
    assert request.code == 400
    assert request.reason == (
        "The server only allows finite sources with at "
        "most 17 points sources. The source in question "
        "has 121 points."
    )


from setuptools import setup, find_packages
from codecs import open
from os import path

here = path.abspath(path.dirname(__file__))

with open(path.join(here, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='coinpayments-py',
    version='0.1.0',
    description='CoinPayments API Client for Python',
    long_description=long_description,
    long_description_content_type='text/markdown',
    url='https://github.com/OnGridSystems/coinpayments-py',
    author='Roman Nesytov',
    author_email='r.nesytov@ongrid.pro',

    classifiers=[
        'Development Status :: 5 - Stable',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: Apache Software License',

        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
    ],

    keywords='coinpayments currencies crypto',

    packages=find_packages(exclude=['tests']),

    install_requires=['requests'],

    python_requires='>=3.4',

    project_urls={
        'Bug Reports': 'https://github.com/OnGridSystems/coinpayments-py/issues',
        'Source': 'https://github.com/OnGridSystems/coinpayments-py',
    },
)


#!/usr/bin/env python3
# pylint: disable=C0301,C0116,C0103,R0903

"""
This script was created by Coopydood as part of the ultimate-macOS-KVM project.

https://github.com/user/Coopydood
https://github.com/Coopydood/ultimate-macOS-KVM
Signature: 4CD28348A3DD016F

"""
import os
import time
import subprocess
import re
import json
import sys
import argparse

def clear(): print("\n" * 150)

class color:
   PURPLE = '\033[95m'
   CYAN = '\033[96m'
   DARKCYAN = '\033[36m'
   BLUE = '\033[94m'
   GREEN = '\033[92m'
   YELLOW = '\033[93m'
   RED = '\033[91m'
   BOLD = '\033[1m'
   UNDERLINE = '\033[4m'
   END = '\033[0m'

output_stream = os.popen('lspci')
vmc1 = output_stream.read()

output_stream1 = os.popen('lspci')
vmc2 = output_stream1.read()

output_stream2 = os.popen('lspci')
vmc3 = output_stream2.read()

detected = 0

global isVM

isVM = False

#for x in vmc1:
if "NVIDIA" in vmc1:
   detected = 1

#for x in vmc2:
if "VirtualBox" in vmc2 or "Oracle" in vmc2:
   detected = 1

#for x in vmc3:
if "Redhat" in vmc3 or "RedHat" in vmc3:
   detected = 1

clear()

if detected == 1:
   isVM = True
   print("\n   "+color.BOLD+color.YELLOW+"⚠ VIRTUAL MACHINE DETECTED"+color.END)
   print("   Virtualized devices detected")
   print("\n   I've determined that it's more than likely that \n   you're using a virtual machine to run this. I won't\n   stop you, but there really isn't much point in continuing."+color.END)

   print("\n   "+color.BOLD+color.YELLOW+"PROBLEM:",color.END+"Virtual hardware detected"+color.END)
   print(color.BOLD+"\n      1. Exit")
   print(color.END+"      2. Continue anyway\n")
   stageSelect = str(input(color.BOLD+"Select> "+color.END))

   if stageSelect == "1":
      isVM = True
      sys.exit
      sys.exit
      sys.exit
      sys.exit

   elif stageSelect == "2":
      isVM = False
      os.system("./main.py -svmc")


import dicom_reader
import con_reader
import con2img
import volume as vol
from matplotlib.pyplot import plot, imshow, show

def test_dicom_reader():

    path = "../data/Eredetikepek/1___AW1295938826.919.1531920932/2018-07-16_1.2.840.113619.2.181.60341967613.14520.1531920932966.2/"
    dc = dicom_reader.DCMreader(path)
    print("Reading was finished!")

    imshow(dc.get_image(2, 23))
    show()

#test_dicom_reader()

def test_con_reader():

    path = "../data/Kontur/Buday_Krisztina_20180712_sa_SER1001_ACQ10.con"
    cn = con_reader.CONreader(path)
    print("Reading was finished!")

    crs = cn.get_hierarchical_contours()
    x, y = crs[7][11][0]['x'], crs[7][11][0]['y']
    plot(x, y, 'ro')
    show()

#test_con_reader()

def test_con_volumedata():
    base_path = "../../data/SA_all_2/19307824AMR806/1301/"
    con_path = base_path + "contour.con"
    cn = con_reader.CONreader(con_path)
    fw, reso, width, weight, height = cn.get_volume_data()
    assert fw[0] == 329.999996 and fw[1] == 329.999996, 'Wrong field view!'
    assert reso[0] == 224 and reso[1] == 224, 'Wrong image resolution!'
    assert width == 8.0, 'Wrong sice width!'
    print('OK: test_con_volumedata')

#test_con_volumedata()

def test_con2img():
    base_path = "../../data/SA_all_2/19194862AMR806/1401/"
    #base_path = "../../data/SA_all_2/19307824AMR806/1301/"
    dcm_path = base_path + "imgs/"
    con_path = base_path + "contour.con"

    con2img.draw_contours2images(dcm_path, con_path)
    print("OK: test_con2img")

test_con2img()

def test_volume():
    path1 = "../../data/volume_test/Takacs_Akos_20180131_038318067_STD19194862AMR806_SER1401_ACQ14.con"
    path2 = "../../data/SA_all/17352962AMR801/901/contour.con"
    path4 = "../../data/SA_all/17577538AMR801/901/contour.con"
    path5 = "../../data/SA_all/17651351AMR806/1301/contour.con"
    path6 = "../../data/SA_all/17827245AMR809/1301/contour.con"

    v = vol.Volume(path6)
    v.calculate_volumes('pixel')
    print('---------------------------')
    print('LEFT VEN.')
    print('LVED: %.3f'%v.lved)
    print('LVED-idx: %.3f'%v.lved_i)
    print('LVES: %.3f'%v.lves)
    print('LVES-idx: %.3f'%v.lves_i)
    print('LVSV: %.3f'%v.lvsv)
    print('LVSV-idx: %.3f'%v.lvsv_i)

    print('---------------------------')
    print('RIGHT VEN.')
    print('RVED: %.3f'%v.rved)
    print('RVED-idx: %.3f'%v.rved_i)
    print('RVES: %.3f'%v.rves)
    print('RVES-idx: %.3f'%v.rves_i)
    print('RVSV: %.3f'%v.rvsv)
    print('RVSV-idx: %.3f'%v.rvsv_i)

#test_volume()


#from bs4 import BeautifulSoup
import requests
import json

bibmap = {
    'journal-article': 'article',
    'book-chapter': 'incollection',
    'dataset': 'techreport',
}

def getCite(q):
    q = q.replace(' ', '+')
    url = "https://api.crossref.org/works?rows=5&query.bibliographic="

    data = requests.get(url+q)
    json_data = json.loads(data.content)
    arts = []
    x = json_data['message']['items']
    for art in x:
        keys = set(['title', 'author', 'published-print'])
        if(keys.issubset(art.keys())):
            bibtex = {}
            bibtex['title'] = art['title'][0]
            authors = [a['family'] +", " + a['given'] for a in art['author']]
            bibtex['author'] = ' and '.join(authors)
            bibtex['year'] = str(art['published-print']['date-parts'][0][0])
            if('volume' in art.keys()):
                bibtex['volume'] = art['volume']
            if('page' in art.keys()):
                bibtex['pages'] = art['page']
            if('publisher' in art.keys()):
                bibtex['publisher'] = art['publisher']
            if('DOI' in art.keys()):
                bibtex['DOI'] = art['DOI']
            if('type' in art.keys()):
                bibtex['entry_type'] = bibmap[art['type']]
            if('container-title' in art.keys()):
                if (bibtex['entry_type']=='article'):
                    bibtex['journal'] = art['container-title'][0]
                elif (bibtex['entry_type']=='incollection'):
                    bibtex['booktitle'] = art['container-title'][0]
            bibtex['citekey'] = art['author'][0]['family'].lower() + bibtex['year'] + bibtex['title'].split(' ')[0]
            arts.append(bibtex)
    print('*****')
    toBibtexStr(arts)

def toBibtexStr(arts):
    bibtex = []
    for art in arts:
        bt = f'''@{art['entry_type']}{{{art['citekey']}'''
        keys = set(art.keys())
        nonkeys = set(['citekey', 'entry_type']);
        for key in keys.difference(nonkeys):
            bt += ', ' + key + '={' + art[key] + '}'

        bt += "}"
        bibtex.append(bt)
    print(bibtex)

getCite('state space precludes unawareness')


#! /usr/bin/env python

# mcast_clients.py -- P. Demorest, 2015/02
#
# Based on code originally in async_mcast.py by PD and S. Ransom
#
# These classes set up networking, and parse incoming Obs and VCI
# documents into appropriate data structures.

import os
import struct
import logging
import asyncore, socket
import urllib
import vcixml_parser
import obsxml_parser

class McastClient(asyncore.dispatcher):
    """Generic class to receive the multicast XML docs."""

    def __init__(self, group, port, name=""):
        asyncore.dispatcher.__init__(self)
        self.name = name
        self.group = group
        self.port = port
        addrinfo = socket.getaddrinfo(group, None)[0]
        self.create_socket(addrinfo[0], socket.SOCK_DGRAM)
        self.set_reuse_addr()
        self.bind(('',port))
        mreq = socket.inet_pton(addrinfo[0],addrinfo[4][0]) \
                + struct.pack('=I', socket.INADDR_ANY)
        self.socket.setsockopt(socket.IPPROTO_IP,
                socket.IP_ADD_MEMBERSHIP, mreq)
        self.read = None

    def handle_connect(self):
        logging.debug('connect %s group=%s port=%d' % (self.name,
            self.group, self.port))

    def handle_close(self):
        logging.debug('close %s group=%s port=%d' % (self.name,
            self.group, self.port))

    def writeable(self):
        return False

    def handle_read(self):
        self.read = self.recv(100000)
        logging.debug('read ' + self.name + ' ' + self.read)
        try:
            self.parse()
        except Exception as e:
            logging.exception("error handling '%s' message" % self.name)

    def handle_error(self, type, val, trace):
        logging.error('unhandled exception: ' + repr(val))

class ObsClient(McastClient):
    """Receives Observation XML.

    If the controller input is given, the controller.add_obs(obs) method will
    be called for every document received.

    If use_configUrl is true, the VCI will be retrieved from the url given
    in the Observation document, parsed, and controller.add_vci(vci) will
    be called if a controller exists.
    """

    def __init__(self,controller=None,use_configUrl=False):
        McastClient.__init__(self,'239.192.3.2',53001,'obs')
        self.controller = controller
        self.use_configUrl = use_configUrl

    def parse(self):
        obs = obsxml_parser.parseString(self.read)
        logging.info("read obs configId='%s' seq=%d" % (obs.configId,
            obs.seq))
        if self.use_configUrl:
            logging.info("retrieve vci from '%s'" % obs.configUrl)
            try:
                vciread = urllib.urlopen(obs.configUrl).read()
                logging.debug('retrieved vci ' + vciread)
                vci = vcixml_parser.parseString(vciread)
                if self.controller is not None:
                    self.controller.add_vci(vci)
            except Exception as e:
                logging.exception("error retrieving VCI from '%s'"
                        % obs.configUrl)
        if self.controller is not None:
            self.controller.add_obs(obs)

class VCIClient(McastClient):
    """Receives VCI XML.

    If the controller input is given, the controller.add_vci(vci) method will
    be called for every document received.
    """

    def __init__(self,controller=None):
        McastClient.__init__(self,'239.192.3.1',53000,'vci')
        self.controller = controller

    def parse(self):
        vci = vcixml_parser.parseString(self.read)
        if type(vci) == vcixml_parser.subArray:
            logging.info("read vci configId='%s'" % vci.configId)
            if self.controller is not None:
                self.controller.add_vci(vci)
        else:
            logging.info("read vci non-subArray, ignoring")

# This is how these would be used in a program.  Note that no controller
# is passed, so the only action taken here is to print log messages when
# each XML document comes in.
if __name__ == '__main__':
    logging.basicConfig(format="%(asctime)-15s %(levelname)8s %(message)s",
            level=logging.DEBUG)
    vci_client = VCIClient()
    obs_client = ObsClient(use_configUrl=True)
    try:
        asyncore.loop()
    except KeyboardInterrupt:
        # Just exit without the trace barf on control-C
        logging.info('got SIGINT, exiting')


from datetime import datetime
from django import forms
from django.contrib.auth.models import User
from django_countries.fields import CountryField

from epa_frontend.models import Properties, Orders, OrderItems, PropertyType

class PropertyTypeForm(forms.ModelForm):
    class Meta:
        model = PropertyType
        fields = ('fname', 'description', 'images')

class PropertyForm(forms.ModelForm):
    class Meta:
        model = Properties
        fields = ('name', 'images', 'merchant_id', 'property_type_id', 'price', 'status', 'created_at', 'location')
        exclude = ('property_type_id', 'merchant_id', 'created_at', 'status')

class OrdersForm(forms.ModelForm):
    class Meta:
        model = Orders
        fields = ('')
        exclude = ('')

class OrderItemsForm(forms.ModelForm):
    class Meta:
        model = OrderItems
        fields = ('')
        exclude = ('')


# crear un programa que ralize la conversion de un valor indicado por el ususario de celcius a farenheit y viceversa
Temperatura = float(input("Ingrese Temperatura a Convertir:"))
tipoDeGrados = input("Es Fahrenheit (F) o es Celsius(C)=:").lower()
if tipoDeGrados == "c":
    fahrenheit = (Temperatura * 9/5 + 32)
    print(fahrenheit, "°F")
elif tipoDeGrados == "f":
    celsius = (Temperatura - 32) * 5/9
    print(celsius, "°C")
else:
    print("Escala incorrecta")


# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

from django.urls import path

from crashstats.monitoring import views

app_name = "monitoring"
urlpatterns = [
    path("monitoring/cron/", views.cron_status, name="cron_status"),
    path("monitoring/", views.index, name="index"),
    path("__broken__", views.broken, name="broken"),
    # Dockerflow endpoints
    path("__heartbeat__", views.dockerflow_heartbeat, name="dockerflow_heartbeat"),
    path(
        "__lbheartbeat__",
        views.dockerflow_lbheartbeat,
        name="dockerflow_lbheartbeat",
    ),
    path("__version__", views.dockerflow_version, name="dockerflow_version"),
    path(
        "permission_required",
        views.permission_required_view,
        name="permission_required",
    ),
]


"""
#############################################
#
#   YOLOv7 Object Detection For Videos
#   23/11/22
#
############################################

Follow the README for explicit instructions

Prior to running:
    Download the yolov7 model prior to running (link in README) and place in a ./models folder
    Create a ./inputs and ./outputs directory, these are gitignored

Run the program using:
    python video_object_detection.py --source <video.mp4> --output <outfile.mp4>

All inputs and outputs are in specific directories so do not need to specify it in --source and --output

"""

# Imports and dependencies
import argparse
from decimal import InvalidContext
from operator import index
import os
import pathlib

import cv2
import numpy as np

from YOLOv7 import YOLOv7

if __name__ == "__main__":

    #Possible arguments
    parser = argparse.ArgumentParser()
    parser.add_argument('--weights', nargs='+', type=str, default='yolov7.pt', help='model.pt path(s)')
    parser.add_argument('--source', type=str, default='inference/images', help='source')  # file/folder, 0 for webcam
    parser.add_argument('--output', type=str, default='videos/', help='output file')
    parser.add_argument('--img-size', type=int, default=640, help='inference size (pixels)')
    parser.add_argument('--conf-thres', type=float, default=0.25, help='object confidence threshold')
    parser.add_argument('--iou-thres', type=float, default=0.45, help='IOU threshold for NMS')
    parser.add_argument('--device', default='', help='cuda device, i.e. 0 or 0,1,2,3 or cpu')
    parser.add_argument('--view-img', action='store_true', help='display results')
    parser.add_argument('--save-txt', action='store_true', help='save results to *.txt')
    parser.add_argument('--save-conf', action='store_true', help='save confidences in --save-txt labels')
    parser.add_argument('--nosave', action='store_true', help='do not save images/videos')
    parser.add_argument('--classes', nargs='+', type=int, help='filter by class: --class 0, or --class 0 2 3')
    parser.add_argument('--agnostic-nms', action='store_true', help='class-agnostic NMS')
    parser.add_argument('--augment', action='store_true', help='augmented inference')
    parser.add_argument('--update', action='store_true', help='update all models')
    parser.add_argument('--project', default='runs/detect', help='save results to project/name')
    parser.add_argument('--name', default='exp', help='save results to project/name')
    parser.add_argument('--exist-ok', action='store_true', help='existing project/name ok, do not increment')
    parser.add_argument('--no-trace', action='store_true', help='don`t trace model')
    opt = parser.parse_args()

    FILE_DIR = pathlib.Path(__file__).parent
    MODEL_DIR = os.path.join(FILE_DIR, "models")
    OUT_DIR = os.path.join(FILE_DIR, "outputs")
    IN_DIR = os.path.join(FILE_DIR, "inputs")
    INFILE = os.path.join(IN_DIR, opt.source)

    # Initialize video
    cap = cv2.VideoCapture(INFILE)

    if cap.isOpened():
        fps = cap.get(cv2.CAP_PROP_FPS) #Get framerate to match for output rate
        width  = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))   # float `width` converted to int
        height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))  # float `height` converted to int

    outputFile = os.path.join(OUT_DIR, opt.output)
    out = cv2.VideoWriter(outputFile, cv2.VideoWriter_fourcc('m', 'p', '4', 'v'), fps, (width, height)) #Specify output file

    # Initialize YOLOv7 model
    model_name = "yolov7-tiny_Nx3x384x640.onnx"         # The chosen YOLO model, follow instructions in the README for download
    model_path = os.path.join(MODEL_DIR, model_name)
    #model_path = "models/yolov7-tiny_Nx3x384x640.onnx"
    yolov7_detector = YOLOv7(model_path, conf_thres=0.5, iou_thres=0.5) #Initialise yolo model

    # Create and display window while processing
    cv2.namedWindow("Detected Objects", cv2.WINDOW_NORMAL)
    while cap.isOpened():

        # Press key q to stop
        if cv2.waitKey(1) == ord('q'):
            break

        try:
            # Read frame from the video
            ret, frame = cap.read()
            if not ret:
                break
        except Exception as e:
            print(e)
            continue

        # Update object localizer
        boxes, scores, class_ids = yolov7_detector(frame)

        combined_img = yolov7_detector.draw_detections(frame)   # Draw the boxes on the image
        cv2.imshow("Detected Objects", combined_img)            # Display new image
        out.write(combined_img)                                 # Save the image to the output file

    # Clear up and save the output video
    out.release()


import numpy as np

# 입력층에서 layer1으로 신호 전달
X = np.array([1.0, 0.5]) # 대문자로 쓰여진것은 행렬을 의미한다.
W1 = np.array([[0.1, 0.3, 0.5],[0.2, 0.4, 0.6]])
B1 = np.array([0.1, 0.2, 0.3])

print(W1.shape) # (2, 3)
print(X.shape)  # (2,)
print(B1.shape) # (3,)

A1 = np.dot(X, W1) + B1 # 내적(스칼라) 내적을 계산한 값의 결과는 실수 즉 스칼라 값이 나온다.
print(A1) # [0.3 0.7 1.1]

# 1층에서의 활성화 함수 처리
def sigmoid(x):
    return 1 /(1+np.exp(-x))

Z1 = sigmoid(A1)
print(Z1) # [0.57444252 0.66818777 0.75026011]

# sigmoid 함수를 쓰는 이유 : 아무리 큰수, 아무리 작은수를 활성화 함수에 넣어도 1보다작고 0보다 크다. 범위를 축소화 해준다.
# ReLu 함수를 적용할 시  x가 양수일 경우는 x, 음수값일 경우  0으로 반환해준다.
# 하나의 값이 상대적으로 크면 단계를 거치면 거칠수록 큰 값이 점점더 부각되어 다른 것들의 값의 차이점을 보이지 않게된다.
# 입력된 신호들이 레이어를 거치면 거칠수록 점점 더 부각되어 지도록 하기위하여 활성화 함수를 사용한다.

# 1층에서 2층으로의 신호 전달
W2 = np.array([[0.1,0.4],[0.2,0.5],[0.3,0.6]])
B2 = np.array([0.1, 0.2])

A2 = np.dot(Z1, W2) + B2
Z2 = sigmoid(A2)

# 2층에서 3층(출력층)으로의 신호 전달
W3 = np.array([[0.1,0.3],[0.2,0.4]])
B3 = np.array([0.1,0.2])

# 항등 함수의 정의 - 출력단
def identity_function(x):
    return x

A3 = np.dot(Z2, W3) + B3
Y = identity_function(A3)

print(Y) # [0.31682708 0.69627909]

# 마지막 층에서는 활성화 함수를 사용할 필요 없다. 최종신호를 출력하면 된다.
# 분류분석의 최종적인 출력은 클래스를 구분


class Solution:
    def compress_string(self, chars: [str]) -> int:
        init_char = ''
        counter_char = 1
        index = 0
        while index < len(chars):
            if init_char == '':
                init_char = chars[index]
            else:
                if chars[index] == init_char:
                    counter_char += 1
                    chars.pop(index-1)
                    index -= 1
                else:
                    if counter_char > 1:
                        chars.insert(index, list(str(counter_char)))
                        index += 1
                    init_char = chars[index]
                    counter_char = 1
            index += 1
        if counter_char > 1:
            chars.insert(index, list(str(counter_char)))
            index += 1
        print(chars)
        return len(chars)

solution = Solution()
print(solution.compress_string(["a","b","b","b","b","b","b","b","b","b","b","b","b"]))
# print(solution.compress_string(["a", "a", "b", "b", "c", "c", "c"]))
# print(solution.compress_string(["a", "a", "a", "a"]))


from opencontext_py.libs.general import LastUpdatedOrderedDict
from opencontext_py.apps.ldata.arachne.api import ArachneAPI

class TypeSupplement():
    """ Class for adding related, supplemental information about types
    """
    RELATES_PREDICATES = [
        'rdfs:seeAlso',
        'skos:example',
        'skos:note'
    ]

    def __init__(self, item_json):
        self.item_json = item_json

    def type_german_mappings(self, keyword):
        """ translates to related german for searches """
        keyword = keyword.lower()
        mappings = {'bucchero': 'etruskischer bucchero'}
        if keyword in mappings:
            keyword = mappings[keyword]
        return keyword

    def get_arachne_comparanda(self):
        """ get a type item including lots of useful related data
        """
        label = self.item_json['label']
        # keyword = self.type_german_mappings(label)
        arachne_search_url = self.check_arachne_relation()
        if isinstance(arachne_search_url, str):
            # print('search url: ' + arachne_search_url)
            a_api = ArachneAPI()
            a_api.get_results_from_search_url(arachne_search_url)
            if a_api.results is not False:
                editorial_pred = LastUpdatedOrderedDict()
                editorial_pred['owl:sameAs'] = 'http://www.w3.org/2004/02/skos/core#editorialNote'
                editorial_pred['slug'] = 'skos-editorialnote'
                editorial_pred['label'] = 'Arachne comparative material'
                editorial_pred['oc-gen:predType'] = 'variable'
                editorial_pred['type'] = 'xsd:string'
                example_pred = LastUpdatedOrderedDict()
                example_pred['owl:sameAs'] = 'http://www.w3.org/2004/02/skos/core#example'
                example_pred['slug'] = 'skos-example'
                example_pred['label'] = 'Comparanda in Arachne'
                example_pred['oc-gen:predType'] = 'link'
                example_pred['type'] = '@id'
                self.item_json['@context'][2]['skos:editorialNote'] = editorial_pred
                self.item_json['@context'][2]['skos:example'] = example_pred
                self.add_arachne_observation(a_api)
        return self.item_json

    def add_arachne_observation(self, a_api):
        """ Adds an observation for Arachne comparanda """
        if 'oc-gen:has-obs' not in self.item_json:
            self.item_json['oc-gen:has-obs'] = []
        arachne_obs = LastUpdatedOrderedDict()
        arachne_obs['id'] = '#obs-' + str(len(self.item_json['oc-gen:has-obs']) + 1)
        arachne_obs['oc-gen:sourceID'] = a_api.DEFAULT_API_BASE_URL
        arachne_obs['oc-gen:obsStatus'] = 'active'
        arachne_obs['type'] = 'oc-gen:observations'
        editorial = LastUpdatedOrderedDict()
        editorial['id'] = '#string-arachne-editorial'
        note = ''
        note += '
Arachne has: ' + str(a_api.result_count) + ' related item(s) with images
'
        note += '
Browse these comparanda: '
        note += '[Link to Arachne search results]
'
        note += '
Open Context editors identified materials in Arachne likley to be relevant for comparison to this type.'
        note += ' Arachne is the central object database of the German Archaeological Institute (DAI)'
        note += ' and the Archaeological Institute of the University of Cologne.
'
        editorial['xsd:string'] = note
        arachne_obs['skos:editorialNote'] = []
        arachne_obs['skos:editorialNote'].append(editorial)
        arachne_obs['skos:example'] = a_api.results
        self.item_json['oc-gen:has-obs'].append(arachne_obs)

    def check_arachne_relation(self):
        """ checks to see if the type is related to an arachne search """
        arachne_search_url = None
        for rel_pred in self.RELATES_PREDICATES:
            if rel_pred in self.item_json:
                if isinstance(self.item_json[rel_pred], list):
                    for item in self.item_json[rel_pred]:
                        if 'id' in item:
                            if ArachneAPI.ARACHNE_SEARCH in item['id']:
                                # we have a link to something in arachne search
                                arachne_search_url = item['id']
                                break
        return arachne_search_url


import argparse

def get_args_parser(add_help=True):
    """ Usage: args = get_args_parser()"""
    parser = argparse.ArgumentParser(description='Name of Project', add_help=add_help)
    parser.add_argument('--source', type=str, default='data/videos', help='the destination path, e.g. video-file/dir.')
    parser.add_argument('--max-det', type=int, default=1000, help='maximal inferences per image.')
    parser.add_argument('--device', default='0', help='device to run our model i.e. 0 or 0,1,2,3 or cpu.')
    parser.add_argument('--webcam', action='store_true', help='whether to use webcam.')
    args = parser.parse_args()
    return args

if __name__ == "__main__":
    args = get_args_parser()
    print(args.source, args.max_det, args.device, args.webcam)


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import sys
import os
import glob

import numpy as np
import tensorflow as tf
import time
import cv2
import random
import json
from moviepy.editor import ImageSequenceClip

sys.path.append(os.path.realpath('../JITNet/utils'))
sys.path.append(os.path.realpath('../JITNet/src'))
sys.path.append(os.path.realpath('../JITNet/datasets'))

import video_distillation

from mask_rcnn_tfrecords import get_dataset, batch_segmentation_masks,\
                                visualize_masks
from mask_rcnn_utils import mask_rcnn_get_best_box_match,\
                            get_full_resolution_mask
from mask_rcnn_stream import MaskRCNNMultiStream, MaskRCNNSequenceStream
from stream import VideoInputStream

#######################
# Dataset Flags #
#######################

tf.app.flags.DEFINE_string(
    'video_path', None, 'Directory containing the dataset.')

tf.app.flags.DEFINE_integer(
    'height', 720, 'The number of samples in each batch.')

tf.app.flags.DEFINE_integer(
    'width', 1280, 'The number of samples in each batch.')

tf.app.flags.DEFINE_integer('max_frames', 100000,
                            'The maximum number of training steps.')

tf.app.flags.DEFINE_string(
    'detections_prefix', None, 'Path to video file.')

tf.app.flags.DEFINE_string(
    'detections_path', '',
    'Path to the detections file')

tf.app.flags.DEFINE_string('video_out_path',
        None, 'Path to output video file.')
tf.app.flags.DEFINE_string('tracks_out_dir',
        None, 'Path to output directory to store tracks.')

tf.app.flags.DEFINE_boolean(
    'scale_boxes', True,
    'Scale the boxes to image height and width.')

FLAGS = tf.app.flags.FLAGS

def get_objects_of_interest(boxes, scores, classes, masks, object_ids):
    interest_mask = np.zeros(classes.shape)
    for id in object_ids:
        interest_mask = np.logical_or(interest_mask, classes == id)
    return boxes[interest_mask], scores[interest_mask], \
           classes[interest_mask], masks[interest_mask]

def main(_):
    if FLAGS.tracks_out_dir is not None and os.path.exists(FLAGS.tracks_out_dir):
        print('Variant seems to have been already run')
        exit(0)

    if FLAGS.tracks_out_dir is not None:
        os.mkdir(FLAGS.tracks_out_dir)

    assert(os.path.isfile(FLAGS.video_path))
    assert(os.path.isfile(FLAGS.detections_path))

    video_files = [ FLAGS.video_path ]
    detections_paths = [ FLAGS.detections_path ]

    print(video_files, detections_paths)

    class_groups = [ ['person'], [ 'car', 'bus', 'truck'],
                       [ 'motorcycle', 'bicycle'] ]
    object_ids = [ video_distillation.detectron_classes.index(c) \
                   for g in class_groups for c in g ]

    tracked_detections = {}
    tracks = {}
    active_tracks = {}
    track_id = 0
    anomaly_id = 0

    pick_threshold = 0.92
    area_threshold = 0.05 * FLAGS.height * 0.05 * FLAGS.width

    discrepancy = False
    input_streams = MaskRCNNSequenceStream(video_files, detections_paths,
                                           start_frame=0, stride=1)
    curr_frame = 0
    prev_frame = np.zeros((FLAGS.height, FLAGS.width, 3), dtype=np.uint8)

    print("Tracking...")
    for frame, boxes, classes, scores, masks, num_objects, \
                                    frame_id in input_streams:
        if curr_frame > FLAGS.max_frames:
            break

        if curr_frame % 500 == 0:
            print("Reached Frame: ", curr_frame)

        if curr_frame not in tracked_detections:
            tracked_detections[curr_frame] = []

        frame = cv2.resize(frame, (FLAGS.width, FLAGS.height))

        frame = np.expand_dims(frame, axis=0)
        boxes = np.expand_dims(boxes, axis=0)
        classes = np.expand_dims(classes, axis=0)
        scores = np.expand_dims(scores, axis=0)
        masks = np.expand_dims(masks, axis=0)
        num_objects = np.expand_dims(num_objects, axis=0)

        boxes, scores, classes, masks = \
                get_objects_of_interest(boxes, scores, classes,
                                        masks, object_ids)

        # For all the active tracks find matches in the current frame
        for tid in active_tracks.keys():
            _, prev_bbox, prev_mask, prev_cls,\
                    prev_score, prev_iou = active_tracks[tid][-1]

            match_threshold = 0.5
            miss_threshold = 0.1

            attn_mask = get_full_resolution_mask(prev_bbox,
                                                 prev_mask,
                                                 (FLAGS.height, FLAGS.width),
                                                 scale_boxes=True)

            picked_idx, picked_iou, picked_area = \
                mask_rcnn_get_best_box_match(boxes, masks,
                                             scores,
                                             prev_bbox,
                                             (FLAGS.height, FLAGS.width),
                                             match_threshold=match_threshold)

            # Anomaly: End track if match not found in current frame
            if picked_idx < 0:
                # print('Lost Track', tid)
                assert(tid not in tracks)
                tracks[tid] = active_tracks[tid]
                active_tracks.pop(tid)
            else:
                # print('Tracking', tid)
                # Track collision ??
                if picked_idx in tracked_detections[curr_frame]:
                    assert(tid not in tracks)
                    tracks[tid] = active_tracks[tid]
                    active_tracks.pop(tid)
                else:
                    tracked_detections[curr_frame].append(picked_idx)
                    active_tracks[tid].append((curr_frame,
                                               boxes[picked_idx],
                                               masks[picked_idx],
                                               classes[picked_idx],
                                               scores[picked_idx],
                                               picked_iou))

        # Start new tracks for all untracked detections in the current frame
        high_conf_idx = np.where((scores > pick_threshold) > 0)

        # Only start tracks for objects which are currently untracked
        untracked_idx = []
        for idx in high_conf_idx[0]:
            if idx not in tracked_detections[curr_frame]:
                untracked_idx.append(idx)

        for uidx in untracked_idx:
            track_info = (curr_frame, boxes[uidx],
                          masks[uidx], classes[uidx],
                          scores[uidx], 0.0)
            tracked_detections[curr_frame].append(uidx)
            track_id = track_id + 1
            active_tracks[track_id] = []
            # print('Starting New Track', track_id)
            active_tracks[track_id].append(track_info)

        curr_frame = curr_frame + 1
        prev_frame = frame[0]

    # End all active tracks
    for tid in active_tracks.keys():
        assert(tid not in tracks)
        tracks[tid] = active_tracks[tid]
        active_tracks.pop(tid)

    store_tracks(FLAGS.tracks_out_dir, FLAGS.video_path, tracks)

def store_tracks(tracks_out_path, video_path, tracks):
    for tid in tracks:
        track = tracks[tid]
        start_frame = track[0][0]
        end_frame = track[-1][0]
        boxes = map(lambda x: (x[1]).tolist(), track)
        curr_track = {'filename': video_path, 'start': start_frame, \
                            'end': end_frame, 'boxes': boxes,  \
                            'w': FLAGS.width, 'h': FLAGS.height}
        with open(tracks_out_path + '/track_' + str(tid) + '.txt', 'w') as outfile:
            json.dump(curr_track, outfile)

if __name__ == '__main__':
  tf.app.run()


from framework.utils import json_reader
from onliner.page_objects.main_page import MainPage
from onliner.page_objects.catalog_page import CatalogPage
from onliner.page_objects.result_page import ResultPage

test_data_path = "onliner\\resources\\test_data.json"
test_data = json_reader.get_json(test_data_path)

def test_onliner_tv_flow(setup):

    main_page = MainPage()
    main_page.onliner_header.click_on_catalog_top_bar("Каталог")

    catalog_page = CatalogPage()
    catalog_page.navigate_to_menu("Электроника")
    catalog_page.navigate_to_submenu("Телевидение и видео")
    catalog_page.click_on_submenu_item("Телевизоры")

    result_page = ResultPage()
    result_page.click_on_filter_checkbox(test_data["VENDOR"])
    result_page.set_max_price(test_data["MAX_PRICE"])
    result_page.click_on_filter_checkbox(test_data["RESOLUTION"])
    result_page.set_min_size(test_data["MIN_SIZE"])
    result_page.set_max_size(test_data["MAX_SIZE"])

    result_page.assert_headers(test_data["VENDOR"])
    result_page.assert_descriptions(
        test_data["RESOLUTION"], test_data["MIN_SIZE"], test_data["MAX_SIZE"])
    result_page.assert_prices(test_data["MAX_PRICE"])


#!/usr/bin/env python

# Import necessary libraries
import rospy
from sensor_msgs.msg import JointState

def publish_joint_states():
    # Initialize the ROS node
    rospy.init_node('joint_state_publisher', anonymous=True)

    # Create a publisher for JointState messages
    pub = rospy.Publisher('/oqp_joint_states', JointState, queue_size=10)

    # Create a new JointState message
    joint_state = JointState()
    joint_state.header.stamp = rospy.Time.now()

    # Define joint names (change these to your specific joint names)
    joint_state.name = ['joint0', 'joint1', 'joint2', 'joint3', 'joint4', 'joint5', 'joint6', 'joint7', 'joint8', 'joint9', 'joint10', 'joint11']

    # Define joint positions (change these values as needed)
    joint_state.position = [0, -0.872665, 1.5708, 0, -0.872665, 1.5708, 0, -0.872665, 1.5708, 0, -0.872665, 1.5708]

    # Optionally define velocities and efforts
    joint_state.velocity = []
    joint_state.effort = []

    rate = rospy.Rate(10) # 10hz
    # Publish the JointState message
    while not rospy.is_shutdown():
        pub.publish(joint_state)
        rate.sleep()

if __name__ == '__main__':
    try:
        publish_joint_states()
    except rospy.ROSInterruptException:
        pass


from __future__ import annotations

from operator import add
from operator import mul
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from collections.abc import Generator

class Expr:
    def __init__(self, inp: str) -> None:
        self.inp = inp

    def evaluate(self, precedence: dict[str, int]) -> int:
        """adapted from https://archive.ph/FAJ9I"""
        postfix: list[int | str] = []
        ops: list[str] = []

        i = 0
        while i < len(self.inp):
            c = self.inp[i]
            if c == "*" or c == "+":
                while ops and precedence[c] <= precedence[ops[-1]]:
                    postfix.append(ops.pop())
                ops.append(c)
            elif "0" <= c <= "9":
                postfix.append(int(c))
            elif c == "(":
                bc = 0
                j = i
                while j < len(self.inp):
                    jc = self.inp[j]
                    if jc == "(":
                        bc += 1
                    elif jc == ")":
                        bc -= 1
                        if bc == 0:
                            break
                    j += 1

                postfix.append(Expr(self.inp[i + 1 : j]).evaluate(precedence))
                i = j

            i += 1

        postfix.extend(reversed(ops))

        s = []
        for p in postfix:
            if isinstance(p, int):
                s.append(p)
            else:
                s.append((mul if p == "*" else add)(s.pop(), s.pop()))

        return s[0]

def parse(filename: str) -> Generator[Expr, None, None]:
    with open(filename) as f:
        for line in f:
            yield Expr(line.strip())

def execute(filename: str, precedence: dict[str, int]) -> int:
    return sum(expr.evaluate(precedence) for expr in parse(filename))

def part1(filename: str) -> int:
    return execute(filename, {"+": 1, "*": 1})

def part2(filename: str) -> int:
    return execute(filename, {"+": 2, "*": 1})

if __name__ == "__main__":
    from advent_of_code.common.main import main

    raise SystemExit(main(part1, part2))


from testapi import test_api

test_data = {"api":"http://api/to/be/tested",
            "method": "get",
            "auth": 0,  # 1 if auth is required, 0 for no authentication. Also, if no "auth" parameter is set, we take it as "auth": 0
#           "auth_details": ("user": "pass")   # if "auth": 1
            "transaction": "s",        # s for single & m for many
            "data_set_count": 3,
            "params_per_url": 1,
            "url_params_count": 3,
            "url_params": [["1234567"], ["DD3464750"], ["3232323"]],
#            "parameters": [{},{}],    if parameters exists
            "results": [{u"status": u"Used"}, {u'Price': 1200, u'status': u'UnUsed'}, {u"status": u"Used"}]   # [{},{}], for more cases
            }

test_data1 = {"api":"http://api/to/be/tested/",
            "method": "get",
            "auth": 0,
            "transaction": "s",
#            "parameters": [{},{}],    if parameters exists
            "params_per_url": 1,
            "url_params_count": 3,
            "url_params": [["1234567"], ["DD3464750"], ["3232323"]],
            "results": [{u"status": u"Used"}, {u'Price': 1200, u'status': u'UnUsed'}, {u"status": u"Used"}]   # [{},{}], for more cases
            }

test_data2_parameters = [
    {'id': 'CBE1234567', 'slotid': '131', 'slottime': '2015-04-23 13:00:00', 'status': '0', 'slotdatetime': '2015-04-23 14:00:00', 'slotpills': 'crocin, erythromycin'},
    ]
test_data2_results = [
    {u"status":u"success",u"slotdatetime":u"2015-04-23 14:00:00",u"slotpills":u"crocin, erythromycin"},
    ]
test_data2 = {"api":"http://api/to/be/tested/",
            "method": "post",
            "auth": 0,
            "transaction": "s",
            "data_set_count": 1,
            "parameters": test_data2_parameters,
            # "params_per_url": 1,
            # "url_params_count": 3,
            # "url_params": [["1234567"], ["DD3464750"], ["3232323"]],
            "results": test_data2_results
            }

# test_api(test_data)
test_api(test_data2)


import os
import math
import pandas as pd

def list_folders(path):
    dir_list = []
    for item in os.listdir(path):
        item_path = os.path.join(path, item)
        if os.path.isdir(item_path):
            dir_list.append(item)
    return dir_list

# session based analysis
def generate_all_session_log(path):
    dir_list = list_folders(path)
    date_list = []
    mouse_list = []
    filename_list = []
    for f in dir_list:
        date_list.append(f[0:10])
        mouse = f[-5:]
        mouse_list.append(mouse)
        filename_list.append(f'data_{mouse}_{f[0:19]}.txt')
    session_log = pd.DataFrame({'date': date_list, 'mouse': mouse_list,
                                'dir': dir_list, 'filename': filename_list})
    session_log = session_log.sort_values(by = ['date', 'mouse'])

    return session_log

def check_proper_end(last_trial):
    # proper end has the largest trial number to be session ending
    session_end = last_trial.loc[(last_trial['key'] == 'session') & (last_trial['value'] == 0)]
    last_trial_end = last_trial.loc[(last_trial['key'] == 'trial') & (last_trial['value'] == 0)]
    if len(session_end) > 0 and len(last_trial_end) > 0:
        return True
    else:
        return False

def get_session_basics(session_df):
    num_trials = session_df.session_trial_num.max()
    last_trial = session_df.loc[session_df['session_trial_num'] == num_trials]
    proper_end = check_proper_end(last_trial)
    if proper_end:
        proper_end = True
    else:
        proper_end = False
        num_trials -= 1
        last_trial = session_df.loc[session_df['session_trial_num'] == num_trials]

    num_blocks = last_trial.loc[(last_trial['key'] == 'trial') & (last_trial['value'] == 1), 'block_num'].iloc[0] + 1
    total_reward = round(session_df.reward_size.sum(), 2)
    total_time = round((session_df.session_time.max() - session_df.session_time.min()), 2)
    session_basic = [num_blocks, num_trials + 1, total_reward, total_time, proper_end]
    return session_basic

# trial based analysis
# preprocessing of raw data
def generate_total_trial_list(session_log, dir_name):
    """makes a list of 0 to total trial number, used to loop in the session"""
    current_session = session_log.loc[session_log.dir == dir_name]
    total_trial_list = range(int(current_session.num_trials.tolist()[0]))
    return total_trial_list

def get_trial_basics(trial):
    """gets the df of a trial, extracts 5 things, and outputs as a dictionary"""
    trial_start = trial.loc[(trial['key'] == 'trial') & (trial['value'] == 1)].iloc[0]
    trial_end = trial.loc[(trial['key'] == 'trial') & (trial['value'] == 0)].iloc[0]

    trial_basics = {'start_time': trial_start['session_time'],
                    'end_time': trial_end['session_time'],
                    'block_num': trial_start['block_num'],
                    'session_trial_num': trial_start['session_trial_num'],
                    'block_trial_num': trial_start['block_trial_num']}
    return trial_basics

def align_trial_number(session, trial_basics):
    session.loc[session['session_time'].between(trial_basics['start_time'], trial_basics['end_time']),
                'block_num'] = trial_basics['block_num']
    session.loc[session['session_time'].between(trial_basics['start_time'], trial_basics['end_time']),
                'session_trial_num'] = trial_basics['session_trial_num']
    session.loc[session['session_time'].between(trial_basics['start_time'], trial_basics['end_time']),
                'block_trial_num'] = trial_basics['block_trial_num']

def get_trial_state_times(trial):
     """gets the df of a trial, extracts start time of each state and outputs as a dictionary"""
     bg_start = trial.loc[(trial['key'] == 'background') & (trial['value'] == 1)].iloc[0]
     wait_start = trial.loc[(trial['key'] == 'wait') & (trial['value'] == 1)].iloc[0]
     if 'consumption' in trial.key.unique():
          consumption_start = trial.loc[(trial['key'] == 'consumption') & (trial['value'] == 1), 'session_time'].iloc[0]
     else:
         consumption_start = math.nan

     trial_state_times = {'bg_start': bg_start['session_time'],
                          'wait_start': wait_start['session_time'],
                          'consumption_start': consumption_start}

     return trial_state_times

def align_trial_states(session, trial_state_times, trial_basics):
    session.loc[session['session_time'].between(trial_state_times['bg_start'],
                                                trial_state_times['wait_start']), 'state'] = 'in_background'
    session.loc[session['session_time'].between(trial_state_times['wait_start'],
                                                trial_state_times['consumption_start']), 'state'] = 'in_wait'
    session.loc[session['session_time'].between(trial_state_times['consumption_start'],
                                                trial_basics['end_time']), 'state'] = 'in_consumption'

def add_trial_time(session, t, trial, trial_basics):
    trial_time = trial.session_time - trial_basics['start_time']
    trial_time = trial_time.tolist()
    session.loc[session['session_trial_num'] == t, 'trial_time'] = trial_time

# adding data to all trials df
def get_trial_bg_data(trial):
    background = trial.loc[trial['state'] == 'in_background']
    bg_length = background.loc[background['key'] == 'background', 'time_bg'].iloc[0]
    num_bg_licks = len(background.loc[(background['key'] == 'lick') & (background['value'] == 1)])
    if bg_length < 2:
        blk_type = 's'
    elif bg_length > 2:
        blk_type = 'l'
    return [bg_length, blk_type, num_bg_licks]

def get_trial_wait_data(trial):
    """gets 3 values about trial performance, takes trial raw data as input"""
    wait_start_time = trial.loc[(trial['key'] == 'wait') & (trial['value'] == 1), 'session_time'].iloc[0]
    if 'consumption' in trial.key.unique():
        miss_trial = False
        reward = trial.loc[trial['key'] == 'consumption', 'reward_size'].iloc[0]
        consumption_start_time = trial.loc[trial['key'] == 'consumption', 'session_time'].iloc[0]
        time_waited = consumption_start_time - wait_start_time
        consumption = trial.loc[trial['state'] == 'in_consumption']
        num_consumption_lick = len(consumption.loc[(consumption['key'] == 'lick') & (consumption['value'] == 1)])
    else:
        miss_trial = True
        reward = math.nan
        time_waited = math.nan
        num_consumption_lick = math.nan

    return [miss_trial, time_waited, reward, num_consumption_lick]

def get_trial_performance(trial):
    bg_data = get_trial_bg_data(trial)
    wait_data = get_trial_wait_data(trial)
    trial_data = bg_data + wait_data
    if (bg_data[2] == 0) & (wait_data[0] == False):
        trial_data.append(True)
    else:
        trial_data.append(False)
    return trial_data

# stitching functions
def generate_stitched_session_log(session_log):
    unique_date_list = session_log.date.unique().tolist()
    unique_mouse_list = session_log.mouse.unique().tolist()

    date_list = []
    mouse_list = []
    dir_list = []
    filename_list = []
    num_sess_list = []

    for d in unique_date_list:
        log_date = session_log.loc[session_log.date == d]
        for m in unique_mouse_list:
            log_date_mouse = log_date.loc[log_date.mouse == m]
            if len(log_date_mouse) == 0:
                continue
            else:
                date_list.append(d)
                mouse_list.append(m)
                dir_list.append(f'{d}_{m}')
                filename_list.append(f'processed_data_{m}_{d}.csv')
                num_sess_list.append(len(log_date_mouse))

    stitched_session_log = pd.DataFrame({'date': date_list, 'mouse': mouse_list, 'dir': dir_list,
                                         'filename': filename_list, 'num_sessions': num_sess_list})

    return(stitched_session_log)

def generate_stitched_all_mice_session_log(session_log):
    unique_date_list = session_log.date.unique().tolist()

    date_list = []
    filename_list = []
    num_sess_list = []

    for d in unique_date_list:
        log_date = session_log.loc[session_log.date == d]
        if len(log_date) == 0:
            continue
        else:
            date_list.append(d)
            filename_list.append(f'processed_data_{d}.csv')
            num_sess_list.append(len(log_date))

    stitched_all_mice_session_log = pd.DataFrame({'date': date_list, 'filename': filename_list,
                                         'num_sessions': num_sess_list})

    return(stitched_all_mice_session_log)

def stitch_sessions(session_1, session_2):
    session_1_basics = get_session_basics(session_1)
    time_offset = session_1_basics[3]
    block_offset = session_1_basics[0]
    trial_offset = session_1_basics[1]

    session_2.session_time = session_2.session_time + time_offset
    session_2.block_num = session_2.block_num + block_offset
    session_2.session_trial_num= session_2.session_trial_num + trial_offset

    stitched_session = pd.concat([session_1, session_2])
    return stitched_session

def stitch_all_trials(all_trials_1, all_trials_2):
    trial_offset = all_trials_1.session_trial_num.max()+1
    block_offset = all_trials_1.block_num.max()+1
    time_offset = all_trials_1.end_time.max()

    all_trials_2.session_trial_num = all_trials_2.session_trial_num + trial_offset
    all_trials_2.block_num = all_trials_2.block_num + block_offset
    all_trials_2.start_time = all_trials_2.start_time + time_offset
    all_trials_2.end_time = all_trials_2.end_time + time_offset

    stitched_all_trials = pd.concat([all_trials_1, all_trials_2])

    return stitched_all_trials


from ddd import *
from time import *
tim = time()
print(tim)
time2 = tim
mmmm={}
def look_for_mac():
    global time2
    liste=[]
    f = ["2019-Mar-12-access.log"]
    global mmmm
    for k in f:

        file = open("Data/"+k)
        data = file.readlines()

        for ooo in range(0,len(data)):

            b = data[ooo]
            c=b.split("][")
            if c[-3].upper() in liste:
                continue
            if not "ksz" in c[-4]:
                continue
            if "anony" in c[-3]:
                continue

            per = ooo/2877*100.

            print(str(per)+ "%")
            kp = start(c[-3].upper())
            print(kp,c[-3].upper())
            if kp in mmmm.keys():
                mmmm[kp]+=[[c[-3],c[-4]]]
            else:
                mmmm[kp]=[[c[-3],c[-4]]]

            liste+=[c[-3].upper()]
            #print(time2-time())
            time2= time()

    return mmmm

print(look_for_mac())
file = open("dic.data","w")
file.write(str(mmmm))
file.close()

print(time()-tim)


# https://www.hackerrank.com/contests/apt-coding-challenge/challenges/toll-cost-digits

if __name__ == '__main__':
    road_nodes, road_edges = map(int, input().split())

    adj = [[] for i in range(road_nodes)]
    for ee in range(road_edges):
        a, b, c = map(int, input().split())
        a -= 1
        b -= 1
        adj[a].append((b, +c % 10))
        adj[b].append((a, -c % 10))

    ovis = [False] * road_nodes
    vis = [[False] * 10 for i in range(road_nodes)]

    ans = [0] * 10
    for s in range(road_nodes):
        if ovis[s]: continue
        queue = [(s, 0)]
        vis[s][0] = True
        f = 0
        ct = [0] * 10
        while f < len(queue):
            i, d = queue[f]
            f += 1
            ct[d] += 1
            for j, nd in adj[i]:
                nd = (nd + d) % 10
                if not vis[j][nd]:
                    vis[j][nd] = True
                    queue.append((j, nd))

        for i, d in queue:
            if ovis[i]:
                continue
            ovis[i] = True
            d = -d % 10
            for nd in range(10):
                ans[(nd + d) % 10] += ct[nd] - vis[i][nd]

    for v in ans: print(v)


from django.shortcuts import get_object_or_404, redirect, render

from .models import Item, Location
from .forms import ItemForm, LocationForm

def list(request):
    """inventory list view"""
    items_list = Item.objects.all()
    context = {'items_list': items_list}
    return render(request, 'inventory/index.html', context)

def detail(request, item_id):
    """item detail view"""
    if request.method == 'GET':
        item = get_object_or_404(Item, pk=item_id)
        return render(request, 'inventory/detail.html', {'item': item})

def create(request):
    """create item view"""
    create_item_form = ItemForm
    if request.method == 'POST':
        form = ItemForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
    return render(request, 'inventory/create.html', {'form': create_item_form})

def update(request, item_id):
    """edit item view"""
    item = Item.objects.get(pk=item_id)
    form = ItemForm(request.POST or None, instance=item)
    if form.is_valid():
        form.save()
        return redirect('/')
    return render(request, 'inventory/update.html', {'item': item, 'form': form})

def delete(request, item_id):
    """delete item view"""
    item = Item.objects.get(pk=item_id)
    item.delete()
    return redirect('/')

def location_list(request):
    """locations view"""
    locations_list = Location.objects.all()
    add_location_form = LocationForm
    context = {'locations_list': locations_list, 'form': add_location_form}
    if request.method == 'POST':
        form = LocationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/location_list/')
    return render(request, 'inventory/list_locations.html', context)

def delete_location(request, location_id):
    """delete location view"""
    location = Location.objects.get(pk=location_id)
    location.delete()
    return redirect('/location_list/')


import json

from .food_establishment import FoodEstablishment
from .local_business import LocalBusiness

archive = open('model/Objetos.json', 'r')
string = archive.read()
objects = json.loads(string)
id = 0
datos = []
for object in objects:
    if object['@type'] == 'FoodEstablishment':
        nuevo = FoodEstablishment(object)
        nuevo.id = id
        id =  id +1
        datos.append(nuevo)
    elif object['@type'] == 'LocalBusiness':
        nuevo = LocalBusiness(object)
        nuevo.id = id
        id =  id +1
        datos.append(nuevo)


import pickle
import yahoo_fin.stock_info as si
from yahoo_fin.stock_info import get_data

# Getting list of tickers for S&P 500, Nasdaq Composite and DJIA
def get_tickers():
    sp500_list = si.tickers_sp500()
    nasdaq_list = si.tickers_nasdaq()
    dow_list = si.tickers_dow()
    combined_list = list(set(sp500_list + nasdaq_list + dow_list))
    print(f"Number of stocks in S&P 500: {len(sp500_list)}")
    print(f"Number of stocks in Nasdaq Composite: {len(nasdaq_list)}")
    print(f"Number of stocks in DJIA: {len(dow_list)}")
    print()
    return combined_list

# Fetching historical data for each ticker
def fetch_historical_data(combined_list, date_start, date_today):
    h_data = {}
    for ticker in combined_list:
        try:
            temp_data = get_data(ticker, start_date=date_start,
                                 end_date=date_today, index_as_date=False,
                                 interval="1wk")
            if not (temp_data['date'].iloc[-1] == temp_data['date'].iloc[0]):
                h_data[ticker] = temp_data
                print(f"Fetching data for {ticker}")
        except Exception as e:
            print(f"Could not fetch data for {ticker}, Error {e}")
    return h_data

# Method to fetch saved historical data
def fetch_saved_data():
    with open(
        'C:\\Users\\sjpar\\Desktop\\iCloudDrive\\DataProject2\\h_data.pkl',
        'rb') as f:
        h_data = pickle.load(f)
    return h_data


import pygame

image_assets = [
    "person_normal.png",
    "person_vax.png",
    "person_zombie.png",
]
grid_start = (150, 150)
cell_dimensions = (100, 100)
BACKGROUND = "#DDC2A1"
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
CELL_COLOR = (233, 222, 188)
screen = pygame.display.set_mode((1200, 800))
pygame.display.set_caption("Outbreak!")
pygame.font.init()
font = pygame.font.SysFont("Impact", 30)
cell_dimensions = (100, 100)
game_window_dimensions = (1400, 800)
person_dimensions = (20, 60)
grid_start = (150, 150)
pygame.display.set_caption("Outbreak!")
# screen = pygame.display.set_mode(game_window_dimensions)
screen.fill("#DDC2A1")

RESET_MOVE_COORDS = (800, 600)
RESET_MOVE_DIMS = (200, 50)

def get_action(B, pixel_x, pixel_y):
    """
    Get the action that the click represents.
    If the click was on the heal button, returns "heal"
    Else, returns the board coordinates of the click (board_x, board_y)
    """
    heal_check = pixel_x >= 900 and pixel_x <= 1100 and pixel_y > 199 and pixel_y < 301
    reset_move_check = (
        pixel_x >= RESET_MOVE_COORDS[0]
        and pixel_x <= RESET_MOVE_COORDS[0] + RESET_MOVE_DIMS[0]
        and pixel_y >= RESET_MOVE_COORDS[1]
        and pixel_y <= RESET_MOVE_COORDS[1] + RESET_MOVE_DIMS[1]
    )
    board_x = int((pixel_x - 150) / 100)
    board_y = int((pixel_y - 150) / 100)
    move_check = (
        board_x >= 0 and board_x < B.columns and board_y >= 0 and board_y < B.rows
    )
    board_coords = (int((pixel_x - 150) / 100), int((pixel_y - 150) / 100))

    if heal_check:
        return "heal"
    elif reset_move_check:
        return "reset move"
    elif move_check:
        return board_coords
    return None

def display_people(StateList, board_dimensions):
    for x in range(len(StateList)):
        if StateList[x].person != None:
            p = StateList[x].person
            char = "Assets/" + image_assets[0]
            if p.isVaccinated:
                char = "Assets/" + image_assets[1]
            elif p.isZombie:
                char = "Assets/" + image_assets[2]
            coords = (
                int(x % board_dimensions[0]) * 100 + 185,
                int(x / board_dimensions[1]) * 100 + 170,
            )
            display_image(screen, char, (35, 60), coords)

def run(GameBoard, bd):
    screen.fill(BACKGROUND)
    build_grid(screen, 5, 100, 150)
    display_image(screen, "Assets/cure.jpeg", cell_dimensions, (950, 200))
    # pygame.display.flip()
    display_people(GameBoard.States, bd)
    display_reset_move_button()
    return pygame.event.get()

def display_reset_move_button():
    rect = pygame.Rect(
        RESET_MOVE_COORDS[0],
        RESET_MOVE_COORDS[1],
        RESET_MOVE_DIMS[0],
        RESET_MOVE_DIMS[1],
    )
    pygame.draw.rect(screen, BLACK, rect)
    screen.blit(font.render("Reset move?", True, WHITE), RESET_MOVE_COORDS)

def display_board(screen, Board):
    screen.fill(BACKGROUND)
    dif = cell_dimensions[0] / 3
    ydif = cell_dimensions[1] / 4
    margin = 5
    i = 0
    for State in Board.States:
        person = State.person
        if person is not None:
            icon = "Assets/" + image_assets[0]
            if person.isZombie:
                icon = "Assets/" + image_assets[2]
            elif person.isVaccinated:
                icon = "Assets/" + image_assets[1]
            position = Board.toCoord(i)
            x_start = (
                (position[0] * cell_dimensions[0])
                + grid_start[0]
                + (cell_dimensions[0] / 3)
            )
            y_pos = (
                (position[1] * cell_dimensions[1])
                + grid_start[1]
                + (cell_dimensions[1] / 4)
            )
            display_image(screen, icon, (35, 60), (x_start, y_pos))
        i += 1
    build_grid(screen, 5, cell_dimensions[0], 150)
    pygame.display.update()

def display_image(screen, itemStr, dimensions, position):
    v = pygame.image.load(itemStr).convert_alpha()
    v = pygame.transform.scale(v, dimensions)
    screen.blit(v, position)

def build_grid(screen, margin, cell_side, start):
    grid_width = 600
    grid_height = 600
    pygame.draw.rect(screen, BLACK, [start - 5, start - 5, 5, grid_height + 10])  # left
    pygame.draw.rect(
        screen, BLACK, [start + grid_width, start - 5, 5, grid_height + 10]
    )  # right
    pygame.draw.rect(
        screen, BLACK, [start - 5, start + grid_height, grid_width + 10, 5]
    )  # bottom
    pygame.draw.rect(screen, BLACK, [start - 5, start - 5, grid_width + 10, 5])  # top
    pygame.draw.rect(screen, CELL_COLOR, [start, start, grid_width, grid_height])
    i = start + cell_side
    while i < start + grid_width:
        pygame.draw.rect(screen, BLACK, [i, start, 5, grid_height])
        i += cell_side
    i = start + cell_side
    while i < start + grid_height:
        pygame.draw.rect(screen, BLACK, [start, i, grid_width, 5])
        i += cell_side

def display_win_screen():
    screen.fill(BACKGROUND)
    screen.blit(
        font.render("You win!", True, WHITE),
        (500, 400),
    )
    pygame.display.update()

    # catch quit event
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return

def display_lose_screen():
    screen.fill(BACKGROUND)
    screen.blit(
        font.render("You lose lol!", True, WHITE),
        (500, 500),
    )
    pygame.display.update()

    # catch quit event
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            return

def direction(coord1, coord2):
    if coord2[1] > coord1[1]:
        return "moveDown"
    elif coord2[1] < coord1[1]:
        return "moveUp"
    elif coord2[0] > coord1[0]:
        return "moveRight"
    elif coord2[0] < coord1[0]:
        return "moveLeft"


import io
import pycurl
from StringIO import StringIO

import stem.process

from stem.util import term

SOCKS_PORT = 7000

def query(url):
	buffer = StringIO()

	query = pycurl.Curl()
	query.setopt(pycurl.URL, url)
	query.setopt(pycurl.PROXY, 'localhost')
	query.setopt(pycurl.PROXYPORT, SOCKS_PORT)
	query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
	query.setopt(pycurl.WRITEFUNCTION, buffer.write)

	try:
		query.perform()
		return buffer.getvalue()
	except pycurl.error as exc:
		return "Unable to read %s (%s)" % (url, exc)

def print_bootstrap_lines(line):
	if "Bootstrapped " in line:
		print(term.format(line, term.Color.RED))

print("Launching Tor:\n")

tor_process = stem.process.launch_tor_with_config(
	config = {
		'SocksPort': str(SOCKS_PORT),
		'ExitNodes': '{ru}',
	},
	init_msg_handler = print_bootstrap_lines,
)

print("\nChecking our endpoint:\n")
print(query("http://www.nytimes.com/"))

print("\nKilling Tor process...\n")

tor_process.kill()

print ("\nExecution complete.\n")


from Bio import SeqIO
import pandas as pd
import sys
'''
This simple script gets transcripts from a fasta file and creates a structured dataframe with them.
'''

# This file has every transcript from hg38.p13 downloaded using Biomart from https://www.ensembl.org/
#FASTA_FILE = '../rawdata/EveryEnsemblTranscript_withflanks.fasta'
#DATAFRAME_OUT_FILE = '../rawdata/mouse_EveryEnsemblTranscript_withflanks_dataframe.csv'
FASTA_FILE = sys.argv[1]
DATAFRAME_OUT_FILE = sys.argv[2]

# These fields come from the fasta file header *IN THIS SPECIFIC ORDER* (based on the fields selected from Biomart)
ensembl_df = pd.DataFrame(columns=['Gene stable ID version', 'Transcript stable ID version', 'Gene start (bp)', 'Chromosome_scaffold name',
                                   'Gene name', 'Transcript start (bp)', 'Transcription start site (TSS)', 'CDS Length', 'CDS start', 'CDS end',
                                   'Transcript end (bp)', 'Start phase', 'End phase', 'cDNA coding start', 'cDNA coding end', 'Genomic coding start',
                                   'Genomic coding end', 'Constitutive exon', 'Exon rank in transcript', 'Strand', 'Exon region start (bp)', 'Exon region end (bp)',
                                   'Exon_stable_ID', 'Sequence'])

ensembl_data = list(SeqIO.parse(FASTA_FILE, "fasta"))

i = 0
for record in ensembl_data:
    Gene_stable_ID_version, Transcript_stable_ID_version, Gene_start_bp, Chromosome_scaffold_name, Gene_name, Transcript_start_bp, \
    Transcription_start_site_TSS, CDS_Length, CDS_start, CDS_end, Transcript_end_bp, Start_phase, End_phase, \
    cDNA_coding_start, cDNA_coding_end, Genomic_coding_start, Genomic_coding_end, Constitutive_exon, Exon_rank_in_transcript, Strand, \
    Exon_region_start_bp, Exon_region_end_bp, Exon_stable_ID = record.id.split('|')

    ensembl_df.loc[i] = [Gene_stable_ID_version, Transcript_stable_ID_version, Gene_start_bp, Chromosome_scaffold_name, Gene_name, Transcript_start_bp, \
                        Transcription_start_site_TSS, CDS_Length, CDS_start, CDS_end, Transcript_end_bp, Start_phase, End_phase, \
                        cDNA_coding_start, cDNA_coding_end, Genomic_coding_start, Genomic_coding_end, Constitutive_exon, Exon_rank_in_transcript, Strand, \
                        Exon_region_start_bp, Exon_region_end_bp, Exon_stable_ID, str(record.seq)]
    i += 1
    print(f'{i}/{len(ensembl_data)}', end='\r', flush=True)

ensembl_df.to_csv(DATAFRAME_OUT_FILE)


# Solution 1: 내 풀이
class Solution:
    def isValid(self, s: str) -> bool:
        stack = []
        for char in s:
            if char in "([{":
                stack.append(char)
                continue
            elif not stack:     # stack이 비었는데 닫는 괄호인 경우
                return False
            if char == ')' and stack[-1] == '(':
                stack.pop()
            elif char == ']' and stack[-1] == '[':
                stack.pop()
            elif char == '}' and stack[-1] == '{':
                stack.pop()
            else:   # stack에 일치하는 짝이 없는 경우
                return False

        if stack:
            return False
        else:   # stack에 문자가 남은 경우
            return True

# Solution 2: 정돈된 코드(풀이 참고)
from collections import defaultdict

class Solution2:
    def isValid(self, s: str) -> bool:
        paren_dict = defaultdict(str)
        paren_dict = {')':'(', '}':'{', ']':'['}
        stack = []

        for char in s:
            if char in paren_dict: # 닫는 괄호일 때
                if not stack or stack.pop() != paren_dict[char]:
                    return False
            else:
                stack.append(char)
        return not stack


from numpy import *

def matrix_multiplication(x, y):

    m1 = matrix(x)

    m2 = matrix(y)

    if m1.shape == m2.shape:

        m3 = m1 * m2

        print(f"\nMatrix 1: \n \n{m1} \n")

        print(f"Matrix 2: \n \n {m2} \n")

        print(f"The result matrix is: \n \n{m3}")

    else:

        print("Error")

matrix_multiplication('3 7 5; 2 6 7; 4 3 2', '6 5 4; 3 2 1; 1 2 3')


from django.urls import path
from .views import (
    StripeIntentOrderView,
    StripeSessionItemView,
    ItemView,
    StripeSessionOrderView,
    StripeIntentItemView,
    OrderView,
    SuccesView,
    FailView,
)

urlpatterns = [
    path("item/<int:pk>", ItemView.as_view(), name="get_item"),
    path("order/<int:order_pk>", OrderView.as_view(), name="get_order"),
    path(
        "buy/session/<int:pk>",
        StripeSessionItemView.as_view(),
        name="create_session_item",
    ),
    path(
        "buy/intent/<int:pk>",
        StripeIntentItemView.as_view(),
        name="create_payment_intent_item",
    ),
    path(
        "order/buy/session/<int:order_pk>",
        StripeSessionOrderView.as_view(),
        name="create_session_order",
    ),
    path(
        "order/buy/intent/<int:order_pk>",
        StripeIntentOrderView.as_view(),
        name="create_payment_order",
    ),
    path("success", SuccesView.as_view(), name="success"),
    path("fail", FailView.as_view(), name="fail"),
]


import curses

class PromptWindow:
    def __init__(self,stdscr=None,title=None):
        self.stdscr = stdscr
        self.title = title
        self.box_text = ""
        self.cursor_index = 0
        self.screen_h = 0
        self.screen_w = 0
        self.win_h = 0
        self.win_w = 0
        self.win_x = 0
        self.win_y = 0
    def set_win_dimensions(self, height, width ):
        self.screen_h, self.screen_w = self.stdscr.getmaxyx()
        self.win_h = height
        self.win_w = width
        self.win_y = (self.screen_h // 2) - (height // 2)
        self.win_x = (self.screen_w // 2) - (width // 2)

    def display(self, stdscr, height= 3, width = 20):
        self.stdscr = stdscr
        self.set_win_dimensions(height,width)
        win = curses.newwin( self.win_h,
                             self.win_w,
                             self.win_y,
                             self.win_x)

        win.box()
        win.addstr(0, (( self.win_w//2) - len(self.title)//2), self.title )

        running = True;

        while running:
            win.clear()
            win.box()
            win.addstr(0, (( self.win_w//2) - len(self.title)//2), self.title )

            if (len(self.box_text) < (self.win_w - 3)):
                win.addstr(1,1, self.box_text)
            else:
                win.addstr(1,1, self.box_text[self.cursor_index - (self.win_w-3):self.cursor_index])

            if (len(self.box_text) < (self.win_w - 3)):
                win.move(1,self.cursor_index+1)
            stdscr.refresh()
            win.refresh()
            key = stdscr.getkey()
            if (key == "KEY_BACKSPACE"): #backspace
                if (self.cursor_index == (len(self.box_text)-1)):
                    self.box_text = self.box_text[:-1]
                else:
                    self.box_text =self.box_text[:self.cursor_index-1]+\
                            self.box_text[self.cursor_index:]
                    if self.cursor_index > 0:
                        self.cursor_index -=1
            elif (key == "\n"): #enter
                running = False
            elif (key == "KEY_LEFT"): #left
                if self.cursor_index >= 0:
                    self.cursor_index -=1
            elif (key == "KEY_RIGHT"): #right
                if self.cursor_index < len(self.box_text):
                    self.cursor_index +=1
            else:
                if (self.cursor_index == (len(self.box_text)-1)):
                    self.box_text+= (key)
                else:
                    self.box_text =self.box_text[:self.cursor_index]+\
                            key + self.box_text[self.cursor_index:]

                self.cursor_index +=1

            #win.refresh()
            #stdscr.refresh()
        return self.box_text

        win.refresh()
        stdscr.refresh()

if __name__ == "__main__":
    my_aw = PromptWindow(title="enter rss feed link")
    print(curses.wrapper(my_aw.display, width=50))


import urllib
from urllib import parse, request
import json

def bot_response(message):
    try:
        text = urllib.parse.urlencode({'text': message})
        text = text.encode('UTF-8')
        url = urllib.request.Request('http://text-processing.com/api/sentiment/', text)
        url.add_header("Content-Type", "application/x-www-form-urlencoded")
        response = urllib.request.urlopen(url).read().decode('utf8', 'ignore')
        response = json.loads(response)
        return response['label']
    except Exception as e:
        return "Sorry, I didn't get that"