# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def findTarget(self, root: Optional[TreeNode], k: int) -> bool:

        stack1 = []
        stack2 = []

        temp = root
        while(temp):
            stack1.append(temp)
            temp = temp.left

        temp = root
        while(temp):
            stack2.append(temp)
            temp = temp.right

        while(stack1 and stack2):

            node1 ,node2 = stack1[-1] , stack2[-1]

            summe = node1.val + node2.val

            if(summe == k) and node1.val != node2.val:
                return True

            elif(summe > k):
                node2 = stack2.pop()

                temp = node2.left
                while(temp):
                    stack2.append(temp)
                    temp = temp.right

            else:
                node1 = stack1.pop()
                temp = node1.right
                while(temp):
                    stack1.append(temp)
                    temp = temp.left

        return False


"""
Created on April, 2018

@author: Siyuan Huang

scripts about camera transformation
"""

"""
Camera notes:
    K: the intrinsic camera parameter
    R_ex: the standard extrinsic camera parameter
    R_tilt: the extrinsic camera parameter after changing the coordinate from left-hand to right-hand
    T:  translation

    [u, v, 1].T = K [R_ex T] [x_w, y_w, z_w, 1].T
    Rtilt = [1 0 0; 0 0 1 ;0 -1 0]*R_ex*[1 0 0; 0 0 -1 ;0 1 0];

    p_world.dot(R_ex.T) = p_camera
    R_ex.T.dot(p_camera)[0, 2, -1] = p_world_right
"""
import numpy as np
from numpy.linalg import inv

def rotation_matrix_3d_z(angle):
    R = np.zeros((3, 3))
    R[0, 0] = np.cos(angle)
    R[1, 1] = np.cos(angle)
    R[0, 1] = -np.sin(angle)
    R[1, 0] = np.sin(angle)
    R[2, 2] = 1
    return R

def rotation_matrix_3d_x(angle):
    R = np.zeros((3, 3))
    R[1, 1] = np.cos(angle)
    R[2, 2] = np.cos(angle)
    R[1, 2] = -np.sin(angle)
    R[2, 1] = np.sin(angle)
    R[0, 0] = 1
    return R

def rotation_matrix_3d_y(angle):
    R = np.zeros((3, 3))
    R[0, 0] = np.cos(angle)
    R[1, 1] = 1
    R[0, 2] = np.sin(angle)
    R[2, 0] = -np.sin(angle)
    R[2, 2] = np.cos(angle)
    return R

def calibrate_cam(vp, h, w):
    """
    Estimate the camera parameters
    Check dhoiem.cs.illinois.edu/courses/vision_spring10/lectures/lecture3_projectivegeomtery.pdf for detail algorithm

    Parameters
    ----------
    vp : numpy array
        vanishing points
    h: float
        height of the image
    w: float
        width of the image
    Return
    ---------
    k: 3x3 numpy array
        intrinsic camera parameter
    r: 3x3 numpy array
        extrinsic camera parameter
    """
    infchk = np.logical_and(vp[:, 0] > 50*w, vp[:, 1] > 50*h)
    if np.sum(infchk) == 0:
        v1 = vp[0, :]
        v2 = vp[1, :]
        v3 = vp[2, :]
        m_11 = v1[0] + v2[0]
        m_12 = v1[1] + v2[1]
        m_13 = v1[0]*v2[0] + v1[1]*v2[1]
        m_21 = v1[0] + v3[0]
        m_22 = v1[1] + v3[1]
        m_23 = v1[0]*v3[0] + v1[1]*v3[1]
        m_31 = v3[0] + v2[0]
        m_32 = v3[1] + v2[1]
        m_33 = v3[0]*v2[0] + v3[1]*v2[1]
        a_11 = m_11 - m_21
        a_12 = m_12 - m_22
        a_21 = m_11 - m_31
        a_22 = m_12 - m_32
        b_1 = m_13 - m_23
        b_2 = m_13 - m_33
        det_a = a_11*a_22 - a_12*a_21
        u0 = (a_22*b_1-a_12*b_2)/det_a
        v0 = (a_11*b_2-a_21*b_1)/det_a
        temp = m_11*u0 + m_12*v0 - m_13 - u0*u0 - v0*v0
        f = temp ** 0.5
    if np.sum(infchk) == 1:
        ii = np.nonzero(infchk == 0)
        v1 = vp[ii[0], :]
        v2 = vp[ii[1], :]
        r = ((w/2 - v1[0])*(v2[0] - v1[0])+(h/2 - v1[1])*(v2[1]-v1[1])) / ((v2[0] - v1[0]) ** 2 + (v2[1] - v1[1]) ** 2)
        u0 = v1[0] + r*(v2[0] - v1[0])
        v0 = v1[1] + r*(v2[1] - v1[1])
        temp = u0 * (v1[0] + v2[0]) + v0*(v2[1] + v1[1]) - (v1[0]*v2[0] + v2[1]*v1[1] + u0**2 + v0**2)
        f = temp ** 0.5
    if 'f' in locals() and 'u0' in locals() and 'v0' in locals():
        k = np.array([[f, 0, u0], [0, f, v0], [0, 0, 1]])
        vecx = inv(k).dot(np.hstack((vp[1, :], 1)).T)
        vecx /= np.linalg.norm(vecx)
        if vp[1, 0] < u0:
            vecx = -vecx
        vecz = inv(k).dot(np.hstack((vp[2, :], 1)).T)
        vecz = -vecz/np.linalg.norm(vecz)
        vecy = np.cross(vecz, vecx)
        r = np.vstack((vecx, vecy, vecz))
    if sum(infchk) == 2:
        if infchk[1] == 1:
            vp[1, :] = vp[1, :]/np.linalg.norm(vp[1, :])
        if infchk[0] == 1:
            vp[0, :] = vp[0, :]/np.linalg.norm(vp[0, :])
        if infchk[2] == 1:
            vp[2, :] = vp[2, :]/np.linalg.norm(vp[2, :])
        u0 = w/2
        v0 = h/2
        if infchk[1] == 1:
            vecx = np.hstack((vp[1, :], 0)).T
            vecx /= np.linalg.norm(vecx)
            if vp[1, 0] < u0:
                vecx = -vecx
        if infchk[0] == 1:
            vecy = np.hstack((vp[0, :], 0)).T
            vecy /= np.linalg.norm(vecy)
            if vp[0, 1] > v0:
                vecy = -vecy
        if infchk[2] == 1:
            vecz = np.hstack((vp[2, :], 0)).T
            vecz = -vecz/np.linalg.norm(vecz)
        if 'vecx' in locals() and 'vecy' in locals():
            vecz = np.cross(vecx, vecy)
        elif 'vecy' in locals() and 'vecz' in locals():
            vecx = np.cross(vecy, vecz)
        else:
            vecy = np.cross(vecz, vecx)
        r = np.vstack((vecx, vecy, vecz))
        f = 544
        k = np.array([[f, 0, u0], [0, f, v0], [0, 0, 1]])
    return k, r

def single_image_to_world(C, p, K, R, h):
    """
    Compute the right world coordinate location from the rgb coordinates given height
    [X, Y, Z]^T = C + \lambda R^-1 K^-1 p

    Parameters
    ----------
    C : np.array([c_x, c_y, c_z])
        3d center of the camera
    p: np.array([u, v, 1])
        2d location in the image
    K: 3x3 numpy array
        intrinsic camera parameter
    R: 3x3 numpy array
        extrinsic camera parameter
    h: float
        height of the 3d points
    Return
    ---------
    loc_3d: np.array([x, y, z])
        location of the 3d point in right-hand coordinate
    """
    temp_foot = inv(R).dot(inv(K)).dot(p)
    temp_foot = temp_foot[[0, 2, 1]]
    temp_foot[2] *= -1
    scale = (h - C[2]) / temp_foot[2]
    x_foot = scale * temp_foot[0]
    y_foot = scale * temp_foot[1]
    z_foot = h
    loc_3d = np.array([x_foot, y_foot, z_foot])
    return loc_3d

def rgbd_to_world(p, depth, K, R_tilt, R=None):
    """
    Compute the right world coordinate location from the pixel position and depth

    Parameters
    ----------
    p: np.array([x, y])
        2d location in image
    K: 3x3 numpy array
        intrinsic camera parameter
    R_tilt: 3x3 numpy array
        extrinsic camera parameter in right-hand coordinates
    R: 3x3 numpy array
        extrinsic camera parameter in left-hand coordinates
    Return
    ---------
    new_coor: np.array([x, y, z])
        location of the 3d point in right-hand coordinate
    """
    cx = K[0, 2]
    cy = K[1, 2]
    fx = K[0, 0]
    fy = K[1, 1]
    x = p[0]
    y = p[1]
    x3 = (x + 1 - cx) * depth / fx
    y3 = (y + 1 - cy) * depth / fy
    z3 = depth
    new_coor = R_tilt.T.dot(np.array([x3, z3, -y3]))   # from camera coordinate to world coordinate so it's R_tilt.T
    # R.T.dot(np.array([x3, y3, z3]))[0, 2, -1]   # this is equal to the last sentence
    return new_coor

def normalize_point(v):
    norm = np.linalg.norm(v)
    if norm == 0:
       return v
    return v / norm

def yaw_pitch_row_from_r(r):
    """
    get the angle of yaw, pitch and row from rotation matrix
    http://planning.cs.uiuc.edu/node103.html
    :param r: numpy array
            rotation matrix
    :return:yaw, pitch, roll: float
            angle of yaw, pitch and roll
    """
    yaw = np.arctan(r[1, 0] / r[0, 0])
    pitch = np.arctan(-r[2, 0] / np.sqrt(r[2, 1] ** 2 + r[2, 2] ** 2))
    roll = np.arctan(r[2, 1] / r[2, 2])
    return yaw, pitch, roll

def points_3d_to_2d(gt3dcorners, K, R_ex):
    """
    :param gt3dcorners: n x 3 numpy array
    :param K: intrinsic parameter
    :param R_ex: extrinsic rotation matrixs
    :return: gt2dcorners: n x 2 numpy arrays
    """
    gt_3dcorners = gt3dcorners.T
    gt_3dcorners_temp = R_ex.dot(gt_3dcorners)
    gt_3dcorners_temp[2, :] = np.abs(gt_3dcorners_temp[2, :])
    gt2dcorners = K.dot(gt_3dcorners_temp)  # note the gt3dcorner
    gt2dcorners = gt2dcorners[:2, :] / gt2dcorners[2, :]
    return gt2dcorners.T

def get_rotation_matrix_from_yaw_roll(yaw, roll):
    """
    :param yaw:
    :param roll:
    :return: R_ex in left hand coordinates
    """
    R = np.zeros((3, 3))
    R[0, 0] = np.cos(yaw)
    R[0, 1] = - np.sin(yaw) * np.cos(roll)
    R[0, 2] = np.sin(roll) * np.sin(yaw)
    R[1, 0] = np.sin(yaw)
    R[1, 1] = np.cos(roll) * np.cos(yaw)
    R[1, 2] = - np.cos(yaw) * np.sin(roll)
    R[2, 0] = 0
    R[2, 1] = np.sin(roll)
    R[2, 2] = np.cos(roll)
    return R


# -*- coding: utf-8 -*-
import sys
from PySide.QtCore import Signal
from PySide.QtGui import QApplication,QWidget,QLabel

class Demo(QWidget):
	my_signal = Signal()

	"""docstring for Demo"""
	def __init__(self):
		super(Demo, self).__init__()
		self.label = QLabel('Hello World', self)
		self.my_signal.connect(self.change_text)
	def change_text(self):
		if self.label.text() == 'Hello World':
			self.label.setText('Hello PyQt')
		else:
			self.label.setText('Hello World')

	def mousePressEvent(self, event):                     # 4
		self.my_signal.emit()

if __name__ == '__main__':
	app = QApplication(sys.argv)
	demo = Demo()
	demo.show()
	sys.exit(app.exec_())


import datetime
import os
import re

import pandas as pd
import pytest
from ruamel.yaml import YAML

from great_expectations import DataContext
from great_expectations.core import ExpectationSuite
from great_expectations.core.batch import Batch, RuntimeBatchRequest
from great_expectations.data_context import BaseDataContext
from great_expectations.data_context.types.base import DataContextConfig
from great_expectations.exceptions import BatchSpecError, ExecutionEngineError
from great_expectations.execution_engine.pandas_batch_data import PandasBatchData
from great_expectations.execution_engine.sqlalchemy_batch_data import (
    SqlAlchemyBatchData,
)
from great_expectations.validator.validator import Validator
from tests.integration.usage_statistics.test_integration_usage_statistics import (
    USAGE_STATISTICS_QA_URL,
)
from tests.test_utils import create_files_in_directory, get_sqlite_temp_table_names

