import math
import numpy as np
from lii3ra.ordertype import OrderType
from lii3ra.technical_indicator.average_true_range import AverageTrueRange
from lii3ra.entry_strategy.entry_strategy import EntryStrategyFactory
from lii3ra.entry_strategy.entry_strategy import EntryStrategy

class AsymmetricAgainIntroSerialFactory(EntryStrategyFactory):
    params = {
        # atr_span, atr_mult
        "default": [15, 0.5, 5, 20]
        , "3038.T": [20, 0.3, 0, 0]
    }

    def create(self, ohlcv, optimization=False):
        strategies = []
        if not optimization:
            #
            s = ohlcv.symbol
            if s in self.params:
                atr_span = self.params[s][0]
                atr_mult = self.params[s][1]
                winner_wait_period = self.params[s][2]
                loser_wait_period = self.params[s][3]
            else:
                atr_span = self.params["default"][0]
                atr_mult = self.params["default"][1]
                winner_wait_period = self.params["default"][2]
                loser_wait_period = self.params["default"][3]
            strategies.append(AsymmetricAgainIntroSerial(ohlcv
                                                         , atr_span
                                                         , atr_mult
                                                         , winner_wait_period
                                                         , loser_wait_period))
        else:
            atr_spans = [i for i in range(5, 25, 5)]
            atr_mults = [i for i in np.arange(0.3, 1.5, 0.2)]
            winner_wait_period_list = [i for i in range(0, 15, 5)]
            loser_wait_period_list = [i for i in range(0, 15, 5)]
            for atr_span in atr_spans:
                for atr_mult in atr_mults:
                    for winner_wait_period in winner_wait_period_list:
                        for loser_wait_period in loser_wait_period_list:
                            strategies.append(AsymmetricAgainIntroSerial(ohlcv
                                                                         , atr_span
                                                                         , atr_mult
                                                                         , winner_wait_period
                                                                         , loser_wait_period))
        return strategies

class AsymmetricAgainIntroSerial(EntryStrategy):
    """
    前日安値でエントリーを判定し、ATRを用いて逆指値注文する
    """

    def __init__(self
                 , ohlcv
                 , atr_span
                 , atr_mult
                 , winner_wait_period
                 , loser_wait_period
                 , order_vol_ratio=0.01):
        self.title = f"AsymmetricAgainIntroSerial[{atr_span:.0f},{atr_mult:.2f}][{winner_wait_period:.0f},{loser_wait_period:.0f}]"
        self.ohlcv = ohlcv
        self.atr = AverageTrueRange(ohlcv, atr_span)
        self.atr_mult = atr_mult
        self.winner_wait_period = winner_wait_period
        self.loser_wait_period = loser_wait_period
        self.symbol = self.ohlcv.symbol
        self.order_vol_ratio = order_vol_ratio

    def _is_indicator_valid(self, idx):
        if (
                self.atr.atr[idx] == 0
        ):
            return False
        else:
            return True

    def check_entry_long(self, idx, last_exit_idx):
        """
        前日安値が当日始値よりも安い場合は逆指値でロングのエントリー
        """
        if not self._is_valid(idx):
            return OrderType.NONE_ORDER
        if not self._is_indicator_valid(idx):
            return OrderType.NONE_ORDER
        if idx <= self.atr.atr_span:
            return OrderType.NONE_ORDER
        if len(self.position.exit_positions_profit) == 0:
            initial_trade = True
            last_exit_profit = 0
        else:
            initial_trade = False
            last_exit_profit = self.position.exit_positions_profit[-1]
        condition1 = initial_trade \
                     or (last_exit_profit > 0 and idx - last_exit_idx >= self.winner_wait_period) \
                     or (last_exit_profit <= 0 and idx - last_exit_idx >= self.loser_wait_period)
        value1 = self.ohlcv.values['open'][idx]
        value2 = self.ohlcv.values['low'][idx - 1]
        if not np.isnan(value1) and not np.isnan(value2) and (value1 >= value2 and condition1):
            return OrderType.STOP_MARKET_LONG
        else:
            return OrderType.NONE_ORDER

    def check_entry_short(self, idx, last_exit_idx):
        """
        前日安値が当日始値よりも高い場合は逆指値でショートのエントリー
        """
        if not self._is_valid(idx):
            return OrderType.NONE_ORDER
        if not self._is_indicator_valid(idx):
            return OrderType.NONE_ORDER
        if idx <= self.atr.atr_span:
            return OrderType.NONE_ORDER
        if len(self.position.exit_positions_profit) == 0:
            initial_trade = True
            last_exit_profit = 0
        else:
            initial_trade = False
            last_exit_profit = self.position.exit_positions_profit[-1]
        condition1 = initial_trade \
                     or (last_exit_profit > 0 and idx - last_exit_idx >= self.winner_wait_period) \
                     or (last_exit_profit <= 0 and idx - last_exit_idx >= self.loser_wait_period)
        value1 = self.ohlcv.values['open'][idx]
        value2 = self.ohlcv.values['low'][idx - 1]
        if np.isnan(value1) or np.isnan(value2) or (value1 >= value2 and condition1):
            return OrderType.NONE_ORDER
        else:
            # return OrderType.NONE_ORDER
            return OrderType.STOP_MARKET_SHORT

    def create_order_entry_long_stop_market_for_all_cash(self, cash, idx, last_exit_idx):
        if not self._is_valid(idx) or cash <= 0:
            return -1, -1
        price = self.create_order_entry_long_stop_market(idx, last_exit_idx)
        vol = self.get_order_vol(cash, idx, price, last_exit_idx)
        return price, vol

    def create_order_entry_short_stop_market_for_all_cash(self, cash, idx, last_exit_idx):
        if not self._is_valid(idx) or cash <= 0:
            return -1, -1
        price = self.create_order_entry_short_stop_market(idx, last_exit_idx)
        vol = self.get_order_vol(cash, idx, price, last_exit_idx)
        return price, vol * -1

    def create_order_entry_long_stop_market(self, idx, last_exit_idx):
        if not self._is_valid(idx):
            return -1
        close = self.ohlcv.values['close'][idx]
        price = math.ceil(close + self.atr_mult * self.atr.atr[idx])
        return price

    def create_order_entry_short_stop_market(self, idx, last_exit_idx):
        if not self._is_valid(idx):
            return -1
        low = self.ohlcv.values['low'][idx]
        price = math.floor(low - self.atr_mult * self.atr.atr[idx])
        return price

    def create_order_entry_long_market_for_all_cash(self, cash, idx, last_exit_idx):
        if not self._is_valid(idx) or cash <= 0:
            return -1, -1
        price = self.ohlcv.values['close'][idx]
        vol = self.get_order_vol(cash, idx, price, last_exit_idx)
        return price, vol

    def create_order_entry_short_market_for_all_cash(self, cash, idx, last_exit_idx):
        if not self._is_valid(idx) or cash <= 0:
            return -1, -1
        price = self.ohlcv.values['close'][idx]
        vol = self.get_order_vol(cash, idx, price, last_exit_idx)
        return price, vol * -1

    def get_indicators(self, idx, last_exit_idx):
        ind1 = self.ohlcv.values['close'][idx] + self.atr.atr[idx] * self.atr_mult
        ind2 = self.ohlcv.values['low'][idx] - self.atr.atr[idx] * self.atr_mult
        ind3 = self.atr.atr[idx]
        ind4 = None
        ind5 = None
        ind6 = None
        ind7 = None
        return ind1, ind2, ind3, ind4, ind5, ind6, ind7


import logging
import os
from datetime import datetime

from bson.objectid import ObjectId
from celery import shared_task as task
from celery.utils.log import get_task_logger

from products.models import Product
from utils.mongodb import mongo_db, mongo_update

logger = get_task_logger(__name__)

@task(name='jms_products_api')
def jms_import_products_api(mon_insert_id):
    import requests
    time_now = datetime.now()
    db = mongo_db()
    id_code = None
    if not mon_insert_id:
        id_code = db.product_logs.insert_one(
            {"user": None, "status": "Processing",
             "created_at": time_now, })
    response_next = None
    page = 1
    status = "done"
    while response_next or page == 1:
        response_next = None
        token = os.environ.get('3JMSTOKEN', '')
        headers = {'Authorization': "Token " + token}
        response = requests.get(
            "https://staging3jms.com/api/v1/inventory/?page=" + str(page),
            headers=headers
        )

        try:
            response_next = response.json()['next']
        except Exception as e:
            logging.exception(e)
            response_next = None
        try:
            response_result = response.json()['results']
        except Exception as e:
            logging.exception(e)
            response_result = []
            if page == 1:
                status = "error"
        page += 1
        for i in response_result:
            result = i
            try:
                Product.objects.update_or_create(
                    sku=result["vws_product_sku"],
                    defaults={
                        'name': result["name"],
                        'brand': result["brand"],
                        'weight': result["weight"],
                        'year': result["year"],
                        'price': result["price"],
                        'currency': result["currency"],
                        'bottle_size': result["bottle_size"],
                        'image_url': result["image_url"],
                        'category': result["category"],
                        'subcategory': result["subcategory"],
                        'upc': result["upc"]})
            except Exception as e:
                logging.exception(e)
                pass
    finish_time = datetime.now()
    mongo_update("product_logs",
                 {"_id": ObjectId(
                     mon_insert_id) if mon_insert_id else id_code.inserted_id},
                 {
                     "$set": {
                         "finished_at": finish_time,
                         "duration": (finish_time - time_now).total_seconds(),
                         "status": status}
                 }
                 )


import os
import subprocess
from ssr.utility.logging_extension import logger
from ssr.utility.os_extension import get_corresponding_files_in_directories
from ssr.utility.os_extension import mkdir_safely

def perform_pan_sharpening(
    pan_ifp, msi_ifp, ofp, resampling_algorithm="cubic"
):
    # https://gdal.org/programs/gdal_pansharpen.html
    # https://gis.stackexchange.com/questions/270476/pansharpening-using-gdal-tools
    #   GDAL pan sharpening algorithm = weighted Brovey algorithm

    ext = os.path.splitext(ofp)[1]
    of = ext[1:]

    call_params = ["gdal_pansharpen.py"]
    call_params += ["-of", of, "-r", resampling_algorithm]

    call_params += [pan_ifp, msi_ifp, ofp]
    logger.vinfo("call_params", call_params)
    sharp_process = subprocess.Popen(call_params)
    sharp_process.wait()

def perform_pan_sharpening_for_folder(
    pan_idp, msi_idp, odp, resampling_algorithm="cubic"
):

    # The created files are using the PAN (AND NOT THE MSI) STEM (i.e. P1BS
    # instead of M1BS) so they can directly be used to replace the original
    # PAN images
    mkdir_safely(odp)

    def get_correspondence_callback(pan_fn):
        # PAN example name: 0001_WV03_15JAN05_135727-P1BS-500497282040_01_P001.png
        # MSI example name: 0001_WV03_15JAN05_135727-M1BS-500497282040_01_P001.png

        pan_parts = pan_fn.split("-P1BS-", 1)
        msi_fn = pan_parts[0] + "-M1BS-" + pan_parts[1]
        return msi_fn

    pan_list, msi_list = get_corresponding_files_in_directories(
        pan_idp,
        msi_idp,
        get_correspondence_callback=get_correspondence_callback,
    )

    for pan_ifp, msi_ifp in zip(pan_list, msi_list):
        msi_sharpened_ofp = os.path.join(odp, os.path.basename(pan_ifp))
        perform_pan_sharpening(
            pan_ifp,
            msi_ifp,
            msi_sharpened_ofp,
            resampling_algorithm=resampling_algorithm,
        )

