import sys

#두개 붙어 있는 경우
def check_block(array, p, q):
    if array[p][q] == '#':
        return False
    return True

def move_o(array, p, q, c):
    if array[p][q] == 'o':

        #밀기
        if (c == 'a') :
            if (array[p][q-1] == 'O'):
                array[p][q-1] = '0'
            else:
                if check_block(array, p, q-1) & (array[p][q-1] != 'o') & (array[p][q-1] != '0')  :
                    array[p][q-1] = 'o'
                else:
                    q += 1
                    return p, q
        elif (c == 'd') :
            if (array[p][q+1] == 'O'):
                array[p][q+1] = '0'
            else:
                if check_block(array, p, q + 1) & (array[p][q+1] != 'o') & (array[p][q+1] != '0')  :
                    array[p][q + 1] = 'o'
                else:
                    q -= 1
                    return p, q
        elif (c == 's'):
            if (array[p+1][q] == 'O'):
                array[p+1][q] = '0'
            else:
                if check_block(array, p+1, q) & (array[p+1][q] != 'o') & (array[p+1][q] != '0')  :
                    array[p+1][q] = 'o'
                else:
                    p -= 1
                    return p, q
        elif (c == 'w'):
            if (array[p-1][q] == 'O'):
                array[p-1][q] = '0'
            else:
                if check_block(array, p-1, q) & (array[p-1][q] != 'o') & (array[p-1][q] != '0')  :
                    array[p - 1][q] = 'o'
                else:
                    p += 1
                    return p, q
        array[p][q] = 'P'
        return p, q
    else:
        return p, q

def print_map(array, p, q, O_trace):
    array[p][q] = 'P'
    for a in O_trace:     ## P 없으면 ,
        if array[a[0]][a[1]] == ' ':
            array[a[0]][a[1]] = 'O'
    for i in array:
        print("".join(i))

def check_all_0(array):
    for i in range(len(array)):
        for j in range(len(array[i])):
            if array[i][j] == 'o':
                return True
    return False

def divide_0_to_o(array, p, q, c):

    if (c =='a') & (array[p][q] == '0'):
        if check_block(array, p, q-1):
            array[p][q-1] = 'o'
            array[p][q] = 'O'
        else:
            q += 1
            return p, q
    elif (c == 'd') & (array[p][q] == '0'):
        if check_block(array, p, q + 1):
            array[p][q+1] = 'o'
            array[p][q] = 'O'
        else:
            q -= 1
            return p, q
    elif (c == 'w') & (array[p][q] == '0'):
        if check_block(array, p-1, q):
            array[p-1][q] = 'o'
            array[p][q] = 'O'
        else:
            p += 1
            return p, q
    elif (c == 's') & (array[p][q] == '0'):
        if check_block(array, p + 1, q):
            array[p+1][q] = 'o'
            array[p][q] = 'O'
        else:
            p -= 1
            return p, q
    return p, q

def main(stage, map):

    print('\n' +stage + '\n')
    for i_map in map:
        print(i_map)

    # 2차원 배열로 변환 저장
    sokoban_array = [list(a) for a in map]
    # player 위치
    p = 0
    q = 0
    O_trace = []

    for i in range(len(sokoban_array)):
        for j in range(len(sokoban_array[i])):
            if sokoban_array[i][j] == "P":
                p = i
                q = j
            if sokoban_array[i][j] == "O":
                a = i
                b = j
                O_trace.append([a, b])
            if sokoban_array[i][j] == "0":
                a = i
                b = j
                O_trace.append([a, b])

    turn = 0
    while check_all_0(sokoban_array):
        print("\nSOKOBAN> ")
        cmd = str(sys.stdin.readline())
        for c in cmd[:-1]:
            if c == 'q':
                print("Bye~")
                return
            if c not in ('w', 'a', 's', 'd'):
                print_map(sokoban_array, p, q, O_trace)
                print(c.upper(), ': (경고!) 해당 명령을 수행할 수 없습니다')
            elif c == 'w':
                sokoban_array[p][q] = ' '
                if check_block(sokoban_array, p-1, q):
                    p -= 1
                    p, q = divide_0_to_o(sokoban_array, p, q, c)
                    p, q = move_o(sokoban_array, p, q, c)
                    print_map(sokoban_array, p, q, O_trace)
                turn += 1
            elif c == 'a':
                sokoban_array[p][q] = ' '
                if check_block(sokoban_array, p, q-1):
                    q -= 1
                    p, q = divide_0_to_o(sokoban_array, p, q, c)
                    p, q = move_o(sokoban_array, p, q, c)
                    print_map(sokoban_array, p, q, O_trace)

                    turn += 1
            elif c == 's':
                sokoban_array[p][q] = ' '
                if check_block(sokoban_array, p+1, q):
                    p += 1
                    p, q = divide_0_to_o(sokoban_array, p, q, c)
                    p, q = move_o(sokoban_array, p, q, c)
                    print_map(sokoban_array, p, q, O_trace)
                turn += 1
            else:  # c == 'd':
                sokoban_array[p][q] = ' '
                if check_block(sokoban_array, p, q+1):
                    q += 1
                    p, q = divide_0_to_o(sokoban_array, p, q, c)
                    p, q = move_o(sokoban_array, p, q, c)
                    print_map(sokoban_array, p, q, O_trace)
                turn += 1
    print('\n' + stage + " Clear")
    print(f'턴수: {turn}')

if __name__ == "__main__":
    print("Sokoban Game Start---")
    map = []
    with open('map.txt', 'r') as f:
        for line in f.readlines():
            map.append(line.strip())

    start = 0
    for i in range(len(map)):
        if ("====" in map[i]):
            main(map[start], map[start + 1:i])
            start = i + 1
        if i == len(map) - 1:
            main(map[start], map[start + 1:])
            start = i + 1


# --*-- coding: utf-8 --*--
# @Author: zhang
# @Email: your email
# @Time: 2019/9/9 16.28
# @File: model_save301.py
# @Software: PyCharm
# desc:模型读取例子

import tensorflow as tf
from mnist201 import MNISTLoader

batch_size = 50