yaml = YAML()

@pytest.fixture
def basic_data_context_v013_config():
    return DataContextConfig(
        **{
            "commented_map": {},
            "config_version": 3,
            "plugins_directory": "plugins/",
            "evaluation_parameter_store_name": "evaluation_parameter_store",
            "validations_store_name": "does_not_have_to_be_real",
            "expectations_store_name": "expectations_store",
            "checkpoint_store_name": "checkpoint_store",
            "config_variables_file_path": "uncommitted/config_variables.yml",
            "datasources": {},
            "stores": {
                "expectations_store": {
                    "class_name": "ExpectationsStore",
                    "store_backend": {
                        "class_name": "TupleFilesystemStoreBackend",
                        "base_directory": "expectations/",
                    },
                },
                "evaluation_parameter_store": {
                    "module_name": "great_expectations.data_context.store",
                    "class_name": "EvaluationParameterStore",
                },
                "checkpoint_store": {
                    "class_name": "CheckpointStore",
                    "store_backend": {
                        "class_name": "TupleFilesystemStoreBackend",
                        "base_directory": "checkpoints/",
                    },
                },
            },
            "data_docs_sites": {},
            "anonymous_usage_statistics": {
                "enabled": True,
                "data_context_id": "6a52bdfa-e182-455b-a825-e69f076e67d6",
                "usage_statistics_url": USAGE_STATISTICS_QA_URL,
            },
        }
    )

def test_ConfigOnlyDataContext_v013__initialization(
    tmp_path_factory, basic_data_context_v013_config
):
    config_path = str(
        tmp_path_factory.mktemp("test_ConfigOnlyDataContext__initialization__dir")
    )
    context = BaseDataContext(
        basic_data_context_v013_config,
        config_path,
    )

    assert len(context.plugins_directory.split("/")[-3:]) == 3
    assert "" in context.plugins_directory.split("/")[-3:]

    pattern = re.compile(r"test_ConfigOnlyDataContext__initialization__dir\d*")
    assert (
        len(
            list(
                filter(
                    lambda element: element,
                    sorted(
                        pattern.match(element) is not None
                        for element in context.plugins_directory.split("/")[-3:]
                    ),
                )
            )
        )
        == 1
    )

def test__normalize_absolute_or_relative_path(
    tmp_path_factory, basic_data_context_v013_config
):
    config_path = str(
        tmp_path_factory.mktemp("test__normalize_absolute_or_relative_path__dir")
    )
    context = BaseDataContext(
        basic_data_context_v013_config,
        config_path,
    )

    pattern_string = os.path.join(
        "^.*test__normalize_absolute_or_relative_path__dir\\d*", "yikes$"
    )
    pattern = re.compile(pattern_string)
    assert (
        pattern.match(context._normalize_absolute_or_relative_path("yikes")) is not None
    )

    assert (
        "test__normalize_absolute_or_relative_path__dir"
        not in context._normalize_absolute_or_relative_path("/yikes")
    )
    assert "/yikes" == context._normalize_absolute_or_relative_path("/yikes")

def test_load_config_variables_file(
    basic_data_context_v013_config, tmp_path_factory, monkeypatch
):
    # Setup:
    base_path = str(tmp_path_factory.mktemp("test_load_config_variables_file"))
    os.makedirs(os.path.join(base_path, "uncommitted"), exist_ok=True)
    with open(
        os.path.join(base_path, "uncommitted", "dev_variables.yml"), "w"
    ) as outfile:
        yaml.dump({"env": "dev"}, outfile)
    with open(
        os.path.join(base_path, "uncommitted", "prod_variables.yml"), "w"
    ) as outfile:
        yaml.dump({"env": "prod"}, outfile)
    basic_data_context_v013_config[
        "config_variables_file_path"
    ] = "uncommitted/${TEST_CONFIG_FILE_ENV}_variables.yml"

    try:
        # We should be able to load different files based on an environment variable
        monkeypatch.setenv("TEST_CONFIG_FILE_ENV", "dev")
        context = BaseDataContext(
            basic_data_context_v013_config, context_root_dir=base_path
        )
        config_vars = context._load_config_variables_file()
        assert config_vars["env"] == "dev"
        monkeypatch.setenv("TEST_CONFIG_FILE_ENV", "prod")
        context = BaseDataContext(
            basic_data_context_v013_config, context_root_dir=base_path
        )
        config_vars = context._load_config_variables_file()
        assert config_vars["env"] == "prod"
    except Exception:
        raise
    finally:
        # Make sure we unset the environment variable we're using
        monkeypatch.delenv("TEST_CONFIG_FILE_ENV")

def test_get_config(empty_data_context):
    context = empty_data_context

    # We can call get_config in several different modes
    assert type(context.get_config()) == DataContextConfig
    assert type(context.get_config(mode="typed")) == DataContextConfig
    assert type(context.get_config(mode="dict")) == dict
    assert type(context.get_config(mode="yaml")) == str
    with pytest.raises(ValueError):
        context.get_config(mode="foobar")

    print(context.get_config(mode="yaml"))
    print(context.get_config("dict").keys())

    assert set(context.get_config("dict").keys()) == {
        "config_version",
        "datasources",
        "config_variables_file_path",
        "plugins_directory",
        "stores",
        "expectations_store_name",
        "validations_store_name",
        "evaluation_parameter_store_name",
        "checkpoint_store_name",
        "data_docs_sites",
        "anonymous_usage_statistics",
        "notebooks",
        "concurrency",
    }

def test_config_variables(empty_data_context):
    context = empty_data_context
    assert type(context.config_variables) == dict
    assert set(context.config_variables.keys()) == {"instance_id"}

def test_get_batch_of_pipeline_batch_data(empty_data_context, test_df):
    context = empty_data_context

    yaml_config = f"""
        class_name: Datasource

        execution_engine:
            class_name: PandasExecutionEngine

        data_connectors:
          my_runtime_data_connector:
            module_name: great_expectations.datasource.data_connector
            class_name: RuntimeDataConnector
            batch_identifiers:
            - airflow_run_id
    """
    # noinspection PyUnusedLocal
    report_object = context.test_yaml_config(
        name="my_pipeline_datasource",
        yaml_config=yaml_config,
        return_mode="report_object",
    )
    # print(json.dumps(report_object, indent=2))
    # print(context.datasources)

    my_batch = context.get_batch(
        datasource_name="my_pipeline_datasource",
        data_connector_name="my_runtime_data_connector",
        data_asset_name="IN_MEMORY_DATA_ASSET",
        batch_data=test_df,
        batch_identifiers={
            "airflow_run_id": 1234567890,
        },
        limit=None,
    )
    assert my_batch.batch_definition["data_asset_name"] == "IN_MEMORY_DATA_ASSET"

    assert my_batch.data.dataframe.equals(test_df)

def test_conveying_splitting_and_sampling_directives_from_data_context_to_pandas_execution_engine(
    empty_data_context, test_df, tmp_path_factory
):
    base_directory = str(
        tmp_path_factory.mktemp(
            "test_conveying_splitting_and_sampling_directives_from_data_context_to_pandas_execution_engine"
        )
    )

    create_files_in_directory(
        directory=base_directory,
        file_name_list=[
            "somme_file.csv",
        ],
        file_content_fn=lambda: test_df.to_csv(header=True, index=False),
    )

    context = empty_data_context

    yaml_config = f"""
class_name: Datasource

execution_engine:
    class_name: PandasExecutionEngine

data_connectors:
    my_filesystem_data_connector:
        class_name: ConfiguredAssetFilesystemDataConnector
        base_directory: {base_directory}

        default_regex:
            pattern: (.+)\\.csv
            group_names:
                - alphanumeric

        assets:
            A:
"""
    # noinspection PyUnusedLocal
    report_object = context.test_yaml_config(
        name="my_directory_datasource",
        yaml_config=yaml_config,
        return_mode="report_object",
    )
    # print(json.dumps(report_object, indent=2))
    # print(context.datasources)

    my_batch = context.get_batch(
        datasource_name="my_directory_datasource",
        data_connector_name="my_filesystem_data_connector",
        data_asset_name="A",
        batch_spec_passthrough={
            "sampling_method": "_sample_using_hash",
            "sampling_kwargs": {
                "column_name": "date",
                "hash_function_name": "md5",
                "hash_value": "f",
            },
        },
    )
    assert my_batch.batch_definition["data_asset_name"] == "A"

    df_data = my_batch.data.dataframe
    assert df_data.shape == (10, 10)
    df_data["date"] = df_data.apply(
        lambda row: datetime.datetime.strptime(row["date"], "%Y-%m-%d").date(), axis=1
    )
    assert (
        test_df[
            (test_df["date"] == datetime.date(2020, 1, 15))
            | (test_df["date"] == datetime.date(2020, 1, 29))
        ]
        .drop("timestamp", axis=1)
        .equals(df_data.drop("timestamp", axis=1))
    )

    my_batch = context.get_batch(
        datasource_name="my_directory_datasource",
        data_connector_name="my_filesystem_data_connector",
        data_asset_name="A",
        batch_spec_passthrough={
            "splitter_method": "_split_on_multi_column_values",
            "splitter_kwargs": {
                "column_names": ["y", "m", "d"],
                "batch_identifiers": {"y": 2020, "m": 1, "d": 5},
            },
        },
    )
    df_data = my_batch.data.dataframe
    assert df_data.shape == (4, 10)
    df_data["date"] = df_data.apply(
        lambda row: datetime.datetime.strptime(row["date"], "%Y-%m-%d").date(), axis=1
    )
    df_data["belongs_in_split"] = df_data.apply(
        lambda row: row["date"] == datetime.date(2020, 1, 5), axis=1
    )
    df_data = df_data[df_data["belongs_in_split"]]
    assert df_data.drop("belongs_in_split", axis=1).shape == (4, 10)

def test_relative_data_connector_default_and_relative_asset_base_directory_paths(
    empty_data_context, test_df, tmp_path_factory
):
    context = empty_data_context

    create_files_in_directory(
        directory=context.root_directory,
        file_name_list=[
            "test_dir_0/A/B/C/logfile_0.csv",
            "test_dir_0/A/B/C/bigfile_1.csv",
            "test_dir_0/A/filename2.csv",
            "test_dir_0/A/filename3.csv",
        ],
        file_content_fn=lambda: test_df.to_csv(header=True, index=False),
    )

    yaml_config = f"""
class_name: Datasource

execution_engine:
    class_name: PandasExecutionEngine

data_connectors:
    my_filesystem_data_connector:
        class_name: ConfiguredAssetFilesystemDataConnector
        base_directory: test_dir_0/A
        glob_directive: "*"
        default_regex:
            pattern: (.+)\\.csv
            group_names:
            - name

        assets:
            A:
                base_directory: B/C
                glob_directive: "log*.csv"
                pattern: (.+)_(\\d+)\\.csv
                group_names:
                - name
                - number
"""
    my_datasource = context.test_yaml_config(
        name="my_directory_datasource",
        yaml_config=yaml_config,
    )
    assert (
        my_datasource.data_connectors["my_filesystem_data_connector"].base_directory
        == f"{context.root_directory}/test_dir_0/A"
    )
    assert (
        my_datasource.data_connectors[
            "my_filesystem_data_connector"
        ]._get_full_file_path_for_asset(
            path="bigfile_1.csv",
            asset=my_datasource.data_connectors["my_filesystem_data_connector"].assets[
                "A"
            ],
        )
        == f"{context.root_directory}/test_dir_0/A/B/C/bigfile_1.csv"
    )

    my_batch = context.get_batch(
        datasource_name="my_directory_datasource",
        data_connector_name="my_filesystem_data_connector",
        data_asset_name="A",
    )

    df_data = my_batch.data.dataframe
    assert df_data.shape == (120, 10)