if __name__ == "__main__":

    # ========================= Single File =======================
    # pan_ifp = '/path/to/0001_WV03_15JAN05_135727-P1BS-500497282040_01_P001_PAN.png'
    # msi_ifp = '/path/to/0001_WV03_15JAN05_135727-M1BS-500497282040_01_P001_MSI.png'
    # ofp = 'path/to/0001_WV03_15JAN05_135727-P1BS-500497282040_01_P001_SHARPENED.png'
    #
    # perform_pan_sharpening(
    #     pan_ifp,
    #     msi_ifp,
    #     ofp,
    #     resampling_algorithm='cubic')

    # ========================= Single File =======================
    pan_idp = "/path/to/pan"
    msi_idp = "/path/to/msi"
    odp = "path/to/pansharped"

    perform_pan_sharpening_for_folder(
        pan_idp, msi_idp, odp, resampling_algorithm="cubic"
    )


"""
Write a Python program to calculate number of days between two dates. Note: try to import datetime module

Sample dates : (2014, 7, 2), (2014, 7, 11)
Expected output : 9 days
"""

from datetime import date
d1 = date(2014, 7, 2)
d2 = date(2014, 7, 11)
nums = d2 - d1
print(nums.days)


##################
# Author : Sooraj Bharadwaj
# Date: 04/13/2022
#################
# IMPORTS
import wikipedia as wk
import json
import tkinter as tk

def randomPageGenerator():

    """
    This function generates a random page from the wikipedia.
    @param: None
    @return: json object with page and page.metadata
    """

    # wikipedia random title generator
    title = wk.random(pages=1)

    # search for the page
    page = wk.page(title)

    # Get meta info about the page
    page_meta = {
        'title' : title,
        'categories' : page.categories
    }

    # Prepare return object
    ret = {
        'page' : page,
        'meta' : page_meta
    }

    return ret

def getCenterPoints(root, window_dim):
    """:
    This function returns the center points of the window
    @param: root, (window.len, window.width)
    @return: center_x, center_y
    """
    x_center = int(root.winfo_screenwidth()/2 - window_dim[0]/2)
    y_center = int(root.winfo_screenheight()/2 - window_dim[1]/2)

    return (x_center, y_center)

def displayPage(root, page_obj):
    pass

def gui(page_obj):
    root = tk.Tk()
    root.title("Random Wikipedia Page")

    # Display the page title
    title_label = tk.Label(root, text=page_obj['meta']['title'])
    title_label.pack()

    # Determine window placement (center)
    centr = getCenterPoints(root, (800, 800))

    # Create Read More button
    read_more_btn = tk.Button(
                        root,
                        text="Show this article",
                        command = displayPage(root, page_obj)
                    )

    # Display Read More button
    read_more_btn.pack(
                    side=tk.BOTTOM,
                    fill=tk.X,
                    expand=True
                )

    root.geometry(f"800x800+{centr[0]}+{centr[1]}")
    root.mainloop()


#!/usr/bin/env python

"""

Table Docstring

The Table class represents the control of the
Turing Machine as the entire functional (edge)
relation between some defined present state and
the next target state.

"""

import math
import copy
from lib.State import State
from typing import Set, List, Tuple
from lib.controls.Write import Write
from lib.Controller import Controller
from lib.controllers.Input import Input
from lib.controllers.Output import Output
from lib.controllers.table.Edge import Edge
from lib.controllers.table.Word import Word
from lib.controllers.binary_table.Bit import Bit
from lib.controllers.binary_table.BinaryTable import BinaryTable
from lib.controllers.binary_table.StateSequence import StateSequence
from lib.controllers.binary_table.ControlSequence import ControlSequence

__author__ = "Dylan Pozorski"
__project__ = "TuringMachine"
__class__ = "Table"

class Table(Controller):
	"""
	Table

	Attributes:
		entries (:obj:`Set[Edge]`): The list of mappings
			composing the finite state machine's graph.

	"""

	def __init__(self, entries: Set[Edge]):
		"""
		Table Constructor.

		:param entries: Set[Edge], The set of mappings
			composing the finite state machine's graph.

		"""

		Controller.__init__(self)
		entries = {} if entries is None else entries
		self.__entries = set()

		for entry in entries:
			self.add(edge=entry)

	def __len__(self) -> int:
		"""
		Return the number of entries that
		are in the table.

		:return: int

		"""

		return 0 if self.entries is None else len(self.entries)

	def __str__(self) -> str:
		"""
		Return the canonical string representation
		of the table object.

		:return: str

		"""

		rep = "Control Table\n"

		for entry in self.entries:
			rep += str(entry) + "\n"

		return rep

	def __repr__(self) -> str:
		"""
		Return the canonical string representation
		of the table object.

		:return: str

		"""

		return self.__str__()

	def is_empty(self) -> bool:
		"""
		Returns whether the table is empty
		of transition records.

		:return: bool

		"""

		return self.__len__() == 0

	def add(self, edge: Edge) -> None:
		"""
		Add the provided edge to the table.

		:param edge: Edge, The edge to add.
		:return: None

		:raises: ValueError If an edge is added
			that leads to an ambiguous init state.

		"""

		if edge not in self.entries:
			if edge.source.root:
				s = self.initial_state()

				if s is None or not s.root \
					or s.label == edge.source.label:
					self.__entries.add(edge)
				elif s.label != edge.source.label:
					msg = "Ambiguous Initial State."
					raise ValueError(msg)
			else:
				self.__entries.add(edge)

	def remove(self, edge: Edge) -> None:
		"""
		Remove the provided edge from the table.

		:param edge: Edge, The edge to remove.
		:return: None

		"""

		if edge is not None:
			for entry in self.entries:
				if entry == edge:
					self.entries.remove(edge)
					break

	def next(self, state: State, input: Input) -> Output:
		"""
		From the specified input, compute the transition
		action and the next graph state.

		:param state: State, The current state that
			the tape head is currently located.
		:param input: Input, The current word
			being read by the print head on the TM.
		:return: Output

		"""

		action, match = None, None

		if state is not None:
			for e in self.entries:
				if input.word == e.condition \
						and e.source == state:
					match = e.target
					action = e.action
					break
		else:
			match = self.initial_state()

		return Output(
			action=action,
			state=match,
			timestep=input.timestep
		)

	def initial_state(self) -> State:
		"""
		Return the initial state of the table's
		transition entries. If no root is specified,
		then the lowest labeled state is selected.

		:return: State

		"""

		root, lowest = None, None

		for entry in self.entries:
			if entry.source.root:
				return entry.source
			elif lowest is None or lowest.label > entry.source.label:
				lowest = entry.source

		return lowest

	def indefinite_states(self) -> List[Tuple[State, Word]]:
		"""
		Return a list of indefinite state-input pairs.
		These pairs indicate accessible states within the
		table, but ones that are not defined across all
		potential inputs/transitions.

		:return: List[Tuple[State, Word]]

		"""

		states = [s.label for s in self.states if not s.terminal]
		vocab = [w.name for w in self.vocab]
		indefinites = list()

		for s in states:
			for w in vocab:
				tmp_s = State(label=s)
				tmp_w = Word(name=w)
				e = Edge(source=tmp_s, condition=tmp_w, target=tmp_s)

				if e not in self.entries:
					indefinites.append((tmp_s, tmp_w))

		return indefinites

	def indefinite_edges(self) -> List[Edge]:
		"""
		Return a list of indefinite edges. With a dummy
		write action (writing the same value as currently)
		on the tape before transitioning to a terminal
		node.

		:return: List[Edge]

		"""

		edges, indefinites = list(), self.indefinite_states()
		labeler = max([s.label for s in self.states])

		for indef in indefinites:
			labeler += 1
			s = State(
				label=labeler,
				terminal=True,
				op_status=1
			)
			edges.append(
				Edge(
					source=indef[0],
					condition=indef[1],
					action=Write(word=indef[1]),
					target=s
				)
			)

		return edges

	def close_domain(self) -> None:
		"""
		Compute the domain's closure and add missing
		elements to the domain. This primarily deals
		with adding all of the indefinite transition
		states to the edge set and terminating them
		with failure nodes.

		:return: None

		"""

		edges = list(self.indefinite_edges())
		edges = list(self.entries) + edges
		self.__entries = set(edges)

	def rebase(self) -> None:
		"""
		Rebasing the table reassigns the state
		labels into a contiguous listing of integer
		labels.

		:return: None

		"""

		states = list()
		[states.append(e.source) for e in self.entries]
		[states.append(e.target) for e in self.entries]
		states = sorted(list(set(states)))
		rebased_edges = list()

		for edge in self.entries:
			n = copy.deepcopy(edge)
			n.source.label = states.index(n.source)
			n.target.label = states.index(n.target)
			rebased_edges.append(n)

		self.__entries = rebased_edges

	def is_binary(self) -> bool:
		"""
		Evaluate whether the current table is a
		binary table (i.e. it only has transition
		conditions and write operations over the
		binary vocabulary {0, 1}).

		:return: bool

		"""

		vocab = [w.name for w in list(self.vocab)]
		return len(vocab) == 2 and Bit.BINARY_LABEL_1 in vocab \
			and Bit.BINARY_LABEL_0 in vocab

	def to_binary(self) -> BinaryTable:
		"""
		Convert the table into a binary table
		controller.

		:return: BinaryTable

		"""

		bits = math.ceil(math.log(len(self.states), 2))
		sources, targets = list(), list()
		controls = list()

		for entry in self.entries:
			targets.append(
				StateSequence(
					identity=entry.target.to_binary(label_size=bits),
					operation=entry.action.to_binary()
				)
			)

		for entry in self.entries:
			found = False
			source = StateSequence(
				identity=entry.source.to_binary(label_size=bits),
				operation=entry.action.to_binary()  # just a placeholder
			)
			condition = entry.condition.to_binary()
			target = StateSequence(
				identity=entry.target.to_binary(label_size=bits),
				operation=entry.action.to_binary()
			)

			for node in targets:
				if node.identity == source.identity:
					found = True
					source.operation = node.operation
					controls.append(
						ControlSequence(
							source=source,
							condition=condition,
							target=target
						)
					)

			if not found and source.root:
				w = Word(name=condition.values[1].value)
				source.operation = Write(word=w).to_binary()
				controls.append(
					ControlSequence(
						source=source,
						condition=condition,
						target=target
					)
				)

		return BinaryTable(entries=set(controls))

	@property
	def entries(self) -> Set[Edge]:
		"""
		:obj:`Set[Edge]` The list of mappings
		composing the finite state machine's graph.

		Set table entries.

		"""

		return self.__entries

	@property
	def states(self) -> Set[State]:
		"""
		:obj:`Set[State]` The set of states that
		are contained within the domain and range
		of the table.

		"""

		states = set()

		for entry in self.entries:
			states.add(entry.source)
			states.add(entry.target)

		return states

	@property
	def vocab(self) -> Set[Word]:
		"""
		:obj:`Set[Word]` The vocabulary of
		words that are conditioned upon for
		transitions. This vocabulary may be
		a subset of the Tape's vocabulary, but
		only trivially so (i.e. in the case where
		the tape includes an unused vocab word).

		"""

		vocab = set()

		for entry in self.entries:
			vocab.add(entry.condition)

			if isinstance(entry.action, Write):
				vocab.add(getattr(entry.action, "word"))

		return vocab