model = tf.saved_model.load("./save/1")
data_loader = MNISTLoader()
sparse_categorical_accuracy = tf.keras.metrics.SparseCategoricalAccuracy()
num_batches = int(data_loader.num_test_data // batch_size)
for batch_index in range(num_batches):
    start_index, end_index = batch_index * batch_size, (batch_index + 1) * batch_size
    y_pred = model(data_loader.test_data[start_index: end_index])
    sparse_categorical_accuracy.update_state(y_true=data_loader.test_label[start_index: end_index], y_pred=y_pred)
print("test accuracy: %f" % sparse_categorical_accuracy.result())


# -*- coding:utf-8 -*-
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:

    def __init__(self):
        self.sumc = 0
        self.a = []
        self.b = []
    # 返回二维列表，内部每个列表表示找到的路径
    def FindPath(self, root, expectNumber):
        # write code here
        if not root:
            return []
        self.sumc += root.val
        self.a.append(root.val)
        if self.sumc == expectNumber and not root.left and not root.right:
            self.b.append(self.a[:])
		#若是有负数的话，则直接改为else
        elif self.sumc < expectNumber:
            self.FindPath(root.left,expectNumber)
            self.FindPath(root.right,expectNumber)
        self.sumc -=self.a[-1]
        self.a.pop()
        return self.b

024-二叉树中和为某一值的路径.py

024-二叉树中和为某一值的路径.py


import pandas as pd
import numpy as np
from scipy.spatial.distance import cdist
from sklearn.cluster import KMeans
from util.helper import data_preparation
import ruptures

from task2_groups import *

# Load the df_sorted DataFrame from the file
s_file_name = 'dataset_sorted.csv'
df_map = find_path(s_file_name)
df_sorted = group_and_sort(df_map)

#df_prepared = data_preparation(df_sorted)
user_id = 2222
#patient_data = df_prepared[df_prepared['user_id'] == user_id]
patient_data = df_sorted[df_sorted['user_id'] == user_id]

# Get unique user IDs
user_ids = df_sorted['user_id'].unique()

# Assign a single cluster to each user based on their multi-day data
user_clusters = {}

for user_id in user_ids:
    # Data for the current user
    user_data = df_sorted[df_sorted['user_id'] == user_id][selected_attributes].to_numpy()

    # Preprocess data for the user
    data = preprocess_data(pd.DataFrame(user_data, columns=selected_attributes))

    # Number of desired clusters
    num_clusters = 3

    # Perform clustering
    cluster_assignments, centroids = k_pod(data, num_clusters)

    # Assign the same cluster label and centroids to the user
    user_clusters[user_id] = {
        'cluster_assignment': cluster_assignments[0],
        'centroids': centroids
    }

# Output user clusters
print("User Clusters:")
for user_id, cluster_info in user_clusters.items():
    cluster_assignment = cluster_info['cluster_assignment']
    centroids = cluster_info['centroids']
    print(f"User ID: {user_id}, Cluster: {cluster_assignment}")
    print(f"Centroids for User ID {user_id}:\n{centroids}")

# Add the cluster assignments to the patient_data DataFrame
# timeline_cluster_labels = cluster_timelines(patient_data)
timeline_cluster_labels = cluster_timelines(patient_data, num_clusters=3)
adherence_cluster_labels = cluster_adherence_percentages(patient_data)
timeline_notes_cluster_labels = cluster_note_timelines(patient_data)

print("Timeline Cluster Labels:", timeline_cluster_labels)
print("Adherence Cluster Labels:", adherence_cluster_labels)
print("Timeline & Notes Cluster Labels:", timeline_notes_cluster_labels)


import base64
import hashlib
import time
import binascii
import base58
from enum import Enum

from bitcoin.wallet import P2PKHBitcoinAddress
from coincurve.utils import verify_signature
from yadacoin.contracts.asset import Asset
from yadacoin.core.collections import Collections
from yadacoin.core.config import get_config
from yadacoin.core.identity import Identity, PrivateIdentity
from yadacoin.core.transaction import (
    InvalidTransactionException,
    InvalidTransactionSignatureException,
    Output,
    Transaction,
)
from yadacoin.core.transactionutils import TU

class PayoutOperators(Enum):
    PERCENT = "percent"
    FIXED = "fixed"

class PayoutType(Enum):
    RECURRING = "recurring"
    ONE_TIME = "one_time"

class ContractTypes(Enum):
    CHANGE_OWNERSHIP = "change_ownership"
    NEW_RELATIONSHIP = "new_relationship"

class Contract:
    def __init__(self, version, expiry, contract_type, identity, creator):
        self.config = get_config()

        if not isinstance(version, int):
            self.report_init_error("version")

        if not isinstance(expiry, int):
            self.report_init_error("expiry")

        if contract_type not in [x.value for x in ContractTypes]:
            self.report_init_error("contract_type")

        if not creator or (
            not isinstance(creator, dict) and not isinstance(creator, str)
        ):
            self.report_init_error("creator")

        self.version = version
        self.expiry = expiry
        self.contract_type = contract_type
        self.identity = PrivateIdentity.from_dict(identity)
        self.creator = (
            Identity.from_dict(creator) if isinstance(creator, dict) else creator
        )

    def get_string(self, p):
        return "" if p is None else str(p)

    def report_init_error(self, member):
        raise Exception(f"Cannot instantiate contract with invalid {member}")

    @staticmethod
    def from_dict(contract):
        from yadacoin.contracts.affiliate import AffiliateContract
        from yadacoin.contracts.changeownership import ChangeOwnershipContract

        cls = None
        if contract.get("contract_type") == ContractTypes.NEW_RELATIONSHIP.value:
            cls = AffiliateContract
        elif contract.get("contract_type") == ContractTypes.CHANGE_OWNERSHIP.value:
            cls = ChangeOwnershipContract

        return cls(**contract)

    async def verify_input(self, trigger_txn):
        if await self.config.BU.is_input_spent(
            trigger_txn.transaction_signature,
            self.identity.public_key,
            inc_mempool=True,
        ):
            raise Exception("input is already spent by contract")

    async def verify(self, contract_txn, trigger_txn=None, mempool_txns=None):
        await getattr(self, f"verify_{self.proof_type}")(contract_txn, trigger_txn)

    async def verify_generation(self, block, generated_txn=None, mempool_txns=None):
        contract_txn = await generated_txn.get_generating_contract()
        if not contract_txn:
            raise Exception("Could not find corresponding smart contract")

        verify_hash = await generated_txn.generate_hash()

        if verify_hash != generated_txn.hash:
            raise InvalidTransactionException("transaction is invalid")

        try:
            result = verify_signature(
                base64.b64decode(generated_txn.miner_signature),
                hashlib.sha256(generated_txn.transaction_signature.encode())
                .hexdigest()
                .encode("utf-8"),
                bytes.fromhex(block.public_key),
            )
            if not result:
                raise Exception("Payout miner signature did not verify")
        except:
            raise InvalidTransactionSignatureException(
                "Payout miner signature did not verify"
            )

        if generated_txn.requested_rid != contract_txn.requested_rid:
            raise Exception("requested_rid does not match that of smart contract")

        await getattr(self, f"verify_{self.proof_type}")(contract_txn, generated_txn)

    async def get_funds(self, contract_txn):
        address = str(
            P2PKHBitcoinAddress.from_pubkey(
                bytes.fromhex(contract_txn.relationship.identity.public_key)
            )
        )
        async for txn in self.config.BU.get_wallet_unspent_transactions(
            address, no_zeros=True
        ):
            yield Transaction.from_dict(txn)

    @staticmethod
    async def get_smart_contract(transaction_obj):
        smart_contract_block = await get_config().mongo.async_db.blocks.find_one(
            {
                "transactions.requested_rid": transaction_obj.requested_rid,
                "transactions": {
                    "$elemMatch": {"relationship.smart_contract": {"$exists": True}}
                },
                "transactions": {
                    "$elemMatch": {"id": {"$ne": transaction_obj.transaction_signature}}
                },
                "transactions": {
                    "$elemMatch": {
                        "relationship.smart_contract.expiry": {
                            "$gt": get_config().LatestBlock.block.index
                        }
                    }
                },
            },
            sort=[("index", 1)],
        )
        if not smart_contract_block:
            return
        for smart_contract in smart_contract_block.get("transactions"):
            if (
                smart_contract.get("relationship")
                and isinstance(smart_contract.get("relationship"), dict)
                and Collections.SMART_CONTRACT.value in smart_contract["relationship"]
            ):
                smart_contract_obj = Transaction.from_dict(smart_contract)
                return smart_contract_obj

    async def expire(self, contract_txn):
        return await getattr(self, f"expire_{self.proof_type}")(contract_txn)


# Automate the Boring Stuff with Python 3
# Vid Lesson 4 - Boolean & Comparison

# Initial discussion of flow charts
# Boolean values
spam = True
eggs = False

# Comparison Operators
spam = 42 # THIS IS AN ASSIGNMENT NOT A COMPARISON

42 == 42 # Evaluates expression to Structures
41 != 41 # False
42 > 42 # False
42 >= 42 # True
4 < 59 # True
4 <= 4 # True

# Boolean Operators
True and True # True
True and False # False
True or False # True
False or False # False
not True # False
# See truth tables to show all the combos

myAge = 25
myPet = 'cat'
myAge > 20 and myPet == 'cat'


from __future__ import print_function
import os, os.path, sys, glob
import platform as P

# Set up model source and tools directory (the "srcdir='src'" thing is
# there to allow us to run SCons in the root cgenie directory for
# development purposes -- normal job builds will pick up an explicit
# job configuration and model source directory file in their build
# directory).

if os.path.exists('version.py'):
    execfile('version.py')
    sys.path.append(scriptdir)
else:
    srcdir = 'src'
    if 'debug' in ARGUMENTS:
        build_type = 'debug'
    else:
        build_type = 'normal'
    sys.path.append('tools')

import utils as U

# Read GENIE configuration.

if not U.read_cgenie_config():
    sys.exit('GENIE not set up: run the setup.py script!')

# Load platform configuration.

platform = U.discover_platform()
print('Using platform "' + platform + '"')
execfile(os.path.join(U.cgenie_root, 'platforms', platform))

# NetCDF paths.

netcdfinc = netcdf['base'][0]
netcdflib = netcdf['base'][1]

# GENIE modules to build.

modules = Split("""atchem
                   biogem
                   embm
                   ents
                   gemlite
                   goldstein
                   goldsteinseaice
                   rokgem
                   sedgem""")
utils = Split('common utils wrappers')

# Subdirectories for compilation.

subdirs = modules + utils

# F90 module search paths.

modpath = map(lambda d: os.path.join('#/build', d), subdirs)

# Set up model version marker.

rev = ARGUMENTS['rev'] if 'rev' in ARGUMENTS else 'UNKNOWN'
defs = [f90['define'] + "REV=" + rev]

# Set up SCons environment: Fortran compiler definitions taken from
# platform configuration.  Some of these things are Windows-specific:
# the Microsoft linker uses the directory given in the TMP environment
# variable for temporary files, and if that's not defined, tries to
# put them in a read-only system directory; SCons uses the HOST_ARCH
# environment setting to decide whether to use 32- or 64-bit tools
# from Visual Studio.

envcopy = { }
envcopy['PATH'] = os.environ['PATH']
if 'TMP' in os.environ: envcopy['TMP'] = os.environ['TMP']
baselinkflags = []
if 'baselinkflags' in f90:
    baselinkflags = f90['baselinkflags']
extraf90flags = []
if build_type in f90: extraf90flags = f90[build_type]
extralinkflags = []
if build_type + '_link' in f90: extralinkflags = f90[build_type + '_link']
extraf90libpaths = []
if 'libpath' in f90: extraf90libpaths.append(f90['libpath'])
extraf90libs = []
if 'libs' in f90: extraf90libs.append(f90['libs'])

target_vs_arch = 'linux'
if 'TARGET_VS_ARCH' in os.environ:
    target_vs_arch = os.environ['TARGET_VS_ARCH']

env = Environment(ENV = envcopy,
                  TOOLS = ['default', f90['compiler']],
                  HOST_ARCH = target_vs_arch,
                  F90FLAGS = f90['baseflags'] + extraf90flags + defs,
                  LINKFLAGS = baselinkflags + extralinkflags,
                  F90PATH = [netcdfinc] + modpath,
                  FORTRANMODDIRPREFIX = f90['module_dir'],
                  FORTRANMODDIR = '${TARGET.dir}',
                  LIBPATH = [netcdflib] + extraf90libpaths,
                  LIBS = netcdf['libs'] + extraf90libs)

if 'ld_library_path' in f90:
    env['ENV']['LD_LIBRARY_PATH'] = f90['ld_library_path']

print('SConstruct from cgenie called')

# Set up prompt progress reporting.

# if 'progress' not in ARGUMENTS or ARGUMENTS['progress'] == '1':
#     if P.system() == 'Windows':
#         screen = open('CON:', 'w')
#     else:
#         screen = open('/dev/tty', 'w')
#     def progress_function(node):
#         node = str(node)
#         if node.endswith('.f90'):
#             print(os.path.relpath(node, srcdir), file=screen)
#     Progress(progress_function)

# Build!

Export('env', 'subdirs', 'build_type')
SConscript(os.path.join(srcdir, 'SConscript'),
           variant_dir='#build', duplicate=0)
Install('.', 'build/genie.exe')


# local
import ivy
import jax
from ivy_tests.test_ivy.helpers import handle_frontend_test
from ivy.functional.frontends.jax._src.tree_util import tree_leaves, tree_map
import hypothesis.strategies as st

# --- Helpers --- #
# --------------- #

@st.composite
def _tree_dict_strategy(draw):
    return draw(tree_strategy())

# --- Main --- #
# ------------ #

def leaf_strategy():
    return st.lists(st.integers(1, 10)).map(ivy.array)

# tree_leaves
@handle_frontend_test(
    fn_tree="jax._src.tree_util.tree_leaves",
    tree=_tree_dict_strategy(),
)
def test_jax_tree_leaves(
    *,
    tree,
    test_flags,
    fn_tree,
    frontend,
    on_device,
    backend_fw,
):
    ivy.set_backend(backend_fw)
    # Apply the tree_leaves function to obtain the leaves of the tree
    result = tree_leaves(tree)

    # compute the expected result
    expected = jax.tree_util.tree_leaves(tree)

    # value test
    assert result == expected
    ivy.previous_backend()

# tree_map
@handle_frontend_test(
    fn_tree="jax._src.tree_util.tree_map",
    tree=_tree_dict_strategy(),
)
def test_jax_tree_map(
    *,
    tree,
    test_flags,
    fn_tree,
    frontend,
    on_device,
    backend_fw,
):
    ivy.set_backend(backend_fw)

    # Define a function to square each leaf node
    def square(x):
        if isinstance(x, ivy.Array):
            return ivy.square(x)
        else:
            return x**2

    # Apply the square function to the tree using tree_map
    result = tree_map(square, tree)

    # compute the expected result
    expected = ivy.square(ivy.Container(tree))

    assert ivy.equal(ivy.Container(result), expected)
    ivy.previous_backend()

def tree_strategy(max_depth=2):
    if max_depth == 0:
        return leaf_strategy()
    else:
        return st.dictionaries(
            keys=st.one_of(
                *[
                    st.text(
                        alphabet=st.characters(min_codepoint=97, max_codepoint=122),
                        min_size=1,
                        max_size=1,
                    ).filter(lambda x: x not in used_keys)
                    for used_keys in [set()]
                ]
            ),
            values=st.one_of(leaf_strategy(), tree_strategy(max_depth - 1)),
            min_size=1,
            max_size=10,
        )


import numpy as np
import cv2
from matplotlib import pyplot as plt
from PIL import Image

# Import image with PIL
img = Image.open('Bilder\Draht1.jpg')

# Rotate image 180 degrees
img_r = img.rotate(180, expand=True)

# Transform image into Numpy Array
img_r = np.array(img_r)

# RGB to BGR
# img_r = img_r[:, :, ::-1].copy()

# Resize image
img_rs = cv2.resize(img_r, None, fx=0.125, fy=0.125, interpolation=cv2.INTER_CUBIC)

# Create a mask for the image
mask = np.zeros(img_rs.shape[:2], np.uint8)

# Create models for both the background and foreground
bgdModel = np.zeros((1, 65), np.float64)
fgdModel = np.zeros((1, 65), np.float64)

rect = (50, 110, 440, 275)
cv2.grabCut(img_rs,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
mask2 = np.where((mask == 2) | (mask == 0), 0, 1).astype('uint8')
img_m = img_rs*mask2[:, :, np.newaxis]

# Show image
plt.imshow(img_m)
plt.show()


import os
import logging

class BaseConfig(object):
    DEBUG = False
    logging.getLogger("flask_ask").setLevel(logging.DEBUG)

class DevelopmentConfig(BaseConfig):
    DEBUG = False
    logging.getLogger("flask_ask").setLevel(logging.DEBUG)
    #ASK_APPLICATION_ID = "<add-your-application-id-here>"

class TestingConfig(BaseConfig):
    DEBUG = True
    logging.getLogger("flask_ask").setLevel(logging.DEBUG)
    ASK_VERIFY_REQUESTS = False # Don't verify whether the requests are from Alexa service

config = {
    "development": "goodbooks_config.DevelopmentConfig",
    "testing": "goodbooks_config.TestingConfig",
    "default": "goodbooks_config.DevelopmentConfig"
}

def configure_app(app):
    config_name = os.getenv('FLASK_CONFIGURATION', 'default')
    app.config.from_object(config[config_name])


import keras
from keras import models
from keras.models import Sequential
from keras.preprocessing.image import ImageDataGenerator
import numpy as np
import os
import shutil

def cnn_eliminate(model_name, eli_path, train_path):
    prefix = "/home/zlstg1/cding0622/scripts/models"
    model_path = os.path.join(prefix, model_name)
    model = models.load_model(model_path)

    train_datagen = ImageDataGenerator(rescale=1./255)
    train_generator = train_datagen.flow_from_directory(
        train_path,
        target_size=(48, 48),
        batch_size=1,
        shuffle=False,
        color_mode='grayscale',
        class_mode='binary')
    p_acc = model.evaluate_generator(train_generator, train_generator.samples)
    print("Accuracy:  ", p_acc[1])

    pred = model.predict_generator(train_generator, train_generator.samples, verbose=1)
    print("\n")
    elim_list = []
    for i in range(train_generator.samples):
        file = train_generator.filenames[i]
        if "benign" in file and pred[i] > 0.5:
            elim_list.append(file)
        elif "malignant" in file and pred[i] <= 0.5:
            elim_list.append(file)
    print("%d files over threshold" % len(elim_list))
    for f in elim_list:
        #f = f.split("/", 1)[1]
        #print(f)
        tmp = os.path.join(eli_path, f)
        #os.remove(tmp)
        shutil.move(tmp, "/home/zlstg1/cding0622/project/eli_visualize")

if __name__ == "__main__":
    cnn_eliminate("model_full.h5", "/home/zlstg1/cding0622/project/cnn_eli/full_data/train", "/home/zlstg1/cding0622/project/ori/full_data/train")


# Faça um programa que leia um numero e mostre na tela o seu sucessor e o seu antecessor.

numero = int(input('Digite um numero:'))

soma = numero + 1
sub = numero - 1

# Meu coodigo
print('Você escolheu o numero {}, e o antecessor dele é {} e o sucessor é o {}'.format(numero, sub, soma))

# Codigo Guanabara, substitui as variaveis para econimizar memoria
print('Você escolheu o numero {}, e o antecessor dele é {} e o sucessor é o {}'.format(numero, (numero-1), (numero+1)))


import cv2
import numpy as np
import cv2.aruco as aruco
import math
import serial
from time import sleep
#cap = cv2.VideoCapture("http://192.168.43.63:4747/video")

ser=serial.Serial('COM5',9600)
sleep(2)
print("connected")

def writeToSerial(a, b, c, d):
    ser.write(str.encode(str(a) + ' ' + str(b) + ' ' + str(c) + ' ' + str(d) + ' 0\n'))
    ser.readline()
    pass
'''
def find_boat_centre():
    while(1):
        ret, arena = cap.read()
        #arena = frame[int(roi[1]):int(roi[1] + roi[3]), int(roi[0]):int(roi[0] + roi[2])]
        aruco_dict = aruco.Dictionary_get(aruco.DICT_5X5_250)
        parameters = aruco.DetectorParameters_create()
        corners, ids, rejectedImgPoints = aruco.detectMarkers(arena, aruco_dict, parameters=parameters)
        if ids is None:
            continue
        img=cv2.circle(arena,(corners[0][0][0][0],corners[0][0][0][1]),5,(0,0,255),2)
        cv2.imshow('img',img)
        cv2.waitKey(0)
        cv2.destroyWindow('img')
        print("corners")
        print(corners)
        for x in range(0,ids.shape[0]):
            p1 = max(corners[x][0][0][0], corners[x][0][1][0],
                    corners[x][0][2][0], corners[x][0][3][0])
            p2 = min(corners[x][0][0][0], corners[x][0][1][0],
                     corners[x][0][2][0], corners[x][0][3][0])
            q1 = max(corners[x][0][0][1], corners[x][0][1][1],
                     corners[x][0][2][1], corners[x][0][3][1])
            q2 = min(corners[x][0][0][1], corners[x][0][1][1],
                     corners[x][0][2][1], corners[x][0][3][1])
            xc = int(p2+abs(p1-p2)/2)
            yc = int(q2+abs(q1-q2)/2)
            return corners,(xc,yc)
'''
def bot_vector(p,i,j):
    return p[0][0][i]-p[0][0][j]

# return direction in which boat have to move
def dirn_of_mov_vector(boat_centre,next_cell):
    #cell_cent=(next_cell)
    #boat_centre[0]-=roi[0]
    #boat_centre[1]-=roi[1]# source of error y and x
    return next_cell-boat_centre

# determine angle between boat direction and direction of movemnet
def cross_pro(dirn_of_mov=[1,1],boat_vector=[0,1]):
    a=np.array(dirn_of_mov)
    b=np.array(boat_vector)
    print(np.cross(a, b))
    mag = (math.sqrt(dirn_of_mov[0] ** 2 + dirn_of_mov[1] ** 2)) * (math.sqrt(boat_vector[0] ** 2 + boat_vector[1] ** 2))
    print(math.degrees(math.asin(np.cross(a,b)/mag)))
    return (math.degrees(math.asin(np.cross(a,b)/mag)))

KP = 7
KD = 70
KI=0
MaxSpeedLine = 150
BaseSpeedLine = 100
#instantStopAngle = 0.250
#instantStopLine = 0.100

#thresholdForRect = 200

#Initializatins
prev_error = 0
rightMotorSpeed=0
leftMotorSpeed=0
motor_speed=0
#desired_value=(200,100)# set desired value according to camera

set_point=[(96,365),(56,269),(104,168),(274,252)]
i=0
'''
while (True):
    ret, image = cap.read()
    if(ret==False):
        break
    print("here1")
    cv2.imshow('frame', image)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    print("here2")

    p,center_of_bot=find_boat_centre()
    bv=bot_vector(p,0,1)
    dv=dirn_of_mov_vector(center_of_bot,set_point[i])
    error=cross_pro(dv,bv)
    if(abs(error)>80):
        # stop bot
        leftMotorSpeed=0
        rightMotorSpeed=0
        i+=1
        if(i>=4):
            i=i%4

        p, b_c = find_boat_centre()
        bv = bot_vector(p, 0, 1)
        dv = dirn_of_mov_vector(b_c, set_point[i])
        angle = cross_pro(bv, dv)
        while (angle > 10 | angle < -10):
            if (angle <= -10):
            # small right turn
                rightMotorSpeed=40
                leftMotorSpeed=40
                lind=0
                rind=1
                writeToSerial(rightMotorSpeed,leftMotorSpeed,rind,lind)
                sleep(0.05)
            elif angle > 10:
                # small left turn
                rightMotorSpeed = 40
                leftMotorSpeed = 40
                lind = 0
                rind = 1
                writeToSerial(rightMotorSpeed, leftMotorSpeed, rind, lind)
                sleep(0.05)

            p, b_c = find_boat_centre()
            bv = bot_vector(p, 0, 1)
            dv = dirn_of_mov_vector(b_c, set_point[i])
            angle = cross_pro(bv, dv)
        continue
    #integral = integral_prior + error * iteration_time
    #derivative = (error – prev_error) / iteration_time
    motor_speed = KP*error + KD*(error-prev_error)
    rightMotorSpeed = BaseSpeedLine - motor_speed
    leftMotorSpeed = BaseSpeedLine + motor_speed

    if (rightMotorSpeed > MaxSpeedLine): rightMotorSpeed = MaxSpeedLine
    if (leftMotorSpeed > MaxSpeedLine): leftMotorSpeed = MaxSpeedLine
    if (rightMotorSpeed < 0): rightMotorSpeed = 0
    if (leftMotorSpeed < 0): leftMotorSpeed = 0
    print('L:', leftMotorSpeed, 'R:', rightMotorSpeed)
    writeToSerial(leftMotorSpeed, rightMotorSpeed, 1, 1)
    prev_error = error
    #integral_prior = integral
    #sleep(iteration_time)
'''
while(1):
    lms=100
    rms=200
    ser.write(b'f')
    print(lms, rms)
    #writeToSerial(100,200,1,1)
    #print(lms,rms)
    sleep(2)


from flask import Blueprint, redirect, url_for
from flask_login import login_required

from extensions import dbs, sched

DebugTools = Blueprint('DebugTools', __name__)

@DebugTools.route('/debug/nickupdate')
@login_required
def nickupdate():
    dbs.update_discord_nicknames()
    return redirect(url_for('index'))

@DebugTools.route('/debug/avupdate')
@login_required
def avdownload():
    sched.run_job('Download avatars')
    return redirect(url_for('index'))


#! /usr/bin/python
# -*- coding: utf-8 -*-

m = 1
n = 1
a = 0
b = 0
c = 0
sumval = 0

while (sumval < 1500 ):
  m+=1
  for n in range (1, m):
    b = 2*m*n
    a = (m * m) - (n * n)
    c = (m * m) + (n * n)
    if ((c * c) == ((a * a) + (b * b))):
      sumval = a + b + c
      myproduct = a * b * c
      print ("a = " + str(a) + "; b = " + str(b) + "; c = " + str(c) + "; m = " + str(m) + " ; n = " + str(n) + "; sum = " + str(sumval) + "; Product = " + str(myproduct))
      if (sumval == 1000):
        print ("found it!")


from openupgradelib import openupgrade

def _fill_111_tax_line(env, column, line_xml_id):
    ref = env.ref(line_xml_id)
    openupgrade.logged_query(
        env.cr,
        """
        INSERT INTO l10n_es_aeat_tax_line
        (res_id, name, field_number, amount, map_line_id, model)
        SELECT t.id, m.name, m.field_number, %s, m.id, '%s'
        FROM %s t
        JOIN l10n_es_aeat_map_tax_line m ON m.id = %s""" % (
            column,
            'l10n.es.aeat.mod111.report',
            'l10n_es_aeat_mod111_report',
            ref.id,
        )
    )

def _fill_111_move_line_refs(env, table, line_xml_id):
    """Fill field move_line_ids."""
    ref = env.ref(line_xml_id)
    openupgrade.logged_query(
        env.cr,
        """
        INSERT INTO account_move_line_l10n_es_aeat_tax_line_rel
        (l10n_es_aeat_tax_line_id, account_move_line_id)
        SELECT l.id, t.account_move_line
        FROM l10n_es_aeat_tax_line l, %s t
        WHERE l.map_line_id = %%s
        AND l.res_id = t.mod111""" % table, (ref.id, )
    )

def fill_111_values(env):
    """Create tax lines with the data that were previously stored on 111."""
    table_prefix = 'mod111_account_move_line'
    prefix = 'l10n_es_aeat_mod111.aeat_mod111_map_line_'
    _fill_111_tax_line(env, 'casilla_02', prefix + '02')
    _fill_111_tax_line(env, 'casilla_03', prefix + '03')
    _fill_111_tax_line(env, 'casilla_05', prefix + '05')
    _fill_111_tax_line(env, 'casilla_06', prefix + '06')
    _fill_111_tax_line(env, 'casilla_08', prefix + '08')
    _fill_111_tax_line(env, 'casilla_09', prefix + '09')
    _fill_111_move_line_refs(env, table_prefix + '02_rel', prefix + '02')
    _fill_111_move_line_refs(env, table_prefix + '03_rel', prefix + '03')
    _fill_111_move_line_refs(env, table_prefix + '05_rel', prefix + '05')
    _fill_111_move_line_refs(env, table_prefix + '06_rel', prefix + '06')
    _fill_111_move_line_refs(env, table_prefix + '08_rel', prefix + '08')
    _fill_111_move_line_refs(env, table_prefix + '09_rel', prefix + '09')

@openupgrade.migrate(use_env=True)
def migrate(env, version):
    fill_111_values(env)
    # Recompute fields
    records = env['l10n.es.aeat.mod111.report'].search([])
    records._compute_casilla_01()
    records._compute_casilla_04()
    records._compute_casilla_07()
    records._compute_casilla_28()
    records._compute_casilla_30()


import unittest
import requests
import os, sys, json
parentdir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, parentdir)

class getAutoStartServiceWatchedListTest(unittest.TestCase):
    ''' 获取自启动服务信息信息 '''

    def setUp(self):
        self.base_url = "http://139.196.104.13:8082/mics/call"

    def tearDown(self):
        print(self.result)

    def test_getAutoStartServiceWatchedList(self):
        payload = {"method":"getAutoStartServiceWatchedList","params":"{'service_type':'http'}","service":"topmics-admin-mics","timeout":30000,"waitReply":True}
        # data = json.dumps(payload)
        r = requests.post(self.base_url, data=payload)
        self.result = r.text
        # self.assertEqual(self.result['status_code'], 200)
        # self.assertEqual(self.result['message'], 'parameter error')

if __name__ == '__main__':
    unittest.main()


import json

import frappe

@frappe.whitelist()
def update_task(args, field_map):
	"""Updates Doc (called via gantt) based on passed `field_map`"""
	args = frappe._dict(json.loads(args))
	field_map = frappe._dict(json.loads(field_map))
	d = frappe.get_doc(args.doctype, args.name)
	d.set(field_map.start, args.start)
	d.set(field_map.end, args.end)
	d.save()


from refactored_coron3_pipeline import RefactoredCoron3Pipeline

import os
from glob import glob
import time
import sys

import pandas as pd

import astropy.io.fits as fits
from astropy.table import Table

import jwst
from jwst.pipeline import Image2Pipeline
from jwst.associations.lib.rules_level3 import Asn_Lv3Coron
from jwst.associations import AssociationPool, AssociationRegistry
from jwst.associations.mkpool import from_cmdline, mkpool
from jwst.associations import generate

from ..util.util_main import get_dataset_dir, get_main_dir
from ..util.util_type import INSTRUME

class CoronPipeline():
    def __init__(self, proposal_id: str, instrume: INSTRUME):
        print(
            f"coron_pipeline.py script activated. Current JWST Version: {jwst.__version__}")
        os.environ["CRDS_PATH"] = '/home/bariskurtkaya/crds_cache/jwst_ops'
        os.environ["CRDS_SERVER_URL"] = 'https://jwst-crds.stsci.edu'

        self.instrume = instrume
        self.proposal_id = proposal_id

        self.dataset_dir = get_dataset_dir()
        self.dataset_dir = self.dataset_dir + \
            f'/{self.instrume}/{self.proposal_id}/mastDownload/JWST/'

    def pipeline_stage2(self, rateints_check: bool = False):

        self.detector = 'nrcalong'

        rateints_files = glob(os.path.join(
            self.dataset_dir, f'**/*{self.detector}_rateints.fits'))
        if rateints_files == []:
            self.detector = 'nrca2'
            rateints_files = glob(os.path.join(
                self.dataset_dir, f'**/*{self.detector}_rateints.fits'))

        if rateints_check:
            self.rateints_check(rateints_files=rateints_files)

        batch_size = 4
        img2pipeline = Image2Pipeline()
        img2pipeline.save_results = True

        for index in range(0, len(rateints_files), batch_size):
            for rateints_files_batch in rateints_files[index:index+batch_size]:
                output_dir = '/'.join(rateints_files_batch.split('/')
                                      [:-1]) + '/'

                img2pipeline.output_dir = output_dir
                img2pipeline(rateints_files_batch)

        del rateints_files, img2pipeline, batch_size

    def pipeline_stage3(self, asn_check: bool = False, calints_check: bool = False):
        calints_files = glob(os.path.join(
            self.dataset_dir, f'**/*{self.detector}_calints.fits'))

        if calints_check:
            self.calints_check(calints_files=calints_files)

        asn_files = self.asn_file_creation(calints_files=calints_files)

        if asn_check:
            self.asn_check(asn_files=asn_files)

        coron3_pipeline = RefactoredCoron3Pipeline()
        coron3_pipeline.output_dir = self.dataset_dir
        coron3_pipeline.save_results = True

        for idx, asn in enumerate(asn_files):
            asn_dict = {}
            for key, value in zip(asn.keys(), asn.values()):
                asn_dict[key] = value

            coron3_pipeline.process(asn_dict)

        del asn_files, calints_files, asn_dict, coron3_pipeline

    def calints_check(self, calints_files):
        print(
            f'Calints control: \n Total Calints: {len(calints_files)} \n First Calints info:')
        calints_sample = fits.open(calints_files[0])
        calints_sample.info()

    def asn_check(self, asn_files):
        print(
            f'ASN control: \n Total ASN Files: {len(asn_files)} \n First ASN info: {asn_files[0]}')

    def rateints_check(self, rateints_files):
        print(
            f'Rateints control: \n Total Rateints: {len(rateints_files)} \n First Rateints info: {rateints_files[0]}')

    def asn_file_creation(self, calints_files):
        pool = mkpool(calints_files)
        pool_df = pool.to_pandas()
        pool_df.to_csv(
            f'calints_{self.instrume}_{self.proposal_id}_pool.csv', index=False)

        asn_coron_rule_dir = get_main_dir() + '/scripts' + '/asn_coron_rule.py'

        registry = AssociationRegistry(
            [asn_coron_rule_dir], include_default=False)

        asn_files = generate(pool, registry)

        return asn_files

if __name__ == "__main__":

    instrume: INSTRUME = 'NIRCAM'
    proposal_id: str = '1386'

    coron = CoronPipeline(proposal_id=proposal_id, instrume=instrume)

    coron.pipeline_stage2()
    coron.pipeline_stage3()


########## SORT METHOD ########## SORT in Alphabet
# METHOD 1: CHANGE THE ORIGINAL LIST when SORT

#This is using python built in method and not custom built
work_days = ["Monday", "Tuesday", "Thursday", "Friday", "Saturday"]

work_days.sort() # ['Friday', 'Monday', 'Saturday', 'Thursday', 'Tuesday']

print(work_days)
# NOTE: Remember...no return. Modifies list

numbers = [1, 11, 115, 13, 1305, 43]
print(numbers)
# PROBELM: This is not possible because no return.
# print(numbers.sort())
# SOLUTION:
numbers.sort() # Sort in smaller and larger number # [1, 11, 13, 43, 115, 1305]
print(numbers)

# METHOD 2: keep original list
########## SORTED - COPY A LIST FOR SORT ##########
numbers = [1, 11, 115, 13, 1305, 43]
numbers_sorted = sorted(numbers)
numbers = sorted([1, 11, 115, 13, 1305, 43]) # the same

print(numbers) #original list # [1, 11, 115, 13, 1305, 43]
print(numbers_sorted) # [1, 11, 13, 43, 115, 1305]

# Sort and reverse, Larger to smaller
numbers = [1, 11, 115, 13, 1305, 43]
numbers_sorted = sorted(numbers)
sorted(numbers, reverse=True) # the same
numbers_sorted.reverse()
print(numbers_sorted) # [1305, 115, 43, 13, 11, 1]

########## CASE INSENSITIVE SORT ##########
'''
When working with strings, 'a' and 'A' are different.
A < AA
A < a
'''
letters = ['a', 'A', 'abc', 'ABC', 'aBc', 'aBC', 'Abc']

letters_sort = sorted(letters)
print(letters_sort) # ['A', 'ABC', 'Abc', 'a', 'aBC', 'aBc', 'abc']

print(sorted(letters, key=str.lower)) # ['a', 'A', 'abc', 'ABC', 'aBc', 'aBC', 'Abc']
# note: they are in order from original list if they are not differen in lower case.

########## SORT BY STRING LENGTH ##########
'''
sort by function
'''
random = ["a", "A", "aa", "AAA", "HELLO", "b", "c", "a"]
print(sorted(random, key=len))
#no () on function! len refers to function. len() invokes function

########## SORT NUMBERS WITH LEXICOGRAPHICAL SORTING ##########
'''
We can sort numbers similar to strings 1, 11, 111, 2, 22, 222
Basically, when we are working with strings,
"111" < "12"  because we compare by character left to right, So we can cast each to a str using the str constructor
'''
numbers = [1, 54, 76, 12, 111, 4343, 6, 8888, 3, 222, 1, 0, 222, -1, -122, 5, -30]
print(sorted(numbers, key=str))

########## COMPARE NUMERICALLY ##########
'''
Just like we compared using strings in the previous section, we can do it with numbers
Talse is 0
True is 1
expression evaluates to true and maintains that value
No data is converted to a float in list.
Strings are still strings.
bools are bools.
'''

age = 5
stuff = [True, False, 0, -1, "0", "1", "10", age < 30, "20", "2", "5", "9001", "5.5", "6.0", 6]
print(sorted(stuff, key=float)) # [-1, False, 0, '0', True, '1', True, '2', '5', '5.5', '6.0', 6, '10', '20', '9001']


from math import ceil, floor
largest_palindrome = 0

for i in range(999, 100, -1):
    for j in range(999, 100, -1):
        product = i * j
        product_str = str(product)
        first_half = product_str[:floor(len(product_str)/2)]
        second_half = product_str[ceil(len(product_str)/2):]
        second_half_reverse = second_half[::-1]
        if i * j > largest_palindrome and first_half == second_half_reverse:
            largest_palindrome = i * j

print(largest_palindrome)


from django.forms import ModelForm
from frAdmin.apps.web.models import UserProfile
from django.contrib.auth.models import User
from frAdmin.apps.web.managers.user_manager import UserManager
from django.contrib.auth.models import Group as GroupDjango
from django import forms

class UserProfileForm(ModelForm):
    class Meta:
        model = UserProfile
        fields = ['pass_limitation', 'mobile', 'unit', 'group', 'image_profile', 'last_pass', 'black_list']

        Widgets = {
            'mobile': forms.IntegerField(),
        }
        error_messages = {
            'image_profile': {
                'invalid': ("Image files only")
            }
        }

    objects = UserManager()

    def __init__(self, *args, **kwargs):
        super(UserProfileForm, self).__init__(*args, **kwargs)
        self.fields['group'].queryset = GroupDjango.objects.all()


import imutils
from imutils.perspective import order_points
import cv2
import numpy as np
import math
import argparse
from threading import Thread

color_spaces_hsv = [
    ((100, 131, 0), (125, 255, 255)),  # blue
    ((70, 0, 0), (90, 255, 190)),  # green
    ((40, 0, 165), (90, 100, 255)),  # yellow
    ((85, 0, 165), (185, 105, 255)),  # white
    ((0, 0, 165), (15, 255, 255)),  # orange
    ((0, 110, 49), (190, 255, 161))  # red
]
colors = {"blue": (0, 0, 255)}

def transform_according_to_reference_square(image, reference_points):
    # obtain a consistent order of the points and unpack them
    # individually
    rect = order_points(reference_points)
    (tl, tr, br, bl) = rect

    # compute the width of the new image, which will be the
    # maximum distance between bottom-right and bottom-left
    # x-coordiates or the top-right and top-left x-coordinates
    new_ref_width_1 = np.sqrt(((br[0] - bl[0]) ** 2) + ((br[1] - bl[1]) ** 2))
    new_ref_width_2 = np.sqrt(((tr[0] - tl[0]) ** 2) + ((tr[1] - tl[1]) ** 2))
    new_ref_width = max(int(new_ref_width_1), int(new_ref_width_2))

    # compute the height of the new image, which will be the
    # maximum distance between the top-right and bottom-right
    # y-coordinates or the top-left and bottom-left y-coordinates
    new_ref_height_1 = np.sqrt(((tr[0] - br[0]) ** 2) + ((tr[1] - br[1]) ** 2))
    new_ref_height_2 = np.sqrt(((tl[0] - bl[0]) ** 2) + ((tl[1] - bl[1]) ** 2))
    new_ref_height = max(int(new_ref_height_1), int(new_ref_height_2))

    # now that we have the dimensions of the new image, construct
    # the set of destination points to obtain a "birds eye view",
    # (i.e. top-down view) of the image, again specifying points
    # in the top-left, top-right, bottom-right, and bottom-left
    # order
    dst = np.array([
        rect[0],
        rect[0] + [new_ref_width - 1, 0],
        rect[0] + [new_ref_width - 1, new_ref_height - 1],
        rect[0] + [0, new_ref_height - 1]], dtype="float32")

    # compute the perspective transform matrix and then apply it
    transform_matrix = cv2.getPerspectiveTransform(rect, dst)
    warped = cv2.warpPerspective(image, transform_matrix, (image.shape[1], image.shape[0]))

    # return the warped image
    return warped

def color_for_rect(image, rect):
    center_rec = get_center_rec(rect, image, rel_margin=0.25)
    mean_color = np.mean(center_rec, axis=(0, 1))
    hsv = cv2.cvtColor(mean_color.reshape((1, 1, 3)).astype(np.uint8), cv2.COLOR_BGR2HSV)
    for j, (lower, upper) in enumerate(color_spaces_hsv):
        if cv2.inRange(hsv, lower, upper):
            return j
    return 6

def find_colored_squares_in_image(image):
    image = imutils.resize(image, height=500)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray, (5, 5), 0)
    edged = cv2.Canny(gray, 50, 100)
    # print("STEP 1: Edge Detection")

    rectangles = get_recs(edged, colored_image=image)
    if len(rectangles) == 0:
        return [], image

    # warp_ratios = get_warp_ratios(rectangles)
    #
    # warp_ratio = np.mean(warp_ratios)
    # if warp_ratio > 0.1:
    #     ref_index = np.argmin(np.abs(warp_ratios - warp_ratio))
    #     reference_rectangle = rectangles[ref_index]
    #     image = transform_according_to_reference_square(image, np.reshape(reference_rectangle, (4, 2)))
    #     gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    #     gray = cv2.GaussianBlur(gray, (5, 5), 0)
    #     edged = cv2.Canny(gray, 50, 100)
    #
    #     rectangles = get_recs(edged, 0.1)

    rectangles = list(rectangles)

    if len(rectangles) < 9:
        for i, (lower, upper) in enumerate(zip([np.array([0, 0, 70]), np.array([100, 0, 0])],
                                               [np.array([91, 255, 170]), np.array([169, 255, 42])])):
            only_colored = cv2.inRange(image, lower, upper)
            colored_recs = get_recs(only_colored, rel_similarity_threshold=0.2, already_found_recs=rectangles)
            if len(colored_recs):
                rectangles.extend(colored_recs)
                rectangles = list(remove_doubles(rectangles))

    if len(rectangles) > 9:
        print("Too many squares found")
        return [], image

    recs_reshaped = np.array([order_points(np.reshape(rec, (4, 2))).astype(np.int32) for rec in rectangles])
    mean_height = int(np.max(recs_reshaped[:, [3, 2], 1] - recs_reshaped[:, [0, 1], 1]))
    recs_reshaped = sorted(recs_reshaped, key=lambda x: x[0, 0] + mean_height * 5 * (x[0, 1] // mean_height))
    found_colors = []
    for i, rec in enumerate(recs_reshaped):
        x = rec[0, 0]
        y = rec[0, 1]
        color = color_for_rect(image, rec)
        cv2.putText(image, f"{color}", (x + 20, y + 30), cv2.FONT_HERSHEY_SIMPLEX, 0.5, [0, 0, 255])
        found_colors.append(color)

    # rectangles = [rec.reshape((4, 1, 2)) for rec in recs_reshaped]
    cv2.drawContours(image, rectangles, -1, (0, 255, 0), 2)
    return found_colors, image

def get_warp_ratios(rectangles):
    np_rectangles = np.zeros((len(rectangles), 4, 1, 2))
    for i, rect in enumerate(rectangles):
        np_rectangles[i] = rect
    # print(np_rectangles.shape, rectangles.shape)
    flattened_recs = np_rectangles[:, :, 0]
    right_order_recs = np.array([order_points(rec) for rec in flattened_recs])
    warp_ratio_dist = right_order_recs[:, 3] - right_order_recs[:, 0]
    warp_ratios = np.abs(warp_ratio_dist[:, 0] / warp_ratio_dist[:, 1])
    return warp_ratios

def get_recs(image_to_extract_from, rel_similarity_threshold=0.05, colored_image=None, already_found_recs=None):
    cnts = cv2.findContours(image_to_extract_from.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[1]
    cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
    rectangles = []
    if already_found_recs is not None:
        for rec in already_found_recs:
            rectangles.append(np.array([rec, cv2.contourArea(rec)]))
    for c in cnts:
        # approximate the contour
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.02 * peri, True)

        # if our approximated contour has four points, then we
        # can assume that we have found a square
        if len(approx) == 4:
            sq_area = cv2.contourArea(approx)
            if sq_area < 1000:
                break

            # check for similarity in color within approx
            if colored_image is not None:
                image_part = get_center_rec(approx, colored_image)
                mean_color_std = np.mean(np.std(image_part, axis=(0, 1)))
                if mean_color_std > 15:
                    continue

            # check for similarity in size
            if len(rectangles) > 0 \
                    and not math.isclose(sq_area, rectangles[-1][1], rel_tol=rel_similarity_threshold):
                if len(rectangles) < 3:
                    rectangles = []
                else:
                    continue
            rectangles.append(np.array([approx, sq_area]))
    if len(rectangles) == 0:
        return np.array([])
    rectangles = np.array(rectangles)
    rectangles = rectangles[:, 0]
    # remove doubles
    rectangles = sorted(rectangles, key=lambda x: np.min(np.sum(x[:, 0], axis=1)))
    rectangles = remove_doubles(rectangles)
    return rectangles

def get_center_rec(approx, image, rel_margin=0.1):
    reshaped = np.reshape(approx, (4, 2))
    x_min, y_min = np.min(reshaped, axis=0)
    x_max, y_max = np.max(reshaped, axis=0)
    width = x_max - x_min
    height = y_max - y_min
    x_min = int(x_min + rel_margin * width)
    x_max = int(x_max - rel_margin * width)
    y_min = int(y_min + rel_margin * height)
    y_max = int(y_max - rel_margin * height)
    image_part = image[y_min:y_max, x_min:x_max]
    return image_part

def remove_doubles(rectangles):
    for i, rec in enumerate(rectangles[:-1]):
        for neighbour in rectangles[i + 1:]:
            if np.sum(np.abs(rec[np.argmin(np.sum(rec[:, 0], axis=1)), 0]
                             - neighbour[np.argmin(np.sum(neighbour[:, 0], axis=1)), 0])) < 10:
                rectangles[i] = None
                break
    rectangles = np.array([rec for rec in rectangles if rec is not None])
    return rectangles

def colors_from_video(video_path=None, show=False):
    colors_for_sides = [[] for _ in range(6)]
    frames_after_sixth_side = 0
    if not video_path:
        vc = cv2.VideoCapture(0)
    else:
        vc = cv2.VideoCapture(video_path)
    while True:
        _, frame = vc.read()
        if frame is None or (not video_path and frames_after_sixth_side == 10):
            break

        found_colors, frame = find_colored_squares_in_image(frame)

        if frames_after_sixth_side > 0:
            frames_after_sixth_side += 1
        if len(found_colors) == 9 and found_colors[4] < 6:
            colors_for_sides[found_colors[4]].append(found_colors)
            if len(colors_for_sides[found_colors[4]]) > 50:
                colors_for_sides[found_colors[4]].pop(0)
            if frames_after_sixth_side == 0 and not any([len(side) == 0 for side in colors_for_sides]):
                frames_after_sixth_side = 1

        if show:
            cv2.imshow("Frame", frame)
            frame_rate = vc.get(cv2.CAP_PROP_FPS)
            time_per_frame = int(1000 / frame_rate)
            key = cv2.waitKey(time_per_frame if show else 1) & 0xFF
            if key == ord("q"):
                break
    if show:
        cv2.destroyAllWindows()
    for i, side in enumerate(colors_for_sides):
        side = np.array(side).transpose()
        colors_for_sides[i] = []
        for field in side:
            numbers, counts = np.unique(field, return_counts=True)
            number = numbers[np.argmax(counts)]
            colors_for_sides[i].append(number)
    vc.release()
    return colors_for_sides

class CubeWebcamStream:
    def __init__(self, src=0, name="CubeVideo"):
        self.stream = cv2.VideoCapture(src)
        _, self.frame = self.stream.read()
        self.colors = None
        self.name = name
        self.stopped = False

    def start(self):
        # start the thread to read frames from the video stream
        t = Thread(target=self.update, name=self.name, args=())
        t.daemon = True
        t.start()
        return self

    def update(self):
        # keep looping infinitely until the thread is stopped
        while True:
            # if the thread indicator variable is set, stop the thread
            if self.stopped:
                return

            # otherwise, read the next frame from the stream
            _, raw_frame = self.stream.read()
            found_colors, frame = find_colored_squares_in_image(raw_frame)
            if len(found_colors) == 9:
                self.frame = frame
                self.colors = found_colors
            else:
                self.frame = raw_frame
                self.colors = None

    def read(self):
        # return the frame most recently read
        return self.colors, self.frame

    def stop(self):
        # indicate that the thread should be stopped
        self.stopped = True

if __name__ == '__main__':
    # images_to_print = [f"cube_1_{i}" for i in range(6)]
    # # images_to_print = ["cube_1_4"]
    # # images_to_print = [f"cube_1_{i}_warped" for i in range(3, 6)]
    # for image_name in images_to_print:
    #     image = cv2.imread(f"./data/{image_name}.png")
    #     found_colors, image = find_colored_squares_in_image(image)
    #     print(f"colors {image_name}:", found_colors)
    #     cv2.imshow(image_name, image)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    # construct the argument parser and parse the arguments
    ap = argparse.ArgumentParser()
    ap.add_argument("-i", "--image", help="path to input image")
    ap.add_argument("-v", "--video", help="path to input video")

    args = vars(ap.parse_args())

    image_path = args.get("image", False)
    video_path = args.get("video", None)
    if image_path:
        image = cv2.imread(image_path)
        found_colors, image = find_colored_squares_in_image(image)
        print(f"colors {image_path}:", found_colors)
        cv2.imshow("Output", image)
        cv2.waitKey(0)
    elif video_path:
        colors = colors_from_video(video_path=video_path, show=not video_path)
        print(colors)
    else:
        stream = CubeWebcamStream().start()
        while True:
            colors, frame = stream.read()

            cv2.imshow("Frame", frame)
            key = cv2.waitKey(1) & 0xFF
            print("colors", colors)

            if key == ord("q"):
                break
        cv2.destroyAllWindows()


"""
High level node object, to access node attribute
and browse address space
"""

from datetime import datetime
import logging
import sys
from typing import Any, Iterable, List, Optional, Set, Union, overload

if sys.version_info >= (3, 8):
    from typing import Literal
else:
    from typing_extensions import Literal

from asyncua import ua
from asyncua.common.session_interface import AbstractSession
from .ua_utils import value_to_datavalue

from .events import Event, get_filter_from_event_type
from .ua_utils import data_type_to_variant_type
from .manage_nodes import create_folder, create_object, create_object_type, create_variable, create_variable_type, \
    create_data_type, create_property, delete_nodes, create_method, create_reference_type
from .methods import call_method

_logger = logging.getLogger(__name__)

def _check_results(results, reqlen=1):
    if not len(results) == reqlen:
        raise ValueError(results)
    for r in results:
        r.check()

def _to_nodeid(nodeid: Union["Node", ua.NodeId, str, int]) -> ua.NodeId:
    if isinstance(nodeid, int):
        return ua.TwoByteNodeId(nodeid)
    if isinstance(nodeid, Node):
        return nodeid.nodeid
    if isinstance(nodeid, ua.NodeId):
        return nodeid
    if isinstance(nodeid, str):
        return ua.NodeId.from_string(nodeid)
    raise ua.UaError(f"Could not resolve '{nodeid}' to a type id")

class Node:
    """
    High level node object, to access node attribute,
    browse and populate address space.
    Node objects are useful as-is but they do not expose the entire
    OPC-UA protocol. Feel free to look at the code of this class and call
    directly UA services methods to optimize your code
    """
    def __init__(self, session: AbstractSession, nodeid: Union["Node", ua.NodeId, str, int]):
        self.session = session
        self.nodeid: ua.NodeId
        if isinstance(nodeid, Node):
            self.nodeid = nodeid.nodeid
        elif isinstance(nodeid, ua.NodeId):
            self.nodeid = nodeid
        elif isinstance(nodeid, str):
            self.nodeid = ua.NodeId.from_string(nodeid)
        elif isinstance(nodeid, int):
            self.nodeid = ua.NodeId(nodeid, 0)
        else:
            raise ua.UaError(f"argument to node must be a NodeId object or a string" f" defining a nodeid found {nodeid} of type {type(nodeid)}")
        self.basenodeid = None

    def __eq__(self, other):
        if isinstance(other, Node) and self.nodeid == other.nodeid:
            return True
        return False

    def __ne__(self, other):
        return not self.__eq__(other)

    def __str__(self):
        return self.nodeid.to_string()

    def __repr__(self):
        return f"Node({self.nodeid})"

    def __hash__(self):
        return self.nodeid.__hash__()

    async def read_browse_name(self) -> ua.QualifiedName:
        """
        Get browse name of a node. A browse name is a QualifiedName object
        composed of a string(name) and a namespace index.
        """
        result = await self.read_attribute(ua.AttributeIds.BrowseName)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return result.Value.Value

    async def read_display_name(self) -> ua.LocalizedText:
        """
        get DisplayName attribute of node
        """
        result = await self.read_attribute(ua.AttributeIds.DisplayName)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return result.Value.Value

    async def read_data_type(self) -> ua.NodeId:
        """
        get data type of node as NodeId
        """
        result = await self.read_attribute(ua.AttributeIds.DataType)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return result.Value.Value

    async def read_data_type_as_variant_type(self) -> ua.VariantType:
        """
        get data type of node as VariantType
        This only works if node is a variable, otherwise type
        may not be convertible to VariantType
        """
        result = await self.read_attribute(ua.AttributeIds.DataType)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return await data_type_to_variant_type(Node(self.session, result.Value.Value))

    async def get_access_level(self) -> Set[ua.AccessLevel]:
        """
        Get the access level attribute of the node as a set of AccessLevel enum values.
        """
        result = await self.read_attribute(ua.AttributeIds.AccessLevel)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return ua.AccessLevel.parse_bitfield(result.Value.Value)

    async def get_user_access_level(self) -> Set[ua.AccessLevel]:
        """
        Get the user access level attribute of the node as a set of AccessLevel enum values.
        """
        result = await self.read_attribute(ua.AttributeIds.UserAccessLevel)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return ua.AccessLevel.parse_bitfield(result.Value.Value)

    async def read_event_notifier(self) -> Set[ua.EventNotifier]:
        """
        Get the event notifier attribute of the node as a set of EventNotifier enum values.
        """
        result = await self.read_attribute(ua.AttributeIds.EventNotifier)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return ua.EventNotifier.parse_bitfield(result.Value.Value)

    async def set_event_notifier(self, values) -> None:
        """
        Set the event notifier attribute.

        :param values: an iterable of EventNotifier enum values.
        """
        event_notifier_bitfield = ua.EventNotifier.to_bitfield(values)
        await self.write_attribute(ua.AttributeIds.EventNotifier, ua.DataValue(ua.Variant(event_notifier_bitfield, ua.VariantType.Byte)))

    async def read_node_class(self) -> ua.NodeClass:
        """
        get node class attribute of node
        """
        result = await self.read_attribute(ua.AttributeIds.NodeClass)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return ua.NodeClass(result.Value.Value)

    async def read_data_type_definition(self) -> ua.DataTypeDefinition:
        """
        read data type definition attribute of node
        only DataType nodes following spec >= 1.04 have that attribute
        """
        result = await self.read_attribute(ua.AttributeIds.DataTypeDefinition)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return result.Value.Value

    async def write_data_type_definition(self, sdef: ua.DataTypeDefinition) -> None:
        """
        write data type definition attribute of node
        only DataType nodes following spec >= 1.04 have that attribute
        """
        v = ua.Variant(sdef, ua.VariantType.ExtensionObject)
        await self.write_attribute(ua.AttributeIds.DataTypeDefinition, ua.DataValue(v))

    async def read_description(self) -> ua.LocalizedText:
        """
        get description attribute class of node
        """
        result = await self.read_attribute(ua.AttributeIds.Description)
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return result.Value.Value

    async def read_value(self) -> Any:
        """
        Get value of a node as a python type. Only variables ( and properties) have values.
        An exception will be generated for other node types.
        WARNING: on server side, this function returns a ref to object in ua database.
        Do not modify it if it is a mutable object unless you know what you are doing
        """
        result = await self.read_data_value()
        assert result.Value is not None, "Value must not be None if the result is in Good status"
        return result.Value.Value

    get_value = read_value  # legacy compatibility

    async def read_data_value(self, raise_on_bad_status: bool = True) -> ua.DataValue:
        """
        Get value of a node as a DataValue object. Only variables (and properties) have values.
        An exception will be generated for other node types.
        DataValue contain a variable value as a variant as well as server and source timestamps
        """
        return await self.read_attribute(ua.AttributeIds.Value, None, raise_on_bad_status)

    async def write_array_dimensions(self, value: int) -> None:
        """
        Set attribute ArrayDimensions of node
        make sure it has the correct data type
        """
        v = ua.Variant(value, ua.VariantType.UInt32)
        await self.write_attribute(ua.AttributeIds.ArrayDimensions, ua.DataValue(v))

    async def read_array_dimensions(self) -> int:
        """
        Read and return ArrayDimensions attribute of node
        """
        res = await self.read_attribute(ua.AttributeIds.ArrayDimensions)
        assert res.Value is not None, "Value must not be None if the result is in Good status"
        return res.Value.Value

    async def write_value_rank(self, value: int) -> None:
        """
        Set attribute ValueRank of node
        """
        v = ua.Variant(value, ua.VariantType.Int32)
        await self.write_attribute(ua.AttributeIds.ValueRank, ua.DataValue(v))

    async def read_value_rank(self) -> int:
        """
        Read and return ValueRank attribute of node
        """
        res = await self.read_attribute(ua.AttributeIds.ValueRank)
        assert res.Value is not None, "Value must not be None if the result is in Good status"
        return ua.ValueRank(res.Value.Value)

    async def write_value(self, value: Any, varianttype: Optional[ua.VariantType] = None) -> None:
        """
        Write value of a node. Only variables(properties) have values.
        An exception will be generated for other node types.
        value argument is either:
        * a python built-in type, converted to opc-ua
        optionally using the variantype argument.
        * a ua.Variant, varianttype is then ignored
        * a ua.DataValue, you then have full control over data send to server
        WARNING: On server side, ref to object is directly saved in our UA db, if this is a mutable object
        and you modify it afterward, then the object in db will be modified without any
        data change event generated
        """
        dv = value_to_datavalue(value, varianttype)
        await self.write_attribute(ua.AttributeIds.Value, dv)

    set_data_value = write_value  # legacy compatibility
    set_value = write_value  # legacy compatibility

    async def set_writable(self, writable: bool = True) -> None:
        """
        Set node as writable by clients.
        A node is always writable on server side.
        """
        if writable:
            await self.set_attr_bit(ua.AttributeIds.AccessLevel, ua.AccessLevel.CurrentWrite)
            await self.set_attr_bit(ua.AttributeIds.UserAccessLevel, ua.AccessLevel.CurrentWrite)
        else:
            await self.unset_attr_bit(ua.AttributeIds.AccessLevel, ua.AccessLevel.CurrentWrite)
            await self.unset_attr_bit(ua.AttributeIds.UserAccessLevel, ua.AccessLevel.CurrentWrite)

    async def set_attr_bit(self, attr: ua.AttributeIds, bit: int) -> None:
        dv = await self.read_attribute(attr)
        assert dv.Value is not None, "Value must not be None if the result is in Good status"
        val = ua.ua_binary.set_bit(dv.Value.Value, bit)
        await self.write_attribute(attr, ua.DataValue(ua.Variant(val, dv.Value.VariantType)))

    async def unset_attr_bit(self, attr: ua.AttributeIds, bit: int) -> None:
        dv = await self.read_attribute(attr)
        assert dv.Value is not None, "Value must not be None if the result is in Good status"
        val = ua.ua_binary.unset_bit(dv.Value.Value, bit)
        await self.write_attribute(attr, ua.DataValue(ua.Variant(val, dv.Value.VariantType)))

    async def set_read_only(self) -> None:
        """
        Set a node as read-only for clients.
        A node is always writable on server side.
        """
        return await self.set_writable(False)

    async def write_attribute(self, attributeid: ua.AttributeIds, datavalue: ua.DataValue, indexrange: Optional[str] = None) -> None:
        """
        Set an attribute of a node
        attributeid is a member of ua.AttributeIds
        datavalue is a ua.DataValue object
        indexrange is a NumericRange (a string; e.g. "1" or "1:3".
            See https://reference.opcfoundation.org/v104/Core/docs/Part4/7.22/)
        """
        attr = ua.WriteValue()
        attr.NodeId = self.nodeid
        attr.AttributeId = attributeid
        attr.Value = datavalue
        attr.IndexRange = indexrange
        params = ua.WriteParameters()
        params.NodesToWrite = [attr]
        result = await self.session.write(params)
        result[0].check()

    async def write_params(self, params: ua.WriteParameters) -> List[ua.StatusCode]:
        result = await self.session.write(params)
        return result

    async def read_attribute(self, attr: ua.AttributeIds, indexrange: Optional[str] = None, raise_on_bad_status: bool = True) -> ua.DataValue:
        """
        Read one attribute of a node
        attributeid is a member of ua.AttributeIds
        indexrange is a NumericRange (a string; e.g. "1" or "1:3".
        result code from server is checked and an exception is raised in case of error
        """
        rv = ua.ReadValueId()
        rv.NodeId = self.nodeid
        rv.AttributeId = attr
        rv.IndexRange = indexrange
        params = ua.ReadParameters()
        params.NodesToRead.append(rv)
        result = await self.session.read(params)
        if raise_on_bad_status:
            result[0].StatusCode.check()
        return result[0]

    async def read_attributes(self, attrs: Iterable[ua.AttributeIds]) -> List[ua.DataValue]:
        """
        Read several attributes of a node
        list of DataValue is returned
        """
        params = ua.ReadParameters()
        for attr in attrs:
            rv = ua.ReadValueId()
            rv.NodeId = self.nodeid
            rv.AttributeId = attr
            params.NodesToRead.append(rv)

        results = await self.session.read(params)
        return results

    async def read_params(self, params: ua.ReadParameters) -> List[ua.DataValue]:
        result = await self.session.read(params)
        return result

    async def get_children(
        self, refs: int = ua.ObjectIds.HierarchicalReferences, nodeclassmask: ua.NodeClass = ua.NodeClass.Unspecified,
    ) -> List["Node"]:
        """
        Get all children of a node. By default hierarchical references and all node classes are returned.
        Other reference types may be given:
        References = 31
        NonHierarchicalReferences = 32
        HierarchicalReferences = 33
        HasChild = 34
        Organizes = 35
        HasEventSource = 36
        HasModellingRule = 37
        HasEncoding = 38
        HasDescription = 39
        HasTypeDefinition = 40
        GeneratesEvent = 41
        Aggregates = 44
        HasSubtype = 45
        HasProperty = 46
        HasComponent = 47
        HasNotifier = 48
        HasOrderedComponent = 49
        """
        return await self.get_referenced_nodes(refs, ua.BrowseDirection.Forward, nodeclassmask)

    async def get_properties(self) -> List["Node"]:
        """
        return properties of node.
        properties are child nodes with a reference of type HasProperty and a NodeClass of Variable
        COROUTINE
        """
        return await self.get_children(refs=ua.ObjectIds.HasProperty, nodeclassmask=ua.NodeClass.Variable)

    async def get_variables(self) -> List["Node"]:
        """
        return variables of node.
        variables are child nodes with a reference of type HasComponent and a NodeClass of Variable
        """
        return await self.get_children(refs=ua.ObjectIds.HasComponent, nodeclassmask=ua.NodeClass.Variable)

    async def get_methods(self) -> List["Node"]:
        """
        return methods of node.
        methods are child nodes with a reference of type HasComponent and a NodeClass of Method
        """
        return await self.get_children(refs=ua.ObjectIds.HasComponent, nodeclassmask=ua.NodeClass.Method)

    async def get_children_descriptions(
        self,
        refs: int = ua.ObjectIds.HierarchicalReferences,
        nodeclassmask: ua.NodeClass = ua.NodeClass.Unspecified,
        includesubtypes: bool = True,
        result_mask: ua.BrowseResultMask = ua.BrowseResultMask.All
    ) -> List[ua.ReferenceDescription]:
        return await self.get_references(refs, ua.BrowseDirection.Forward, nodeclassmask, includesubtypes, result_mask)

    async def get_encoding_refs(self) -> List["Node"]:
        return await self.get_referenced_nodes(ua.ObjectIds.HasEncoding, ua.BrowseDirection.Forward)

    async def get_description_refs(self) -> List["Node"]:
        return await self.get_referenced_nodes(ua.ObjectIds.HasDescription, ua.BrowseDirection.Forward)

    async def get_references(
        self,
        refs: int = ua.ObjectIds.References,
        direction: ua.BrowseDirection = ua.BrowseDirection.Both,
        nodeclassmask: ua.NodeClass = ua.NodeClass.Unspecified,
        includesubtypes: bool = True,
        result_mask: ua.BrowseResultMask = ua.BrowseResultMask.All
    ) -> List[ua.ReferenceDescription]:
        """
        returns references of the node based on specific filter defined with:

        refs = ObjectId of the Reference
        direction = Browse direction for references
        nodeclassmask = filter nodes based on specific class
        includesubtypes = If true subtypes of the reference (ref) are also included
        result_mask = define what results information are requested
        """
        desc = ua.BrowseDescription()
        desc.BrowseDirection = direction
        desc.ReferenceTypeId = _to_nodeid(refs)
        desc.IncludeSubtypes = includesubtypes
        desc.NodeClassMask = nodeclassmask
        desc.ResultMask = result_mask
        desc.NodeId = self.nodeid
        params = ua.BrowseParameters()
        params.View.Timestamp = ua.get_win_epoch()
        params.NodesToBrowse.append(desc)
        params.RequestedMaxReferencesPerNode = 0
        results = await self.session.browse(params)
        references = await self._browse_next(results)
        return references

    async def _browse_next(self, results: Iterable[ua.BrowseResult]) -> List[ua.ReferenceDescription]:
        head = next(iter(results))
        references = head.References
        while head.ContinuationPoint:
            params = ua.BrowseNextParameters()
            params.ContinuationPoints = [head.ContinuationPoint]
            params.ReleaseContinuationPoints = False
            results = await self.session.browse_next(params)
            references.extend(head.References)
        return references

    async def get_referenced_nodes(
        self,
        refs: int = ua.ObjectIds.References,
        direction: ua.BrowseDirection = ua.BrowseDirection.Both,
        nodeclassmask: ua.NodeClass = ua.NodeClass.Unspecified,
        includesubtypes: bool = True,
    ) -> List["Node"]:
        """
        returns referenced nodes based on specific filter
        Parameters are the same as for get_references

        """
        references = await self.get_references(refs, direction, nodeclassmask, includesubtypes)
        nodes = []
        for desc in references:
            node = Node(self.session, desc.NodeId)
            nodes.append(node)
        return nodes

    async def read_type_definition(self) -> Optional[ua.NodeId]:
        """
        returns type definition of the node.
        """
        references = await self.get_references(refs=ua.ObjectIds.HasTypeDefinition, direction=ua.BrowseDirection.Forward)
        if len(references) == 0:
            return None
        return references[0].NodeId

    @overload
    async def get_path(self, max_length: int = 20, as_string: Literal[False] = False) -> List["Node"]:
        ...

    @overload
    async def get_path(self, max_length: int = 20, as_string: Literal[True] = True) -> List["str"]:
        ...

    async def get_path(self, max_length: int = 20, as_string: bool = False) -> Union[List["Node"], List[str]]:
        """
        Attempt to find path of node from root node and return it as a list of Nodes.
        There might several possible paths to a node, this function will return one
        Some nodes may be missing references, so this method may
        return an empty list
        Since address space may have circular references, a max length is specified
        """
        path = await self._get_path(max_length)
        nodes = [Node(self.session, ref.NodeId) for ref in path]
        nodes.append(self)
        if as_string:
            return [(await el.read_browse_name()).to_string() for el in nodes]
        return nodes

    async def _get_path(self, max_length: int = 20) -> List[ua.ReferenceDescription]:
        """
        Attempt to find path of node from root node and return it as a list of Nodes.
        There might several possible paths to a node, this function will return one
        Some nodes may be missing references, so this method may
        return an empty list
        Since address space may have circular references, a max length is specified

        """
        path = []
        node = self
        while True:
            refs = await node.get_references(refs=ua.ObjectIds.HierarchicalReferences, direction=ua.BrowseDirection.Inverse)
            if len(refs) > 0:
                path.insert(0, refs[0])
                node = Node(self.session, refs[0].NodeId)
                if len(path) >= (max_length - 1):
                    return path
            else:
                return path

    async def get_parent(self) -> Optional["Node"]:
        """
        returns parent of the node.
        A Node may have several parents, the first found is returned.
        This method uses reverse references, a node might be missing such a link,
        thus we will not find its parent.
        """
        refs = await self.get_references(refs=ua.ObjectIds.HierarchicalReferences, direction=ua.BrowseDirection.Inverse)
        if len(refs) > 0:
            return Node(self.session, refs[0].NodeId)
        return None

    @overload
    async def get_child(
        self, path: Union[ua.QualifiedName, str, Iterable[Union[ua.QualifiedName, str]]], return_all: Literal[False] = False
    ) -> "Node":
        ...

    @overload
    async def get_child(
        self, path: Union[ua.QualifiedName, str, Iterable[Union[ua.QualifiedName, str]]], return_all: Literal[True] = True
    ) -> List["Node"]:
        ...

    async def get_child(
        self, path: Union[ua.QualifiedName, str, Iterable[Union[ua.QualifiedName, str]]], return_all: bool = False
    ) -> Union["Node", List["Node"]]:
        """
        get a child specified by its path from this node.
        A path might be:
        * a string representing a qualified name.
        * a qualified name
        * a list of string
        * a list of qualified names
        """
        if isinstance(path, (ua.QualifiedName, str)):
            path = [path]
        rpath = self._make_relative_path(path)
        bpath = ua.BrowsePath()
        bpath.StartingNode = self.nodeid
        bpath.RelativePath = rpath
        results = await self.session.translate_browsepaths_to_nodeids([bpath])
        result = results[0]
        result.StatusCode.check()
        if return_all:
            return [Node(self.session, target.TargetId) for target in result.Targets]
        return Node(self.session, result.Targets[0].TargetId)

    async def get_children_by_path(
        self,
        paths: Iterable[Union[ua.QualifiedName, str, Iterable[Union[ua.QualifiedName, str]]]],
        raise_on_partial_error: bool = True
    ) -> List[List[Optional["Node"]]]:
        """
        get children specified by their paths from this node.
        A path might be:
        * a string representing a qualified name.
        * a qualified name
        * a list of string
        * a list of qualified names
        """
        bpaths: List[ua.BrowsePath] = []
        for path in paths:
            if isinstance(path, (ua.QualifiedName, str)):
                path = [path]
            rpath = self._make_relative_path(path)
            bpath = ua.BrowsePath()
            bpath.StartingNode = self.nodeid
            bpath.RelativePath = rpath
            bpaths.append(bpath)

        results = await self.session.translate_browsepaths_to_nodeids(bpaths)
        try:
            if raise_on_partial_error:
                for result in results:
                    result.StatusCode.check()
        except ua.UaStatusCodeError:
            codes = [result.StatusCode.value for result in results]
            raise ua.UaStatusCodeErrors(codes)
        return [
            [Node(self.session, target.TargetId) for target in result.Targets]
            if result.StatusCode.is_good() else None
            for result in results
        ]

    def _make_relative_path(self, path: Iterable[Union[ua.QualifiedName, str]]) -> ua.RelativePath:
        rpath = ua.RelativePath()
        for item in path:
            el = ua.RelativePathElement()
            el.ReferenceTypeId = ua.TwoByteNodeId(ua.ObjectIds.HierarchicalReferences)
            el.IsInverse = False
            el.IncludeSubtypes = True
            if isinstance(item, ua.QualifiedName):
                el.TargetName = item
            else:
                el.TargetName = ua.QualifiedName.from_string(item)
            rpath.Elements.append(el)
        return rpath

    async def read_raw_history(
        self,
        starttime: Optional[datetime] = None,
        endtime: Optional[datetime] = None,
        numvalues: int = 0,
        return_bounds: bool = True
    ) -> List[ua.DataValue]:
        """
        Read raw history of a node
        result code from server is checked and an exception is raised in case of error
        If numvalues is > 0 and number of events in period is > numvalues
        then result will be truncated
        """
        details = ua.ReadRawModifiedDetails()
        details.IsReadModified = False
        if starttime:
            details.StartTime = starttime
        else:
            details.StartTime = ua.get_win_epoch()
        if endtime:
            details.EndTime = endtime
        else:
            details.EndTime = ua.get_win_epoch()
        details.NumValuesPerNode = numvalues
        details.ReturnBounds = return_bounds
        history = []
        continuation_point = None
        while True:
            result = await self.history_read(details, continuation_point)
            result.StatusCode.check()
            continuation_point = result.ContinuationPoint
            history.extend(result.HistoryData.DataValues)  # type: ignore[attr-defined]
            # No more data available
            if continuation_point is None:
                break
            # No more data needed
            if numvalues > 0:
                break
        return history

    async def history_read(self, details: ua.ReadRawModifiedDetails, continuation_point: Optional[bytes] = None) -> ua.HistoryReadResult:
        """
        Read raw history of a node, low-level function
        result code from server is checked and an exception is raised in case of error
        """
        valueid = ua.HistoryReadValueId()
        valueid.NodeId = self.nodeid
        valueid.IndexRange = ''
        valueid.ContinuationPoint = continuation_point
        params = ua.HistoryReadParameters()
        params.HistoryReadDetails = details
        params.TimestampsToReturn = ua.TimestampsToReturn.Both
        params.ReleaseContinuationPoints = False
        params.NodesToRead.append(valueid)
        return (await self.session.history_read(params))[0]

    async def read_event_history(
        self,
        starttime: datetime = None,
        endtime: datetime = None,
        numvalues: int = 0,
        evtypes: Union["Node", ua.NodeId, str, int, Iterable[Union["Node", ua.NodeId, str, int]]] = ua.ObjectIds.BaseEventType
    ) -> List[Event]:
        """
        Read event history of a source node
        result code from server is checked and an exception is raised in case of error
        If numvalues is > 0 and number of events in period is > numvalues
        then result will be truncated
        """
        details = ua.ReadEventDetails()
        if starttime:
            details.StartTime = starttime
        else:
            details.StartTime = ua.get_win_epoch()
        if endtime:
            details.EndTime = endtime
        else:
            details.EndTime = ua.get_win_epoch()
        details.NumValuesPerNode = numvalues
        if isinstance(evtypes, (Node, ua.NodeId, str, int)):
            evtypes = [evtypes]
        evtype_nodes = [Node(self.session, evtype) for evtype in evtypes]
        evfilter = await get_filter_from_event_type(evtype_nodes)
        details.Filter = evfilter
        result = await self.history_read_events(details)
        result.StatusCode.check()
        event_res = []
        for res in result.HistoryData.Events:  # type: ignore[attr-defined]
            event_res.append(Event.from_event_fields(evfilter.SelectClauses, res.EventFields))
        return event_res

    async def history_read_events(self, details: Iterable[ua.ReadEventDetails]) -> ua.HistoryReadResult:
        """
        Read event history of a node, low-level function
        result code from server is checked and an exception is raised in case of error
        """
        valueid = ua.HistoryReadValueId()
        valueid.NodeId = self.nodeid
        valueid.IndexRange = ''
        params = ua.HistoryReadParameters()
        params.HistoryReadDetails = details
        params.TimestampsToReturn = ua.TimestampsToReturn.Both
        params.ReleaseContinuationPoints = False
        params.NodesToRead.append(valueid)
        return (await self.session.history_read(params))[0]

    async def delete(self, delete_references: bool = True, recursive: bool = False) -> List["Node"]:
        """
        Delete node from address space
        """
        nodes, results = await delete_nodes(self.session, [self], recursive, delete_references)
        for r in results:
            r.check()
        return nodes

    def _fill_delete_reference_item(self, rdesc: ua.ReferenceDescription, bidirectional: bool = False):
        ditem = ua.DeleteReferencesItem()
        ditem.SourceNodeId = self.nodeid
        ditem.TargetNodeId = rdesc.NodeId
        ditem.ReferenceTypeId = rdesc.ReferenceTypeId
        ditem.IsForward = rdesc.IsForward
        ditem.DeleteBidirectional = bidirectional
        return ditem

    async def delete_reference(
        self, target: Union["Node", ua.NodeId, str, int], reftype: int, forward: bool = True, bidirectional: bool = True
    ) -> None:
        """
        Delete given node's references from address space
        """
        known_refs = await self.get_references(reftype, includesubtypes=False)
        targetid = _to_nodeid(target)
        for r in known_refs:
            if r.NodeId == targetid and r.IsForward == forward:
                rdesc = r
                break
        else:
            raise ua.UaStatusCodeError(ua.StatusCodes.BadNotFound)
        ditem = self._fill_delete_reference_item(rdesc, bidirectional)
        (await self.session.delete_references([ditem]))[0].check()

    async def add_reference(
        self, target: Union["Node", ua.NodeId, str, int], reftype: int, forward: bool = True, bidirectional: bool = True,
    ) -> None:
        """
        Add reference to node
        """
        aitem = ua.AddReferencesItem()
        aitem.SourceNodeId = self.nodeid
        aitem.TargetNodeId = _to_nodeid(target)
        aitem.ReferenceTypeId = _to_nodeid(reftype)
        aitem.IsForward = forward
        params = [aitem]
        if bidirectional:
            aitem2 = ua.AddReferencesItem()
            aitem2.SourceNodeId = aitem.TargetNodeId
            aitem2.TargetNodeId = aitem.SourceNodeId
            aitem2.ReferenceTypeId = aitem.ReferenceTypeId
            aitem2.IsForward = not forward
            params.append(aitem2)
        results = await self.session.add_references(params)
        _check_results(results, len(params))

    async def set_modelling_rule(self, mandatory: bool) -> None:
        """
        Add a modelling rule reference to Node.
        When creating a new object type, its variable and child nodes will not
        be instantiated if they do not have modelling rule
        if mandatory is None, the modelling rule is removed
        """
        # remove all existing modelling rule
        rules = await self.get_references(ua.ObjectIds.HasModellingRule)
        await self.session.delete_references(list(map(self._fill_delete_reference_item, rules)))
        # add new modelling rule as requested
        if mandatory is not None:
            rule = ua.ObjectIds.ModellingRule_Mandatory if mandatory else ua.ObjectIds.ModellingRule_Optional
            await self.add_reference(rule, ua.ObjectIds.HasModellingRule, True, False)

    async def add_folder(self, nodeid: Union[ua.NodeId, str], bname: Union[ua.QualifiedName, str]) -> "Node":
        return await create_folder(self, nodeid, bname)

    async def add_object(
        self,
        nodeid: Union[ua.NodeId, str],
        bname: Union[ua.QualifiedName, str],
        objecttype: Optional[int] = None,
        instantiate_optional: bool = True,
    ) -> "Node":
        return await create_object(self, nodeid, bname, objecttype, instantiate_optional)

    async def add_variable(
        self,
        nodeid: Union[ua.NodeId, str],
        bname: Union[ua.QualifiedName, str],
        val: Any,
        varianttype: Optional[ua.VariantType] = None,
        datatype: Optional[Union[ua.NodeId, int]] = None,
    ) -> "Node":
        return await create_variable(self, nodeid, bname, val, varianttype, datatype)

    async def add_object_type(self, nodeid: Union[ua.NodeId, str], bname: Union[ua.QualifiedName, str]) -> "Node":
        return await create_object_type(self, nodeid, bname)

    async def add_variable_type(self, nodeid: Union[ua.NodeId, str], bname: Union[ua.QualifiedName, str], datatype: Union[ua.NodeId, int]) -> "Node":
        return await create_variable_type(self, nodeid, bname, datatype)

    async def add_data_type(self, nodeid: Union[ua.NodeId, str], bname: Union[ua.QualifiedName, str], description: Optional[str] = None) -> "Node":
        return await create_data_type(self, nodeid, bname, description=description)

    async def add_property(
        self,
        nodeid: Union[ua.NodeId, str],
        bname: Union[ua.QualifiedName, str],
        val: Any,
        varianttype: Optional[ua.VariantType] = None,
        datatype: Optional[Union[ua.NodeId, int]] = None,
    ) -> "Node":
        return await create_property(self, nodeid, bname, val, varianttype, datatype)

    async def add_method(self, *args) -> "Node":
        return await create_method(self, *args)

    async def add_reference_type(
        self, nodeid: Union[ua.NodeId, str], bname: Union[ua.QualifiedName, str], symmetric: bool = True, inversename: Optional[str] = None
    ) -> "Node":
        return await create_reference_type(self, nodeid, bname, symmetric, inversename)

    async def call_method(self, methodid: Union[ua.NodeId, ua.QualifiedName, str], *args) -> Any:
        return await call_method(self, methodid, *args)

    async def register(self) -> None:
        """
        Register node for faster read and write access (if supported by server)
        Rmw: This call modifies the nodeid of the node, the original nodeid is
        available as node.basenodeid
        """
        nodeid = (await self.session.register_nodes([self.nodeid]))[0]
        self.basenodeid = self.nodeid
        self.nodeid = nodeid

    async def unregister(self) -> None:
        if self.basenodeid is None:
            return
        await self.session.unregister_nodes([self.nodeid])
        self.nodeid = self.basenodeid
        self.basenodeid = None

    @staticmethod
    def new_node(session, nodeid: ua.NodeId) -> "Node":
        """
        Helper function to init nodes with out importing Node
        """
        return Node(session, nodeid)


# galerias/views.py
from django.shortcuts import render, HttpResponse, redirect
from .models import *
from .forms import *

# Create your views here

def index(request):
    context = {} # Aqui van las variables para la plantilla
    return render(request, 'index.html', context)

def ver_cuadro(request):
    cuadros = Cuadro.objects.all()

    return render(request, 'ver_cuadro.html', {"cuadros":cuadros})

def ver_galeria(request):
    galerias = Galeria.objects.all()

    return render(request, 'ver_galeria.html', {"galerias":galerias})

def crear_cuadro(request):
    if request.method == 'POST':
        form = CuadroForm(request.POST, request.FILES)

        if form.is_valid():
            form.save()
            return redirect('ver_cuadro')
    else:
        form = CuadroForm()

    return render(request, 'crear_cuadro.html', {"form":form})

def crear_galeria(request):
    if request.method == 'POST':
        form = GaleriaForm(request.POST)

        if form.is_valid():
            form.save()
            return redirect('ver_galeria')
    else:
        form = GaleriaForm()

    return render(request, 'crear_galeria.html', {"form":form})

def borrar_cuadro(request, n):
    c = Cuadro.objects.get(id=n)
    c.delete()

    return redirect('ver_cuadro')

def borrar_galeria(request, n):
    g = Galeria.objects.get(id=n)
    g.delete()

    return redirect('ver_galeria')

def modificar_cuadro(request, n):
    c = Cuadro.objects.get(id=n)
    form = CuadroForm(instance=c)

    if request.method == 'POST':
        form = CuadroForm(request.POST, request.FILES, instance=c)

        if form.is_valid():
            form.save()

            return redirect('ver_cuadro')

    return render(request, 'modificar_cuadro.html', {"form":form, "n":n})

def modificar_galeria(request, n):
    g = Galeria.objects.get(id=n)
    form = GaleriaForm(instance=g)

    if request.method == 'POST':
        form = GaleriaForm(request.POST, instance=g)

        if form.is_valid():
            form.save()

            return redirect('ver_galeria')

    return render(request, 'modificar_galeria.html', {"form":form, "n":n})


# El programa, teniendo en cuenta ciertos criterios, calcula el aumento de sueldo
# para un grupo de trabajadores. Imprime el nuevo sueldo del trabajador y la nómina
# correspondiente

nom = 0

sue = float(input("Ingrese su sueldo: $"))

while sue != -1:
	if sue < 1001:
		nsue = sue * 1.15
	else:
		nsue = sue * 1.12
	nom += nsue
	print("Su nuevo sueldo será de %.2f" %(nsue))

	sue = float(input("Ingrese el siguiente sueldo: $"))

print("La nomina es de %.2f" %(nom))


from django.http.request import QueryDict
from django.shortcuts import render, redirect, reverse, HttpResponse
from django.views import View
from crm import form
from crm import models
from utils.pagination import Pagination
from django.db.models import Q
from django.db import transaction
from django.conf import settings

# 展示客户页面  公私户
class CustomerList(View):
    # get请求页面
    def get(self, request):
        q = self.search(["name", "qq"])
        if request.path_info == reverse("list"):
            customer = models.Customer.objects.filter(q, consultant__isnull=True, )  # 显示共户的内容
        else:
            customer = models.Customer.objects.filter(q, consultant=request.user_obj)  # 展示私户的内容
        present_page = request.GET.get("page", "1")  # 当前页数
        pag = Pagination(present_page, len(customer), request.GET.copy(), 2)  # 掉用分页的方法
        # print(pag.page_num)
        return render(request, "customer/customer_list.html",
                      {"customer_obj": customer[pag.start:pag.end], "ret": pag.page_html})

    def post(self, request):
        action = request.POST.get("action")
        # print(action)
        if hasattr(self, action):
            ret = getattr(self, action)()  # 利用反射调用公司户的转换
            if ret:
                return ret
        return self.get(request)

    # 公户转私户
    def multi_apply(self):
        ids = self.request.POST.get("ids", "")
        count = models.Customer.objects.filter(consultant=self.request.user_obj).count()
        if (count + len(ids)) > settings.MAX_CUSTOMERS:  # 限制私户的客户数量
            return HttpResponse("你客户太多了 先把现在客户成单了")
        with transaction.atomic():
            # 加行级锁select_for_update
            queryset = models.Customer.objects.filter(pk__in=ids, consultant__isnull=True).select_for_update()
            if len(queryset) == len(ids):
                queryset.update(consultant=self.request.user_obj, )
            else:
                return HttpResponse("你的客户被别人抢走了")

    # 私户转公户
    def multi_pub(self):
        ids = self.request.POST.get("ids", "")
        models.Customer.objects.filter(pk__in=ids).update(consultant=None)

    # q 方法使用函数
    def search(self, field_list):
        query = self.request.GET.get("query", "")
        q = Q()
        q.connector = "OR"
        for i in field_list:
            # Q(Q(name__contains=query)|Q(qq__contains=query ))
            # q.children.append(Q(('{}__contains'.format(i),query)))
            q.children.append(Q((f"{i}__contains", query)))
        return q

# 编辑添加
def customer_change(request, edit_id=None):
    obj = models.Customer.objects.filter(pk=edit_id).first()  # 取信息的对象
    from_obj = form.AddForm(instance=obj)
    if request.method == "POST":
        from_obj = form.AddForm(request.POST, instance=obj)  # 吧POST请求交给modelform对象
        if from_obj.is_valid():
            from_obj.save()  # models 直接生成input标签
            taxt = request.GET.get("next")
            return redirect(taxt)  # 重定向到 customer_list 页面里面
    stutas = "编辑客户" if edit_id else "添加客户"  # 用三元表达式你要判断的
    return render(request, "customer/customer_edit.html", {"form_obj": from_obj, "stutas": stutas})