def test__get_data_context_version(empty_data_context, titanic_data_context):
    context = empty_data_context

    assert not context._get_data_context_version("some_datasource_name", **{})
    assert not context._get_data_context_version(arg1="some_datasource_name", **{})

    yaml_config = f"""
class_name: Datasource

execution_engine:
    class_name: PandasExecutionEngine

data_connectors:
    general_runtime_data_connector:
      module_name: great_expectations.datasource.data_connector
      class_name: RuntimeDataConnector
      batch_identifiers:
      - airflow_run_id
"""
    # noinspection PyUnusedLocal
    my_datasource = context.test_yaml_config(
        name="some_datasource_name",
        yaml_config=yaml_config,
    )

    assert context._get_data_context_version("some_datasource_name", **{}) == "v3"
    assert context._get_data_context_version(arg1="some_datasource_name", **{}) == "v3"

    context = titanic_data_context
    root_dir = context.root_directory
    batch_kwargs = {
        "datasource": "mydatasource",
        "path": f"{root_dir}/../data/Titanic.csv",
    }
    assert context._get_data_context_version(arg1=batch_kwargs) == "v2"
    assert context._get_data_context_version(batch_kwargs) == "v2"
    assert (
        context._get_data_context_version(
            "some_value", **{"batch_kwargs": batch_kwargs}
        )
        == "v2"
    )

def test_in_memory_data_context_configuration(
    titanic_pandas_data_context_with_v013_datasource_with_checkpoints_v1_with_empty_store_stats_enabled,
):
    project_config_dict: dict = titanic_pandas_data_context_with_v013_datasource_with_checkpoints_v1_with_empty_store_stats_enabled.get_config(
        mode="dict"
    )
    project_config_dict["plugins_directory"] = None
    project_config_dict["validation_operators"] = {
        "action_list_operator": {
            "class_name": "ActionListValidationOperator",
            "action_list": [
                {
                    "name": "store_validation_result",
                    "action": {"class_name": "StoreValidationResultAction"},
                },
                {
                    "name": "store_evaluation_params",
                    "action": {"class_name": "StoreEvaluationParametersAction"},
                },
                {
                    "name": "update_data_docs",
                    "action": {"class_name": "UpdateDataDocsAction"},
                },
            ],
        }
    }
    project_config: DataContextConfig = DataContextConfig(**project_config_dict)
    data_context = BaseDataContext(
        project_config=project_config,
        context_root_dir=titanic_pandas_data_context_with_v013_datasource_with_checkpoints_v1_with_empty_store_stats_enabled.root_directory,
    )

    my_validator: Validator = data_context.get_validator(
        datasource_name="my_datasource",
        data_connector_name="my_basic_data_connector",
        data_asset_name="Titanic_1912",
        create_expectation_suite_with_name="my_test_titanic_expectation_suite",
    )

    assert my_validator.expect_table_row_count_to_equal(1313)["success"]
    assert my_validator.expect_table_column_count_to_equal(7)["success"]

def test_get_batch_with_query_in_runtime_parameters_using_runtime_data_connector(
    sa,
    data_context_with_runtime_sql_datasource_for_testing_get_batch,
    sqlite_view_engine,
):
    context: DataContext = (
        data_context_with_runtime_sql_datasource_for_testing_get_batch
    )

    batch: Batch

    batch = context.get_batch(
        batch_request=RuntimeBatchRequest(
            datasource_name="my_runtime_sql_datasource",
            data_connector_name="my_runtime_data_connector",
            data_asset_name="IN_MEMORY_DATA_ASSET",
            runtime_parameters={
                "query": "SELECT * FROM table_partitioned_by_date_column__A"
            },
            batch_identifiers={
                "pipeline_stage_name": "core_processing",
                "airflow_run_id": 1234567890,
            },
        ),
    )

    assert batch.batch_spec is not None
    assert batch.batch_definition["data_asset_name"] == "IN_MEMORY_DATA_ASSET"
    assert isinstance(batch.data, SqlAlchemyBatchData)

    selectable_table_name = batch.data.selectable.name
    selectable_count_sql_str = f"select count(*) from {selectable_table_name}"
    sa_engine = batch.data.execution_engine.engine

    assert sa_engine.execute(selectable_count_sql_str).scalar() == 120
    assert batch.batch_markers.get("ge_load_time") is not None
    # since create_temp_table defaults to True, there should be 1 temp table
    assert len(get_sqlite_temp_table_names(batch.data.execution_engine.engine)) == 1

    # if create_temp_table in batch_spec_passthrough is set to False, no new temp tables should be created
    batch = context.get_batch(
        batch_request=RuntimeBatchRequest(
            datasource_name="my_runtime_sql_datasource",
            data_connector_name="my_runtime_data_connector",
            data_asset_name="IN_MEMORY_DATA_ASSET",
            runtime_parameters={
                "query": "SELECT * FROM table_partitioned_by_date_column__A"
            },
            batch_identifiers={
                "pipeline_stage_name": "core_processing",
                "airflow_run_id": 1234567890,
            },
            batch_spec_passthrough={"create_temp_table": False},
        ),
    )
    assert len(get_sqlite_temp_table_names(batch.data.execution_engine.engine)) == 1

def test_get_validator_with_query_in_runtime_parameters_using_runtime_data_connector(
    sa,
    data_context_with_runtime_sql_datasource_for_testing_get_batch,
):
    context: DataContext = (
        data_context_with_runtime_sql_datasource_for_testing_get_batch
    )
    my_expectation_suite: ExpectationSuite = context.create_expectation_suite(
        "my_expectations"
    )

    validator: Validator

    validator = context.get_validator(
        batch_request=RuntimeBatchRequest(
            datasource_name="my_runtime_sql_datasource",
            data_connector_name="my_runtime_data_connector",
            data_asset_name="IN_MEMORY_DATA_ASSET",
            runtime_parameters={
                "query": "SELECT * FROM table_partitioned_by_date_column__A"
            },
            batch_identifiers={
                "pipeline_stage_name": "core_processing",
                "airflow_run_id": 1234567890,
            },
        ),
        expectation_suite=my_expectation_suite,
    )

    assert len(validator.batches) == 1

def test_get_batch_with_path_in_runtime_parameters_using_runtime_data_connector(
    sa,
    titanic_pandas_data_context_with_v013_datasource_with_checkpoints_v1_with_empty_store_stats_enabled,
):
    context: DataContext = titanic_pandas_data_context_with_v013_datasource_with_checkpoints_v1_with_empty_store_stats_enabled
    data_asset_path = os.path.join(
        context.root_directory, "..", "data", "titanic", "Titanic_19120414_1313.csv"
    )

    batch: Batch

    batch = context.get_batch(
        batch_request=RuntimeBatchRequest(
            datasource_name="my_datasource",
            data_connector_name="my_runtime_data_connector",
            data_asset_name="IN_MEMORY_DATA_ASSET",
            runtime_parameters={"path": data_asset_path},
            batch_identifiers={
                "pipeline_stage_name": "core_processing",
                "airflow_run_id": 1234567890,
            },
        ),
    )

    assert batch.batch_spec is not None
    assert batch.batch_definition["data_asset_name"] == "IN_MEMORY_DATA_ASSET"
    assert isinstance(batch.data, PandasBatchData)
    assert len(batch.data.dataframe.index) == 1313
    assert batch.batch_markers.get("ge_load_time") is not None

    # using path with no extension
    data_asset_path_no_extension = os.path.join(
        context.root_directory, "..", "data", "titanic", "Titanic_19120414_1313"
    )

    # with no reader_method in batch_spec_passthrough
    with pytest.raises(ExecutionEngineError):
        context.get_batch(
            batch_request=RuntimeBatchRequest(
                datasource_name="my_datasource",
                data_connector_name="my_runtime_data_connector",
                data_asset_name="IN_MEMORY_DATA_ASSET",
                runtime_parameters={"path": data_asset_path_no_extension},
                batch_identifiers={
                    "pipeline_stage_name": "core_processing",
                    "airflow_run_id": 1234567890,
                },
            ),
        )

    # with reader_method in batch_spec_passthrough
    batch = context.get_batch(
        batch_request=RuntimeBatchRequest(
            datasource_name="my_datasource",
            data_connector_name="my_runtime_data_connector",
            data_asset_name="IN_MEMORY_DATA_ASSET",
            runtime_parameters={"path": data_asset_path_no_extension},
            batch_identifiers={
                "pipeline_stage_name": "core_processing",
                "airflow_run_id": 1234567890,
            },
            batch_spec_passthrough={"reader_method": "read_csv"},
        ),
    )

    assert batch.batch_spec is not None
    assert batch.batch_definition["data_asset_name"] == "IN_MEMORY_DATA_ASSET"
    assert isinstance(batch.data, PandasBatchData)
    assert len(batch.data.dataframe.index) == 1313
    assert batch.batch_markers.get("ge_load_time") is not None

def test_get_validator_with_path_in_runtime_parameters_using_runtime_data_connector(
    sa,
    titanic_pandas_data_context_with_v013_datasource_with_checkpoints_v1_with_empty_store_stats_enabled,
):
    context: DataContext = titanic_pandas_data_context_with_v013_datasource_with_checkpoints_v1_with_empty_store_stats_enabled
    data_asset_path = os.path.join(
        context.root_directory, "..", "data", "titanic", "Titanic_19120414_1313.csv"
    )
    my_expectation_suite: ExpectationSuite = context.create_expectation_suite(
        "my_expectations"
    )

    validator: Validator

    validator = context.get_validator(
        batch_request=RuntimeBatchRequest(
            datasource_name="my_datasource",
            data_connector_name="my_runtime_data_connector",
            data_asset_name="IN_MEMORY_DATA_ASSET",
            runtime_parameters={"path": data_asset_path},
            batch_identifiers={
                "pipeline_stage_name": "core_processing",
                "airflow_run_id": 1234567890,
            },
        ),
        expectation_suite=my_expectation_suite,
    )

    assert len(validator.batches) == 1

    # using path with no extension
    data_asset_path_no_extension = os.path.join(
        context.root_directory, "..", "data", "titanic", "Titanic_19120414_1313"
    )

    # with no reader_method in batch_spec_passthrough
    with pytest.raises(ExecutionEngineError):
        context.get_validator(
            batch_request=RuntimeBatchRequest(
                datasource_name="my_datasource",
                data_connector_name="my_runtime_data_connector",
                data_asset_name="IN_MEMORY_DATA_ASSET",
                runtime_parameters={"path": data_asset_path_no_extension},
                batch_identifiers={
                    "pipeline_stage_name": "core_processing",
                    "airflow_run_id": 1234567890,
                },
            ),
            expectation_suite=my_expectation_suite,
        )

    # with reader_method in batch_spec_passthrough
    validator = context.get_validator(
        batch_request=RuntimeBatchRequest(
            datasource_name="my_datasource",
            data_connector_name="my_runtime_data_connector",
            data_asset_name="IN_MEMORY_DATA_ASSET",
            runtime_parameters={"path": data_asset_path_no_extension},
            batch_identifiers={
                "pipeline_stage_name": "core_processing",
                "airflow_run_id": 1234567890,
            },
            batch_spec_passthrough={"reader_method": "read_csv"},
        ),
        expectation_suite=my_expectation_suite,
    )

    assert len(validator.batches) == 1


import mock
import os
import shutil
import tempfile

from schmenkins import exceptions
from schmenkins import utils
from schmenkins import tests

class TestUtils(tests.SchmenkinsTest):
    def test_itpl(self):
        d = {'abc': 'def',
             'AbC': 'ghi'}

        self.assertEquals(utils.itpl('123${abc}456', d), '123def456')
        self.assertEquals(utils.itpl('123${AbC}456', d), '123ghi456')
        self.assertEquals(utils.itpl('123${Ab}456', d), '123456')
        self.assertEquals(utils.itpl('123$Ab456', d), '123')
        self.assertEquals(utils.itpl('123$AbC456', d), '123')
        self.assertEquals(utils.itpl('123$AbC', d), '123ghi')

    def test_run_cmd(self):
        with tempfile.NamedTemporaryFile(delete=False) as fp:
            try:
                fp.close()
                utils.run_cmd(['bash', '-c', 'echo -n hello > %s' % (fp.name,)])
                self.assertEquals(open(fp.name, 'r').read(), 'hello')
            finally:
                os.unlink(fp.name)

    def test_run_cmd_dry_run(self):
        with tempfile.NamedTemporaryFile(delete=False) as fp:
            try:
                fp.close()
                utils.run_cmd(['bash', '-c', 'echo -n hello > %s' % (fp.name,)],
                               dry_run=True)
                self.assertEquals(open(fp.name, 'r').read(), '')
            finally:
                os.unlink(fp.name)

    def test_run_cmd_output(self):
        mock_logger = mock.MagicMock()
        output = utils.run_cmd(['bash', '-c', 'echo -n hello'])
        self.assertEquals(output, 'hello')

    def test_run_cmd_logging(self):
        mock_logger = mock.MagicMock()
        output = utils.run_cmd(['bash', '-c', 'echo -n hello'],
                                logger=mock_logger)
        mock_logger.debug.assert_called_with('hello')
        self.assertEquals(output, 'hello')

    def test_run_cmd_failure(self):
        self.assertRaises(exceptions.SchmenkinsCommandFailed,
                          utils.run_cmd, ['false'])

    def test_ensure_dir(self):
        tmpdir = tempfile.mkdtemp()
        try:
            path = os.path.join(tmpdir, 'onemorelevel')
            utils.ensure_dir(path)
            self.assertTrue(os.path.isdir(path))

            # Test for idempotency
            utils.ensure_dir(path)
        finally:
            shutil.rmtree(tmpdir)

    @mock.patch('schmenkins.utils.ensure_dir')
    def test_ensure_dir_wrapper(self, ensure_dir):
        @utils.ensure_dir_wrapper
        def somedir(foo, bar='baz'):
            self.assertEquals(foo, 'wibble')
            self.assertEquals(bar, 'wobble')
            return 'fakedir'

        somedir('wibble', bar='wobble')
        ensure_dir.assert_called_with('fakedir')


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

