from test.base import QiskitExperimentsTestCase

import copy

import numpy as np

from ddt import ddt, data, unpack

from qiskit.circuit import Delay, QuantumCircuit, Parameter, Gate
from qiskit.circuit.library import SXGate, CXGate, TGate, CZGate
from qiskit.exceptions import QiskitError
from qiskit.providers.fake_provider import FakeManila, FakeManilaV2, FakeWashington, FakeParis
from qiskit.pulse import Schedule, InstructionScheduleMap
from qiskit.quantum_info import Operator
from qiskit.transpiler.basepasses import TransformationPass
from qiskit.transpiler import Layout, PassManager, CouplingMap

from qiskit_aer import AerSimulator
from qiskit_aer.noise import NoiseModel, depolarizing_error

from qiskit_experiments.database_service.exceptions import ExperimentEntryNotFound
from qiskit_experiments.framework.composite import ParallelExperiment
from qiskit_experiments.library import randomized_benchmarking as rb

class RBTestMixin:
    """Mixin for RB tests."""

    def assertAllIdentity(self, circuits):
        """Test if all experiment circuits are identity."""
        for circ in circuits:
            num_qubits = circ.num_qubits
            qc_iden = QuantumCircuit(num_qubits)
            circ.remove_final_measurements()
            self.assertTrue(Operator(circ).equiv(Operator(qc_iden)))