import torch
import torch.nn as nn
import numpy as np
import math

# Embeds each token in vocab into vector space. Simple lookup table.
class TokenEmbedding(nn.Module):
    def __init__(self, vocab_size: int = 256, dim: int = 64) -> None:
        super(TokenEmbedding, self).__init__()
        self.dim = dim
        self.embedding = nn.Embedding(vocab_size, self.dim)

    def forward(self, x: torch.Tensor) -> torch.Tensor:
        return self.embedding(x) * np.sqrt(self.dim)

# Captures information about word order when passing tokens through self-attention
class PositionalEncoding(nn.Module):
    def __init__(self, emb_size: int, dropout: float, maxlen: int = 5000):
        super(PositionalEncoding, self).__init__()
        den = torch.exp(-torch.arange(0, emb_size, 2) * math.log(10000) / emb_size)
        pos = torch.arange(0, maxlen).reshape(maxlen, 1)
        pos_embedding = torch.zeros((maxlen, emb_size))
        pos_embedding[:, 0::2] = torch.sin(pos * den)
        pos_embedding[:, 1::2] = torch.cos(pos * den)
        pos_embedding = pos_embedding.unsqueeze(-2)

        self.dropout = nn.Dropout(dropout)
        self.register_buffer("pos_embedding", pos_embedding)

    def forward(self, token_embedding: torch.Tensor):
        return self.dropout(
            token_embedding + self.pos_embedding[: token_embedding.size(0), :]
        )


class BaseOp:

    def __init__(self, command, required_params, optional_params):
        self.command = command
        self.required_params = required_params
        self.optional_params = optional_params

    def check_parameters(self, parameters):
        # Check for required arguments
        required = set(self.required_params.keys())
        required_missing = required.difference(set(parameters.keys()))
        if required_missing:
            raise KeyError("MissingRequiredParameters", f"{self.command} requires parameters {list(required_missing)}")
        for param_name, param_value in parameters.items():
            if param_name in self.required_params:
                param_type = self.required_params[param_name]
            elif param_name in self.optional_params:
                param_type = self.optional_params[param_name]
            else:
                raise KeyError("BadParameter", f"{param_name} not a required or optional parameter for {self.command}")
            if not isinstance(param_value, param_type):
                raise TypeError("BadType" f"{param_value} has type {type(param_value)} not {param_type}")

    def do_op(self, df):
        return df


# https://www.acmicpc.net/problem/17299
# Solving Date: 20.03.25.

import sys
read = sys.stdin.readline

def solve(num_arr):
    # 1,000,000이 들어가기 위해서는 1이 포함되어야 한다.
    freq_arr = [0 for _ in range(1000001)]
    for index in num_arr:
        freq_arr[index] += 1
    ans_arr = [-1 for _ in range(len(num_arr))]
    stack = []
    for index, content in enumerate(num_arr):
        while stack and freq_arr[num_arr[stack[-1]]] < freq_arr[content]:
            ans_arr[stack.pop()] = content
        stack.append(index)
    return ans_arr

def main(mode=''):
    arr_num = 0
    num_arr = []
    if mode == 'f':
        file = open('baekjoon_17299_input.txt', mode='r', encoding='utf-8')
        arr_num = int(file.readline().strip())
        num_arr = file.readline().split()
    else:
        arr_num = int(read().strip())
        num_arr = read().split()
    num_arr = [int(x) for x in num_arr]
    ans_arr = solve(num_arr)
    ans_arr = [str(x) for x in ans_arr]
    print(' '.join(ans_arr))

if __name__ == '__main__':
    main()


import os

import numpy as np
import cv2

import classifier
from sklearn.model_selection import train_test_split

from modelevaluation import load_rep_images

import matplotlib.pyplot as plt

# set constants
args = {
    "images_per_category": 10000,
    "num_categories": 43,
    "testing_data_directory": "gtsrb-testing",
    "training_data_directory": "gtsrb-training",
    "epochs": 10
}

# set filenames for training and testing datasets
sm_filenames = {
    "x_train": "smx_train",
    "y_train": "smy_train",
    "x_test": "smx_test",
    "y_test": "smy_test"
}
lg_filenames = {
    "x_train": "x_train",
    "y_train": "y_train",
    "x_test": "x_test",
    "y_test": "y_test"
}
train_test_filenames = lg_filenames

# Set constants for CLAHE parameter ranges
grid_sizes = [2, 4, 8]
clip_limits = [5, 10, 20, 30, 40]
ids = ['gray', 'gray_eq', 'lab', 'lab_eq', 'orig']

TEST_SIZE = 0.20              # Allows user to modify proportion of data set

############################################################################
def load_split_save_images(
        training_dir,
        num_categories,
        images_per_category,
        tt_filenames):
    """
    Takes as input the training directory, the number of categories, number of
    images per category, and a dictionary tt_filenames specifying how to label
    the saved training/testing sets.

    This method will load the specified images from the training directory,
    then split them into training and testing sets, then save the training
    and testing sets to files in a directory called 'presplitimages' with
    filenames specified by the last input parameter.

    This method should be run ONE TIME for a specified set of models.  All models
    can then be trained and tested on the same data.
    """
    # load training data
    images, labels = load_training_data(
        training_dir,
        num_categories,
        images_per_category
    )

    # Split data into training and testing sets
    labels = tf.keras.utils.to_categorical(labels)
    x_train, x_test, y_train, y_test = train_test_split(
        np.array(images), np.array(labels), test_size=TEST_SIZE
    )

    # Save training and testing sets to files
    np.save(f"{os.path.join('presplitimages',tt_filenames['x_train'])}.npy", x_train)
    np.save(f"{os.path.join('presplitimages',tt_filenames['y_train'])}.npy", y_train)
    np.save(f"{os.path.join('presplitimages',tt_filenames['x_test'])}.npy", x_test)
    np.save(f"{os.path.join('presplitimages',tt_filenames['y_test'])}.npy", y_test)

    return x_train, x_test, y_train, y_test

def load_presplit_images(tt_filenames):
    """
    Loads a saved set of testing and training images from the directory
    'presplitimages/'.  This is so we
    can use the same training/testing sets on many models.
    """
    x_train = np.load(f"{os.path.join('presplitimages',tt_filenames['x_train'])}.npy")
    x_test = np.load(f"{os.path.join('presplitimages',tt_filenames['x_test'])}.npy")
    y_train = np.load(f"{os.path.join('presplitimages',tt_filenames['y_train'])}.npy")
    y_test = np.load(f"{os.path.join('presplitimages',tt_filenames['y_test'])}.npy")
    return x_train, x_test, y_train, y_test

def get_mod_images(x_train_orig, x_test_orig, im_type, cl = None):
    """
    Returns two lists of modified images, modified according to
    im_type (which can be 'orig', 'gray', 'gray_eq', 'lab', or 'lab_eq')
    and cl which can specify the parameters for a CLAHE filter.

    cl, if specified should have the form (grid_size, clip_limit).
    """
    x_train, x_test = [], []

    # If im_type is orig, do not modify
    if im_type == 'orig':
        return x_train_orig, x_test_orig

    # Set the filter to be applied according to im_type
    if im_type[:4] == 'gray':
        filt = cv2.COLOR_BGR2GRAY
    elif im_type[:3] == 'lab':
        filt = cv2.COLOR_BGR2LAB

    # Apply the filter
    for img in x_train_orig:
        x_train.append(cv2.cvtColor(img, filt))
    for img in x_test_orig:
        x_test.append(cv2.cvtColor(img, filt))

    # If images should be equalized, apply histogram
    # appropriately
    if im_type == "gray_eq":
        x_train = [cv2.equalizeHist(img) for img in x_train]
        x_test =  [cv2.equalizeHist(img) for img in x_test]

    if im_type == "lab_eq":
        for i in range(len(x_train)):
            lab_planes = cv2.split(x_train[i])
            lab_planes[0] = cv2.equalizeHist(lab_planes[0])
            x_train[i] = cv2.merge(lab_planes)
        for i in range(len(x_test)):
            lab_planes = cv2.split(x_test[i])
            lab_planes[0] = cv2.equalizeHist(lab_planes[0])
            x_test[i] = cv2.merge(lab_planes)

    # Convert to numpy ndarrays, then reshape if necessary
    x_train, x_test = np.array(x_train), np.array(x_test)

    # grayscale images will now have the incorrect shape
    # as ndarrays, so reshape them
    dim = len(x_train[0].shape)
    if dim == 2:
        width, height = x_train.shape[1], x_train.shape[2]
        x_train = x_train.reshape(x_train.shape[0],width, height, 1)
        x_test = x_test.reshape(x_test.shape[0],width, height, 1)

    # Return modified images, or apply CLAHE filter as appropriate
    if not cl:
        return x_train, x_test
    else:
        grid_size, clip_limit = cl[0], cl[1]
        cl_obj = cv2.createCLAHE(
            clipLimit = clip_limit,
            tileGridSize = (grid_size, grid_size)
        )
        if im_type[:4] == "gray":
            for coll in [x_train, x_test]:
                for i in range(len(coll)):
                    img = coll[i]
                    mod_img = cl_obj.apply(img)
                    mod_img = mod_img.reshape(mod_img.shape[0], mod_img.shape[1], 1)
                    coll[i] = mod_img
        elif im_type[:3] == "lab":
            for coll in [x_train, x_test]:
                for i in range(len(coll)):
                    img = coll[i]
                    lab_planes = cv2.split(img)
                    lab_planes[0] = cl_obj.apply(lab_planes[0])
                    mod_img = cv2.merge(lab_planes)
                    coll[i] = mod_img

    return x_train, x_test

def make_train_evaluate_model(
        x_train_orig,
        x_test_orig,
        y_train,
        y_test,
        im_type,
        cl = None):
    """
    Makes a model, modifies the training/testing images according to im_type, then
    trains and evaluates the model on the specified training/testing sets.

    im_type can be any of 'orig', 'gray', 'lab', 'gray_eq', 'lab_eq'

    Returns a dictionary whose keys are {'training_loss', 'training_acc',
    'testing_loss', 'testing_acc'}
    """
    ch = 1 if im_type[:4] == 'gray' else 3
    x_train, x_test = get_mod_images(x_train_orig, x_test_orig, im_type, cl)
    model = get_model(None, num_categories = args["num_categories"], channels = ch)
    model.fit(x_train, y_train, epochs = args['epochs'], verbose = 2)
    print(f"done training {im_type} model, with {cl if cl else 'no'} CLAHE filter")
    model_res = dict()
    res = model.evaluate(x_train, y_train, verbose = 0)
    model_res['training_loss'] = res[0]
    model_res['training_acc'] = res[1]
    res = model.evaluate(x_test, y_test, verbose = 0)
    model_res['testing_loss'] = res[0]
    model_res['testing_acc'] = res[1]
    return model_res