from graph import Graph

def egreedy_policy(q_values, state, action, epsilon = 0.1):
    '''
    Choose an action based on a epsilon greedy policy.
    A random action is selected with epsilon probability, else select the best action.
    We need to separate the action selectd in state 0/A and the action selectd in 1/B
    '''
    if (state == 0):
        if np.min(q_values[state]) == np.max(q_values[state]):
            action = np.random.choice(2)
        else:
            if np.random.random() < epsilon:
                action =  np.random.choice(2)
            elif np.max(q_values[state]) == np.min(q_values[state]):
                action =  np.random.choice(2)
            else:
                action =  np.argmax(q_values[state])
        return action

    elif(state == 1):
        #return np.random.choice(number_of_actions_from_1)
        if np.random.random() < epsilon:
            action =  np.random.choice(number_of_actions_from_1)
        else:
            action =  np.argmax(q_values[state])
        return action
        # return np.argmax(q_values[state][action])

def double_q_learning(env, num_episodes=500, render=True, exploration_rate=0.1,
          learning_rate=0.5, discount_factor=0.9):
    q_1_values_double_learning = [np.zeros(2), np.zeros(number_of_actions_from_1), 0, 0]
    q_2_values_double_learning = [np.zeros(2), np.zeros(number_of_actions_from_1), 0, 0]
    left_actions_counter = 0
    left_actions_percentage_list = []

    ep_rewards = []
    aggiornamento_q_1= 0
    n_aggiornamenti = 0

    for episode_index in range(1, num_episodes+1):
        if (episode_index % 5000 == 0):
            print(str(episode_index) + "/" + str(num_episodes))
        state = env.reset()
        done = False
        reward_sum = 0

        # Choose action

        # summed_q_values = q_1_values_double_learning + q_2_values_double_learning
        # action = egreedy_policy(summed_q_values, state, exploration_rate)

        while not done:
            # Choose action
            summed_q_values = [ [q_1_values_double_learning[0]/2 + q_2_values_double_learning[0]/2 ],  [q_1_values_double_learning[1]/2 + q_2_values_double_learning[1]/2 ], 0, 0]
            action = egreedy_policy(summed_q_values, state, exploration_rate)

            if (state == 0):
                if action == 1:
                    left_actions_counter += 1
                left_actions_percentage_list.append(left_actions_counter/episode_index)

            # Do the action and observe the reward and the following state
            next_state, reward, done = env.step(state, action)
            reward_sum += reward

            random_value = random.uniform(0, 1)

            # Update q_values

            # if random_value < 0.5 we update q_1, else we update q_2

            if (random_value < 0.5):
                aggiornamento_q_1 += 1
                if (next_state >= 2 ):
                    td_target = reward
                else:
                    td_target = reward + discount_factor * q_2_values_double_learning[next_state][ np.argmax(q_1_values_double_learning[next_state]) ]   # target found using q-learning
                td_error = td_target - q_1_values_double_learning[state][action]
                q_1_values_double_learning[state][action] += learning_rate * td_error
            else:
                if (next_state >= 2 ):
                    td_target = reward
                else:
                    td_target = reward + discount_factor * q_1_values_double_learning[next_state][ np.argmax(q_2_values_double_learning[next_state]) ]   # target found using q-learning
                td_error = td_target - q_2_values_double_learning[state][action]
                q_2_values_double_learning[state][action] += learning_rate * td_error
            n_aggiornamenti += 1

            # Update state
            state = next_state

        ep_rewards.append(reward_sum)

    # print("percentuale aggiornamento q_1 = ", aggiornamento_q_1/n_aggiornamenti)
    return ep_rewards, summed_q_values, left_actions_percentage_list

env = Graph()
# we find the 20 random returns for this attempt
number_of_actions_from_1 = 3

random_returns = norm.rvs(size = number_of_actions_from_1)-0.1

print("media = ",np.mean(random_returns))
print(random_returns)

print(np.zeros(number_of_actions_from_1))

# q_values = [list(np.zeros(2)), list(random_returns), 0, 0]

n_episodes = 1000
n_simulations = 5000
average_values = np.zeros(n_episodes)

for simulation_index in range(n_simulations):
    np.random.seed(simulation_index)
    rewards = [list(np.zeros(2)), list(random_returns), 0, 0]

    if (simulation_index % 50 == 0):
        print(str(simulation_index) + "/" + str(n_simulations))
    _, summed_q_values, left_action_percentage = double_q_learning(env, num_episodes=n_episodes, exploration_rate = 0.1,  discount_factor = 1, learning_rate = 0.1)
    # fare media tra tutti i valori delle simulazioni
    #
    # print(left_action_percentage)
    # print(summed_q_values)
    average_values = (simulation_index * average_values + left_action_percentage)/(simulation_index +1)

pd.DataFrame.to_csv(pd.DataFrame(average_values), "data/result_double_q_learning.csv")

plt.plot(average_values)
plt.show()

Example 4 - Double Q-learning advantages/double_q_learning.py


def add(*args):
    print(args)  # tuple
    return sum(args)

print(add(1, 5, 2, 42, 632))

def calculate(n, **kwargs):
    print(kwargs)  # dictionary
    # for key, value in kwargs.items():
    #     print(key)
    #     print(value)
    print(kwargs["add"])
    n += kwargs["add"]
    n *= kwargs["multiply"]
    print(n)

calculate(2, add=3, multiply=5)

class Car:

    def __init__(self, **kw):
        self.make = kw.get("make")
        self.model = kw.get("model")
        self.year = kw.get("year")

my_car = Car(make="Nissan", model="GT-R")
print(my_car.year)

# GUI

import tkinter
# from tkinter import *  # This way you don't have to write tkinter.

window = tkinter.Tk()

window.title("My First GUI in Python")
window.minsize(width=500, height=300)
window.config(padx=20, pady=20)

# Label
my_label = tkinter.Label(text="I Am a Label", font=("Arial", 24, "bold"))
# my_label.pack()
# my_label.place(x=100, y=200)
my_label.grid(column=0, row=0)

# Button
def button_clicked():
    # my_label["text"] = "I got clicked"
    my_label.config(text=input_field.get())

button = tkinter.Button(text="Click Me", command=button_clicked)
# button.pack()
button.grid(column=1, row=1)

new_button = tkinter.Button(text="New Button")
new_button.grid(column=2, row=0)

# Entry
input_field = tkinter.Entry(width=25)
input_field.insert(tkinter.END, string="Some text to begin with.")
# input_field.pack()
input_field.grid(column=3, row=2)

# # Text
# text = tkinter.Text(height=5, width=30)
# # Puts cursor in textbox.
# text.focus()
# # Adds some text to begin with.
# text.insert(tkinter.END, "Example of multi-line text entry.")
# # Get's current value in textbox at line 1, character 0
# print(text.get("1.0", tkinter.END))
# text.pack()
#
#
# # Spinbox
# def spinbox_used():
#     # gets the current value in spinbox.
#     print(spinbox.get())
#
#
# spinbox = tkinter.Spinbox(from_=0, to=10, width=5, command=spinbox_used)
# spinbox.pack()
#
#
# # Scale
# # Called with current scale value.
# def scale_used(value):
#     print(value)
#
#
# scale = tkinter.Scale(from_=0, to=100, command=scale_used)
# scale.pack()
#
#
# # Checkbutton
# def checkbutton_used():
#     # Prints 1 if On button checked, otherwise 0.
#     print(checked_state.get())
#
#
# # variable to hold on to checked state, 0 is off, 1 is on.
# checked_state = tkinter.IntVar()
# checkbutton = tkinter.Checkbutton(text="Is On?", variable=checked_state, command=checkbutton_used)
# checked_state.get()
# checkbutton.pack()
#
#
# # Radiobutton
# def radio_used():
#     print(radio_state.get())
#
#
# # Variable to hold on to which radio button value is checked.
# radio_state = tkinter.IntVar()
# radiobutton1 = tkinter.Radiobutton(text="Option1", value=1, variable=radio_state, command=radio_used)
# radiobutton2 = tkinter.Radiobutton(text="Option2", value=2, variable=radio_state, command=radio_used)
# radiobutton1.pack()
# radiobutton2.pack()
#
#
# # Listbox
# def listbox_used(event):
#     # Gets current selection from listbox
#     print(listbox.get(listbox.curselection()))
#
#
# listbox = tkinter.Listbox(height=4)
# fruits = ["Apple", "Pear", "Orange", "Banana"]
# for item in fruits:
#     listbox.insert(fruits.index(item), item)
# listbox.bind("<<ListboxSelect>>", listbox_used)
# listbox.pack()

# # Other Solution
# def lstbox_used(event):
#     print(lst_box.get(lst_box.curselection()))
#
#
# list_content = tkinter.Variable(value=["Apples", "Banana", "Oranges"])
# lst_box = tkinter.Listbox(listvariable=list_content, height=4)
# lst_box.bind("<<ListboxSelect>>", lstbox_used)
# lst_box.pack()

window.mainloop()


#-----------------------------------------------------------------------------
# Description: PyRogue Cypress S25FL PROM Series
#
# Note: Used with surf/devices/Micron/n25q firmware
#
#-----------------------------------------------------------------------------
# This file is part of the 'SLAC Firmware Standard Library'. It is subject to
# the license terms in the LICENSE.txt file found in the top-level directory
# of this distribution and at:
#    https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
# No part of the 'SLAC Firmware Standard Library', including this file, may be
# copied, modified, propagated, or distributed except according to the terms
# contained in the LICENSE.txt file.
#-----------------------------------------------------------------------------

import surf.devices.micron
import click
import time
import datetime

class CypressS25Fl(surf.devices.micron.AxiMicronN25Q):
    def __init__(self,
                 description = "Container for Cypress S25FL PROM device",
                 addrMode    = True, # False = 24-bit Address mode, True = 32-bit Address Mode
                 hidden      = True,
                 **kwargs):

        super().__init__(description=description, hidden=hidden, addrMode=addrMode, **kwargs)

        ########################################
        # Overwrite with Cypress S25FL Constants
        ########################################
        self.ERASE_4BYTE_CMD = (0xDC << 16)
        self.WRITE_4BYTE_CMD = (0x12 << 16)
        self.FLAG_STATUS_REG = (0x05 << 16)
        self.FLAG_STATUS_RDY = (0x01)
        self.BRAC_CMD        = (0xB9 << 16)

    def _LoadMcsFile(self,arg):

        click.secho(('LoadMcsFile: %s' % arg), fg='green')
        self._progDone = False

        # Start time measurement for profiling
        start = time.time()

        # Reset the SPI interface
        self.resetFlash()

        # Print the status registers
        print("CypressS25Fl Manufacturer ID Code  = {}".format(hex(self.getManufacturerId())))
        print("CypressS25Fl Manufacturer Type     = {}".format(hex(self.getManufacturerType())))
        print("CypressS25Fl Manufacturer Capacity = {}".format(hex(self.getManufacturerCapacity())))
        print("CypressS25Fl Status Register       = {}".format(hex(self.getPromStatusReg())))

        # Open the MCS file
        self._mcs.open(arg)

        # Erase the PROM
        self.eraseProm()

        # Write to the PROM
        self.writeProm()

        # Verify the PROM
        self.verifyProm()

        # End time measurement for profiling
        end = time.time()
        elapsed = end - start
        click.secho('LoadMcsFile() took %s to program the PROM' % datetime.timedelta(seconds=int(elapsed)), fg='green')

        # Add a power cycle reminder
        self._progDone = True
        click.secho(
            "\n\n\
            ***************************************************\n\
            ***************************************************\n\
            The MCS data has been written into the PROM.       \n\
            To reprogram the FPGA with the new PROM data,      \n\
            a IPROG CMD or power cycle is be required.\n\
            ***************************************************\n\
            ***************************************************\n\n"
            , bg='green',
        )

    def resetFlash(self):
        # Send the "Mode Bit Reset" command
        self.setCmdReg(self.WRITE_MASK|(0xFF << 16))
        time.sleep(0.001)
        # Send the "Software Reset" Command
        self.setCmdReg(self.WRITE_MASK|(0xF0 << 16))
        time.sleep(0.001)
        # Set the addressing mode
        self.setModeReg()
        # Check the address mode
        if (self._addrMode):
            self.setCmd(self.WRITE_MASK|self.BRAC_CMD|0x80)
        else:
            self.setCmd(self.WRITE_MASK|self.BRAC_CMD)

    def waitForFlashReady(self):
        while True:
            # Get the status register
            self.setCmdReg(self.READ_MASK|self.FLAG_STATUS_REG|0x1)
            status = (self.getCmdReg()&0xFF)
            # Check if not busy
            if ( (status & self.FLAG_STATUS_RDY) == 0 ): # active Low READY
                break