@ddt
class TestStandardRB(QiskitExperimentsTestCase, RBTestMixin):
    """Test for StandardRB without running the experiments."""

    def setUp(self):
        """Setup the tests."""
        super().setUp()
        self.backend = FakeManilaV2()

    # ### Tests for configuration ###
    @data(
        {"qubits": [3, 3], "lengths": [1, 3, 5, 7, 9], "num_samples": 1, "seed": 100},
        {"qubits": [0, 1], "lengths": [1, 3, 5, -7, 9], "num_samples": 1, "seed": 100},
        {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": -4, "seed": 100},
        {"qubits": [0, 1], "lengths": [1, 3, 5, 7, 9], "num_samples": 0, "seed": 100},
        {"qubits": [0, 1], "lengths": [1, 5, 5, 5, 9], "num_samples": 2, "seed": 100},
    )
    def test_invalid_configuration(self, configs):
        """Test raise error when creating experiment with invalid configs."""
        self.assertRaises(QiskitError, rb.StandardRB, **configs)

    def test_experiment_config(self):
        """Test converting to and from config works"""
        exp = rb.StandardRB(qubits=(0,), lengths=[10, 20, 30], seed=123)
        loaded_exp = rb.StandardRB.from_config(exp.config())
        self.assertNotEqual(exp, loaded_exp)
        self.assertTrue(self.json_equiv(exp, loaded_exp))

    def test_roundtrip_serializable(self):
        """Test round trip JSON serialization"""
        exp = rb.StandardRB(qubits=(0,), lengths=[10, 20, 30], seed=123)
        self.assertRoundTripSerializable(exp, self.json_equiv)

    def test_analysis_config(self):
        """ "Test converting analysis to and from config works"""
        analysis = rb.RBAnalysis()
        loaded = rb.RBAnalysis.from_config(analysis.config())
        self.assertNotEqual(analysis, loaded)
        self.assertEqual(analysis.config(), loaded.config())

    # ### Tests for circuit generation ###
    @data([[3], 4], [[4, 7], 5], [[0, 1, 2], 3])
    @unpack
    def test_generate_circuits(self, qubits, length):
        """Test RB circuit generation"""
        exp = rb.StandardRB(qubits=qubits, lengths=[length], num_samples=1)
        circuits = exp.circuits()
        self.assertAllIdentity(circuits)

    def test_return_same_circuit(self):
        """Test if setting the same seed returns the same circuits."""
        exp1 = rb.StandardRB(
            qubits=(0, 1),
            lengths=[10, 20, 30],
            seed=123,
            backend=self.backend,
        )

        exp2 = rb.StandardRB(
            qubits=(0, 1),
            lengths=[10, 20, 30],
            seed=123,
            backend=self.backend,
        )

        circs1 = exp1.circuits()
        circs2 = exp2.circuits()

        self.assertEqual(circs1[0].decompose(), circs2[0].decompose())
        self.assertEqual(circs1[1].decompose(), circs2[1].decompose())
        self.assertEqual(circs1[2].decompose(), circs2[2].decompose())

    def test_full_sampling_single_qubit(self):
        """Test if full sampling generates different circuits."""
        exp1 = rb.StandardRB(
            qubits=(0,),
            lengths=[10, 20, 30],
            seed=123,
            backend=self.backend,
            full_sampling=False,
        )
        exp2 = rb.StandardRB(
            qubits=(0,),
            lengths=[10, 20, 30],
            seed=123,
            backend=self.backend,
            full_sampling=True,
        )
        circs1 = exp1.circuits()
        circs2 = exp2.circuits()

        self.assertEqual(circs1[0].decompose(), circs2[0].decompose())

        # fully sampled circuits are regenerated while other is just built on top of previous length
        self.assertNotEqual(circs1[1].decompose(), circs2[1].decompose())
        self.assertNotEqual(circs1[2].decompose(), circs2[2].decompose())

    def test_full_sampling_2_qubits(self):
        """Test if full sampling generates different circuits."""
        exp1 = rb.StandardRB(
            qubits=(0, 1),
            lengths=[10, 20, 30],
            seed=123,
            backend=self.backend,
            full_sampling=False,
        )

        exp2 = rb.StandardRB(
            qubits=(0, 1),
            lengths=[10, 20, 30],
            seed=123,
            backend=self.backend,
            full_sampling=True,
        )

        circs1 = exp1.circuits()
        circs2 = exp2.circuits()

        self.assertEqual(circs1[0].decompose(), circs2[0].decompose())

        # fully sampled circuits are regenerated while other is just built on top of previous length
        self.assertNotEqual(circs1[1].decompose(), circs2[1].decompose())
        self.assertNotEqual(circs1[2].decompose(), circs2[2].decompose())

    # ### Tests for transpiled circuit generation ###
    def test_calibrations_via_transpile_options(self):
        """Test if calibrations given as transpile_options show up in transpiled circuits."""
        qubits = (2,)
        my_sched = Schedule(name="custom_sx_gate")
        my_inst_map = InstructionScheduleMap()
        my_inst_map.add(SXGate(), qubits, my_sched)

        exp = rb.StandardRB(
            qubits=qubits, lengths=[3], num_samples=4, backend=self.backend, seed=123
        )
        exp.set_transpile_options(inst_map=my_inst_map)
        transpiled = exp._transpiled_circuits()
        for qc in transpiled:
            self.assertTrue(qc.calibrations)
            self.assertTrue(qc.has_calibration_for((SXGate(), [qc.qubits[q] for q in qubits], [])))
            self.assertEqual(qc.calibrations["sx"][(qubits, tuple())], my_sched)

    def test_calibrations_via_custom_backend(self):
        """Test if calibrations given as custom backend show up in transpiled circuits."""
        qubits = (2,)
        my_sched = Schedule(name="custom_sx_gate")
        my_backend = copy.deepcopy(self.backend)
        my_backend.target["sx"][qubits].calibration = my_sched

        exp = rb.StandardRB(qubits=qubits, lengths=[3], num_samples=4, backend=my_backend)
        transpiled = exp._transpiled_circuits()
        for qc in transpiled:
            self.assertTrue(qc.calibrations)
            self.assertTrue(qc.has_calibration_for((SXGate(), [qc.qubits[q] for q in qubits], [])))
            self.assertEqual(qc.calibrations["sx"][(qubits, tuple())], my_sched)

    def test_backend_with_directed_basis_gates(self):
        """Test if correct circuits are generated from backend with directed basis gates."""
        my_backend = copy.deepcopy(self.backend)
        del my_backend.target["cx"][(1, 2)]  # make cx on {1, 2} one-sided

        exp = rb.StandardRB(qubits=(1, 2), lengths=[3], num_samples=4, backend=my_backend)
        transpiled = exp._transpiled_circuits()
        for qc in transpiled:
            self.assertTrue(qc.count_ops().get("cx", 0) > 0)
            expected_qubits = (qc.qubits[2], qc.qubits[1])
            for inst in qc:
                if inst.operation.name == "cx":
                    self.assertEqual(inst.qubits, expected_qubits)

@ddt
class TestInterleavedRB(QiskitExperimentsTestCase, RBTestMixin):
    """Test for InterleavedRB without running the experiments."""

    def setUp(self):
        """Setup the tests."""
        super().setUp()
        self.backend = FakeManila()
        self.backend_with_timing_constraint = FakeWashington()

    # ### Tests for configuration ###
    def test_non_clifford_interleaved_element(self):
        """Verifies trying to run interleaved RB with non Clifford element throws an exception"""
        with self.assertRaises(QiskitError):
            rb.InterleavedRB(
                interleaved_element=TGate(),  # T gate is not Clifford, this should fail
                qubits=[0],
                lengths=[1, 2, 3, 5, 8, 13],
            )

    @data([5, "dt"], [1e-7, "s"], [32, "ns"])
    @unpack
    def test_interleaving_delay_with_invalid_duration(self, duration, unit):
        """Raise if delay with invalid duration is given as interleaved_element"""
        with self.assertRaises(QiskitError):
            rb.InterleavedRB(
                interleaved_element=Delay(duration, unit=unit),
                qubits=[0],
                lengths=[1, 2, 3],
                backend=self.backend_with_timing_constraint,
            )

    def test_experiment_config(self):
        """Test converting to and from config works"""
        exp = rb.InterleavedRB(
            interleaved_element=SXGate(),
            qubits=(0,),
            lengths=[10, 20, 30],
            seed=123,
        )
        loaded_exp = rb.InterleavedRB.from_config(exp.config())
        self.assertNotEqual(exp, loaded_exp)
        self.assertTrue(self.json_equiv(exp, loaded_exp))

    def test_roundtrip_serializable(self):
        """Test round trip JSON serialization"""
        exp = rb.InterleavedRB(
            interleaved_element=SXGate(), qubits=(0,), lengths=[10, 20, 30], seed=123
        )
        self.assertRoundTripSerializable(exp, self.json_equiv)

    def test_analysis_config(self):
        """ "Test converting analysis to and from config works"""
        analysis = rb.InterleavedRBAnalysis()
        loaded = rb.InterleavedRBAnalysis.from_config(analysis.config())
        self.assertNotEqual(analysis, loaded)
        self.assertEqual(analysis.config(), loaded.config())

    # ### Tests for circuit generation ###
    class ThreeQubitGate(Gate):
        """A 3-qubit Clifford gate for tests"""

        def __init__(self):
            super().__init__("3q-gate", 3, [])

        def _define(self):
            qc = QuantumCircuit(3, name=self.name)
            qc.cx(0, 1)
            qc.x(2)
            self.definition = qc

    @data([SXGate(), [3], 4], [CXGate(), [4, 7], 5], [ThreeQubitGate(), [0, 1, 2], 3])
    @unpack
    def test_generate_interleaved_circuits(self, interleaved_element, qubits, length):
        """Test interleaved circuit generation"""
        exp = rb.InterleavedRB(
            interleaved_element=interleaved_element, qubits=qubits, lengths=[length], num_samples=1
        )
        circuits = exp.circuits()
        self.assertAllIdentity(circuits)

    @data([SXGate(), [3], 4], [CXGate(), [4, 7], 5])
    @unpack
    def test_interleaved_structure(self, interleaved_element, qubits, length):
        """Verifies that when generating an interleaved circuit, it will be
        identical to the original circuit up to additions of
        barrier and interleaved element between any two Cliffords.
        """
        exp = rb.InterleavedRB(
            interleaved_element=interleaved_element, qubits=qubits, lengths=[length], num_samples=1
        )

        circuits = exp.circuits()
        c_std = circuits[0]
        c_int = circuits[1]
        if c_std.metadata["interleaved"]:
            c_std, c_int = c_int, c_std
        num_cliffords = c_std.metadata["xval"]
        std_idx = 0
        int_idx = 0
        for _ in range(num_cliffords):
            # clifford
            self.assertEqual(c_std[std_idx], c_int[int_idx])
            # barrier
            self.assertEqual(c_std[std_idx + 1][0].name, "barrier")
            self.assertEqual(c_int[std_idx + 1][0].name, "barrier")
            # for interleaved circuit: interleaved element + barrier
            self.assertEqual(c_int[int_idx + 2][0].name, interleaved_element.name)
            self.assertEqual(c_int[int_idx + 3][0].name, "barrier")
            std_idx += 2
            int_idx += 4

    def test_preserve_interleaved_circuit_element(self):
        """Interleaved RB should not change a given interleaved circuit during RB circuit generation."""
        interleaved_circ = QuantumCircuit(2, name="bell_with_delay")
        interleaved_circ.h(0)
        interleaved_circ.delay(1.0e-7, 0, unit="s")
        interleaved_circ.cx(0, 1)

        exp = rb.InterleavedRB(
            interleaved_element=interleaved_circ, qubits=[2, 1], lengths=[1], num_samples=1
        )
        circuits = exp.circuits()
        # Get the first interleaved operation in the interleaved RB sequence:
        # 0: clifford, 1: barrier, 2: interleaved
        actual = circuits[1][2].operation
        self.assertEqual(interleaved_circ.count_ops(), actual.definition.count_ops())

    def test_interleaving_delay(self):
        """Test delay instruction can be interleaved."""
        # See qiskit-experiments/#727 for details
        from qiskit_experiments.framework.backend_timing import BackendTiming

        timing = BackendTiming(self.backend)
        exp = rb.InterleavedRB(
            interleaved_element=Delay(timing.round_delay(time=1.0e-7)),
            qubits=[0],
            lengths=[1],
            num_samples=1,
            seed=1234,  # This seed gives a 2-gate clifford
            backend=self.backend,
        )
        int_circs = exp.circuits()[1]
        self.assertEqual(int_circs.count_ops().get("delay", 0), 1)
        self.assertAllIdentity([int_circs])

    def test_interleaving_circuit_with_delay(self):
        """Test circuit with delay can be interleaved."""
        delay_qc = QuantumCircuit(2)
        delay_qc.delay(160, [0])
        delay_qc.x(1)

        exp = rb.InterleavedRB(
            interleaved_element=delay_qc,
            qubits=[1, 2],
            lengths=[1],
            num_samples=1,
            seed=1234,
            backend=self.backend,
        )
        int_circ = exp.circuits()[1]
        self.assertAllIdentity([int_circ])

    def test_interleaving_parameterized_circuit(self):
        """Fail if parameterized circuit is interleaved but after assigned it may be interleaved."""
        qubits = (2,)
        theta = Parameter("theta")
        phi = Parameter("phi")
        lam = Parameter("lambda")
        cliff_circ_with_param = QuantumCircuit(1)
        cliff_circ_with_param.rz(theta, 0)
        cliff_circ_with_param.sx(0)
        cliff_circ_with_param.rz(phi, 0)
        cliff_circ_with_param.sx(0)
        cliff_circ_with_param.rz(lam, 0)

        with self.assertRaises(QiskitError):
            rb.InterleavedRB(
                interleaved_element=cliff_circ_with_param,
                qubits=qubits,
                lengths=[3],
                num_samples=4,
                backend=self.backend,
            )

        # # TODO: Enable after Clifford supports creation from circuits with rz
        # # parameters must be assigned before initializing InterleavedRB
        # param_map = {theta: np.pi / 2, phi: -np.pi / 2, lam: np.pi / 2}
        # cliff_circ_with_param.assign_parameters(param_map, inplace=True)
        #
        # exp = rb.InterleavedRB(
        #     interleaved_element=cliff_circ_with_param,
        #     qubits=qubits,
        #     lengths=[3],
        #     num_samples=4,
        #     backend=self.backend,
        # )
        # circuits = exp.circuits()
        # for qc in circuits:
        #     self.assertEqual(qc.num_parameters, 0)

    # ### Tests for transpiled circuit generation ###
    def test_interleaved_circuit_is_decomposed(self):
        """Test if interleaved circuit is decomposed in transpiled circuits."""
        delay_qc = QuantumCircuit(2)
        delay_qc.delay(160, [0])
        delay_qc.x(1)

        exp = rb.InterleavedRB(
            interleaved_element=delay_qc,
            qubits=[1, 2],
            lengths=[3],
            num_samples=1,
            seed=1234,
            backend=self.backend,
        )
        transpiled = exp._transpiled_circuits()
        for qc in transpiled:
            self.assertTrue(all(not inst.operation.name.startswith("circuit") for inst in qc))
            self.assertTrue(all(not inst.operation.name.startswith("Clifford") for inst in qc))

    def test_interleaving_cnot_gate_with_non_supported_direction(self):
        """Test if cx(0, 1) can be interleaved for backend that support only cx(1, 0)."""
        my_backend = FakeManilaV2()
        del my_backend.target["cx"][(0, 1)]  # make support only cx(1, 0)

        exp = rb.InterleavedRB(
            interleaved_element=CXGate(),
            qubits=(0, 1),
            lengths=[3],
            num_samples=4,
            backend=my_backend,
        )
        transpiled = exp._transpiled_circuits()
        for qc in transpiled:
            self.assertTrue(qc.count_ops().get("cx", 0) > 0)
            expected_qubits = (qc.qubits[1], qc.qubits[0])
            for inst in qc:
                if inst.operation.name == "cx":
                    self.assertEqual(inst.qubits, expected_qubits)

class RBRunTestCase(QiskitExperimentsTestCase, RBTestMixin):
    """Base test case for running RB experiments defining a common noise model."""

    def setUp(self):
        """Setup the tests."""
        super().setUp()

        # depolarizing error
        self.p1q = 0.02
        self.p2q = 0.10
        self.pvz = 0.0
        self.pcz = 0.15

        # basis gates
        self.basis_gates = ["rz", "sx", "cx"]

        # setup noise model
        sx_error = depolarizing_error(self.p1q, 1)
        rz_error = depolarizing_error(self.pvz, 1)
        cx_error = depolarizing_error(self.p2q, 2)
        cz_error = depolarizing_error(self.pcz, 2)

        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(sx_error, "sx")
        noise_model.add_all_qubit_quantum_error(rz_error, "rz")
        noise_model.add_all_qubit_quantum_error(cx_error, "cx")
        noise_model.add_all_qubit_quantum_error(cz_error, "cz")

        self.noise_model = noise_model
        self.basis_gates = noise_model.basis_gates

        # Need level1 for consecutive gate cancellation for reference EPC value calculation
        self.transpiler_options = {
            "basis_gates": self.basis_gates,
            "optimization_level": 1,
        }

        # Aer simulator
        self.backend = AerSimulator(
            noise_model=noise_model,
            seed_simulator=123,
            coupling_map=AerSimulator.from_backend(FakeManila()).configuration().coupling_map,
        )

def decr_dep_param(q, q_1, q_2, coupling_map):
    """Helper function to generate a one-qubit depolarizing channel whose
    parameter depends on coupling map distance in a backend"""
    d = min(coupling_map.distance(q, q_1), coupling_map.distance(q, q_2))
    return 0.0035 * 0.999**d

class NonlocalCXDepError(TransformationPass):
    """Transpiler pass for simulating nonlocal errors in a quantum device"""

    def __init__(self, coupling_map, initial_layout=None):
        """Maps a DAGCircuit onto a `coupling_map` using swap gates.
        Args:
            coupling_map (CouplingMap): Directed graph represented a coupling map.
            initial_layout (Layout): initial layout of qubits in mapping
        """
        super().__init__()
        self.coupling_map = coupling_map
        self.initial_layout = initial_layout

    def run(self, dag):
        """Runs the NonlocalCXDepError pass on `dag`

        Args:
            dag (DAGCircuit): DAG to map.

        Returns:
            DAGCircuit: A mapped DAG.

        Raises:
            TranspilerError: initial layout and coupling map do not have the
            same size
        """

        if self.initial_layout is None:
            if self.property_set["layout"]:
                self.initial_layout = self.property_set["layout"]
            else:
                self.initial_layout = Layout.generate_trivial_layout(*dag.qregs.values())

        if len(dag.qubits) != len(self.initial_layout):
            raise TranspilerError("The layout does not match the amount of qubits in the DAG")

        if len(self.coupling_map.physical_qubits) != len(self.initial_layout):
            raise TranspilerError(
                "Mappers require to have the layout to be the same size as the coupling map"
            )

        canonical_register = dag.qregs["q"]
        trivial_layout = Layout.generate_trivial_layout(canonical_register)
        current_layout = trivial_layout.copy()

        subdags = []
        for layer in dag.layers():
            graph = layer["graph"]
            cxs = graph.op_nodes(op=CXGate)
            if len(cxs) > 0:
                for cx in cxs:
                    qubit_1 = current_layout[cx.qargs[0]]
                    qubit_2 = current_layout[cx.qargs[1]]
                    for qubit in range(dag.num_qubits()):
                        dep_param = decr_dep_param(qubit, qubit_1, qubit_2, self.coupling_map)
                        graph.apply_operation_back(
                            depolarizing_error(dep_param, 1).to_instruction(),
                            qargs=[canonical_register[qubit]],
                            cargs=[],
                        )
            subdags.append(graph)

        err_dag = dag.copy_empty_like()
        for subdag in subdags:
            err_dag.compose(subdag)

        return err_dag

class NoiseSimulator(AerSimulator):
    """Quantum device simulator that has nonlocal CX errors"""

    def run(self, circuits, validate=False, parameter_binds=None, **run_options):
        """Applies transpiler pass NonlocalCXDepError to circuits run on this backend"""
        pm = PassManager()
        cm = CouplingMap(couplinglist=self.configuration().coupling_map)
        pm.append([NonlocalCXDepError(cm)])
        noise_circuits = pm.run(circuits)
        return super().run(
            noise_circuits, validate=validate, parameter_binds=parameter_binds, **run_options
        )

@ddt
class TestMirrorRB(QiskitExperimentsTestCase, RBTestMixin):
    """Test for mirror RB."""

    def setUp(self):
        """Setup the tests."""
        super().setUp()
        self.backend = FakeParis()

        self.basis_gates = ["sx", "rz", "cx"]

        self.transpiler_options = {
            "basis_gates": self.basis_gates,
            "optimization_level": 1,
        }

    def test_single_qubit(self):
        """Test single qubit mirror RB."""
        exp = rb.MirrorRB(
            qubits=(0,),
            lengths=list(range(2, 300, 20)),
            seed=124,
            backend=self.backend,
            num_samples=30,
        )
        # exp.analysis.set_options(gate_error_ratio=None)
        exp.set_transpile_options(**self.transpiler_options)
        self.assertAllIdentity(exp.circuits())

        expdata = exp.run()
        self.assertExperimentDone(expdata)

        # Given we have gate number per Clifford n_gpc, we can compute EPC as
        # EPC = 1 - (1 - r)^n_gpc
        # where r is gate error of SX gate, i.e. dep-parameter divided by 2.
        # We let transpiler use SX and RZ.
        # The number of physical gate per Clifford will distribute
        # from 0 to 2, i.e. arbitrary U gate can be decomposed into up to 2 SX with RZs.
        # We may want to expect the average number of SX is (0 + 1 + 2) / 3 = 1.0.
        # But for mirror RB, we must also add the SX gate number per Pauli n_gpp,
        # which is 2 for X and Y gates and 0 for I and Z gates (average = 1.0). So the
        # formula should be EPC = 1 - (1 - r)^(n_gpc + n_gpp) = 1 - (1 - r)^2
        epc = expdata.analysis_results("EPC")
        epc_expected = 1 - (1 - 1 / 2 * self.p1q) ** 2.0
        self.assertAlmostEqual(epc.value.n, epc_expected, delta=0.1 * epc_expected)

    def test_two_qubit(self):
        """Test two qubit RB."""
        two_qubit_gate_density = 0.2
        exp = rb.MirrorRB(
            qubits=(0, 1),
            lengths=list(range(2, 300, 20)),
            seed=123,
            backend=self.backend,
            num_samples=30,
            two_qubit_gate_density=two_qubit_gate_density,
        )
        exp.analysis.set_options(gate_error_ratio=None)
        exp.set_transpile_options(**self.transpiler_options)
        self.assertAllIdentity(exp.circuits())

        expdata = exp.run()
        self.assertExperimentDone(expdata)

        # Given a two qubit gate density xi and an n qubit circuit, a Clifford
        # layer has n*xi two-qubit gates. Obviously a Pauli has no two-qubit
        # gates, so on aveage, a Clifford + Pauli layer has n*xi two-qubit gates
        # and 2*n - 2*n*xi one-qubit gates (two layers have 2*n lattice sites,
        # 2*n*xi of which are occupied by two-qubit gates). For two-qubit
        # mirrored RB, the average infidelity is ((2^2 - 1)/2^2 = 3/4) times
        # the two-qubit depolarizing parameter
        epc = expdata.analysis_results("EPC")
        cx_factor = (1 - 3 * self.p2q / 4) ** (2 * two_qubit_gate_density)
        sx_factor = (1 - self.p1q / 2) ** (2 * 2 * (1 - two_qubit_gate_density))
        epc_expected = 1 - cx_factor * sx_factor
        self.assertAlmostEqual(epc.value.n, epc_expected, delta=0.1 * epc_expected)

    def test_two_qubit_nonlocal_noise(self):
        """Test for 2 qubit Mirrored RB with a nonlocal noise model"""
        # depolarizing error
        p1q = 0.0
        p2q = 0.01
        pvz = 0.0

        # setup noise model
        sx_error = depolarizing_error(p1q, 1)
        rz_error = depolarizing_error(pvz, 1)
        cx_error = depolarizing_error(p2q, 2)

        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(sx_error, "sx")
        noise_model.add_all_qubit_quantum_error(rz_error, "rz")
        noise_model.add_all_qubit_quantum_error(cx_error, "cx")

        basis_gates = ["id", "sx", "rz", "cx"]
        # Need level1 for consecutive gate cancellation for reference EPC value calculation
        transpiler_options = {
            "basis_gates": basis_gates,
            "optimization_level": 1,
        }
        # Coupling map is 3 x 3 lattice
        noise_backend = NoiseSimulator(
            noise_model=noise_model,
            seed_simulator=123,
            coupling_map=CouplingMap.from_grid(3, 3).get_edges(),
        )

        two_qubit_gate_density = 0.2
        exp = rb.MirrorRB(
            qubits=(0, 1),
            lengths=list(range(2, 110, 20)),
            seed=123,
            backend=noise_backend,
            num_samples=20,
            two_qubit_gate_density=two_qubit_gate_density,
        )
        exp.analysis.set_options(gate_error_ratio=None)
        exp.set_transpile_options(**transpiler_options)
        self.assertAllIdentity(exp.circuits())
        expdata = exp.run(noise_backend)
        self.assertExperimentDone(expdata)

        epc = expdata.analysis_results("EPC")
        # Compared to expected EPC in two-qubit test without nonlocal noise above,
        # we include an extra factor for the nonlocal CX error. This nonlocal
        # error is modeled by a one-qubit depolarizing channel on each qubit after
        # each CX, so the expected number of one-qubit depolarizing channels
        # induced by CXs is (number of CXs) * (number of qubits) = (two qubit gate
        # density) * (number of qubits) * (number of qubits).
        num_q = 2
        cx_factor = (1 - 3 * p2q / 4) ** (num_q * two_qubit_gate_density)
        sx_factor = (1 - p1q / 2) ** (2 * num_q * (1 - two_qubit_gate_density))
        cx_nonlocal_factor = (1 - 0.0035 / 2) ** (num_q * num_q * two_qubit_gate_density)
        epc_expected = 1 - cx_factor * sx_factor * cx_nonlocal_factor
        self.assertAlmostEqual(epc.value.n, epc_expected, delta=0.1 * epc_expected)

    def test_three_qubit_nonlocal_noise(self):
        """Test three-qubit mirrored RB on a nonlocal noise model"""
        # depolarizing error
        p1q = 0.001
        p2q = 0.01
        pvz = 0.0

        # setup noise modelle
        sx_error = depolarizing_error(p1q, 1)
        rz_error = depolarizing_error(pvz, 1)
        cx_error = depolarizing_error(p2q, 2)

        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(sx_error, "sx")
        noise_model.add_all_qubit_quantum_error(rz_error, "rz")
        noise_model.add_all_qubit_quantum_error(cx_error, "cx")

        basis_gates = ["id", "sx", "rz", "cx"]
        # Need level1 for consecutive gate cancellation for reference EPC value calculation
        transpiler_options = {
            "basis_gates": basis_gates,
            "optimization_level": 1,
        }
        noise_backend = NoiseSimulator(
            noise_model=noise_model,
            seed_simulator=123,
            coupling_map=CouplingMap.from_grid(3, 3).get_edges(),
        )

        two_qubit_gate_density = 0.2
        exp = rb.MirrorRB(
            qubits=(0, 1, 2),
            lengths=list(range(2, 110, 50)),
            seed=123,
            backend=noise_backend,
            num_samples=20,
            two_qubit_gate_density=two_qubit_gate_density,
        )
        exp.analysis.set_options(gate_error_ratio=None)
        exp.set_transpile_options(**transpiler_options)
        self.assertAllIdentity(exp.circuits())
        expdata = exp.run(noise_backend)
        self.assertExperimentDone(expdata)

        epc = expdata.analysis_results("EPC")
        # The expected EPC was computed in simulations not presented here.
        # Method:
        # 1. Sample N Clifford layers according to the edgegrab algorithm
        #    in clifford_utils.
        # 2. Transpile these into SX, RZ, and CX gates.
        # 3. Replace each SX and CX with one- and two-qubit depolarizing
        #    channels, respectively, and remove RZ gates.
        # 4. Use qiskit.quantum_info.average_gate_fidelity on these N layers
        #    to compute 1 - EPC for each layer, and average over the N layers.
        epc_expected = 0.0124
        self.assertAlmostEqual(epc.value.n, epc_expected, delta=0.2 * epc_expected)

    def test_add_more_circuit_yields_lower_variance(self):
        """Test variance reduction with larger number of sampling."""
        exp1 = rb.MirrorRB(
            qubits=(0, 1),
            lengths=list(range(2, 30, 4)),
            seed=123,
            backend=self.backend,
            num_samples=3,
            inverting_pauli_layer=False,
        )
        exp1.analysis.set_options(gate_error_ratio=None)
        exp1.set_transpile_options(**self.transpiler_options)
        expdata1 = exp1.run()
        self.assertExperimentDone(expdata1)

        exp2 = rb.MirrorRB(
            qubits=(0, 1),
            lengths=list(range(2, 30, 4)),
            seed=456,
            backend=self.backend,
            num_samples=10,
            inverting_pauli_layer=False,
        )
        exp2.analysis.set_options(gate_error_ratio=None)
        exp2.set_transpile_options(**self.transpiler_options)
        expdata2 = exp2.run()
        self.assertExperimentDone(expdata2)

        self.assertLess(
            expdata2.analysis_results("EPC").value.s,
            expdata1.analysis_results("EPC").value.s,
        )

    def test_return_same_circuit(self):
        """Test if setting the same seed returns the same circuits."""
        lengths = [10, 20]
        exp1 = rb.MirrorRB(
            qubits=(0, 1),
            lengths=lengths,
            seed=123,
            backend=self.backend,
        )

        exp2 = rb.MirrorRB(
            qubits=(0, 1),
            lengths=lengths,
            seed=123,
            backend=self.backend,
        )

        circs1 = exp1.circuits()
        circs2 = exp2.circuits()

        for circ1, circ2 in zip(circs1, circs2):
            self.assertEqual(circ1.decompose(), circ2.decompose())

    def test_full_sampling(self):
        """Test if full sampling generates different circuits."""
        exp1 = rb.MirrorRB(
            qubits=(0, 1),
            lengths=[10, 20],
            seed=123,
            backend=self.backend,
            num_samples=1,
            full_sampling=True,
        )

        exp2 = rb.MirrorRB(
            qubits=(0, 1),
            lengths=[10, 20],
            seed=123,
            backend=self.backend,
            num_samples=1,
            full_sampling=False,
        )

        circs1 = exp1.circuits()
        circs2 = exp2.circuits()

        self.assertNotEqual(circs1[0].decompose(), circs2[0].decompose())

        # fully sampled circuits are regenerated while other is just built on
        # top of previous length
        self.assertNotEqual(circs1[1].decompose(), circs2[1].decompose())

    def test_target_bitstring(self):
        """Test if correct target bitstring is returned."""
        qc = QuantumCircuit(9)
        qc.z(0)
        qc.y(1)
        qc.y(2)
        qc.z(3)
        qc.y(4)
        qc.x(7)
        qc.y(8)
        exp = rb.MirrorRB(qubits=[0], lengths=[2], backend=self.backend)
        expected_tb = exp._clifford_utils.compute_target_bitstring(qc)
        actual_tb = "110010110"
        self.assertEqual(expected_tb, actual_tb)

    def test_zero_2q_gate_density(self):
        """Test that there are no two-qubit gates when the two-qubit gate
        density is set to 0."""
        exp = rb.MirrorRB(
            qubits=(0, 1),
            lengths=[40],
            seed=124,
            backend=self.backend,
            num_samples=1,
            two_qubit_gate_density=0,
        )
        circ = exp.circuits()[0].decompose()
        for datum in circ.data:
            inst_name = datum[0].name
            self.assertNotEqual("cx", inst_name)

    def test_max_2q_gate_density(self):
        """Test that every intermediate Clifford layer is filled with two-qubit
        gates when the two-qubit gate density is set to 0.5, its maximum value
        (assuming an even number of qubits and a backend coupling map with full
        connectivity)."""
        backend = AerSimulator(coupling_map=CouplingMap.from_full(4).get_edges())
        exp = rb.MirrorRB(
            qubits=(0, 1, 2, 3),
            lengths=[40],
            seed=125,
            backend=backend,
            num_samples=1,
            two_qubit_gate_density=0.5,
        )
        circ = exp.circuits()[0].decompose()
        num_cxs = 0
        for datum in circ.data:
            if datum[0].name == "cx":
                num_cxs += 1
        self.assertEqual(80, num_cxs)

    def test_local_clifford(self):
        """Test that the number of layers is correct depending on whether
        local_clifford is set to True or False by counting the number of barriers."""
        exp = rb.MirrorRB(
            qubits=(0,),
            lengths=[2],
            seed=126,
            backend=self.backend,
            num_samples=1,
            local_clifford=True,
            pauli_randomize=False,
            two_qubit_gate_density=0.2,
            inverting_pauli_layer=False,
        )
        circ = exp.circuits()[0]
        num_barriers = 0
        for datum in circ.data:
            if datum[0].name == "barrier":
                num_barriers += 1
        self.assertEqual(5, num_barriers)

    def test_pauli_randomize(self):
        """Test that the number of layers is correct depending on whether
        pauli_randomize is set to True or False by counting the number of barriers."""
        exp = rb.MirrorRB(
            qubits=(0,),
            lengths=[2],
            seed=126,
            backend=self.backend,
            num_samples=1,
            local_clifford=False,
            pauli_randomize=True,
            two_qubit_gate_density=0.2,
            inverting_pauli_layer=False,
        )
        circ = exp.circuits()[0]
        num_barriers = 0
        for datum in circ.data:
            if datum[0].name == "barrier":
                num_barriers += 1
        self.assertEqual(6, num_barriers)

    def test_inverting_pauli_layer(self):
        """Test that a circuit with an inverting Pauli layer at the end (i.e.,
        a layer of Paulis before the final measurement that restores the output
        to |0>^num_qubits up to a global phase) composes to the identity (up to
        a global phase)"""
        exp = rb.MirrorRB(
            qubits=(0, 1, 2),
            lengths=[2],
            seed=127,
            backend=self.backend,
            num_samples=3,
            local_clifford=True,
            pauli_randomize=True,
            two_qubit_gate_density=0.2,
            inverting_pauli_layer=True,
        )
        self.assertAllIdentity(exp.circuits())

    @data(
        {
            "qubits": [3, 3],
            "lengths": [2, 4, 6, 8, 10],
            "num_samples": 1,
            "seed": 100,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # repeated qubits
        {
            "qubits": [0, 1],
            "lengths": [2, 4, 6, -8, 10],
            "num_samples": 1,
            "seed": 100,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # negative length
        {
            "qubits": [0, 1],
            "lengths": [2, 4, 6, 8, 10],
            "num_samples": -4,
            "seed": 100,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # negative number of samples
        {
            "qubits": [0, 1],
            "lengths": [2, 4, 6, 8, 10],
            "num_samples": 0,
            "seed": 100,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # zero samples
        {
            "qubits": [0, 1],
            "lengths": [2, 6, 6, 6, 10],
            "num_samples": 2,
            "seed": 100,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # repeated lengths
        {
            "qubits": [0, 1],
            "lengths": [2, 4, 5, 8, 10],
            "num_samples": 2,
            "seed": 100,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # odd length
        {
            "qubits": [0, 1],
            "lengths": [2, 4, 6, 8, 10],
            "num_samples": 1,
            "seed": 100,
            "two_qubit_gate_density": -0.1,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # negative two-qubit gate density
    )
    def test_invalid_configuration(self, configs):
        """Test raise error when creating experiment with invalid configs."""
        self.assertRaises(QiskitError, rb.MirrorRB, **configs)

    @data(
        {
            "qubits": [0, 1],
            "lengths": [2, 4, 6, 8, 10],
            "num_samples": 1,
            "seed": 100,
            "backend": None,
        },  # no backend
    )
    def test_no_backend(self, configs):
        """Test raise error when no backend is provided for sampling circuits."""
        mirror_exp = rb.MirrorRB(**configs)
        self.assertRaises(QiskitError, mirror_exp.run)

    @data(
        {
            "qubits": [0, 4],
            "lengths": [2, 4, 6, 8, 10],
            "num_samples": 1,
            "seed": 100,
            "backend": AerSimulator.from_backend(FakeManila()),
        },  # Uncoupled qubits to test edgegrab algorithm warning
        {
            "qubits": [0, 1],
            "lengths": [2, 4, 6, 8, 10],
            "num_samples": 1,
            "seed": 100,
            "two_qubit_gate_density": 0.6,
            "backend": AerSimulator(coupling_map=[[0, 1], [1, 0]]),
        },  # High two-qubit gate density warning
    )
    def test_warnings(self, configs):
        """Test raise warnings when creating experiment."""
        mirror_exp = rb.MirrorRB(**configs)
        self.assertWarns(Warning, mirror_exp.run)

    def test_experiment_config(self):
        """Test converting to and from config works"""
        exp = rb.MirrorRB(qubits=(0,), lengths=[10, 20, 30], seed=123, backend=self.backend)
        loaded_exp = rb.MirrorRB.from_config(exp.config())
        self.assertNotEqual(exp, loaded_exp)
        self.assertTrue(self.json_equiv(exp, loaded_exp))

    def test_roundtrip_serializable(self):
        """Test round trip JSON serialization"""
        exp = rb.MirrorRB(qubits=(0,), lengths=[10, 20, 30], seed=123)
        self.assertRoundTripSerializable(exp, self.json_equiv)

    def test_analysis_config(self):
        """ "Test converting analysis to and from config works"""
        analysis = rb.RBAnalysis()
        loaded = rb.RBAnalysis.from_config(analysis.config())
        self.assertNotEqual(analysis, loaded)
        self.assertEqual(analysis.config(), loaded.config())

    def test_expdata_serialization(self):
        """Test serializing experiment data works."""
        exp = rb.MirrorRB(
            qubits=(0,),
            lengths=list(range(2, 200, 50)),
            seed=123,
            backend=self.backend,
            inverting_pauli_layer=False,
        )
        exp.set_transpile_options(**self.transpiler_options)
        expdata = exp.run()
        self.assertExperimentDone(expdata)
        self.assertRoundTripSerializable(expdata, check_func=self.experiment_data_equiv)
        self.assertRoundTripPickle(expdata, check_func=self.experiment_data_equiv)

class TestEPGAnalysis(QiskitExperimentsTestCase):
    """Test case for EPG calculation from EPC.

    EPG and depolarizing probability p are assumed to have following relationship

        EPG = (2^n - 1) / 2^n · p
    This p is provided to the Aer noise model, thus we verify EPG computation
    by comparing the value with the depolarizing probability.
    """

    def setUp(self):
        """Setup the tests."""
        super().setUp()

        # Setup noise model, including more gate for complicated EPG computation
        # Note that 1Q channel error is amplified to check 1q channel correction mechanism
        self.p_x = 0.04
        self.p_h = 0.02
        self.p_s = 0.0
        self.p_cx = 0.09
        x_error = depolarizing_error(self.p_x, 1)
        h_error = depolarizing_error(self.p_h, 1)
        s_error = depolarizing_error(self.p_s, 1)
        cx_error = depolarizing_error(self.p_cx, 2)

        noise_model = NoiseModel()
        noise_model.add_all_qubit_quantum_error(x_error, "x")
        noise_model.add_all_qubit_quantum_error(h_error, "h")
        noise_model.add_all_qubit_quantum_error(s_error, "s")
        noise_model.add_all_qubit_quantum_error(cx_error, "cx")

        # Need level1 for consecutive gate cancellation for reference EPC value calculation
        transpiler_options = {
            "basis_gates": ["x", "h", "s", "cx"],
            "optimization_level": 1,
        }

        # Aer simulator
        backend = AerSimulator(noise_model=noise_model, seed_simulator=123)

        # Prepare experiment data and cache for analysis
        exp_1qrb_q0 = rb.StandardRB(
            qubits=(0,),
            lengths=[1, 10, 30, 50, 80, 120, 150, 200],
            seed=123,
            backend=backend,
        )
        exp_1qrb_q0.set_transpile_options(**transpiler_options)
        expdata_1qrb_q0 = exp_1qrb_q0.run(analysis=None).block_for_results(timeout=300)

        exp_1qrb_q1 = rb.StandardRB(
            qubits=(1,),
            lengths=[1, 10, 30, 50, 80, 120, 150, 200],
            seed=123,
            backend=backend,
        )
        exp_1qrb_q1.set_transpile_options(**transpiler_options)
        expdata_1qrb_q1 = exp_1qrb_q1.run(analysis=None).block_for_results(timeout=300)

        exp_2qrb = rb.StandardRB(
            qubits=(0, 1),
            lengths=[1, 3, 5, 10, 15, 20, 30, 50],
            seed=123,
            backend=backend,
        )
        exp_2qrb.set_transpile_options(**transpiler_options)
        expdata_2qrb = exp_2qrb.run(analysis=None).block_for_results(timeout=300)

        self.expdata_1qrb_q0 = expdata_1qrb_q0
        self.expdata_1qrb_q1 = expdata_1qrb_q1
        self.expdata_2qrb = expdata_2qrb

    def test_default_epg_ratio(self):
        """Calculate EPG with default ratio dictionary. H and X have the same ratio."""
        analysis = rb.RBAnalysis()
        analysis.set_options(outcome="0")
        result = analysis.run(self.expdata_1qrb_q0, replace_results=False)
        self.assertExperimentDone(result)

        s_epg = result.analysis_results("EPG_s")
        h_epg = result.analysis_results("EPG_h")
        x_epg = result.analysis_results("EPG_x")

        self.assertEqual(s_epg.value.n, 0.0)

        # H and X gate EPG are assumed to be the same, so this underestimate X and overestimate H
        self.assertEqual(h_epg.value.n, x_epg.value.n)
        self.assertLess(x_epg.value.n, self.p_x * 0.5)
        self.assertGreater(h_epg.value.n, self.p_h * 0.5)

    def test_no_epg(self):
        """Calculate no EPGs."""
        analysis = rb.RBAnalysis()
        analysis.set_options(outcome="0", gate_error_ratio=None)
        result = analysis.run(self.expdata_1qrb_q0, replace_results=False)
        self.assertExperimentDone(result)

        with self.assertRaises(ExperimentEntryNotFound):
            result.analysis_results("EPG_s")

        with self.assertRaises(ExperimentEntryNotFound):
            result.analysis_results("EPG_h")

        with self.assertRaises(ExperimentEntryNotFound):
            result.analysis_results("EPG_x")

    def test_with_custom_epg_ratio(self):
        """Calculate no EPGs with custom EPG ratio dictionary."""
        analysis = rb.RBAnalysis()
        analysis.set_options(outcome="0", gate_error_ratio={"x": 2, "h": 1, "s": 0})
        result = analysis.run(self.expdata_1qrb_q0, replace_results=False)
        self.assertExperimentDone(result)

        h_epg = result.analysis_results("EPG_h")
        x_epg = result.analysis_results("EPG_x")

        self.assertAlmostEqual(x_epg.value.n, self.p_x * 0.5, delta=0.005)
        self.assertAlmostEqual(h_epg.value.n, self.p_h * 0.5, delta=0.005)

    def test_2q_epg(self):
        """Compute 2Q EPG without correction.
        Since 1Q gates are designed to have comparable EPG with CX gate,
        this will overestimate the error of CX gate.
        """
        analysis = rb.RBAnalysis()
        analysis.set_options(outcome="00")
        result = analysis.run(self.expdata_2qrb, replace_results=False)
        self.assertExperimentDone(result)

        cx_epg = result.analysis_results("EPG_cx")

        self.assertGreater(cx_epg.value.n, self.p_cx * 0.75)

    def test_2q_epg_with_correction(self):
        """Check that 2Q EPG with 1Q depolarization correction gives a better (smaller) result than
        without the correction."""
        analysis_1qrb_q0 = rb.RBAnalysis()
        analysis_1qrb_q0.set_options(outcome="0", gate_error_ratio={"x": 2, "h": 1, "s": 0})
        result_q0 = analysis_1qrb_q0.run(self.expdata_1qrb_q0, replace_results=False)
        self.assertExperimentDone(result_q0)

        analysis_1qrb_q1 = rb.RBAnalysis()
        analysis_1qrb_q1.set_options(outcome="0", gate_error_ratio={"x": 2, "h": 1, "s": 0})
        result_q1 = analysis_1qrb_q1.run(self.expdata_1qrb_q1, replace_results=False)
        self.assertExperimentDone(result_q1)

        analysis_2qrb = rb.RBAnalysis()
        analysis_2qrb.set_options(
            outcome="00",
        )
        result_2qrb = analysis_2qrb.run(self.expdata_2qrb)
        self.assertExperimentDone(result_2qrb)
        cx_epg_raw = result_2qrb.analysis_results("EPG_cx")

        analysis_2qrb = rb.RBAnalysis()
        analysis_2qrb.set_options(
            outcome="00",
            epg_1_qubit=result_q0.analysis_results() + result_q1.analysis_results(),
        )
        result_2qrb = analysis_2qrb.run(self.expdata_2qrb)
        self.assertExperimentDone(result_2qrb)
        cx_epg_corrected = result_2qrb.analysis_results("EPG_cx")
        self.assertLess(
            np.abs(cx_epg_corrected.value.n - self.p_cx * 0.75),
            np.abs(cx_epg_raw.value.n - self.p_cx * 0.75),
        )


import torch
import numpy as np

def predict(model, dataloader, device):
    """
    :param model:
    :param dataloader:
    :param device:
    :param get_x_fun:
    :return:
    """
    model = model.to(device)

    num_elements = len(dataloader.dataset)
    num_batches = len(dataloader)

    batch_size = dataloader.batch_size

    predictions = torch.zeros(num_elements)
    true_labels = torch.zeros(num_elements)

    for i, batch in enumerate(dataloader):
        start = i * batch_size
        end = start + batch_size
        if i == num_batches - 1:
            end = num_elements

        x, y = batch
        logits = model.forward(x.to(device))
        pred = torch.argmax(logits, dim=1)
        predictions[start:end] = pred.detach()
        true_labels[start:end] = y.detach()

    return predictions, true_labels


import bs4
import json
import string
from urllib.request import urlopen,Request
from bs4 import BeautifulSoup as soup

# class untuk membuat tuple dalam bentuk json
class Result:
    def __init__(self, scr_id, product_id, name, label, category, subcategory,real_price,sale_price):
        self.id = scr_id
        self.product_id = product_id
        self.name = name
        self.label = label
        self.category = category
        self.subcategory = subcategory
        self.real_price = real_price
        self.sale_price = sale_price

    def getJson(self):
        return {
            "id": self.id,
            "product_id": self.product_id,
            "name": self.name,
            "label": self.label,
            "category": self.category,
            "subcategory": self.subcategory,
            "real_price": self.real_price,
            "sale_price":self.sale_price
        }

# fungsi untuk mengumpulkan link2 untuk setiap kategori koleksi
def getNav(cat_container):
    # barang-barang new in
    new_in = cat_container.find("li", {"class" : "_category-link-wrapper menu-item menu-item--level-2 menu-item--is-leaf"})
    newin_atag = new_in.find("a", {"class" : "_category-link menu-item__category-link"})
    newin_link = newin_atag.get("href")
    navigators.append(newin_link)

    collection = cat_container.find("li", {"class" : "_category-link-wrapper menu-item menu-item--level-2 menu-item--current _displayUnfolded"})

    # untuk koleksi tanpa subkategori
    links = collection.find_all("li", {"class": "_category-link-wrapper menu-item menu-item--level-3 menu-item--is-leaf"})
    for i in range(len(links)):
        atag = links[i].find("a", {"class" : "_category-link menu-item__category-link"})
        if(atag):
            navigator = atag.get("href")
        else:
            navigator = "None"
        if(navigator!="None" and navigator and navigator not in navigators):
            navigators.append(navigator)

    # untuk koleksi dengan subkategori
    links = collection.find_all("li", {"class": "_category-link-wrapper menu-item menu-item--level-3"})
    for i in range(len(links)):
        subcat_ultag = links[i].find("ul", {"class" : "_subcategories subcategory-menu subcategory-menu--level-3"})
        subcats = subcat_ultag.find_all("li", {"class" : "_category-link-wrapper menu-item menu-item--level-4 menu-item--is-leaf"})
        for j in range(len(subcats)):
            subcat_name = subcats[j].get("data-name")
            if(subcat_name!="Lihat Semua"):
                subcat_atag = subcats[j].find("a", {"class" : "_category-link menu-item__category-link"})
                subcat_navigator = subcat_atag.get("href")
                subcat_navigator_2 = subcat_atag.get("data-href")
                if(subcat_navigator):
                    navigators.append(subcat_navigator)
                elif(subcat_navigator_2):
                    navigators.append(subcat_navigator_2)

    return navigators

# fungsi untuk mendapatkan kategori dan subkategori
def getCategory(cat_container):
    # barang-barang new in
    new_in = cat_container.find("li", {"class" : "_category-link-wrapper menu-item menu-item--level-2 menu-item--is-leaf"})
    cat_name = new_in.get("data-name")
    cat_tuple = (cat_name, "None")
    categories.append(cat_tuple)

    collection = cat_container.find("li", {"class" : "_category-link-wrapper menu-item menu-item--level-2 menu-item--current _displayUnfolded"})
    # untuk koleksi tanpa subkategori
    links = collection.find_all("li", {"class": "_category-link-wrapper menu-item menu-item--level-3 menu-item--is-leaf"})
    for i in range(len(links)):
        cat_name = links[i].get("data-name")
        if(cat_name!="Lihat Semua"):
            cat_tuple = (cat_name,"None")
            categories.append(cat_tuple)

    # untuk koleksi dengan subkategori
    links = collection.find_all("li", {"class": "_category-link-wrapper menu-item menu-item--level-3"})
    for i in range(len(links)):
        cat_name = links[i].get("data-name")
        subcat_ultag = links[i].find("ul", {"class" : "_subcategories subcategory-menu subcategory-menu--level-3"})
        subcats = subcat_ultag.find_all("li", {"class" : "_category-link-wrapper menu-item menu-item--level-4 menu-item--is-leaf"})
        for j in range(len(subcats)):
            subcat_name = subcats[j].get("data-name")
            if(subcat_name!="Lihat Semua"):
                cat_tuple = (cat_name,subcat_name)
                categories.append(cat_tuple)

    return categories

# mendapatkan HTML body dari page myurl
def getBody(myurl):
    headers = {'User-Agent': 'Chrome/5.0'}
    uClient = Request(myurl, headers=headers)
    page_html = urlopen(uClient).read()
    page_soup = soup(page_html,"html.parser")
    body = page_soup.body
    return body

# mendapatkan data koleksi wanita
def getData(navigators, categories):
    #menyimpan seluruh data barang
    data = []
    # menandakan sekarang sedang memparsing page categori yang mana
    cat_now = 0
    # jumlah produk / ID pada tuple json
    num_product = 1;
    for page in navigators:
        # print(cat_now, page)
        container = getBody(page)
        wraps = container.find_all("div",{"class":"_groups-wrap"})
        ultag = wraps[0].find("ul")
        litags = ultag.find_all("li")
        i=0
        for i in range(len(litags)):
            # get kode produk
            id = litags[i].get("id")
            product_info = litags[i].find("div", {"class": "product-info _product-info"})
            if(product_info):
                product_label = product_info.find("div", {"class" : "product-info-item product-info-item-label"})
                # get label produk
                if(product_label):
                    label = product_label.text
                else:
                    label = "None"
                product_name = product_info.find("a", {"class" : "name _item"})
                # get nama produk
                if(product_name):
                    name_temp = product_name.text
                    name_clean = name_temp.replace('\'', '')
                    name = name_temp.replace('\xa0', '')
                product_main_price = product_info.find("span", {"class" : "main-price"})
                # get harga barang ada 2 kasus
                # kasus 1 : bukan barang sale
                if(product_main_price):
                    main_price = product_main_price.get("data-price")
                    main_price_2 = main_price.replace(' IDR', '')
                    new_main_price = main_price_2.replace('.','')
                    # harga diskon kosong
                    new_price_sale = -1
                    res = Result(num_product, id, name, label, categories[cat_now][0], categories[cat_now][1] , int(new_main_price),int(new_price_sale))
                    data.append(res.getJson())
                    num_product+=1
                # kasus 2 : barang sale
                else:
                    product_main_price = product_info.find("span", {"class" : "line-through"})
                    product_price_sale = product_info.find("span", {"class" : "sale"})
                    # harga asli
                    if(product_main_price):
                        main_price = product_main_price.get("data-price")
                        main_price_2 = main_price.replace(' IDR', '')
                        new_main_price = main_price_2.replace('.','')
                    # harga diskon
                    if(product_price_sale):
                        price_sale = product_price_sale.get("data-price")
                        price_sale_2 = price_sale.replace(' IDR', '')
                        new_price_sale = price_sale_2.replace('.','')
                    res = Result(num_product, id, name, label, categories[cat_now][0], categories[cat_now][1] ,int(new_main_price),int(new_price_sale))
                    data.append(res.getJson())
                    num_product+=1
            i+=1
        cat_now+=1
    with open('../data/zara_women.json', 'w') as fp:
        fp.write(json.dumps(data, indent = 2))

# ------------------ Main Program ---------------------
# menyimpan link navigator untuk menuju page yang sesuai kategori
navigators = []
# menyimpan kategori dan subkategori barang dengan format tuple(kategori, subkategori)
categories = []

myurl = 'https://www.zara.com/id/id/woman-special-prices-l1314.html?v1=1446216'
container = getBody(myurl)
women_container = container.find("div",{"class" : "_container-nav navigation-menu"})
cat_container = women_container.find("li", {"class": "_category-link-wrapper menu-item menu-item--level-1 menu-item--current"})
navigators = getNav(cat_container)
categories = getCategory(cat_container)
print("please wait...")
getData(navigators, categories)
print("done!")


import cv2
import numpy as np

cam = cv2.VideoCapture(0)

EVT=0
start_point=(0,0)
RDown=0
LDown=0

def draw_rectangle(event,x,y,flags,param):
    global EVT
    global PNT
    if event == cv2.EVENT_LBUTTONDOWN:
        EVT = cv2.EVENT_LBUTTONDOWN
        PNT = (x, y)
    if event == cv2.EVENT_LBUTTONUP:
        EVT = cv2.EVENT_LBUTTONUP
        PNT = (x, y)
    if event == cv2.EVENT_RBUTTONDOWN:
        EVT = cv2.EVENT_RBUTTONDOWN
    if event == cv2.EVENT_RBUTTONUP:
        EVT = cv2.EVENT_RBUTTONUP
        cv2.destroyWindow('image_ROI')

while True:
    _, img=cam.read()
    imgOriginal = img
    cv2.imshow('MBS3523',img)
    cv2.setMouseCallback('MBS3523', draw_rectangle)

    if EVT == cv2.EVENT_LBUTTONDOWN:
        start_point=PNT

    if EVT == cv2.EVENT_LBUTTONUP:
        cv2.rectangle(img, start_point, PNT, (255, 0, 0), 3)
        imgBound = img[start_point[1]:PNT[1], start_point[0]:PNT[0]]
        cv2.imshow('image_ROI', imgBound)
        LDown=1

    if EVT == cv2.EVENT_RBUTTONDOWN:
        RDown=1

    if EVT == cv2.EVENT_RBUTTONUP & RDown==1:
        if LDown==1:
            LDown=0
        img = imgOriginal
        RDown=0

    cv2.imshow('MBS3523', img)

    if cv2.waitKey(20) & 0xff == 27:
            break

capture.release()
cv2.destroyAllWindows()


"""add consumed column to media

Revision ID: 96d7aa4b4895
Revises: 7e43b75b7a9b
Create Date: 2017-12-21 19:54:28.613492

"""
from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = '96d7aa4b4895'
down_revision = '7e43b75b7a9b'
branch_labels = None
depends_on = None

def upgrade():
    op.add_column('media', sa.Column('consumed', sa.Boolean, default=False))
    op.execute(
        """
        UPDATE media
        SET consumed = 'f';
        """
    )

def downgrade():
    op.drop_column('media', 'consumed')


import os
import pickle
from collections import OrderedDict
import random
import glob

import pandas as pd
from dgllife.utils import smiles_to_bigraph, CanonicalAtomFeaturizer
import dgl
import numpy as np
import torch
from rdkit import Chem
from rdkit.Chem.rdmolops import GetAdjacencyMatrix
import networkx as nx
from Bio.PDB import *
import deepchem
import pickle

random.seed(0)

pk = deepchem.dock.ConvexHullPocketFinder()

def one_of_k_encoding(x, allowable_set):
    if x not in allowable_set:
        raise Exception("input {0} not in allowable set{1}:".format(x, allowable_set))
    # print list((map(lambda s: x == s, allowable_set)))
    return list(map(lambda s: x == s, allowable_set))

def one_of_k_encoding_unk(x, allowable_set):
    """Maps inputs not in the allowable set to the last element."""
    if x not in allowable_set:
        x = allowable_set[-1]
    return list(map(lambda s: x == s, allowable_set))

def atom_feature(atom):
    return np.array(one_of_k_encoding_unk(atom.GetSymbol(),
                                          ['C', 'N', 'O', 'S', 'F', 'P', 'Cl', 'Br', 'B', 'H']) +
                    one_of_k_encoding(atom.GetDegree(), [0, 1, 2, 3, 4, 5, 6, 7, 8]) +
                    one_of_k_encoding_unk(atom.GetTotalNumHs(), [0, 1, 2, 3, 4]) +
                    one_of_k_encoding_unk(atom.GetImplicitValence(), [0, 1, 2, 3, 4, 5]) +
                    [atom.GetIsAromatic()])  # (10, 6, 5, 6, 1) --> total 28

def get_atom_feature(m):
    H = []
    for i in range(len(m)):
        H.append(atom_feature(m[i][0]))
    H = np.array(H)

    return H

def process_protein(pdb_file):
    m = Chem.MolFromPDBFile(pdb_file)
    am = GetAdjacencyMatrix(m)
    pockets = pk.find_pockets(pdb_file)
    n2 = m.GetNumAtoms()
    c2 = m.GetConformers()[0]
    d2 = np.array(c2.GetPositions())
    binding_parts = []
    not_in_binding = [i for i in range(0, n2)]
    constructed_graphs = []
    for bound_box in pockets:
        x_min = bound_box.x_range[0]
        x_max = bound_box.x_range[1]
        y_min = bound_box.y_range[0]
        y_max = bound_box.y_range[1]
        z_min = bound_box.z_range[0]
        z_max = bound_box.z_range[1]
        binding_parts_atoms = []
        idxs = []
        for idx, atom_cord in enumerate(d2):
            if x_min < atom_cord[0] < x_max and y_min < atom_cord[1] < y_max and z_min < atom_cord[2] < z_max:
                binding_parts_atoms.append((m.GetAtoms()[idx], atom_cord))
                idxs.append(idx)
                if idx in not_in_binding:
                    not_in_binding.remove(idx)

        ami = am[np.array(idxs)[:, None], np.array(idxs)]
        H = get_atom_feature(binding_parts_atoms)
        g = nx.convert_matrix.from_numpy_matrix(ami)
        graph = dgl.DGLGraph(g)
        graph.ndata['h'] = torch.Tensor(H)
        graph = dgl.add_self_loop(graph)
        constructed_graphs.append(graph)
        binding_parts.append(binding_parts_atoms)

    constructed_graphs = dgl.batch(constructed_graphs)

    return binding_parts, not_in_binding, constructed_graphs

node_featurizer = CanonicalAtomFeaturizer(atom_data_field='h')

zero = np.eye(2)[1]
one = np.eye(2)[0]

protein_to_pdb = {}
with open("InterpretableDTIP-master/IBM_BindingDBuniprotPdb.txt", 'r') as fp:
    raw = fp.read()

for item in raw.split("\n")[1:-1]:
    data = item.split(",")
    protein_to_pdb[data[0].strip()] = data[1].strip()[0:4]

ligand_id_to_smile_train = {}
with open("InterpretableDTIP-master/data/train/chem.repr", 'r') as fp:
    raw = fp.read().split('\n')

with open("InterpretableDTIP-master/data/train/chem", 'r') as fp:
    raw_id = fp.read().split('\n')

for idx, smile in zip(raw_id, raw):
    ligand_id_to_smile_train[idx] = smile

with open("InterpretableDTIP-master/data/train/edges.neg", 'r') as fp:
    raw = fp.read().split('\n')

with open("InterpretableDTIP-master/data/train/edges.pos", 'r') as fp:
    raw2 = fp.read().split('\n')

raw = [(a, 0) for a in raw]
raw2 = [(a, 1) for a in raw2]
raw_all = raw + raw2
random.shuffle(raw_all)
previous_pdb = ''
#count = len(raw_all)
#raw_all_new = raw_all[int(8 * len(raw_all)/10):]
count = len(raw_all)
for j in range(10, 12):
    i = 1
    negative_train = []
    for item in raw_all[int(j * len(raw_all)/12):int((j+1) * len(raw_all)/12)]:
        print(f"{j}: {i}/{count/12}")
        try:
            a = item[0].split(',')
            smile = ligand_id_to_smile_train[a[1]]
            pdb_code = protein_to_pdb[a[3]]
            if pdb_code != '5veu':
                if previous_pdb != pdb_code:
                    pdbl = PDBList()
                    pdbl.retrieve_pdb_file(
                        pdb_code, pdir='./pdbs/', overwrite=True, file_format="pdb"
                    )
                    # Rename file to .pdb from .ent
                    os.rename(
                        './pdbs/' + "pdb" + pdb_code + ".ent", './pdbs/' + pdb_code + ".pdb"
                    )
                    # Assert file has been downloaded
                    assert any(pdb_code in s for s in os.listdir('./pdbs/'))
                    print(f"Downloaded PDB file for: {pdb_code}")
                    _, _, constructed_graphs = process_protein(f"./pdbs/{pdb_code}.pdb")

                    previous_pdb = pdb_code

                g = smiles_to_bigraph(smile, node_featurizer=node_featurizer)
                g = dgl.add_self_loop(g)
                negative_train.append(((constructed_graphs, g), item[1]))

        except Exception as e:
            print(e)
            continue
        i += 1
    with open(f"ibm_bindingdb_train_{j}.pkl", 'wb') as fp:
        pickle.dump(negative_train, fp)


import serial

port = "COM3"
baud = 19200

ser = serial.Serial(port, baud, timeout=1)
    # open the serial port
if ser.isOpen():
     print(ser.name + ' is open...')

while True:
    cmd = raw_input("Enter command or 'exit':")
        # for Python 2
    # cmd = input("Enter command or 'exit':")
        # for Python 3
    if cmd == 'exit':
        ser.close()
        exit()
    else:
        ser.write(cmd.encode('ascii')+'\r\n')
        out = ser.read()
        print('Receiving...'+out)


import xlrd
import matplotlib.pyplot as plt
# 打开excel表格
data_excel = xlrd.open_workbook('2.xlsx')
table = data_excel.sheets()[0]
#划定饼状图区域
b_row=11  #开始行
e_row=17  #结束行
b_col=9   #开始列
e_col=14  #结束列

#读取饼状图标签
list_values=[]
for i in range(b_row, e_row):
    row = table.row_values(i)[1]
    list_values.append(row)
# print(list_values)

#提取单元格内容
for x in range(b_col,e_col):
    values = []
    col = table.col_values(x)
    col1=table.col_values(x)[1]
    for i in range(b_row, e_row):
        values.append(col[i])
    # print(values)
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 正常显示中文标签
    labels = values
    sizes = values
    # explode = (0, 0.1, 0, 0)
    fig1, ax1 = plt.subplots()
    ax1.pie(sizes, labels=labels, autopct='%1.1f%%', shadow=False, startangle=90)
    ax1.axis('equal')
    plt.legend(list_values,loc="upper left",bbox_to_anchor=(-0.168,0.95))
    plt.title(col1+"任务分配与经费占比情况")
    plt.savefig("C:/Users/LLLLL/Desktop/作图任务/{}任务分配与经费占比情况.png".format(col1))
    plt.show()


import torch
import numpy as np

class NTXentLoss(torch.nn.Module):
    def __init__(self, device, batch_size, temperature, use_cosine_similarity=True):
        super(NTXentLoss, self).__init__()
        self.batch_size = batch_size
        self.temperature = temperature
        self.device = device
        self.softmax = torch.nn.Sigmoid()
        #self.mask_samples_from_same_repr = self._get_correlated_mask(x).type(torch.bool)
        self.similarity_function = self._get_similarity_function(use_cosine_similarity)
        self.criterion = torch.nn.CrossEntropyLoss(reduction="sum")

    def _get_similarity_function(self, use_cosine_similarity):
        if use_cosine_similarity:
            self._cosine_similarity = torch.nn.CosineSimilarity(dim=-1)
            return self._cosine_simililarity
        else:
            return self._dot_simililarity

    def _get_correlated_mask(self,x):
        self.batch_size=x.shape[0]
        diag = np.eye(2 * self.batch_size)
        l1 = np.eye((2 * self.batch_size), 2 * self.batch_size, k=-self.batch_size)
        l2 = np.eye((2 * self.batch_size), 2 * self.batch_size, k=self.batch_size)
        mask = torch.from_numpy((diag + l1 + l2))
        mask = (1 - mask).type(torch.bool)
        return mask.to(self.device)

    @staticmethod
    def _dot_simililarity(x, y):
        v = torch.tensordot(x.unsqueeze(1), y.T.unsqueeze(0), dims=2)
        # x shape: (N, 1, C)
        # y shape: (1, C, 2N)
        # v shape: (N, 2N)
        return v

    def _cosine_simililarity(self, x, y):
        # x shape: (N, 1, C)
        # y shape: (1, 2N, C)
        # v shape: (N, 2N)
        v = self._cosine_similarity(x.unsqueeze(1), y.unsqueeze(0))
        return v

    def forward(self, zis, zjs):
        representations = torch.cat([zjs, zis], dim=0)
        #print('p1: ',zis)
        #print(zjs.shape)
        #print(representations)
        similarity_matrix = self.similarity_function(representations, representations)
        #print(similarity_matrix.shape)
        self.batch_size=zjs.shape[0]
        # filter out the scores from the positive samples
        l_pos = torch.diag(similarity_matrix, self.batch_size)
        #print('l_pos: ',l_pos)
        r_pos = torch.diag(similarity_matrix, -self.batch_size)
        #print('r_pos: ',r_pos)
        positives = torch.cat([l_pos, r_pos]).view(2 * self.batch_size, 1)
        self.mask_samples_from_same_repr = self._get_correlated_mask(zis).type(torch.bool)
        negatives = similarity_matrix[self.mask_samples_from_same_repr].view(2 * self.batch_size, -1)

        logits = torch.cat((positives, negatives), dim=1)
        logits /= self.temperature

        labels = torch.zeros(2 * self.batch_size).to(self.device).long()
        loss = self.criterion(logits, labels)

        #print('loss: ',loss)
        return loss / (2 * self.batch_size)

class Align_score(torch.nn.Module):
    def __init__(self, device, batch_size):
        super(Align_score, self).__init__()
        self.batch_size = batch_size
        self.device = device
    def forward(self,zis, zjs):
        align_loss = (zis - zjs).norm(p=2, dim=1).pow(2).mean()
        #print(align_loss)
        return align_loss

class Uniform_score(torch.nn.Module):
    def __init__(self, device, batch_size):
        super(Uniform_score, self).__init__()
        self.batch_size = batch_size
        self.device = device
    def forward(self,zis, zjs, t=2):
        uniform_loss1=torch.pdist(zis, p=2).pow(2).mul(-t).exp().mean().log()
        uniform_loss2 = torch.pdist(zjs, p=2).pow(2).mul(-t).exp().mean().log()
        uniform_loss=(uniform_loss1 + uniform_loss2) / 2
        #print(uniform_loss)
        return uniform_loss


from collections import defaultdict
from sqlalchemy import delete
from sqlalchemy.sql import select

from src.main.controller.view.curricula import Curricula, Curriculas
from src.main.repository.model.curricula import CurriculaDB
from src.main.repository.config import commit_rollback, db

class CurriculaRepository:
    @staticmethod
    async def create(create_from: Curriculas):
        """create Lead data"""
        for curricula in create_from:
            for subject_id in curricula.subjects_ids:
                db.add(
                    CurriculaDB(carrer_id=curricula.carrer_id, subject_id=subject_id)
                )
        await commit_rollback()

    @staticmethod
    async def delete(carrer_id: int):
        """delete curricula data by carrer id"""

        query = delete(CurriculaDB).where(CurriculaDB.carrer_id == carrer_id)
        await db.execute(query)
        await commit_rollback()

    @staticmethod
    async def get_all() -> Curriculas:
        query = select(CurriculaDB)
        result = (await db.scalars(query)).fetchall()

        curriculas = defaultdict(list)
        for curricula in result:
            curriculas[curricula.carrer_id].append(curricula.subject_id)

        curriculas = Curriculas(
            [Curricula(carrer_id=k, subjects_ids=v) for k, v in curriculas.items()]
        )
        return curriculas


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

from django.db import migrations, models

class Migration(migrations.Migration):

    dependencies = [
        ('system', '0012_auto_20161114_1922'),
    ]

    operations = [
        migrations.AlterField(
            model_name='condominiumfloor',
            name='name',
            field=models.CharField(max_length=32, blank=True, verbose_name='floor name'),
        ),
        migrations.AlterField(
            model_name='condominiumporch',
            name='name',
            field=models.CharField(max_length=64, default='', blank=True, verbose_name='porch name'),
            preserve_default=False,
        ),
    ]


from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ValidationError

from qt_utils.model_loaders import get_outstanding_token_model, get_user_model

def user_email_not_taken_validator(email):
    User = get_user_model()
    if User.is_email_taken(email):
        raise ValidationError(
            _("An account for the email already exists."),
        )

def user_email_exists_validator(email):
    User = get_user_model()
    if not User.is_email_taken(email):
        raise ValidationError(_("No user found with this email."))

def outstanding_token_exists(refresh_token):
    OutstandingToken = get_outstanding_token_model()
    if not OutstandingToken.objects.filter(token=refresh_token).exists():
        raise ValidationError(
            _("Oustanding token not found."),
        )


from scene import Scene

import numpy as np
import torch
import _pickle as pickle
import copy
import cv2
import os
import time

start_time = time.time()
all_data = []

def cache_frames(ann,output_directory):

    # for each frame idx
    for f_idx in range (2700):

        if len(ann.data[f_idx]) == 0: # past last frame
            break

        # for each camera

        for c_idx in range(len(ann.cameras)):
            cam_frame_annotations = []

            camera = ann.cameras[c_idx]
            cam_name = ann.cameras[c_idx].name

            # get set of objects labeled within that camera
            ts_data = list(ann.data[ann.frame_idx].values())
            ts_data = list(filter(lambda x: x["camera"] == camera.name,ts_data))

            if len(ts_data) == 0:
                continue
            ids = [item["id"] for item in ts_data]
            if len(ts_data) > 0:
                boxes = torch.stack([torch.tensor([obj["x"],obj["y"],obj["l"],obj["w"],obj["h"],obj["direction"]]).float() for obj in ts_data])

                # convert into image space
                im_boxes = ann.hg.state_to_im(boxes,name = camera.name)

            for i in range (len(ts_data)):
                # for each object, append the image-space box to the ts_data annotation
                ts_data[i]["im_box"] = im_boxes[i]
                ts_data[i]["box"] = boxes[i]
                ts_data[i]["frame_idx"] = f_idx
                if "gen" not in ts_data[i].keys(): ts_data[i]["gen"] = "Manual"
                cam_frame_annotations.append(ts_data[i])

            # generate image path
            im_directory = "{}/im".format(output_directory)
            if not os.path.exists(im_directory):
                    os.mkdir(im_directory)
            scene_directory = "{}/im/scene_{}".format(output_directory,ann.scene_id)
            if not os.path.exists(scene_directory):
                    os.mkdir(scene_directory)
            cam_directory   = "{}/im/scene_{}/{}".format(output_directory,ann.scene_id,cam_name)
            if not os.path.exists(cam_directory):
                    os.mkdir(cam_directory)

            im_path = "{}/{}.png".format(cam_directory,str(f_idx).zfill(4))
            if not os.path.exists(im_path):
                frame = ann.buffer[ann.buffer_frame_idx][c_idx].copy() # second item is timestamp or dummy value
                frame = cv2.resize(frame,(1920,1080))
                cv2.imwrite(im_path,frame)

            # generate label path
            lab_directory = "{}/label".format(output_directory)
            if not os.path.exists(lab_directory):
                    os.mkdir(lab_directory)
            scene_directory = "{}/label/scene_{}".format(output_directory,ann.scene_id)
            if not os.path.exists(scene_directory):
                    os.mkdir(scene_directory)
            cam_directory   = "{}/label/scene_{}/{}".format(output_directory,ann.scene_id,cam_name)
            if not os.path.exists(cam_directory):
                    os.mkdir(cam_directory)

            label_directory = "{}/label/scene_{}/{}".format(output_directory,scene_id,cam_name)
            if not os.path.exists(label_directory):
                os.mkdir(label_directory)
            lab_path = "{}/{}.cpkl".format(label_directory,str(f_idx).zfill(4))

            with open(lab_path,"wb") as f:
                pickle.dump(cam_frame_annotations,f)

            # after all objects have been  added
            all_data.append([im_path,lab_path])

        # advance cameras
        ann.next()
        if f_idx % 100 == 0:
            t_est = time.time() - start_time
            print("Cached scene {} frame {}, {} fps cache rate".format(scene_id,f_idx,f_idx/t_est))

        if f_idx > 10:
            break

    save_label_path = "{}/data_summary.cpkl".format(output_directory)
    with open(save_label_path,"wb") as f:
        pickle.dump(all_data,f)

if __name__ == "__main__":

    video_dir = "/home/worklab/Documents/I24-3D/video"
    data_dir  = "/home/worklab/Documents/I24-3D/data"
    out_dir = "/home/worklab/Documents/I24-3D/cache"

    for scene_id in [1,2,3]:
        ann = Scene(video_dir,data_dir,scene_id = scene_id)
        cache_frames(ann,output_directory = out_dir)


from datetime import datetime
from service.booking import is_room_available

def define_room(room_number:int, capacity:str, floor_number:str):
    """
    Define a room with the provided room number, capacity, and floor number.

    Args:
        room_number (int): The unique room number.
        capacity (int): The capacity of the room.
        floor_number (int): The floor number where the room is located.

    Returns:
        dict: A dictionary representing the room with room_number, capacity, and floor_number.
    """
    room = {
        "room_number" : room_number,
        "capacity" : capacity,
        "floor_number" : floor_number,
    }
    return room

def list_rooms_with_availability(all_floors, all_bookings, start_time=None, end_time=None):
    """
    List all rooms with their availability status for a specified time slot.

    Args:
        all_floors (dict): A dictionary containing information about all floors and their rooms.
        all_bookings (dict): A dictionary containing all booking information.
        start_time (datetime, optional): The start time of the time slot. Defaults to current time.
        end_time (datetime, optional): The end time of the time slot. Defaults to current time.

    Returns:
        list: A list of dictionaries representing rooms with their availability status.
    """
    if start_time is None:
        start_time = datetime.now()
    if end_time is None:
        end_time = start_time

    rooms_with_availability = []

    for floor_number, floor_info in all_floors.items():
        rooms_on_floor = floor_info.get("rooms", {})

        for room_number, room_info in rooms_on_floor.items():
            availability = is_room_available(all_bookings, floor_number, room_number, start_time, end_time)
            room_info["currently_available"] = availability
            rooms_with_availability.append({"floor_number": floor_number, "room_info": room_info})

    return rooms_with_availability


from typing import List
import collections

class Solution:
  def countCharacters(self, words: List[str], chars: str) -> int:
    result, charsCounter = 0, collections.Counter(chars)
    for word in words:
      wordCounter = collections.Counter(word)
      isValidWord = True
      for c in wordCounter:
        if c not in charsCounter or wordCounter[c] > charsCounter[c]:
          isValidWord = False
          break
      if isValidWord:
        result += len(word)
    return result

words = ["cat","bt","hat","tree"]
chars = "atach"
s = Solution()
result = s.countCharacters(words, chars)
print(result)


TEMPLATE = "FNFPPNKPPHSOKFFHOFOC"
INPUT = """VS -> B
SV -> C
PP -> N
NS -> N
BC -> N
PB -> F
BK -> P
NV -> V
KF -> C
KS -> C
PV -> N
NF -> S
PK -> F
SC -> F
KN -> K
PN -> K
OH -> F
PS -> P
FN -> O
OP -> B
FO -> C
HS -> F
VO -> C
OS -> B
PF -> V
SB -> V
KO -> O
SK -> N
KB -> F
KH -> C
CC -> B
CS -> C
OF -> C
FS -> B
FP -> H
VN -> O
NB -> N
BS -> H
PC -> H
OO -> F
BF -> O
HC -> P
BH -> S
NP -> P
FB -> C
CB -> H
BO -> C
NN -> V
SF -> N
FC -> F
KK -> C
CN -> N
BV -> F
FK -> C
CF -> F
VV -> B
VF -> S
CK -> C
OV -> P
NC -> N
SS -> F
NK -> V
HN -> O
ON -> P
FH -> O
OB -> H
SH -> H
NH -> V
FF -> B
HP -> B
PO -> P
HB -> H
CH -> N
SN -> P
HK -> P
FV -> H
SO -> O
VH -> V
BP -> V
CV -> P
KP -> K
VB -> N
HV -> K
SP -> N
HO -> P
CP -> H
VC -> N
CO -> S
BN -> H
NO -> B
HF -> O
VP -> K
KV -> H
KC -> F
HH -> C
BB -> K
VK -> P
OK -> C
OC -> C
PH -> H
"""
from collections import defaultdict, Counter
from tqdm import tqdm

d = defaultdict(str)
for line in INPUT.splitlines():
    pair, inserted = line.split(' -> ')
    d[pair.strip()] = inserted.strip()

def step(template: str, rules: dict) -> str:
    """performs one insertion step as described here: https://adventofcode.com/2021/day/14"""
    split = [template[i:i+2] for i in range(len(template)-1)]
    new_template = [item[0] + d[item] + item[1] for item in split]
    nt = new_template[0]
    for item in new_template[1:]:
        nt += item[1:]
    return nt

# template = TEMPLATE
# for i in tqdm(range(10)):
#     template = step(template, d)

# c = {}
# for letter in set(template):
#     c[letter] = template.count(letter)
# print(max(c.values()) - min(c.values()))

# part 2 (kudos to Flo Reichel)

# Find count of AB pairs in initial string
first_element = 'F'
c = Counter()
for idx in range(len(TEMPLATE[:-1])):
    c[TEMPLATE[idx:idx+2]] += 1

# Loop steps
for i in range(40):
    # Copy and re-initialise counter
    cc = c
    c = Counter()
    for el in cc.keys():
        # Increment counter for AX and XB
        c[el[0] + d[el]] += cc[el]
        c[d[el] + el[1]] += cc[el]

# Now count the actual elements
l = Counter()
# Add back the very first element, since the loop below will only consider the second half of each pair
l[first_element] = 1
for el, ct in c.items():
    l[el[1]] += ct

print(l.most_common()[0][1] - l.most_common()[-1][1])


import joblib
import numpy as np
def get_price_of_mbike(enc_path, model_path):
    # Program need low letters because onehotencoder categories also are lower letters.
    brand = str(input("Select brand?: ")).lower()
    b_model = str(input("Select model?: ")).lower()
    capacity = int(input("What's the capacity of the model?: "))
    kilometers = int(input("How many kilometers motorcycle has driven?: "))
    year = int(input("What's the year of motorcycle?: "))

    model = joblib.load(model_path)
    enc = joblib.load(enc_path)
    # len(enc.categories_) is equal to 2, that's why I use list comprehension
    # to extreact data from list
    enc_cat_lst = [enc for model in enc.categories_ for enc in model]
    while True:
        if brand in enc_cat_lst:
            if b_model in enc_cat_lst:
                sample = np.array([brand, b_model, capacity, kilometers, year])
                cat = sample[:2]
                cat = cat.reshape(1, 2)
                sample_encoded = enc.transform(cat).toarray()
                sample_numerical = sample[2:].reshape(1, 3)
                full_sample = np.concatenate((sample_numerical, sample_encoded), axis=1)
                m_price = model.predict(full_sample)
                return "Price of your motorbike is equal to {} PLN".format(int(m_price[0]))
            else:
                return 'Unidentified model of motorbike please check spelling!'
        else:
            return 'Unidentified brand of a motorbike, please check spelling!'

if __name__ == "__main__":
    price = get_price_of_mbike(r'encoder\encoder.joblib', r'models\GradientRModel.joblib')
    print(price)


import time
import requests
from pathlib import Path
from mognet_demo.models import Job, UploadJobResult
from mognet.model.result_state import READY_STATES, SUCCESS_STATES

_cwd = Path(__file__).parent

def test_full_a_to_z():
    """
    Test the "full A-Z", i.e., upload a file through the API, wait for the task,
    and get the result.
    """

    # 1. Upload the file.
    with (_cwd / "files.zip").open("rb") as files:
        submit_response = requests.post(
            "http://localhost:8000/jobs", files={"file": files}
        )

    assert submit_response.ok

    # 2. Get the job to wait for...
    job = Job.parse_obj(submit_response.json())

    # 3. Wait for it, through polling...
    while True:
        result_response = requests.get(
            f"http://localhost:8000/jobs/{job.job_id}/result?wait=10"
        )

        assert result_response.ok

        result = UploadJobResult.parse_obj(result_response.json())

        if result.job_status not in READY_STATES:
            time.sleep(1)

        break

    # 4 .And assert that it succeeds.
    assert result.job_status in SUCCESS_STATES

    assert result.result is not None

    assert len(result.result.documents) == 30


import os
import subprocess
import sys
import argparse

import numpy as np
import mxnet as mx
import scipy.io as sio
from utils.evaluation import eval_feature

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("gpu", default=0, type=int)
    parser.add_argument("model_path", type=str)
    parser.add_argument("--distractor", action="store_true")
    args = parser.parse_args()

    model_path = args.model_path
    basename = os.path.splitext(os.path.basename(model_path))[0]
    prefix = "-".join(basename.split("-")[:-1])
    epoch_idx = int(basename.split("-")[-1])
    gpu = args.gpu
    dataset = model_path.split("/")[1]

    assert dataset in ["market", "cuhk", "duke", "msmt"]

    print("%s/%s-%d" % (dataset, prefix, epoch_idx))

    # extract feature
    cmd = "python%c -m utils.extract --prefix %s --gpu-id %d --epoch-idx %d --dataset %s" % (
        sys.version[0], prefix, gpu, epoch_idx, dataset)

    if args.distractor and dataset == "market":
        cmd += " --distractor"

    subprocess.check_call(cmd.split(" "))

    # load extracted feature
    query_features_path = 'features/%s/query-%s.mat' % (dataset, prefix)
    gallery_features_path = "features/%s/gallery-%s.mat" % (dataset, prefix)
    assert os.path.exists(query_features_path) and os.path.exists(gallery_features_path)

    query_mat = sio.loadmat(query_features_path)
    gallery_mat = sio.loadmat(gallery_features_path)

    query_features = query_mat["feat"]
    query_ids = query_mat["ids"].squeeze()
    query_cam_ids = query_mat["cam_ids"].squeeze()

    gallery_features = gallery_mat["feat"]
    gallery_ids = gallery_mat["ids"].squeeze()
    gallery_cam_ids = gallery_mat["cam_ids"].squeeze()

    eval_feature(query_features, gallery_features, query_ids, query_cam_ids, gallery_ids, gallery_cam_ids,
                 ctx=mx.gpu(args.gpu), metric="cosine")

    if args.distractor:
        for i in range(3):
            distractor_features_path = 'features/%s/distractor%d-%s.mat' % (dataset, i + 1, prefix)
            distractor_mat = sio.loadmat(distractor_features_path)

            distractor_features = distractor_mat["feat"]
            distractor_ids = distractor_mat["ids"].squeeze()
            distractor_cam_ids = distractor_mat["cam_ids"].squeeze()

            gallery_features = np.concatenate([gallery_features, distractor_features], axis=0)
            gallery_ids = np.concatenate([gallery_ids, distractor_ids], axis=0)
            gallery_cam_ids = np.concatenate([gallery_cam_ids, distractor_cam_ids], axis=0)

            eval_feature(query_features, gallery_features, query_ids, query_cam_ids, gallery_ids, gallery_cam_ids,
                         ctx=mx.gpu(i) if i < 2 else mx.cpu(), metric="cosine")

            del distractor_features
            del distractor_cam_ids
            del distractor_ids

    print("\n")

    cmd = "python%c -m post_processing.post_clustering %s %s" % (sys.version[0], dataset, prefix)
    subprocess.check_call(cmd.split(" "))


#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Developed by Shangchen Zhou <shangchenzhou@gmail.com>

from easydict import EasyDict as edict
import os
import socket

__C     = edict()
cfg     = __C

#
# Common
#
__C.CONST                               = edict()
__C.CONST.DEVICE                        = 'all'                   # '0'
__C.CONST.NUM_WORKER                    = 1                       # number of data workers
__C.CONST.WEIGHTS                       = './ckpt/best-ckpt.pth.tar'
__C.CONST.TRAIN_BATCH_SIZE              = 1
__C.CONST.TEST_BATCH_SIZE               = 1
#
# Dataset
#
__C.DATASET                             = edict()
__C.DATASET.DATASET_NAME                = 'VideoDeblur'       # VideoDeblur, VideoDeblurReal

#
# Directories
#
__C.DIR                                 = edict()
__C.DIR.OUT_PATH = './output'

if cfg.DATASET.DATASET_NAME == 'VideoDeblur':
    __C.DIR.DATASET_JSON_FILE_PATH = './datasets/VideoDeblur.json'
    __C.DIR.DATASET_ROOT = '/data/DeepVideoDeblurringDataset/'
    __C.DIR.IMAGE_BLUR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/input/%s.jpg')
    __C.DIR.IMAGE_CLEAR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/GT/%s.jpg')
# real
elif cfg.DATASET.DATASET_NAME == 'VideoDeblurReal':
    __C.DIR.DATASET_JSON_FILE_PATH = './datasets/VideoDeblurReal.json'
    __C.DIR.DATASET_ROOT = '/data/qualitative_datasets/'
    __C.DIR.IMAGE_BLUR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/input/%s.jpg')
    __C.DIR.IMAGE_CLEAR_PATH = os.path.join(__C.DIR.DATASET_ROOT,'%s/%s/input/%s.jpg')

#
# data augmentation
#
__C.DATA                                = edict()
__C.DATA.STD                            = [255.0, 255.0, 255.0]
__C.DATA.MEAN                           = [0.0, 0.0, 0.0]
__C.DATA.CROP_IMG_SIZE                  = [320, 448]              # Crop image size: height, width
__C.DATA.GAUSSIAN                       = [0, 1e-4]               # mu, std_var
__C.DATA.COLOR_JITTER                   = [0.2, 0.15, 0.3, 0.1]   # brightness, contrast, saturation, hue
__C.DATA.SEQ_LENGTH                     = 20

#
# Network
#
__C.NETWORK                             = edict()
__C.NETWORK.DEBLURNETARCH               = 'DeblurNet'             # available options: DeblurNet
__C.NETWORK.LEAKY_VALUE                 = 0.1
__C.NETWORK.BATCHNORM                   = False
__C.NETWORK.PHASE                       = 'test'                 # available options: 'train', 'test', 'resume'

#
# Training
#

__C.TRAIN                               = edict()
__C.TRAIN.USE_PERCET_LOSS               = True
__C.TRAIN.NUM_EPOCHES                   = 400                    # maximum number of epoches
__C.TRAIN.LEARNING_RATE                 = 1e-4
__C.TRAIN.LR_MILESTONES                 = [80,160,250]
__C.TRAIN.LR_DECAY                      = 0.1                    # Multiplicative factor of learning rate decay
__C.TRAIN.MOMENTUM                      = 0.9
__C.TRAIN.BETA                          = 0.999
__C.TRAIN.BIAS_DECAY                    = 0.0                    # regularization of bias, default: 0
__C.TRAIN.WEIGHT_DECAY                  = 0.0                    # regularization of weight, default: 0
__C.TRAIN.PRINT_FREQ                    = 10
__C.TRAIN.SAVE_FREQ                     = 10                     # weights will be overwritten every save_freq epoch

__C.LOSS                                = edict()
__C.LOSS.MULTISCALE_WEIGHTS             = [0.3, 0.3, 0.2, 0.1, 0.1]

#
# Testing options
#
__C.TEST                                = edict()
__C.TEST.VISUALIZATION_NUM              = 10
__C.TEST.PRINT_FREQ                     = 5
if __C.NETWORK.PHASE == 'test':
    __C.CONST.TEST_BATCH_SIZE           = 1