def show_hist_results(results, ids):
    """
    Shows a histogram of the results from the initial comparison of models
    trained on the same set of images, each with a different filter applied.
    The filters are {'orig', 'gray', 'gray_eq', 'lab', 'lab_eq'}
    """
    labels = ids
    tr_acc = [results[name]['training_acc'] for name in labels]
    te_acc = [results[name]['testing_acc'] for name in labels]

    x = np.arange(len(labels))
    width = 0.35

    fig, ax = plt.subplots()
    rects1 = ax.bar(x-width/2, tr_acc, width, label = "tr acc.")
    rects2 = ax.bar(x+width/2, te_acc, width, label = "te acc.")

    # Add some text for labels, title and custom x-axis tick labels, etc.
    ax.set_ylabel('Accuracy')
    ax.set_title('Accuracy by image type on training/testing sets')
    ax.set_xticks(x)
    ax.set_xticklabels([label[1:] for label in labels])
    ax.legend()

    ax.bar_label(rects1, padding=3)
    ax.bar_label(rects2, padding=3)

    fig.tight_layout()

    plt.ylim(.8, 1)

    plt.show()

def show_CLAHE_3d_bar(results, im_type, cutoff = .8):
    """
    Makes a 3d bar plot for the results of the models trained on image
    sets with CLAHE filters applied to `im_type` images.  `im_type` can
    be {gray, gray_eq, lab, lab_eq}.

    Cutoff specifies a lower cutoff for the z-axis.
    """
    fig = plt.figure(figsize=(8, 3))
    ax1 = fig.add_subplot(121, projection='3d')
    ax2 = fig.add_subplot(122, projection='3d')

    # arange x and y values
    _x = np.arange(5)
    _y = np.arange(3)
    _xx, _yy = np.meshgrid(_x, _y)
    x, y = _xx.ravel(), _yy.ravel()

    xtoCL = {a:clip for a,clip in zip(_x, clip_limits)}
    ytoGS = {b:size for b,size in zip(_y, grid_sizes)}

    top1 = [results[(im_type, ytoGS[b], xtoCL[a])]['training_acc'] - cutoff
            for a,b in zip(x,y)]
    top2 = [results[(im_type, ytoGS[b], xtoCL[a])]['testing_acc'] - cutoff
            for a,b in zip(x,y)]
    bottom = [cutoff for a in x]
    width = depth = 1

    ax1.bar3d(x, y, bottom, width, depth, top1, shade=True)
    ax1.set_title('Training Accuracy')
    ax1.set_xlabel('Clip Limit')
    ax1.set_xticks(_x)
    ax1.set_xticklabels(clip_limits)
    ax1.set_yticks(_y)
    ax1.set_yticklabels(grid_sizes)

    ax1.set_ylabel('Grid Size')
    ax1.set_zlim(cutoff,1)

    ax2.bar3d(x, y, bottom, width, depth, top2, shade=True)
    ax2.set_title('Testing Accuracy')
    ax2.set_xlabel('Clip Limit')
    ax1.set_xticks(_x)
    ax1.set_xticklabels(clip_limits)
    ax1.set_yticks(_y)
    ax1.set_yticklabels(grid_sizes)
    ax2.set_ylabel('Grid Size')
    ax2.set_zlim(cutoff,1)

    plt.show()

def compare_model_avgs(results, dim, vals):
    """
    Given an axis, `dim`, across which to compare (should be one of {'im_type',
    'clip_limit', 'grid_size'), and a list of values within that axis, this
    function returns a pair of dictionaries, one for testing results and
    another for training results.  Each of the dictionaries has `vals` as its
    keys.  The value of dict[key] for any given key is the average performance
    of all the models trained on that type of image (with various CLAHE filters).
    """
    dim_dict = {'im_type':0, 'grid_size': 1, 'clip_limit': 2}

    teres = {val: [] for val in vals}
    trres = {val: [] for val in vals}
    for key, val in results.items():
        if key[dim_dict[dim]] in vals:
            teres[key[dim_dict[dim]]].append(val['testing_acc'])
            trres[key[dim_dict[dim]]].append(val['training_acc'])
    for thing in vals:
        teres[thing] = sum(teres[thing])/len(teres[thing])
        trres[thing] = sum(trres[thing])/len(trres[thing])
    return teres, trres

############################################################################

# Load images, train_test_split them

# x_train, x_test, y_train, y_test = load_split_save_images(
#     args["training_data_directory"],
#     args["num_categories"],
#     args["images_per_category"],
#     train_test_filenames
# )

# load saved training/testing sets
# x_train_orig, x_test_orig, y_train_orig, y_test_orig = load_presplit_images(
#     train_test_filenames)
# y_train, y_test = y_train_orig, y_test_orig

# We need a bunch of models, one for each triple (clip, grid, im_type)
# For each triple, we will modify the training and testing sets
# to conform to the image type, then make and train a model, then evaluate
# the model.  Finally, we save the evaluation data to a dictionary.
# The dictionary is saved to a file.

# Make, train, and evaluate models without CLAHE filters applied
# results = dict()

# for im_type in ids:
#     print(f"model {im_type}")
#     results[im_type] = make_train_evaluate_model(
#         x_train_orig,
#         x_test_orig,
#         y_train,
#         y_test,
#         im_type
#     )

# for im_type in ids[:-1]:
#     for grid_size in grid_sizes:
#         for clip_limit in clip_limits:
#             print(f"Model {im_type} with CLAHE filter: clip = {clip_limit}, grid = {grid_size}")
#             results[(im_type, grid_size, clip_limit)] = make_train_evaluate_model(
#                 x_train_orig,
#                 x_test_orig,
#                 y_train,
#                 y_test,
#                 im_type,
#                 (grid_size, clip_limit)
#             )

# Show histogram of results for model accuracy on models without
# CLAHE filters
show_hist_results(results, ids)

# Show a 3d bar plot comparing performance of all CLAHE operators applied within a
# specified image type
show_CLAHE_3d_bar(results, 'lab_eq')
show_CLAHE_3d_bar(results, 'gray')

# Based on this analysis, the model that performs optimally does so on equalized lab images and uses a CLAHE filter with grid_size = 8 and clip_limit = 10.


#!/usr/bin/env python
import time
'''
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)

GPIO.setup(12, GPIO.OUT)

p = GPIO.PWM(12, 50)

p.start(0)
delay = 3

try:
    while True:
        p.ChangeDutyCycle(5)  # turn left towards -90 degree
        p.stop()
        time.sleep(delay) # sleep 1 second
        p.ChangeDutyCycle(7.5)  # turn neutral towards 0 degree
        time.sleep(delay) # sleep 1 second
        p.ChangeDutyCycle(10) # turn right towards +90 degree
        time.sleep(delay) # sleep 1 second
except KeyboardInterrupt:
    p.stop()
    GPIO.cleanup()

'''

'''
.=======================================================================.
| refer to http://abyz.me.uk/rpi/pigpio/python.html                     |
| This module uses the services of the C pigpio library. pigpio must be |
| running on the Pi(s) whose GPIO are to be manipulated. The normal way |
| to start pigpio is as a daemon (during system start).                 |
|                                                                       |
| This test uses SG90 servo. It has 3 pins, red is connected to 5v,     |
| brown is connected to GND, orange is connected to GPIO18              |
|                                                                       |
| pi@raspberrypi:~ $ sudo pigpiod                                       |
`======================================================================='
'''
import pigpio

pwmPin = 18
pi = pigpio.pi()    # Connect to local Pi's GPIO.
delay = 2
try:
    while True:
        pi.set_servo_pulsewidth(pwmPin, 500)    # Clockwise to the end (180 degree)
        time.sleep(delay)
        pi.set_servo_pulsewidth(pwmPin, 1500)   # The middle (90 degree)
        time.sleep(delay)
        pi.set_servo_pulsewidth(pwmPin, 2500)   # Counter-clockewise to the end (0 degree)
        time.sleep(delay)

except KeyboardInterrupt:
    pi.set_servo_pulsewidth(pwmPin,0)
    pi.stop()


import logging
import os
import re
import signal
import sys
from typing import Callable, List, TYPE_CHECKING, Union

import dill as pickle
from oletools.olevba import VBA_Parser
from oletools.thirdparty.oledump.plugin_biff import cBIFF

from symbexcel.excel_wrapper import ExcelWrapper, parse_excel_doc
from .boundsheet import Cell
from .state import State

if TYPE_CHECKING:
    pass

log = logging.getLogger(__name__)

# define useful type shortcuts
Stash = List[State]