# Uses python3
import sys
from collections import namedtuple
Segment = namedtuple('Segment', 'start end')
#print(Segment)
def optimal_points(segments):
    sortedBeg = sorted(segments, key = lambda x: x[0])
    sortedEnd = sorted(segments, key = lambda x: x[1])
    #print(sortedBeg)
    #print(sortedEnd)

    threshold = sortedBeg[0][0] - 1
    listOfPoints = []
    for i in range(len(sortedEnd) - 1):
        beg, end = sortedEnd[i]
        if beg > threshold:
            listOfPoints.append(end)
            threshold = end

    if (listOfPoints[len(listOfPoints) - 1] < sortedEnd[len(sortedEnd) - 1][0]):
        if (sortedEnd):
            listOfPoints.append(sortedEnd[len(sortedEnd) - 1][0])
    print(len(listOfPoints))
    result = []
    for p in listOfPoints:
        result.append(p)

    print(*result)

if __name__ == '__main__':
    input = sys.stdin.read()
    n, *data = map(int, input.split())
    segments = list(map(lambda x: Segment(x[0], x[1]), zip(data[::2], data[1::2])))
    #segments = sorted(segments,key=lambda x: x[1])
    #print(segments)
    optimal_points(segments)


# -*- coding: utf-8 -*-
from scrapy import Spider, Request
from HomeLink.items import HouseInfoItem
import re

#根据行政区列表爬取对应行政区所有成交房源
class HouseinfoSpider(Spider):
    name = "houseinfo"
    allowed_domains = ["bj.lianjia.com"]
#     start_urls = ['http://bj.lianjia.com/']
    xiaoqu_url = 'http://bj.lianjia.com/xiaoqu/'
    chengjiao_url = 'http://bj.lianjia.com/chengjiao/'
    #平谷，怀柔，密云，延庆样本量过少直接pass
    #目前已完成：东城、西城、海淀、房山（未入mongodb）、石景山、丰台,朝阳（还差6000条以后再说）、昌平（54000）
    #          、通州（差4000:珠江逸景:812、新华联家园北区:602、京贸国际城西区：502、海棠湾一期：353，蓝调沙龙东区：295，靓景明居：375，首开国风美仑：78
    #润枫领尚：92，世纪星城：1243，西马庄园：603，百合湾：237，）   、大兴（差1000左右，保利茉莉公馆：739）,顺义（28000）
    #未完成：亦庄开发区（8158）、门头沟（7415）
    #这里输入需要爬取的行政区列表，建议分批爬取，每次爬取的数量不超过10万条。
    district_list = [
             'yizhuangkaifaqu','mentougou'
#         ,'yizhuangkaifaqu','mentougou'
#         ,'pinggu','huairou','miyun','yanqing','fangshan','xicheng','haidian','dongcheng','fengtai','shijingshan','chaoyang' ,'changping'，'tongzhou','daxing'
#           ,'shunyi'
    ]

    def start_requests(self):
        for district in self.district_list:
#             print(self.main_url+district)
            yield Request(url = self.xiaoqu_url+district+"/pg1", callback = self.parse_xiaoqu_list)
#         yield Request(url = 'https://bj.lianjia.com/chengjiao/c1111027377579/', callback = self.parse_xiaoqu_chengjiao_list)

    def parse_xiaoqu_list(self,response):
        curPage = re.search("totalPage.*?:(.*?),.*?curPage.*?:(.*?)}", response.text, re.S).group(2)
        totalPage = re.search("totalPage.*?:(.*?),.*?curPage.*?:(.*?)}", response.text, re.S).group(1)
        xiaoqu_id_list = response.css('.listContent li::attr(data-id)').extract()
        for xiaoqu_id in xiaoqu_id_list:
            yield Request(url = self.chengjiao_url+'c'+xiaoqu_id, callback = self.parse_xiaoqu_chengjiao_list)
        if curPage != totalPage:
            next_page = int(curPage)+1
            yield Request(url = response.url.split('pg')[0]+'pg'+str(next_page), callback = self.parse_xiaoqu_list)
#         if int(curPage) <= 5:
#             next_page = int(curPage)+1
#             yield Request(url = response.url.split('pg')[0]+'pg'+str(next_page), callback = self.parse_xiaoqu_list)

    def parse_xiaoqu_chengjiao_list(self, response):
        curPage = re.search("totalPage.*?:(.*?),.*?curPage.*?:(.*?)}", response.text, re.S).group(2)
        totalPage = re.search("totalPage.*?:(.*?),.*?curPage.*?:(.*?)}", response.text, re.S).group(1)
        house_info_url_list = response.css(".listContent li .title a::attr(href)").extract()
        for house_info_url in house_info_url_list:
            yield Request(url = house_info_url, callback = self.parse_house_info)
        if curPage != totalPage:
            next_page = int(curPage)+1
            yield Request(url = response.url.split('pg')[0]+'pg'+str(next_page), callback = self.parse_xiaoqu_chengjiao_list)

    def parse_house_info(self, response):
        item = HouseInfoItem()
        #行政区名称
        item['district'] = response.css('.deal-bread a::text').extract()[2][0:-7]
        #行政区内区域名称
        item['district_area'] = response.css('.deal-bread a::text').extract()[3][0:-7]
        #小区名称
        item['xiaoqu'] = re.search("resblockName:'(.*?)'",response.text,re.S).group(1)
        #小区id
        item['xiaoqu_id'] = re.search("resblockId:'(.*?)'",response.text,re.S).group(1)
        #小区经度 用正则表达式解析
        item['xiaoqu_long'] = re.search("resblockPosition:'(.*?),",response.text,re.S).group(1)
        #小区纬度 用正则表达式解析
        item['xiaoqu_lat'] = re.search("resblockPosition:'.*?,(.*?)'",response.text,re.S).group(1)
        #链家ID
        item['lianjia_id'] = re.search("houseCode:'(.*?)'",response.text,re.S).group(1)
        #成交名称
        item['title'] = response.css('.wrapper::text').extract_first()
        #成交日期
        item['deal_date'] = response.css('.wrapper span::text').re('(.*) (.*)')[0]
        #成交公司
        item['deal_com'] = response.css('.wrapper span::text').re('(.*) (.*)')[1]
        #成交总价
        item['total_price'] = response.css('.price .dealTotalPrice i::text').extract_first()
        #成交单价
        item['unit_price'] = response.css('.price b::text').extract_first()
        if response.css('.info.fr .msg span label::text').extract():
            #挂牌价格
            item['list_price'] = response.css('.info.fr .msg span label::text').extract()[0]
            #成交周期
            item['deal_cycle'] = response.css('.info.fr .msg span label::text').extract()[1]
            #调价次数
            item['price_adj_num'] = response.css('.info.fr .msg span label::text').extract()[2]
            #带看次数
            item['see_num'] = response.css('.info.fr .msg span label::text').extract()[3]
            #关注人数
            item['follow_num'] = response.css('.info.fr .msg span label::text').extract()[4]
            #浏览次数
            item['view_num'] = response.css('.info.fr .msg span label::text').extract()[5]
        else:
            #挂牌价格
            item['list_price'] = ''
            #成交周期
            item['deal_cycle'] = ''
            #调价次数
            item['price_adj_num'] = ''
            #带看次数
            item['see_num'] = ''
            #关注人数
            item['follow_num'] = ''
            #浏览次数
            item['view_num'] = ''
        if response.css('.introContent .base .content ul li::text').extract():
            #户型
            item['house_type'] = response.css('.introContent .base .content ul li::text').extract()[0].strip()
            #建筑面积
            item['build_area'] = response.css('.introContent .base .content ul li::text').extract()[2].strip()
            #套内面积
            item['dwelling_area'] = response.css('.introContent .base .content ul li::text').extract()[4].strip()
            #房屋朝向
            item['orientation'] = response.css('.introContent .base .content ul li::text').extract()[6].strip()
            #装修情况
            item['decoration'] = response.css('.introContent .base .content ul li::text').extract()[8].strip()
            #供暖方式
            item['heating'] = response.css('.introContent .base .content ul li::text').extract()[10].strip()
            #产权年限
            item['property_time'] = response.css('.introContent .base .content ul li::text').extract()[12].strip()
            #所在楼层
            item['floor'] = response.css('.introContent .base .content ul li::text').extract()[1].strip()
            #户型结构
            item['house_type_str'] = response.css('.introContent .base .content ul li::text').extract()[3].strip()
            #建筑类型
            item['build_type'] = response.css('.introContent .base .content ul li::text').extract()[5].strip()
            #建筑年代
            item['build_year'] = response.css('.introContent .base .content ul li::text').extract()[7].strip()
            #建筑结构
            item['build_archit'] = response.css('.introContent .base .content ul li::text').extract()[9].strip()
            #梯户比例
            item['elevator_rate'] = response.css('.introContent .base .content ul li::text').extract()[11].strip()
            #配备电梯
            item['elevator_'] = response.css('.introContent .base .content ul li::text').extract()[13].strip()
        else:
            #户型
            item['house_type'] = ''
            #建筑面积
            item['build_area'] = ''
            #套内面积
            item['dwelling_area'] = ''
            #房屋朝向
            item['orientation'] = ''
            #装修情况
            item['decoration'] = ''
            #供暖方式
            item['heating'] = ''
            #产权年限
            item['property_time'] = ''
            #所在楼层
            item['floor'] = ''
            #户型结构
            item['house_type_str'] = ''
            #建筑类型
            item['build_type'] = ''
            #建筑年代
            item['build_year'] = ''
            #建筑结构
            item['build_archit'] = ''
            #梯户比例
            item['elevator_rate'] = ''
            #配备电梯
            item['elevator_'] = ''
        if response.css('.introContent .transaction .content ul li::text').extract():
            #挂牌时间
            item['list_time'] = response.css('.introContent .transaction .content ul li::text').extract()[2].strip()
            #房屋年限
            item['house_year'] = response.css('.introContent .transaction .content ul li::text').extract()[4].strip()
            #交易权属
            item['deal_type'] = response.css('.introContent .transaction .content ul li::text').extract()[1].strip()
            #房屋用途
            item['house_usage'] = response.css('.introContent .transaction .content ul li::text').extract()[3].strip()
            #房屋权属
            item['house_owner'] = response.css('.introContent .transaction .content ul li::text').extract()[5].strip()
        else:
            #挂牌时间
            item['list_time'] = ''
            #房屋年限
            item['house_year'] = ''
            #交易权属
            item['deal_type'] = ''
            #房屋用途
            item['house_usage'] = ''
            #房屋权属
            item['house_owner'] = ''
        #历史成交纪录
        item['deal_histry'] = response.css('.chengjiao_record .record_list li p::text').extract()
        #房源标签
        item['house_tag'] = response.css('.newwrap.baseinform .tags.clear a::text').extract()
        #房源特色
        item['house_feature'] = response.css('.newwrap.baseinform .baseattribute.clear .content::text').extract()
        #图片链接
        item['img_list'] = response.css('.thumbnail ul li::attr(data-src)').extract()
        yield item


import pytest