class SimulationManager:

    def __init__(self, excel_doc=None, filename=None, com=None, nocache=None, keep_predecessors=0,
                 enable_delegations=False, default_handlers=False, check_symbolic_args=True):
        """
        :param excel_doc: The excel document that you want to analyse
        """
        if not excel_doc and ExcelWrapper.get_file_type(filename) is None:
            raise RuntimeError('The sample has an invalid filetype, aborting')

        self.excel_doc = excel_doc or parse_excel_doc(filename, com, nocache)
        self.MAX_INSNS = 1000000

        self.sha1 = self.excel_doc.sha1

        self.vba_code = ''
        self.dconn = dict()
        self.dconn_cells = list()

        self.enable_delegations = enable_delegations
        self.default_handlers = default_handlers
        self.check_symbolic_args = check_symbolic_args

        self.keep_predecessors = keep_predecessors
        self.insns_count = 0
        self.symbolic = False
        self._halt    = False
        self.error    = list()
        # create an XLM parser
        self.xlm_parser = ExcelWrapper.get_parser()

        # initialize empty stashes
        self._stashes = {
            'active': [],
            'deadended': [],
            'found': [],
            'pruned': []
        }

        sheets      = self.excel_doc.get_sheets()
        entrypoints = self.excel_doc.get_entrypoints()

        defined_names = self.excel_doc.get_defined_names()
        log.debug(f'Defined names: {defined_names}')

        _vba_run_cell_regex_str = r'Application\.Run Sheets\(\"(?P<sheet>.*?)\"\)\.Range\(\"(?P<cell>.*?)\"\)'
        _vba_run_cell_regex = re.compile(_vba_run_cell_regex_str)
        _vba_run_name_regex_str = r'Application\.Run \(\"(?P<name>.*?)\"\)'
        _vba_run_name_regex = re.compile(_vba_run_name_regex_str)
        try:
            vbaparser = VBA_Parser(filename)

            # try to parse entrypoints from VBA code
            vba_code = vbaparser.get_vba_code_all_modules()

            for i, (sheet, cell_str) in enumerate(_vba_run_cell_regex.findall(vba_code)):
                entrypoints += [(f'vba_run_cell_{i}', sheets[sheet][cell_str])]
            for i, name in enumerate(_vba_run_name_regex.findall(vba_code)):
                entrypoints += [(f'vba_run_name_{i}', defined_names[name.lower()])]

            # parse DCONN
            for excel_stream in ('Workbook', 'Book'):
                if vbaparser.ole_file.exists(excel_stream):
                    data = vbaparser.ole_file.openstream(excel_stream).read()
                    biff_plugin = cBIFF(name=[excel_stream], stream=data, options='-o DCONN -s')
                    conn = biff_plugin.Analyze()
                    if conn:
                        self.dconn[conn[-1].strip().lower()] = conn[-2]
        except:
            self.set_error('OleVBA parsing failed')

        if len(entrypoints) == 0:
            self.set_error('Entrypoint(s) not found!')
            return

        if self.dconn:
            print(f'DCONN entries: {self.dconn}')

        # Create initial states.
        for name, cell in entrypoints:
            if not isinstance(cell, Cell):
                log.warning('Skipping invalid entry point: %s %s' % (name, cell))
                continue

            log.info(f'Entry point {name}: "{cell.a1}"')
            state = State(simgr=self, curr_cell=cell, memory=sheets)
            self.active.append(state)

    def set_error(self, s):
        log.error(f'[ERROR] {s}')
        self.error += [s]

    def __getstate__(self):
        state = dict(self.__dict__)
        # del state['excel_doc']
        del state['xlm_parser']
        return state

    def __setstate__(self, state):
        self.__dict__ = state
        self.xlm_parser = ExcelWrapper.get_parser()

    @property
    def states(self) -> Union[State, None]:
        """
        :return: All the states
        """
        return sum(self._stashes.values(), [])

    @property
    def active(self) -> Stash:
        """
        :return: Active stash
        """
        return self._stashes['active']

    @property
    def deadended(self) -> Stash:
        """
        :return: Deadended stash
        """
        return self._stashes['deadended']

    @property
    def found(self) -> Stash:
        """
        :return: Found stash
        """
        return self._stashes['found']

    @property
    def one_active(self) -> Union[State, None]:
        """
        :return: First element of the active stash, or None if the stash is empty
        """
        if len(self._stashes['active']) > 0:
            return self._stashes['active'][0]
        else:
            return None

    @property
    def one_deadended(self) -> Union[State, None]:
        """
        :return: First element of the deadended stash, or None if the stash is empty
        """
        if len(self._stashes['deadended']) > 0:
            return self._stashes['deadended'][0]
        else:
            return None

    @property
    def one_found(self) -> Union[State, None]:
        """
        :return: First element of the found stash, or None if the stash is empty
        """
        if len(self._stashes['found']) > 0:
            return self._stashes['found'][0]
        else:
            return None

    def halt(self, signum, frame):
        log.error(f'[TIMEOUT] Simulation manager for {self.sha1} timed out')

        for state in self.states:
            state.halt = True
            state.error = 'TimeoutError'

        self.set_error("TIMEOUT")
        self._halt = True

    def move(self, from_stash: str, to_stash: str, filter_func: Callable[[State], bool] = lambda s: True) -> None:
        """
        Move all the states that meet the filter_func condition from from_stash to to_stash
        :param from_stash: Source stash
        :param to_stash: Destination Stash
        :param filter_func: A function that discriminates what states should be moved
        :return: None
        """
        for s in list(self._stashes[from_stash]):
            if filter_func(s):
                self._stashes[from_stash].remove(s)
                self._stashes[to_stash].append(s)

    def step(self, n: int = 1) -> None:
        """
        Perform n steps (default is 1), after each step move all the halted states to the deadended stash
        :param n: Number of steps
        :return: None
        """
        for _ in range(n):
            for state in list(self.active):
                try:
                    state.step()
                except Exception as e:
                    exc_type, exc_obj, exc_tb = sys.exc_info()
                    fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]

                    log.exception('Something went wrong during the deobfuscation.')
                    self.set_error(f'{exc_type.__name__} at {fname}:{exc_tb.tb_lineno}')
                    state.error = e.__class__

            self.move(from_stash='active', to_stash='deadended', filter_func=lambda s: s.halt or s.error)

    def run(self, find: Callable[[State], bool] = lambda s: False, checkpoint=None, timeout=0) -> None:
        """
        Run the simulation manager, until the `find` condition is met. The analysis will stop when there are no more
        active states or some states met the `find` condition (these will be moved to the found stash)
        example: simgr.run(find=lambda s: '=ALERT' in s.formula)
        :param find: Function that will be called after each step. The matching states will be moved to the found stash
        :param timeout: Max running time, in seconds
        :return: None
        """

        # handle timeout
        signal.signal(signal.SIGALRM, self.halt)
        signal.alarm(timeout)

        try:
            while len(self.active) > 0 and len(self.found) == 0 and not self._halt:
                if checkpoint and self.insns_count == checkpoint:
                    with open(f'/tmp/symbexcel.{self.sha1}.checkpoint.{checkpoint}', 'wb') as f:
                        pickle.dump(self, f)
                self.move(from_stash='active', to_stash='found', filter_func=find)

                self.step()

                self.insns_count += 1
                if self.insns_count >= self.MAX_INSNS:
                    log.error(f"Exceeded MAX_INSNS ({self.MAX_INSNS})")
                    self.set_error(f"Exceeded MAX_INSNS ({self.MAX_INSNS})")
                    self.move(from_stash='active', to_stash='pruned')
                    self._halt = True
        except Exception as e:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]

            log.exception(f'Exception while stepping the Simulation Manager')
            self.set_error(f'{exc_type.__name__} at {fname}:{exc_tb.tb_lineno}')
        finally:
            signal.alarm(0)
            if checkpoint == -1:
                with open(f'/tmp/symbexcel.{self.sha1}.checkpoint.{checkpoint}', 'wb') as f:
                    pickle.dump(self, f)

    def __str__(self) -> str:
        stashes_str = [f'{len(stash)} {stash_name}' #  {[s for s in stash]}'
                       for stash_name, stash in self._stashes.items() if len(stash)]
        errored_count = len([s for stash_name, stash in self._stashes.items() if len(stash) for s in stash if s.error])
        stashes_str += [f'({errored_count} errored)']
        return f'<SimulationManager[{self.insns_count}] with {", ".join(stashes_str)}>'

    def __repr__(self) -> str:
        return self.__str__()


import numpy as np

from arpym.tools.cpca_cov import cpca_cov
from arpym.tools.pca_cov import pca_cov
from arpym.tools.gram_schmidt import gram_schmidt

def transpose_square_root(sigma2, method='Riccati', d=None, v=None):

    n_ = sigma2.shape[0]

    if np.ndim(sigma2) < 2:
        return np.squeeze(np.sqrt(sigma2))

    method = method.lower()

    if method == 'cpca' and d is None:
        method = 'pca'

    # Step 1: Riccati
    if method == 'riccati':
        e, lam = pca_cov(sigma2)
        s = e @ np.diag(np.sqrt(lam)) @ e.T

    # Step 2: Conditional principal components
    elif method == 'cpca':
        e_d, lam_d = cpca_cov(sigma2, d)
        s = np.linalg.inv(e_d).T @ np.diag(np.sqrt(lam_d))

    # Step 3: Principal components
    elif method == 'pca':
        e, lam = pca_cov(sigma2)
        s = e @ np.diag(np.sqrt(lam))

    # Step 4: Gram-Schmidt
    elif method == 'gram-schmidt':
        if v is None:
            v = np.eye(n_)

        w = gram_schmidt(v, sigma2)
        s = np.linalg.inv(w).T

    # Step 5: Cholesky
    elif method == 'cholesky':
        s = np.linalg.cholesky(sigma2)

    return s


# pylint: disable = missing-module-docstring

from .feature_params import FeatureParams
from .split_params import SplittingParams
from .train_params import TrainingParams
from .square_transformer_params import SquareTransformerParams
from .train_pipeline_params import (
    read_training_pipeline_params,
    TrainingPipelineParamsSchema,
    TrainingPipelineParams,
)
from .predict_pipeline_params import (
    PredictPipelineParams,
    PredictPipelineParamsSchema,
    read_predict_pipeline_params
)

__all__ = [
    "FeatureParams",
    "SplittingParams",
    "TrainingPipelineParams",
    "SquareTransformerParams",
    "TrainingPipelineParamsSchema",
    "TrainingParams",
    "read_training_pipeline_params",
    "PredictPipelineParams",
    "PredictPipelineParamsSchema",
    "read_predict_pipeline_params"
]


import os
from time import sleep
import re

command0 ='adb shell ime list -s'
command1 ='adb shell settings get secure default_input_method'
command2 ='adb shell ime set com.android.inputmethod.latin/.LatinIME'
command3 ='adb shell ime set io.appium.android.ime/.UnicodeIME'

def list_IME():
    "列出系统现在所安装的所有输入法"
    os.system(command0)

def enable_LatinIME():
    "切换latin输入法为当前输入法"
    os.system(command2)

def enable_UnicodeIME():
    "#切换appium输入法为当前输入法"
    os.system(command3)

"adb封装的公共方法，原生的用法"

class AndroidDebugBridge(object): #缩短可以用as
    def calladb(self, command):
        "实现adb命令发射器,下面可以省略了adb和methods"
        cmd_res = " "
        cmd_text = "adb %s" % command
        res = os.popen(cmd_text, "r")
        while 1:
            line = res.readline()
            if not line: break
            cmd_res += line
            res.close()
        return cmd_res

    def get_PhoneMsg(self, cmdlog, deviceName):
        "获取手机信息 做报告使用"
        path = os.path.abspath(os.path.dirname(__file__))
        cmdlog = path + '\\' + cmdlog
        os.system('adb -s %s shell cat /system/build.prop > %s' % (deviceName, cmdlog))
        PhoneMsg = {}
        with open(cmdlog, "r") as fobj:
            lines = fobj.readlines()  # 一次性读多行
            for line in lines:
                line = line.split('=')  # 切割读出来的数据
                # print(line)
                if (line[0] == 'ro.build.version.release'):  # 得到系统
                    s = line[1]
                    s = s.strip('\n')
                    PhoneMsg["系统"] = s
                if (line[0] == 'ro.product.model'):  # 得到手机名字
                    s = line[1]
                    s = s.strip('\n')
                    PhoneMsg["名称"] = s
                if (line[0] == 'ro.product.brand'):  # 得到手机品牌
                    s = line[1]
                    s = s.strip('\n')
                    PhoneMsg["品牌"] = s

        if os.path.exists(cmdlog):  # 最后移除文件
            os.remove(cmdlog)
        return PhoneMsg

    def get_men_total(seld, cmdlog):
        """
        获取当前手机内存,不是应用的
        :param cmdlog:
        :return:
        """
        os.system("adb shell cat /proc/meminfo >" + cmdlog)
        men_total = ""
        with open(cmdlog, "r") as fobj:
            lines = fobj.readlines()
            for line in lines:
                line = line.split('=')
                if line[0]:
                    men_total = re.findall(r"\d+", line[0])[0]
                    break
        if os.path.exists(cmdlog):
            os.remove(cmdlog)
        return str(cmdlog(int(men_total) / 1000)) + "M"

    def attached_devices(self):
        """
        检查设备是否存在
        :return:
        """
        res = self.calladb("devices") #adb封装的
        devices = res.partition('\n')[2].replace('\n', '').split('\tdevice')
        flag = [device for device in devices if len(device) > 2]  # 大于3行代表通过
        if flag:
            print("devices exists")
            return True
        else:
            self.calladb("kill-server")
            sleep(3)
            res = self.calladb("start-server")  # 二个一起用的
            return res or False

    def get_apppix(self):
        "手机分辨率"
        res = self.calladb("shell wm size")
        return res.readline().split("Physical size:")[1]

    def get_state(self):
        """
        设备的状态有 3 钟，device , offline , unknown
        device：设备正常连接
        offline：连接出现异常，设备无响应
        unknown：没有连接设备
        :return: None
        """
        res = self.calladb("get-state")
        res = res.strip(' \t\n\r')  # 去除空格
        return res or None  # 返回结果或者无

    def _push(self, local, remote):
        """
        电脑文件推到手机里面 local代表本地 remote手机
        :param local:
        :param remote:
        :return:
        """
        res = self.calladb("push {0} {1}".format(local, remote))
        return res

    def _pull(self, remote, local):
        """
        手机啦数据到电脑里面  local代表本地 remote手机
        :param remote:
        :param local:
        :return:
        """
        res = self.calladb("pull {0} {1}".format(remote, local))
        return res

    def _open_apk(self, package, Activity):
        """
        (原生)打开指定app am start -n ｛包(package)名｝/｛包名｝.{活动(activity)名称}
        :param package:包名
        :param Activity: Activity
        :return:
        """
        res = self.calladb("shell am start -n {0}/{1}".format(package, Activity))
        check = res.partition('\n')[2].replace('\n', '').split('\t ')
        if check[0].find("Error") >= 1:
            return False
        else:
            return True

    def get_app_pid(self, package):
        """
        根据package得到进程名"
        :param package:
        :return:
        """
        string = self.calladb("shell ps | grep " + package)
        if string == '':
            return "the process doesn't exist."
        res = string.split(" ")
        return res[4]

    def get_cpu(self,devices,package):
        """
        根据手机id+包名拿到cpu
        :param devices:devicesid
        :param package:包名
        :return:
        """
        res ="adb -s"+devices+" shell dumpsys cpuinfo|grep -w"+package+":"
        get_res =os.popen(res).readlines()
        for i in get_res:
            return float(i.split()[2].split("%")[0])

    def get_mem(self,devices,package):
        """
        根据手机id+包名拿到内存
        :param devices:
        :param package:
        :return:
        """
        res = "adb -s"+devices+" shell dumpsys meminfo {0}".format(package)
        total ="TOTAL"
        get_res =os.popen(res).readlines()
        for info in get_res:
            info_sp = info.strip().split()
            for i in range(len(info_sp)):
                if info_sp[i]==total:
                    return int(info_sp[i+1])

    def get_devices(self):
        '''
        获得所有的设备名称
        :return: list
        '''
        devices = []
        import subprocess
        bstr = subprocess.check_output('adb devices', shell=True)
        # 将二进制转换为字符串
        str = bstr.decode('ascii')
        str = str.strip()
        lst = str.splitlines()
        for s in lst:
            if '\tdevice' in s:
                i = s.find('device')
                name = s[:i]
                devices.append(name.strip())
        return devices


""".vscode/settings.json file constants."""
# region .vscode/settings.json Constants
from src.constants.pylintrc import PYLINTRC_FILENAME
from src.constants.pyproject_toml import PYPROJECT_TOML_FILENAME
from src.constants.shared import REPO_NAME

VSCODE_SETTINGS_JSON_FILENAME = ".vscode/settings.json"
REPO_IGNORE_PATTERN = f"./{REPO_NAME}/**"

PYTHON_LANGUAGE_KEY = "[python]"
EDITOR_CODE_ACTIONS_ON_SAVE_KEY = "editor.codeActionsOnSave"
SOURCE_ORGANIZE_IMPORTS_KEY = "source.organizeImports"
EDITOR_DEFAULT_FORMATTER_KEY = "editor.defaultFormatter"
EDITOR_FORMAT_ON_SAVE_KEY = "editor.formatOnSave"
AUTOPEP8_ARGS_KEY = "autopep8.args"
BLACK_FORMATTER_ARGS_KEY = "black-formatter.args"
BLACK_FORMATTER_ARGS_VALUE = f"--config={PYPROJECT_TOML_FILENAME}"
FLAKE8_ARGS_KEY = "flake8.args"
FLAKE8_ARGS_RCFILE_VALUE = "--rcfile=.flake8"
ISORT_ARGS_KEY = "isort.args"
ISORT_ARGS_VALUE = f"--settings={PYPROJECT_TOML_FILENAME}"
PYLINT_ARGS_KEY = "pylint.args"
PYLINT_ARGS_RCFILE_VALUE = f"--rcfile={PYLINTRC_FILENAME}"

PYTHON_ANALYSIS_AUTO_IMPORT_COMPLETIONS_KEY = "python.analysis.autoImportCompletions"
PYTHON_ANALYSIS_AUTO_SEARCH_PATHS_KEY = "python.analysis.autoSearchPaths"
PYTHON_ANALYSIS_DIAGNOSTIC_MODE_KEY = "python.analysis.diagnosticMode"
PYTHON_ANALYSIS_EXCLUDE_KEY = "python.analysis.exclude"
PYTHON_ANALYSIS_IMPORT_FORMAT_KEY = "python.analysis.importFormat"
PYTHON_ANALYSIS_INDEXING_KEY = "python.analysis.indexing"
PYTHON_ANALYSIS_INLAY_HINTS_FUNCTION_RETURN_TYPES_KEY = "python.analysis.inlayHints.functionReturnTypes"
PYTHON_ANALYSIS_INLAY_HINTS_PYTEST_PARAMETERS_KEY = "python.analysis.inlayHints.pytestParameters"
PYTHON_ANALYSIS_INLAY_HINTS_VARIABLE_TYPES_KEY = "python.analysis.inlayHints.variableTypes"

PYTHON_ANALYSIS_PACKAGE_INDEX_DEPTHS_KEY = "python.analysis.packageIndexDepths"
DEPTH_KEY = "depth"
INCLUDE_ALL_SYMBOLS_KEY = "includeAllSymbols"
NAME_KEY = "name"
INDEX_NAMES = [
    "alembic",
    "boto3",
    "django",
    "environ",
    "httpx",
    "matplotlib",
    "moto",
    "fastapi",
    "pydantic",
    "requests",
    "rest_framework",
    "scipy",
    "sklearn",
    "sqlalchemy",
    "sqlmodel",
]
DEFAULT_DEPTH = 2

PYTHON_ANALYSIS_TYPE_CHECKING_MODE_KEY = "python.analysis.typeCheckingMode"
PYTHON_ANALYSIS_USE_LIBRARY_CODE_FOR_TYPES_KEY = "python.analysis.useLibraryCodeForTypes"

PYTHON_DEFAULT_INTERPRETER_KEY = "python.defaultInterpreterPath"
PYTHON_FORMATTING_PROVIDER_KEY = "python.formatting.provider"
PYTHON_LINTING_BANDIT_ARGS_KEY = "python.linting.banditArgs"
PYTHON_LINTING_BANDIT_ENABLED_KEY = "python.linting.banditEnabled"
PYTHON_LINTING_ENABLED_KEY = "python.linting.enabled"
PYTHON_LINTING_FLAKE8_ARGS_KEY = "python.linting.flake8Args"
PYTHON_LINTING_FLAKE8_ENABLED_KEY = "python.linting.flake8Enabled"
PYTHON_LINTING_IGNORE_PATTERNS_KEY = "python.linting.ignorePatterns"
PYTHON_LINTING_MYPY_ARGS_KEY = "python.linting.mypyArgs"
PYTHON_LINTING_MYPY_ENABLED_KEY = "python.linting.mypyEnabled"
PYTHON_LINTING_PROSPECTOR_ARGS_KEY = "python.linting.prospectorArgs"
PYTHON_LINTING_PROSPECTOR_ENABLED_KEY = "python.linting.prospectorEnabled"
PYTHON_LINTING_PYCODESTYLE_ARGS_KEY = "python.linting.pycodestyleArgs"
PYTHON_LINTING_PYCODESTYLE_ENABLED_KEY = "python.linting.pycodestyleEnabled"
PYTHON_LINTING_PYDOCSTYLE_ARGS_KEY = "python.linting.pydocstyleArgs"
PYTHON_LINTING_PYDOCSTYLE_ARGS_VALUE = f"--config=./{PYPROJECT_TOML_FILENAME}"
PYTHON_LINTING_PYDOCSTYLE_ENABLED_KEY = "python.linting.pydocstyleEnabled"
PYTHON_LINTING_PYLAMA_ARGS_KEY = "python.linting.pylamaArgs"
PYTHON_LINTING_PYLAMA_ENABLED_KEY = "python.linting.pylamaEnabled"
PYTHON_LINTING_PYLINT_ARGS_KEY = "python.linting.pylintArgs"
PYTHON_LINTING_PYLINT_ENABLED_KEY = "python.linting.pylintEnabled"
PYTHON_TESTING_PYTEST_ARGS_KEY = "python.testing.pytestArgs"
PYTHON_TESTING_PYTEST_ENABLED_KEY = "python.testing.pytestEnabled"
PYTHON_TESTING_UNITTEST_ARGS_KEY = "python.testing.unittestArgs"
PYTHON_TESTING_UNITTEST_ENABLED_KEY = "python.testing.unittestEnabled"
SEARCH_EXCLUDE_KEY = "search.exclude"