@pytest.fixture(params=["watchdog", "fsnotify"])
def remote_fs_observer(request):
    from robocorp_ls_core.remote_fs_observer_impl import RemoteFSObserver

    backend = request.param
    remote_fsobserver = RemoteFSObserver(backend, None)
    try:
        port = remote_fsobserver.start_server()
        assert port
        yield remote_fsobserver
    finally:
        remote_fsobserver.dispose()

def test_remote_fs_observer(remote_fs_observer, tmpdir):
    from robocorp_ls_core import watchdog_wrapper
    from robocorp_ls_core.watchdog_wrapper import PathInfo
    from robocorp_ls_core.unittest_tools.fixtures import wait_for_test_condition
    from robocorp_ls_core.watchdog_wrapper import IFSObserver

    tmpdir.join("dir_not_rec").mkdir()
    tmpdir.join("dir_rec").mkdir()

    found = []

    def on_change(filepath, *args):
        found.append(filepath)
        assert args == ("foo", "bar")

    notifier = watchdog_wrapper.create_notifier(on_change, timeout=0.1)
    observer: IFSObserver = remote_fs_observer

    watch = observer.notify_on_any_change(
        [
            PathInfo(tmpdir.join("dir_not_rec"), False),
            PathInfo(tmpdir.join("dir_rec"), True),
        ],
        notifier.on_change,
        call_args=("foo", "bar"),
    )

    try:
        tmpdir.join("dir_not_rec").join("mya.txt").write("foo")
        tmpdir.join("dir_not_rec").join("mya.libspec").write("foo")

        tmpdir.join("dir_rec").join("myb.txt").write("foo")
        tmpdir.join("dir_rec").join("myb.libspec").write("foo")

        def collect_basenames():
            import os.path

            basenames = [os.path.basename(x) for x in found]
            return set(basenames)

        def check1():
            expected = {"myb.txt", "mya.libspec", "myb.libspec", "mya.txt"}
            return collect_basenames().issuperset(expected)

        wait_for_test_condition(
            check1, msg=lambda: f"Basenames found: {collect_basenames()}"
        )

    finally:
        watch.stop_tracking()
        notifier.dispose()
        observer.dispose()

def test_remote_fs_observer_conflicts(remote_fs_observer, tmpdir):
    from robocorp_ls_core import watchdog_wrapper
    from robocorp_ls_core.watchdog_wrapper import PathInfo
    from robocorp_ls_core.unittest_tools.fixtures import wait_for_test_condition
    from robocorp_ls_core.watchdog_wrapper import IFSObserver
    import os

    tmpdir.join("dir").mkdir()

    found_not_recursive = []
    found_recursive = []
    found_recursive2 = []

    def on_change_not_recursive(filepath, *args):
        found_not_recursive.append(os.path.basename(filepath))

    def on_change_recursive(filepath, *args):
        found_recursive.append(os.path.basename(filepath))

    def on_change_recursive2(filepath, *args):
        found_recursive2.append(os.path.basename(filepath))

    notifier_not_recursive = watchdog_wrapper.create_notifier(
        on_change_not_recursive, timeout=0.1
    )
    notifier_recursive = watchdog_wrapper.create_notifier(
        on_change_recursive, timeout=0.1
    )
    notifier_recursive2 = watchdog_wrapper.create_notifier(
        on_change_recursive2, timeout=0.1
    )

    observer: IFSObserver = remote_fs_observer

    watch_not_recursive = observer.notify_on_any_change(
        [
            PathInfo(tmpdir.join("dir"), False),
        ],
        notifier_not_recursive.on_change,
    )
    watch_recursive = observer.notify_on_any_change(
        [
            PathInfo(tmpdir.join("dir"), True),
        ],
        notifier_recursive.on_change,
    )
    watch_recursive2 = observer.notify_on_any_change(
        [
            PathInfo(tmpdir.join("dir"), True),
        ],
        notifier_recursive2.on_change,
    )

    # This should be almost a no-op.
    observer.notify_on_any_change(
        [
            PathInfo(tmpdir.join("dir"), True),
        ],
        lambda *args, **kwargs: None,
    ).stop_tracking()

    # Sleep a bit because things may take a bit of time to be setup in the
    # other process.
    import time

    time.sleep(2)
    try:
        tmpdir.join("dir").join("mya.txt").write("foo")
        tmpdir.join("dir").join("dir_inside").mkdir()
        tmpdir.join("dir").join("dir_inside").join("myb.txt").write("bar")

        def check_recursive():
            expected = {"mya.txt", "myb.txt"}
            return set(found_recursive).issuperset(expected)

        wait_for_test_condition(
            check_recursive,
            msg=lambda: f"Basenames found: {found_recursive}",
        )

        def check_recursive2():
            expected = {"mya.txt", "myb.txt"}
            return set(found_recursive2).issuperset(expected)

        wait_for_test_condition(
            check_recursive2,
            msg=lambda: f"Basenames found: {found_recursive2}",
        )

        def check_not_recursive():
            expected = {"mya.txt"}
            return (
                set(found_not_recursive).issuperset(expected)
                and "myb.txt" not in found_not_recursive
            )

        wait_for_test_condition(
            check_not_recursive,
            msg=lambda: f"Basenames found: {found_not_recursive}",
        )

    finally:
        watch_not_recursive.stop_tracking()
        watch_recursive.stop_tracking()
        watch_recursive2.stop_tracking()
        notifier_not_recursive.dispose()
        notifier_recursive.dispose()
        notifier_recursive2.dispose()
        observer.dispose()

def test_glob_matches_path():
    from robocorp_ls_core.load_ignored_dirs import glob_matches_path
    import sys

    # Linux
    for sep, altsep in (("\\", "/"), ("/", None)):

        def build(path):
            if sep == "/":
                return path
            else:
                return ("c:" + path).replace("/", "\\")

        assert glob_matches_path(build("/a"), r"*", sep, altsep)

        assert not glob_matches_path(
            build("/a/b/c/some.py"), "/a/**/c/so?.py", sep, altsep
        )

        assert glob_matches_path("/a/b/c", "/a/b/*")
        assert not glob_matches_path("/a/b", "/*")
        assert glob_matches_path("/a/b", "/*/b")
        assert glob_matches_path("/a/b", "**/*")
        assert not glob_matches_path("/a/b", "**/a")

        assert glob_matches_path(build("/a/b/c/d"), "**/d", sep, altsep)
        assert not glob_matches_path(build("/a/b/c/d"), "**/c", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d"), "**/c/d", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d"), "**/b/c/d", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d"), "/*/b/*/d", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d"), "**/c/*", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d"), "/a/**/c/*", sep, altsep)

        # I.e. directories are expected to end with '/', so, it'll match
        # something as **/directory/**
        assert glob_matches_path(build("/a/b/c/"), "**/c/**", sep, altsep)
        assert glob_matches_path(build("/a/b/c/"), "**/c/", sep, altsep)
        # But not something as **/directory (that'd be a file match).
        assert not glob_matches_path(build("/a/b/c/"), "**/c", sep, altsep)
        assert not glob_matches_path(build("/a/b/c"), "**/c/", sep, altsep)

        assert glob_matches_path(build("/a/b/c/d.py"), "/a/**/c/*", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d.py"), "/a/**/c/*.py", sep, altsep)
        assert glob_matches_path(build("/a/b/c/some.py"), "/a/**/c/so*.py", sep, altsep)
        assert glob_matches_path(
            build("/a/b/c/some.py"), "/a/**/c/som?.py", sep, altsep
        )
        assert glob_matches_path(build("/a/b/c/d"), "/**", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d"), "/**/d", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d.py"), "/**/*.py", sep, altsep)
        assert glob_matches_path(build("/a/b/c/d.py"), "**/c/*.py", sep, altsep)

        if sys.platform == "win32":
            assert glob_matches_path(build("/a/b/c/d.py"), "**/C/*.py", sep, altsep)
            assert glob_matches_path(build("/a/b/C/d.py"), "**/c/*.py", sep, altsep)

        # Expected not to match.
        assert not glob_matches_path(build("/a/b/c/d"), "/**/d.py", sep, altsep)
        assert not glob_matches_path(build("/a/b/c/d.pyx"), "/a/**/c/*.py", sep, altsep)
        assert not glob_matches_path(build("/a/b/c/d"), "/*/d", sep, altsep)

        if sep == "/":
            assert not glob_matches_path(
                build("/a/b/c/d"), r"**\d", sep, altsep
            )  # Match with \ doesn't work on linux...
            assert not glob_matches_path(
                build("/a/b/c/d"), r"c:\**\d", sep, altsep
            )  # Match with drive doesn't work on linux...
        else:
            # Works in Windows.
            assert glob_matches_path(build("/a/b/c/d"), r"**\d", sep, altsep)
            assert glob_matches_path(build("/a/b/c/d"), r"c:\**\d", sep, altsep)

        # Corner cases
        assert not glob_matches_path(build("/"), r"", sep, altsep)
        assert glob_matches_path(build(""), r"", sep, altsep)
        assert not glob_matches_path(build(""), r"**", sep, altsep)
        assert glob_matches_path(build("/"), r"**", sep, altsep)
        assert glob_matches_path(build("/"), r"*", sep, altsep)

def test_create_accept_directory_callable():
    from robocorp_ls_core.load_ignored_dirs import create_accept_directory_callable

    accept_directory = create_accept_directory_callable("")
    assert not accept_directory("/my/node_modules")
    assert accept_directory("/my")

    accept_directory = create_accept_directory_callable('["**/bazel_out/**"]')
    assert accept_directory("/my/foobar")
    assert not accept_directory(
        "/Users/ichamberlain/Documents/workspace/bazel_out/execroot/my_org/bazel_out/execroot/my_org/bazel_out/execroot/my_org"
    )


from collections import deque

from src.config.nodepair import check_city_id
from src.graph.abstractGraph import AbstractGraph

class Bfs(object):

    def __init__(self, graph):
        if not isinstance(graph, AbstractGraph):
            raise TypeError("Value of a \"graph\" parameter has to be AbstractGraph")
        self._graph = graph

    def find_path(self, starting_node, last_node):
        solution = self._solve(starting_node, last_node)

        if not solution:
            return []

        return self._reconstruct_path(starting_node, last_node, solution)

    def find_path_cities(self, starting_city, destination_city):
        c_from = check_city_id(starting_city)
        c_to = check_city_id(destination_city)
        return self.find_path(c_from, c_to)

    def _solve(self, starting_node, last_node):
        node_queue = deque()
        node_queue.append(starting_node)

        visited = [False if i != starting_node else True for i in self._graph.get_node_list()]
        soution = [None for _ in self._graph.get_node_list()]

        while len(node_queue):
            current_node = node_queue.popleft()
            neighbours = self._graph.get_neighbour_nodes(current_node)

            for next_node in neighbours:
                if not visited[next_node]:
                    node_queue.append(next_node)
                    visited[next_node] = True
                    soution[next_node] = current_node

        if len(visited) <= last_node or not visited[last_node]:
            return []

        return soution

    @staticmethod
    def _reconstruct_path(starting_node, last_node, solution):
        path = []
        actual = last_node

        while actual is not None:
            path.append(actual)
            actual = solution[actual]

        path.reverse()

        if path[0] == starting_node:
            return path
        return []


# -*- coding: utf-8 -*-
from odoo import fields, models,api
from openerp.exceptions import except_orm, Warning, RedirectWarning

class order(models.Model):
    _name = 'g.order'
    product_ids = fields.One2many('product.product', 'order_id')
    code = fields.Char()
    customer_id = fields.Many2one('res.users','Khách hàng')
    state = fields.Selection(selection=[
        ('create', 'Khởi tạo'),
        ('pending', 'Chờ lấy hàng'),
        ('cancel', 'Hủy'),
        ('delivering', 'Đang giao hàng'),
        ('paid', 'Đã thu tiền'),
        ('completed', 'Hoàn thành')
    ], default='create',string='Trạng thái')

    def pending(self):
        if self.state == 'create':
            self.state = 'pending'
        else :
            raise Warning("loi qui trinh")
# da thu tien va hoan thanh,thi khong the huy
    def cancel(self):
        if self.state in ['paid','completed'] :
            raise Warning('khong the xoa')
        return models.Model.unlink(self)
# neu khong co hang,thi khong cho giao hang
    def delivering(self):
        k = 0
        for x in self :
            if x.product_ids :
                k = 1
        if self.state == 'pending' and k == 1:
            self.state = 'delivering'
        else :
            raise Warning("loi qui trinh")

# giao hang xong thi moi thu tien
    def paid(self):
        if self.state == 'delivering':
            self.state = 'paid'
        else :
            raise Warning("loi qui trinh")