SAMPLE_VSCODE_SETTINGS = {
    PYTHON_LANGUAGE_KEY: {
        EDITOR_CODE_ACTIONS_ON_SAVE_KEY: {SOURCE_ORGANIZE_IMPORTS_KEY: True},
        EDITOR_DEFAULT_FORMATTER_KEY: "<python_formatter>",
        EDITOR_FORMAT_ON_SAVE_KEY: True,
    },
    AUTOPEP8_ARGS_KEY: [],
    BLACK_FORMATTER_ARGS_KEY: [BLACK_FORMATTER_ARGS_VALUE],
    FLAKE8_ARGS_KEY: [FLAKE8_ARGS_RCFILE_VALUE],
    ISORT_ARGS_KEY: [ISORT_ARGS_VALUE],
    PYLINT_ARGS_KEY: [PYLINT_ARGS_RCFILE_VALUE],
    PYTHON_ANALYSIS_AUTO_IMPORT_COMPLETIONS_KEY: True,
    PYTHON_ANALYSIS_AUTO_SEARCH_PATHS_KEY: True,
    PYTHON_ANALYSIS_DIAGNOSTIC_MODE_KEY: "workspace",
    PYTHON_ANALYSIS_EXCLUDE_KEY: ["**/node_modules", "**/__pycache__", ".git", REPO_IGNORE_PATTERN],
    PYTHON_ANALYSIS_IMPORT_FORMAT_KEY: "absolute",
    PYTHON_ANALYSIS_INDEXING_KEY: True,
    PYTHON_ANALYSIS_INLAY_HINTS_FUNCTION_RETURN_TYPES_KEY: True,
    PYTHON_ANALYSIS_INLAY_HINTS_PYTEST_PARAMETERS_KEY: True,
    PYTHON_ANALYSIS_INLAY_HINTS_VARIABLE_TYPES_KEY: True,
    PYTHON_ANALYSIS_TYPE_CHECKING_MODE_KEY: "basic",
    PYTHON_ANALYSIS_USE_LIBRARY_CODE_FOR_TYPES_KEY: True,
    PYTHON_DEFAULT_INTERPRETER_KEY: "~/.venvs/<project>/bin/python",
    PYTHON_FORMATTING_PROVIDER_KEY: "none",
    PYTHON_LINTING_BANDIT_ARGS_KEY: [],
    PYTHON_LINTING_BANDIT_ENABLED_KEY: False,
    PYTHON_LINTING_ENABLED_KEY: False,
    PYTHON_LINTING_FLAKE8_ARGS_KEY: [FLAKE8_ARGS_RCFILE_VALUE],
    PYTHON_LINTING_FLAKE8_ENABLED_KEY: False,
    PYTHON_LINTING_IGNORE_PATTERNS_KEY: [
        ".vscode/*.py",
        "**/site-packages/**/*.py",
        REPO_IGNORE_PATTERN,
    ],
    PYTHON_LINTING_MYPY_ARGS_KEY: ["--ignore-missing-imports", "--follow-imports=silent"],
    PYTHON_LINTING_MYPY_ENABLED_KEY: False,
    PYTHON_LINTING_PROSPECTOR_ARGS_KEY: [],
    PYTHON_LINTING_PROSPECTOR_ENABLED_KEY: False,
    PYTHON_LINTING_PYCODESTYLE_ARGS_KEY: [],
    PYTHON_LINTING_PYCODESTYLE_ENABLED_KEY: False,
    PYTHON_LINTING_PYDOCSTYLE_ARGS_KEY: [PYTHON_LINTING_PYDOCSTYLE_ARGS_VALUE],
    PYTHON_LINTING_PYDOCSTYLE_ENABLED_KEY: False,
    PYTHON_LINTING_PYLAMA_ARGS_KEY: [],
    PYTHON_LINTING_PYLAMA_ENABLED_KEY: False,
    PYTHON_LINTING_PYLINT_ARGS_KEY: [PYLINT_ARGS_RCFILE_VALUE],
    PYTHON_LINTING_PYLINT_ENABLED_KEY: False,
    PYTHON_TESTING_PYTEST_ARGS_KEY: [f"--ignore={REPO_IGNORE_PATTERN}"],
    PYTHON_TESTING_PYTEST_ENABLED_KEY: False,
    PYTHON_TESTING_UNITTEST_ARGS_KEY: ["-v", "-s", ".", "-p", "*test*.py"],
    PYTHON_TESTING_UNITTEST_ENABLED_KEY: False,
    SEARCH_EXCLUDE_KEY: {
        "**/.git/**": True,
        "**/node_modules/**": True,
        "**/__pycache__/**": True,
        ".coverage": True,
        ".pytest_cache/**": True,
        "htmlcov/**": True,
        "poetry.lock": True,
        f"{REPO_NAME}/**": True,
    },
}

# endregion


class TreeNode:
    def __init__(self, data, leftChild = None, rightChild = None) -> None:
        self.data = data
        self.leftChild = leftChild
        self.rightChild = rightChild

class BinarySearchTree:
    rootNode: TreeNode

    def __init__(self, node: TreeNode = None) -> None:
        self.rootNode = node

    #search for a node
    def search(self, data, node: TreeNode = None, searchFromRoot = True):
        #setup search from root
        if searchFromRoot:
            currentNode = self.rootNode
        else:
            currentNode = node

        #base case
        if currentNode is None or currentNode.data == data:
            return currentNode

        if data < currentNode.data:
            return self.search(data, currentNode.leftChild, False)
        elif data > currentNode.data:
            return self.search(data, currentNode.rightChild, False)

    #insert nodes
    def insert(self, data, node: TreeNode = None, searchFromRoot = True):
        #setup search from root
        if searchFromRoot:
            currentNode = self.rootNode
        else:
            currentNode = node

        #for inserting into an empty BST
        if self.rootNode is None:
            self.rootNode = TreeNode(data)
            return True

        #for inserting into an existing BST
        if data <= currentNode.data:
            if currentNode.leftChild is None:
                currentNode.leftChild = TreeNode(data)
            else:
                self.insert(data, currentNode.leftChild, False)
        else:
            if currentNode.rightChild is None:
                currentNode.rightChild = TreeNode(data)
            else:
                self.insert(data, currentNode.rightChild, False)

        return True

#Test
#node_1 = TreeNode(10)
#node_2 = TreeNode(40)
#node_3 = TreeNode(20, node_1,node_2)

tree = BinarySearchTree()
tree.insert(20)
tree.insert(40)
tree.insert(10)

findNode: TreeNode = tree.search(40)
print(findNode.data if findNode else None)


# This file is part of PAINTicle.
#
# PAINTicle is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PAINTicle is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PAINTicle.  If not, see <http://www.gnu.org/licenses/>.

# The particle painter, that's using the gpu directly

# <pep8 compliant>

from . import simulationstep

from .. import numpyutils

from bpy.props import FloatProperty
import numpy as np

class FrictionStep(simulationstep.SimulationStep):

    friction_coefficient: FloatProperty(name="Friction",
                                        description="The friction coefficient (how sticky is the surface).",
                                        min=0.0, soft_max=0.1, default=0.01, options=set())

    def simulate(self, sim_data: simulationstep.SimulationData, particles: simulationstep.ParticleData,
                 forces: simulationstep.Forces, new_particles: simulationstep.ParticleData):
        # Friction calculation
        # Project forces onto normal vector
        # We don't need to divide by the square length of normal, since this is a normalized vector.
        unormal = numpyutils.unstructured(particles.normal)
        factor = numpyutils.vec_dot(unormal, forces)
        ortho_force = unormal * factor[:, np.newaxis]
        # The force on the plane is then just simple vector subtraction
        plane_force = forces - ortho_force
        # factor is the inverse of what we need here, since the normal is pointing to the outside of the surface,
        # but friction only applies if force is applied towards the surface. Hence we use (1+x) instead of (1-x)
        friction = np.clip(1+self.friction_coefficient*factor/numpyutils.vec_length(plane_force), 0, 1)
        return plane_force * friction[:, np.newaxis]


import numpy as np
from enum import Enum

from udacidrone import Drone
import time
visdom_available= True
try:
    import visdom
except:
    visdom_available = False

class PlaneMode(Enum):
    """
    Constant which isn't defined in Mavlink but useful when dealing with
    the airplane simulation
    """
    SUB_MODE_MANUAL = 1
    SUB_MODE_LONGITUDE = 2
    SUB_MODE_LATERAL = 3
    SUB_MODE_STABILIZED = 4
    SUB_MODE_VTOL_ATTITUDE = 9
    SUB_MODE_VTOL_POSITION = 10

class Udaciplane(Drone):
    """
    Udaciplane class for use with the Unity Fixed Wing/Flying Car simulation
    """

    def __init__(self, connection, tlog_name="TLog.txt"):

        super().__init__(connection, tlog_name)

    def cmd_stabilized(self, roll, altitude, sideslip, airspeed):
        """Command the stabilized mode of the drone

        Args:
            roll: in radians
            altitude: in meters (positive up)
            sideslip: in radians (positive nose left)
            airspeed: in meters/sec

        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_STABILIZED.value)
        self.connection.cmd_moment(roll, altitude, sideslip, airspeed)

    def cmd_longitude_mode(self, elevator, throttle, roll = 0, sideslip = 0,
                           t=0):
        """Command the longitude mode while lateral is stabilized

        Args:
            elevator: in percentage of maximum elevator (-1:1)
            throttle: in percentage of maximum throttle RPM (0:1)
            roll: in radians
            sideslip: in radians (positive nose left)
        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_LONGITUDE.value)
        self.connection.cmd_moment(roll, elevator, sideslip, throttle, t)

    def cmd_lateral_mode(self, aileron, rudder, altitude, airspeed):
        """Command the lateral mode while longitudinal mode is stabilized

        Args:
            aileron: in percentage of maximum aileron (-1:1)
            rudder: in percentage of maximum rudder (-1:1)
            altitude: in meters (positive up)
            airspeed: in meters/sec
        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_LATERAL.value)
        self.connection.cmd_moment(aileron, altitude, rudder, airspeed)

    def cmd_controls(self, aileron, elevator, rudder, throttle):
        """Command the manual aircraft controls

        Args:
            aileron: in percentage of maximum aileron (-1:1)
            rudder: in percentage of maximum rudder (-1:1)
            elevator: in percentage of maximum elevator (-1:1)
            throttle: in percentage of maximum throttle RPM (0:1)
        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_MANUAL.value)
        controls = [aileron, elevator, rudder, throttle]
        self.connection.cmd_controls(controls)

    def cmd_hybrid(self, aileron, elevator, rudder, throttle, roll_moment, pitch_moment, yaw_moment, thrust):
        """Command the manual aircraft controls, the VTOL moments and total thrust force

        Args:
            aileron: in percentage of maximum aileron (-1:1)
            rudder: in percentage of maximum rudder (-1:1)
            elevator: in percentage of maximum elevator (-1:1)
            throttle: in percentage of maximum throttle RPM (0:1)
            roll_moment: in percentage of maximum roll moment (-1:1)
            pitch_moment: in percentage of maximum pitch moment (-1:1)
            yaw_moment: in percentage of maximum yaw_moment (-1:1)
            thrust: in percentage of maximum thrust (0:1)
        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_MANUAL.value)
        controls = [aileron, elevator, rudder, throttle, roll_moment, pitch_moment, yaw_moment , thrust]
        self.connection.cmd_controls(controls)

    def cmd_moment(self, roll_moment, pitch_moment, yaw_moment, thrust):
        """Command the VTOL moments and total thrust force

        Args:
            roll_moment: in percentage of maximum roll moment (-1:1)
            pitch_moment: in percentage of maximum pitch moment (-1:1)
            yaw_moment: in percentage of maximum yaw_moment (-1:1)
            thrust: in percentage of maximum thrust (0:1)
        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_MANUAL.value)
        controls = [0.0, 0.0, 0.0, 0.0, roll_moment, pitch_moment, yaw_moment, thrust]
        self.connection.cmd_controls(controls)

    def cmd_vtol_position(self, north, east, altitude, heading):
        """Command the local position and drone heading.

        Args:
            north: local north in meters
            east: local east in meters
            altitude: altitude above ground in meters
            heading: drone yaw in radians
        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_VTOL_POSITION.value)
        self.cmd_position(north, east, altitude, heading)

    def cmd_vtol_attitude(self,roll, pitch, yaw_rate, vert_vel):
        """Command the drone through attitude command

        Args:
            roll: in radians
            pitch: in randians
            yaw_rate: in radians/second
            vert_vel: upward velocity in meters/second
        """
        self.connection.set_sub_mode(PlaneMode.SUB_MODE_VTOL_ATTITUDE.value)
        self.cmd_attitude(roll, pitch, yaw_rate, vert_vel)


states = {}
state = '.'
checksum = 0
tape = {}

def parseFile(content):
    global states, state, checksum
    content = content.split('\n\n')
    state = content[0][15]
    checksum = int(content[0].split()[9])

    for s in content[1:]:
        part = s.split(':')
        instructionsZero = part[2].split('-')
        ifZero = {}
        ifZero['nextValue'] = instructionsZero[1][17]
        ifZero['move'] = 'right' if instructionsZero[2][22] == 'r' else 'left'
        ifZero['nextState'] = instructionsZero[3][21]

        instructionsOne = part[3].split('-')
        ifOne = {}
        ifOne['nextValue'] = instructionsOne[1][17]
        ifOne['move'] = 'right' if instructionsOne[2][22] == 'r' else 'left'
        ifOne['nextState'] = instructionsOne[3][21]

        states[s[9]] = {'0': ifZero, '1': ifOne}

def day25(checksum, state, states, tape):
    cursor = 0
    print(states)
    for step in range(checksum):
        # On initialise à 0 s'il n'existe pas actuellement dans la bande
        if str(cursor) not in tape.keys():
            tape[str(cursor)] = '0'
        print('Step ' + str(step))
        # print("State : " + state)
        # print('Cursor = ' + str(cursor))
        # print('Value = ' + tape[str(cursor)])
        # print(tape)
        last = cursor
        cursor = cursor - 1 if states[state][tape[str(cursor)]]['move'] == 'left' else cursor + 1
        lastState = state
        state = states[state][tape[str(last)]]['nextState']
        tape[str(last)] = states[lastState][tape[str(last)]]['nextValue']

    total = 0
    for val in tape.values():
        if val == '1':
            total += 1

    return total

if __name__ == "__main__":
    with open('input.txt', 'r') as f:
        content = f.read()

    parseFile(content)

    print("Le résultat est " + str(day25(checksum, state, states, tape)))


#!/usr/bin/env python3
"""
Base64 encode an image and output the element based on the specified format.

Usage:
    Base64_encode.py [options] [image]
"""

import argparse
import base64
import sys
import tempfile
from urllib.parse import urlparse

import requests

parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("image", nargs="?", help="URL, or path to image file")
parser.add_argument("--html", action="store_true", help="output HTML")
parser.add_argument("--markdown", action="store_true", help="output Markdown")
parser.add_argument("--json", action="store_true", help="output JSON")
args = parser.parse_args()

image_formats = {
    "png": "image/png",
    "jpg": "image/jpeg",
    "jpeg": "image/jpeg",
    "gif": "image/gif",
    "svg": "image/svg+xml",
}

# if the image is a URL, validate and download it to a temporary file
def download_image(image):
    """Download the image to a temporary file."""
    # Parse the URL and remove trailing slashes
    url = urlparse(image)
    url = url._replace(path=url.path.rstrip("/"))

    # Recreate the URL string from the parsed URL object
    image = url.geturl()

    if url.scheme in ["http", "https"]:
        response = requests.get(image, stream=True, timeout=5)
        response.raise_for_status()

        # Extract image format from the URL
        image_format = get_image_format(image)
        if image_format not in image_formats:
            print(f"Error: The format '{image_format}' is not supported.")
            return None, None

        # Create a temporary file and write the image to the temporary file
        with tempfile.NamedTemporaryFile(delete=False) as temp_file:
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:  # Filter out keep-alive new chunks
                    temp_file.write(chunk)
            temp_file_path = temp_file.name  # Get the path of the temporary file

        return temp_file_path, image_format

    # If not an image, return the original path and the format
    image_format = get_image_format(image)
    if image_format not in image_formats:
        print(f"Error: The format '{image_format}' is not supported.")
        return None, None
    return image, image_format

def get_image_format(path):
    """Get the image format from the file extension."""
    path = urlparse(path).path  # Extract the path from the URL
    filename = path.split("/")[-1]  # Get the filename from the URL path
    return filename.split(".")[-1].lower()

def get_image_data_url(image_data, mime_type):
    """Get the image data URL."""
    # mime_type = image_formats[image_format]
    encoded_string = base64.b64encode(image_data).decode("utf-8")
    data_url = f"data:{mime_type};base64,{encoded_string}"
    return data_url

def output_html(img_element):
    """Output the HTML."""
    return f'<img src="{img_element}">'

def output_markdown(img_element):
    """Output the Markdown."""
    return f"![image]({img_element})"

def output_json(img_element):
    """Output the JSON."""
    return f'{{"image": "{img_element}"}}'

def main():
    """Read from a file or stdin and output the encoded string."""
    if args.image:
        try:
            image_path, image_format = download_image(args.image)
            with open(image_path, "rb") as image:
                image_data = image.read()
                mime_type = image_formats[image_format]
        except FileNotFoundError:
            print(f"Error: The file '{args.image}' was not found.")
            return
        except PermissionError:
            print(
                f"Error: Permission denied when trying to open the file '{args.image}'."
            )
            return
    else:
        image_data = sys.stdin.buffer.read()
        mime_type = "image/png"
    data_url = get_image_data_url(image_data, mime_type)
    if args.html:
        print(output_html(data_url))
    elif args.markdown:
        print(output_markdown(data_url))
    elif args.json:
        print(output_json(data_url))
    else:
        print("No output format specified. Use --html, --markdown, or --json.")

if __name__ == "__main__":
    main()


class Solution(object):
	"""docstring for Solution"""
	def isPalindrome(self, x):

		string = str(x)

		n = len(string)

		beginning = 0
		ending = n - 1

		while beginning < ending:

			if string[beginning] != string[ending]:
				return False

			beginning += 1
			ending -= 1

		return True

solution = Solution()
result = solution.isPalindrome(123454321)
print(result)


r = 1
while r == 1:
    cadena = input("Digite la cadena a reducir: ")
    lon = len(cadena)
    i = 0

    if cadena.isalpha() and cadena.islower():
        while True:

            lon1 = len(cadena)
            for i in range(len(cadena)):
                if i < (len(cadena)-1):
                    if cadena[i] == cadena[i+1]:
                        cadena = cadena[0:i] + cadena[i+2:len(cadena)+1]
                    lon2 = len(cadena)
                    lon = len(cadena)
                    i += 1
                    print(f"cadena: {cadena}\nlongitud1: {lon1}  longitud2: {lon2}")
                if lon1 != lon2:
                    i = lon1
            lon2 = len(cadena)
            print(f"cadena: {cadena}\nlongitud1: {lon1}  longitud2: {lon2}")
            if lon1 == lon2:
                break
        if cadena == "":
            print(f"Empty string")
        print(f"{cadena}")
    r = int(input("Desea seguir con otra cadena (si=1 ; no=0)?:"))

códigos clases/mios/cadena de strings/reduccion_cadena.py


#!/usr/bin/env python

__author__ = 'danielcarlin'
import pandas
import scipy.stats
import numpy.random
from optparse import OptionParser
from theano_maskedRBM import makeMatricesAgree
import operator
from math import fabs

def corr_matrices(data_in,rbm_out,spearman=True):
    """Take two matrices and return the correlation of their corresponding columns. Defaults to Spearman."""
    entities_x=list(data_in.columns.values)[1:]
    sample_names=list(data_in[data_in.columns[0]])

    entities_out=list(rbm_out.columns.values)[1:]
    out_names=list(rbm_out[rbm_out.columns[0]])

    [m1,m2,entities_agree]=makeMatricesAgree(rbm_out,entities_out,data_in,entities_x)

    spr={}
    null_model={}

    for i in xrange(m1.shape[1]):
        if spearman:
            spr[i]=scipy.stats.spearmanr(m1[:,i],m2[:,i])
            null_model[i]=scipy.stats.spearmanr(m1[:,i],m2[:,numpy.random.randint(low=0,high=m2.shape[1])])
        else:
            spr[i]=scipy.stats.pearsonr(m1[:,i],m2[:,i])
            null_model[i]=scipy.stats.pearsonr(m1[:,i],m2[:,numpy.random.randint(low=0,high=m2.shape[1])])

    return spr,entities_agree, null_model

def write_regulators_table(rbm_w,table_file='targets_table.txt',giveN=5):
    """Outputs a table of top N targets for each TF"""

    fh=open(table_file,'w')

    for tf in list(rbm_w.columns.values)[1:]:
        targets=list(rbm_w.loc[rbm_w[tf] !=0][rbm_w.columns[0]])
        weights=list(rbm_w.loc[rbm_w[tf] !=0][tf])
        to_sort=zip(targets,weights)
        sorted_values = sorted(to_sort, key=lambda target:fabs(target[1]),reverse=True)
        sorted_targets=[l[0] for l in sorted_values[0:giveN]]
        sorted_weights=[str(l[1]) for l in sorted_values[0:giveN]]
        fh.write(tf+'\t'+','.join(sorted_targets)+'\t'+','.join(sorted_weights)+'\n')

if __name__ == '__main__':
    parser = OptionParser()
    parser.add_option("-d", "--data", dest="train_data_file", action="store", type="string", default='/Users/danielcarlin/projects/regulator_RBM/test_data/all_data.tab',
                      help="File containining a samples (rows) by genes (columns), tab delimited data")
    parser.add_option('-r', "--rbm-output", dest="rbm_output_file", action="store", type="string", default='output.txt',help ="output file of hidden layer probabilities")
    parser.add_option('-w',"--rbm-weights",dest="rbm_weights_file",action="store",type="string",default=None,help="weights composing the hidden layer ofr the RBM")
    parser.add_option('-c', "--correlation-file", dest="corr_file", action='store', type='string', default=None, help="file for correlation between expression and regulon")
    parser.add_option('-n', "--null-model", dest="null_file", action='store', type='string', default=None, help="file for null model output")
    parser.add_option('-p', "--pearson", dest="pearson", action='store_true', default=False, help="Pearson rather than Spearman correlation")
    parser.add_option('-t','--target-table', dest="target_table",default=None, help="table for learned targets")

    (opts, args) = parser.parse_args()

    data_in = pandas.read_table(opts.train_data_file)
    rbm_out = pandas.read_table(opts.rbm_output_file)

    if opts.pearson:
        spr,ent,nm=corr_matrices(data_in,rbm_out,spearman=False)
    else:
        spr,ent,nm=corr_matrices(data_in,rbm_out)

    fh=open(opts.corr_file,'w')

    for k in spr.keys():
        fh.write(ent[k]+'\t'+str(spr[k][0])+'\t'+str(spr[k][1])+'\n')

    fh.close()

    fh2=open(opts.null_file,'w')

    for k in spr.keys():
        fh2.write(ent[k]+'\t'+str(nm[k][0])+'\t'+str(nm[k][1])+'\n')

    fh2.close()

    if opts.target_table is not None:
        rbm_w = pandas.read_table(opts.rbm_weights_file)
        write_regulators_table(rbm_w,table_file=opts.target_table,giveN=5)


import asyncio
import sys

from room import ChatRoom

def main(argv):
    name = argv[1] if len(argv) >= 2 else "AChat"
    port = int(argv[2]) if len(argv) >= 3 else 9999

    loop = asyncio.get_event_loop()
    chat_room = ChatRoom(name, port, loop)
    server = chat_room.run()

    loop.run_forever()

if __name__ == '__main__':
    main(sys.argv)