# thu tien xong thi moi duoc hoan thanh
    def completed(self):
        if self.state == 'paid':
            self.state = 'completed'
        else :
            raise Warning("loi qui trinh")


import pyrealsense2.pyrealsense2 as rs
import bbot.box as Box
import numpy as np
import math

class Camera:
    def __init__(self):
        self.color_frame = False
        self.aligned_depth_frame = False

    def setup(self) -> None:
        # Create a pipeline
        self.pipeline = rs.pipeline()

        # Create a config and configure the pipeline to stream
        config = rs.config()
        config.enable_stream(rs.stream.depth, 1280, 720, rs.format.z16, 30)
        config.enable_stream(rs.stream.color, 1920, 1080, rs.format.bgr8, 30)

        # Start streaming
        self.pipeline.start(config)

	    # Allow some frames for the auto-exposure controller to stablise
        for i in range(30):
            self.pipeline.wait_for_frames()

        # Create an align object
        # rs.align allows us to perform alignment of depth frames to others frames
        # The "align_to" is the stream type to which we plan to align depth frames.
        align_to = rs.stream.color
        self.align = rs.align(align_to)

    def take_photo(self) -> None:
        # Get frames of color and depth
        frames = self.pipeline.wait_for_frames()

        # Align the depth frame to color frame
        aligned_frames = self.align.process(frames)

        # Get aligned frames
        self.aligned_depth_frame = aligned_frames.get_depth_frame()
        color_frame = aligned_frames.get_color_frame()

        # Validate that both frames are valid
        if not self.aligned_depth_frame or not color_frame:
            return

        self.color_intrin = color_frame.profile.as_video_stream_profile().intrinsics
        self.color_image = np.asanyarray(color_frame.get_data())

    def get_color_frame(self) -> np.ndarray:
        return self.color_image

    def get_depth_in_mm(self, box: Box) -> int:
        # convert m to mm
        x, y = box.get_center()

        return int(self.aligned_depth_frame.get_distance(x,y) * 1000)

    def get_diameter_in_mm(self, box: Box) -> int:
        # Get xy for max size
        x_1, y_1, x_2, y_2 = box.get_max_size()

        # Calculate distance at center
        x_center, y_center = box.get_center()
        dist = self.aligned_depth_frame.get_distance(x_center, y_center)

        # Convert 2D to 3D point
        # Take into account: depth and intrinsics of the hardware
        point_1 = rs.rs2_deproject_pixel_to_point(self.color_intrin, [x_1, y_1], dist)
        point_2 = rs.rs2_deproject_pixel_to_point(self.color_intrin, [x_2, y_2], dist)

        # Calculate euclidean distance between the two points
        diameter = math.sqrt(math.pow(point_1[0] - point_2[0], 2) + math.pow(point_1[1] - point_2[1],2) + math.pow(point_1[2] - point_2[2], 2))

        # convert m to mm
        return int(diameter * 1000)


from chipgr8 import Query, Observer, NamedList
from numpy   import clip

K_NONE = 0x0000
K_0    = 0x0001
K_1    = 0x0002
K_2    = 0x0004
K_3    = 0x0008
K_4    = 0x0010
K_5    = 0x0020
K_6    = 0x0040
K_7    = 0x0080
K_8    = 0x0100
K_9    = 0x0200
K_A    = 0x0400
K_B    = 0x0800
K_C    = 0x1000
K_D    = 0x2000
K_E    = 0x4000
K_F    = 0x8000

class Game(object):
    '''
    A generic class for game specific data. Game specific instances of this
    class exist for each included ROM (cave, pong, worm).
    '''

    actions = None
    '''
    A list of valid actions (key values) for the given game.
    '''

    ROM = None
    '''
    The name of the ROM file for this game.
    '''

    def __init__(self, ROM, observer, actions):
        '''
        Creates a new standard game object.

        @params ROM         str         the game ROM path
                observer    Observer    the game observer
                actions     ndarray     valid game actions
        '''
        self.ROM        = ROM
        self.actions    = actions
        self.__observer = observer

    def observe(self, vm):
        '''
        Returns a set of game specific observations given a vm.
        '''
        return self.__observer.observe(vm)

Puzzle15 = Game(
    ROM      = '15 Puzzle',
    observer = Observer(),
    actions  = NamedList(
        [
            'none',
            'shift0', 'shift1', 'shift2', 'shift3',
            'shift4', 'shift5', 'shift6', 'shift7',
            'shift8', 'shift9', 'shiftA', 'shiftB',
            'shiftC', 'shiftD', 'shiftE', 'shiftF',
        ], [
            K_NONE,
            K_1, K_2, K_3, K_C,
            K_3, K_5, K_6, K_D,
            K_7, K_8, K_9, K_E,
            K_A, K_0, K_B, K_F,
        ],
    )
)

Airplane = Game(
    ROM      = 'Airplane',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'drop'],
        [ K_NONE, K_8  ],
    )
)

AnimalRace = Game(
    ROM      = 'Animal Race',
    observer = Observer(),
    actions  = NamedList(
        [
            'none',
            'betA',  'betB',  'betC', 'betD', 'betE',
            'bet1$', 'bet2$', 'bet3$',
            'bet4$', 'bet5$', 'bet6$',
            'bet7$', 'bet8$', 'bet9$',
        ], [
            K_NONE,
            K_A, K_B, K_C, K_D, K_E,
            K_1, K_2, K_3,
            K_4, K_5, K_6,
            K_7, K_8, K_9,
        ],
    )
)

AstroDodge = Game(
    ROM      = 'Astro Dodge',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'start', 'left', 'right'],
        [ K_NONE, K_5,     K_4,    K_6   ],
    )
)

Blinky = Game(
    ROM      = 'Blinky',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'left', 'right', 'up', 'done', 'blink'],
        [ K_NONE, K_7,    K_8,     K_3,  K_6,    K_F   ],
    )
)

Breakout = Game(
    ROM      = 'Breakout',
    observer = Observer()
        .addQuery('ballX', Query(addr=374))
        .addQuery('ballY', Query(addr=375))
        .addQuery('myX', Query(addr=380))
        .addQuery('score', Query(addr=373))
        .addQuery('done', lambda o, vm : vm.VM.PC == 0x2DE),
    actions  = NamedList(
        ['none', 'left', 'right'],
        [ K_NONE, K_4,    K_6   ],
    )
)

Brix = Game(
    ROM      = 'Brix',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'left', 'right'],
        [ K_NONE, K_4,    K_6   ],
    )
)

Cave = Game(
    ROM      = 'Cave',
    observer = Observer()
        .addQuery('x',          Query(addr=379))
        .addQuery('y',          Query(addr=380))
        .addQuery('upClear',    lambda o, vm : not vm.ctx()[clip(o.x, 0, 63), clip(o.y - 1, 0, 31)])
        .addQuery('downClear',  lambda o, vm : not vm.ctx()[clip(o.x, 0, 63), clip(o.y + 1, 0, 31)])
        .addQuery('leftClear',  lambda o, vm : not vm.ctx()[clip(o.x - 1, 0, 63), clip(o.y, 0, 31)])
        .addQuery('rightClear', lambda o, vm : not vm.ctx()[clip(o.x + 1, 0, 63), clip(o.y, 0, 31)])
        .addQuery('done',       lambda o, vm : vm.VM.PC == 0x570),
    actions  = NamedList(
        ['none', 'left', 'right', 'up', 'down', 'start'],
        [ K_NONE, K_4,    K_6,     K_2,  K_8,    K_F],
    )
)

Filter = Game(
    ROM      = 'Filter',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'left', 'right'],
        [ K_NONE, K_4,    K_6   ],
    )
)

Hidden = Game(
    ROM      = 'Hidden',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'start', 'left', 'right', 'up', 'down', 'select'],
        [ K_NONE, K_F,     K_4,    K_6,     K_2,  K_8,    K_5    ],
    )
)

LunarLander = Game(
    ROM      = 'Lunar Lander',
    observer = Observer(),
    actions  = NamedList(
        [
            'none',
            'option1', 'option2', 'option3',
            'thrust', 'left', 'right',
        ], [
            K_NONE,
            K_1, K_2, K_3,
            K_2, K_4, K_6,
        ],
    )
)

Pong1Player = Game(
    ROM      = 'Pong (1 player)',
    observer = Observer()
        .addQuery('opponent',    Query(addr=756))
        .addQuery('p1Score',     Query(addr=755))
        .addQuery('p2Score',     Query(addr=756))
        .addQuery('myY',         Query(addr=379))
        .addQuery('ballX',       Query(addr=374))
        .addQuery('ballY',       Query(addr=375))
        .addQuery('score',       lambda o, vm: o.p1Score - o.p2Score)
        .addQuery('bestOf3Done', lambda o, vm: o.p1Score >= 3 or o.p2Score >= 3)
        .addQuery('bestOf5Done', lambda o, vm: o.p1Score >= 5 or o.p2Score >= 5)
        .addQuery('bestOf5Done', lambda o, vm: o.p1Score >= 7 or o.p2Score >= 7)
        .addQuery('bestOf5Done', lambda o, vm: o.p1Score >= 9 or o.p2Score >= 9)
        .addQuery('done',        lambda o, vm: o.p1Score >= 9 or o.p2Score >= 9),
    actions  = NamedList(
        ['none',   'up', 'down'],
        [ K_NONE,   K_1,  K_4  ],
    ),
)

Pong2Player = Game(
    ROM      = 'Pong (2 player)',
    observer = Observer()
        .addQuery('opponent', Query(addr=756))
        .addQuery('score',    Query(addr=755))
        .addQuery('done',     lambda o, vm: vm.VM.RAM[755] >= 3 or vm.VM.RAM[756] >= 3),
    actions  = NamedList(
        ['none',   'p1Up', 'p1Down', 'p2Up', 'p2Down'],
        [ K_NONE,   K_1,    K_4,      K_C,    K_D    ],
    ),
)

SpaceInvaders = Game(
    ROM      = 'Space Invaders',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'start', 'shoot', 'left', 'right'],
        [ K_NONE, K_5,     K_5,     K_4,    K_6   ],
    )
)

Squash = Game(
    ROM      = 'Squash',
    observer = Observer()
        .addQuery('lives',   Query(addr=370))
        .addQuery('ballX',   Query(addr=375))
        .addQuery('ballY',   Query(addr=376))
        .addQuery('paddleY', Query(addr=372))
        .addQuery('score',   lambda o, vm: vm.VM.clock)
        .addQuery('done',    lambda o, vm: o.lives == 0 and vm.VM.clock > 12),
    actions  = NamedList(
        ['none', 'up', 'down'],
        [ K_NONE, K_1,  K_4  ],
    ),
)

Tetris = Game(
    ROM      = 'Tetris',
    observer = Observer(),
    actions  = NamedList(
        ['none', 'rotate', 'left', 'right', 'drop'],
        [ K_NONE, K_4,      K_5,    K_6,     K_8  ],
    )
)

Tron = Game(
    ROM      = 'Tron',
    observer = Observer(),
    actions  = NamedList(
        [],
        [],
    )
)

Worm = Game(
    ROM      = 'worm',
    observer = Observer()
        .addQuery('score',  Query(addr=370))
        .addQuery('length', Query(addr=370))
        .addQuery('headX',  Query(addr=378))
        .addQuery('headY',  Query(addr=379))
        .addQuery('foodX',  Query(addr=380))
        .addQuery('foodY',  Query(addr=381))
        .addQuery('done',   lambda o, vm : vm.VM.PC == 0x36E),
    actions  = NamedList(
        ['none', 'left', 'right', 'up', 'down'],
        [ K_NONE, K_4,    K_6,     K_2,  K_8  ],
    ),
)


#While Practice
num = int(input ("Enter a number: "))

#checking number is added corrected
print ("You have entered: ", num)

#count down using while
while num > 0:
    print (num)
    num = num - 1

#We can also use num-=1


# -*- coding: utf-8 -*-

from sys import platform
import os,stat
import subprocess

# little info:
# cwd == current work directory

def code_dir():                                                 # return directory with this script
    return os.path.dirname(os.path.realpath(__file__))

def CodeInfo (dir = os.path.dirname(os.path.realpath(__file__)) ):                              # info about files in code directory
    code_direcroty = os.path.dirname(os.path.realpath(__file__))
    cwd = os.path.abspath(os.curdir)
    files_in_dir = os.listdir(dir)

    print("- Code directory:", code_direcroty)
    print("- Current work directory:", cwd)
    print("- Files in", dir, ":", files_in_dir)

def create_py_file_examle(pyfile_name = ".demo.py"):            # create py file for demonstrate how we call it
    pyfile = open(pyfile_name, "w")
    pyfile.write("print(\"You can run any files!\")")
    pyfile.close()

def create_scr_mac(script_file = ".script.sh", pyfile_name = ".demo.py"):       # creation script for macOS .sh
    f = open(script_file,"w")
    script = "pwd>>$1\nwhoami>>$1\npython3 " + pyfile_name

    f.write(script)
    f.close()

def work_linux():
	print("\nScript working in Linux.")

def work_mac(script_file = ".script.sh", file_to_write = ".result.txt"):
    print("\nScript working in macOS.")
    try:
        create_py_file_examle()
        create_scr_mac(script_file)
        os.chmod(script_file, 0o777)
        subprocess.run("./"+script_file+" "+file_to_write, text = True, shell=True)
        # os.chflags(dname+"/"+script_file, 0)                                          # read in Google
        # os.chflags(script_file, stat.UF_IMMUTABLE)                                    # read in Google
    except:
        print("\n!!! Some errors with runnig script:", script_file)

def work_win():
	print("\nScript working in Windows.")

#------------------names of files-------------------------
file_to_write = ".result.txt"
script_file = ".script.sh"
pyfile_name = ".demo.py"
#---------------------------------------------------------

if __name__ == "__main__":
    print("Work with console.")

    # ---------------------change cwd---------------------
    decision = input("For creation new directory for demonstration code print 'Yes', else print nothing: ")

    dname = code_dir()
    if decision in ['Yes','yes','y']:
        newCWD = ".HereIsScriptsAndResults"                     # new cwd
        newCWD = dname + "/" + newCWD
        try:
            os.mkdir(newCWD)                                    # create new directory
        except:
            pass
        os.chdir(newCWD)                                        # change cwd
    else:
        newCWD = dname
        os.chdir(newCWD)                                        # change cwd

    CodeInfo()

    # ---------------------define OS----------------------
    if platform == "linux" or platform == "linux2":             # OS is Linux
        work_linux()            # создаю скрипт для сканирования инфы
    elif platform == "darwin":                                  # OS is MACOS
        work_mac()
        # os.remove(dname+"/"+script_file)
    elif platform == "win32":                                   # OS is Windows
        work_win()


import json
import logging
import threading
import time
import psutil
import shutil
import os
import requests
from typing import Optional, Any
from paho.mqtt.client import Client
from multiprocessing.synchronize import Event

from frigate.config import FrigateConfig
from frigate.const import RECORD_DIR, CLIPS_DIR, CACHE_DIR
from frigate.types import StatsTrackingTypes, CameraMetricsTypes
from frigate.version import VERSION
from frigate.edgetpu import EdgeTPUProcess

logger = logging.getLogger(__name__)

def get_latest_version() -> str:
    try:
        request = requests.get(
            "https://api.github.com/repos/blakeblackshear/frigate/releases/latest",
            timeout=10,
        )
    except:
        return "unknown"

    response = request.json()

    if request.ok and response and "tag_name" in response:
        return str(response.get("tag_name").replace("v", ""))
    else:
        return "unknown"

def stats_init(
    camera_metrics: dict[str, CameraMetricsTypes], detectors: dict[str, EdgeTPUProcess]
) -> StatsTrackingTypes:
    stats_tracking: StatsTrackingTypes = {
        "camera_metrics": camera_metrics,
        "detectors": detectors,
        "started": int(time.time()),
        "latest_frigate_version": get_latest_version(),
    }
    return stats_tracking

def get_fs_type(path: str) -> str:
    bestMatch = ""
    fsType = ""
    for part in psutil.disk_partitions(all=True):
        if path.startswith(part.mountpoint) and len(bestMatch) < len(part.mountpoint):
            fsType = part.fstype
            bestMatch = part.mountpoint
    return fsType

def read_temperature(path: str) -> Optional[float]:
    if os.path.isfile(path):
        with open(path) as f:
            line = f.readline().strip()
            return int(line) / 1000
    return None

def get_temperatures() -> dict[str, float]:
    temps = {}

    # Get temperatures for all attached Corals
    base = "/sys/class/apex/"
    if os.path.isdir(base):
        for apex in os.listdir(base):
            temp = read_temperature(os.path.join(base, apex, "temp"))
            if temp is not None:
                temps[apex] = temp

    return temps

def stats_snapshot(stats_tracking: StatsTrackingTypes) -> dict[str, Any]:
    camera_metrics = stats_tracking["camera_metrics"]
    stats: dict[str, Any] = {}

    total_detection_fps = 0

    for name, camera_stats in camera_metrics.items():
        total_detection_fps += camera_stats["detection_fps"].value
        pid = camera_stats["process"].pid if camera_stats["process"] else None
        cpid = (
            camera_stats["capture_process"].pid
            if camera_stats["capture_process"]
            else None
        )
        stats[name] = {
            "camera_fps": round(camera_stats["camera_fps"].value, 2),
            "process_fps": round(camera_stats["process_fps"].value, 2),
            "skipped_fps": round(camera_stats["skipped_fps"].value, 2),
            "detection_fps": round(camera_stats["detection_fps"].value, 2),
            "pid": pid,
            "capture_pid": cpid,
        }

    stats["detectors"] = {}
    for name, detector in stats_tracking["detectors"].items():
        pid = detector.detect_process.pid if detector.detect_process else None
        stats["detectors"][name] = {
            "inference_speed": round(detector.avg_inference_speed.value * 1000, 2),
            "detection_start": detector.detection_start.value,
            "pid": pid,
        }
    stats["detection_fps"] = round(total_detection_fps, 2)

    stats["service"] = {
        "uptime": (int(time.time()) - stats_tracking["started"]),
        "version": VERSION,
        "latest_version": stats_tracking["latest_frigate_version"],
        "storage": {},
        "temperatures": get_temperatures(),
    }

    for path in [RECORD_DIR, CLIPS_DIR, CACHE_DIR, "/dev/shm"]:
        storage_stats = shutil.disk_usage(path)
        stats["service"]["storage"][path] = {
            "total": round(storage_stats.total / 1000000, 1),
            "used": round(storage_stats.used / 1000000, 1),
            "free": round(storage_stats.free / 1000000, 1),
            "mount_type": get_fs_type(path),
        }

    return stats

class StatsEmitter(threading.Thread):
    def __init__(
        self,
        config: FrigateConfig,
        stats_tracking: StatsTrackingTypes,
        mqtt_client: Client,
        topic_prefix: str,
        stop_event: Event,
    ):
        threading.Thread.__init__(self)
        self.name = "frigate_stats_emitter"
        self.config = config
        self.stats_tracking = stats_tracking
        self.mqtt_client = mqtt_client
        self.topic_prefix = topic_prefix
        self.stop_event = stop_event

    def run(self) -> None:
        time.sleep(10)
        while not self.stop_event.wait(self.config.mqtt.stats_interval):
            stats = stats_snapshot(self.stats_tracking)
            self.mqtt_client.publish(
                f"{self.topic_prefix}/stats", json.dumps(stats), retain=False
            )
        logger.info(f"Exiting watchdog...")


from functools import reduce
import datetime
from operator import add
import pandas as pd
import numpy as np
from datetime import datetime
'''for implementing simple logisticregression'''
import sklearn
from sklearn.linear_model import LogisticRegressionCV
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
from sklearn.metrics import roc_curve,roc_auc_score,auc
from sklearn.model_selection import train_test_split
from sklearn.metrics import precision_recall_curve
from sklearn.preprocessing import MinMaxScaler
'''for saving models'''
from joblib import load
from simple_etl import *
import sklearn.decomposition as skdc
import pickle as pk

docker = 1
EVAL_PATH = '../synthetic_data/evaluation/' # should be "/data/" for docker.
MODEL_PATH = '../model/' # should be "/model/" for docker.
OUTPUT_PATH = '../output/'

if docker == 1:
    EVAL_PATH = '/data/'
    MODEL_PATH = '/model/'
    OUTPUT_PATH = '/output/'

def add_COVID_measurement_date():
    measurement = pd.read_csv(EVAL_PATH + "measurement.csv",usecols =['person_id','measurement_date','measurement_concept_id','value_as_concept_id'])
    measurement = measurement.loc[measurement['measurement_concept_id']==706163]
    measurement = measurement.loc[(measurement['value_as_concept_id']==45877985)|(measurement['value_as_concept_id']==45884084)]
    measurement = measurement.sort_values(['measurement_date'],ascending=False).groupby('person_id').head(1)
    covid_measurement = measurement[['person_id','measurement_date']]
    return covid_measurement

def add_demographic_data(covid_measurement):
    '''add demographic data including age, gender and race'''
    person = pd.read_csv(EVAL_PATH  + 'person.csv',usecols = ['person_id','gender_concept_id','year_of_birth','race_concept_id'])
    demo = pd.merge(covid_measurement,person,on=['person_id'], how='inner')
    demo['measurement_date'] = pd.to_datetime(demo['measurement_date'], format='%Y-%m-%d')
    demo['year_of_birth'] = pd.to_datetime(demo['year_of_birth'], format='%Y')
    demo['age'] = demo['measurement_date'] - demo['year_of_birth']
    demo['age'] = demo['age'].apply(lambda x: x.days/365.25)
    print("patients' ages are calculated", flush = True)
    person["count"] = 1
    gender = person.pivot(index = "person_id", columns="gender_concept_id", values="count")
    gender.reset_index(inplace = True)
    gender.fillna(0,inplace = True)
    race = person.pivot(index ="person_id", columns="race_concept_id", values="count")
    race.reset_index(inplace = True)
    race.fillna(0,inplace = True)
    race = race[['person_id', 8516, 8515, 8527, 8552]]
    gender = gender[['person_id',8532]]
    print("patients gender and race information are added", flush = True)
    scaler = MinMaxScaler(feature_range = (0, 1), copy = True)
    scaled_column = scaler.fit_transform(demo[['age']])
    demo = pd.concat([demo, pd.DataFrame(scaled_column,columns = ['scaled_age'])],axis=1)
    predictors = demo[['person_id','scaled_age']]
    predictors = predictors.merge(gender, on = ['person_id'], how = 'left')
    predictors = predictors.merge(race, on = ['person_id'], how = 'left')
    predictors.fillna(0,inplace = True)
    return predictors

def prediction(predictors):
    clf = load(MODEL_PATH + 'baseline.joblib')
    X = predictors.drop(['person_id'], axis = 1)
    # PCA transform
    pca_reload = pk.load(open(MODEL_PATH + "pca.pkl",'rb'))
    X = pca_reload.transform(X)

    Y_pred = clf.predict_proba(X)[:,1]
    output = pd.DataFrame(Y_pred,columns = ['score'])
    person_id = predictors.person_id
    person = pd.read_csv(EVAL_PATH + 'person.csv',usecols =['person_id'])
    output_prob = pd.concat([person_id,output],axis = 1)
    output_prob.columns = ["person_id", "score"]
    output_prob = person.merge(output_prob, on = ['person_id'], how = 'left')
    output_prob = output_prob.fillna(0)
    output_prob.to_csv(OUTPUT_PATH+'predictions.csv', index = False)
    print("Inferring stage finished", flush = True)

if __name__ == '__main__':
    #covid_measurement = add_COVID_measurement_date()
    #predictors = add_demographic_data(covid_measurement)
    predictors = get_features_from_list(True)
    idSet = get_id_from_train()
    predictors = add_additional_concepts(predictors, idSet)
    prediction(predictors)


from airflow.hooks.postgres_hook import PostgresHook
from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults

class DataQualityOperator(BaseOperator):

    ui_color = '#89DA59'

    @apply_defaults
    def __init__(self,
                redshift_conn_id="",
                dq_checks="",
                *args, **kwargs):

        super(DataQualityOperator, self).__init__(*args, **kwargs)
        self.redshift_conn_id = redshift_conn_id
        self.dq_checks = dq_checks

    def execute(self, context):
        redshift = PostgresHook(postgres_conn_id=self.redshift_conn_id)

        for sql_check in self.dq_checks:
            check = sql_check['check_sql']
            expected_result = sql_check['expected_result']
            results = redshift.get_records(sql_check)[0][0]
            self.log.info(f'Results: {results}')

            if results != expected_result:
                self.log.info(f'Expected result was: {self.expected_result}. We got: {results}')
                raise ValueError("Data quality check failed")

            else:
                self.log.info("Data quality check was successful! No null values")