import numpy as np

"""awsConnections.py: Models aws connections in app stream 2.0 for aws project.
					Incorporates connection time, streaming time, disconnecting time.
					Details of a particular connection are stored in seconds in each instance.
					Output is generic aggregate statistics."""

__author__ = "Joaquin Casaubon"

######## Variables ########
# number of hours to run model
hours_model_runs = 1
# number of instances
aws_instances = 4000
# aws cost per hour
aws_one_instance_cost_per_hour = 1.00
# connecting
mean_connection_time = 8 # seconds on average to connect
sigma_connection_time = 2 # seconds of standard deviation
min_connection_time = 5 # seconds minimum for a connection
max_connection_time = 15 # seconds maximum for a connection
# streaming
mean_streaming_time = 300 # seconds on average to stream
sigma_streaming_time = 100 # seconds of standard deviation
min_streaming_time = 20 # seconds minimum for an entire stream session
max_streaming_time = 800 # seconds maximum for an entire stream session
# disconnection, cleanup, back into pool
mean_disconnection_time = 60 # seconds on average to disconnect, cleanup, back in pool
sigma_disconnection_time = 10 # seconds of standard deviation
min_disconnection_time = 5 # seconds minimum for a disconnect, cleanup, back in pool
max_disconnection_time = 70 # seconds maximum for a disconnect, cleanup, back in pool
###########################

######## Global Vars ########
seconds_in_experiment = hours_model_runs * 3600
#############################

# Models behavior of one aws instance
class AwsInstance:
	READY_STATE = 0 # Ready with no connections
	CONNECTED_STATE = 1 # Getting connection
	STREAMING_STATE = 2 # Connected and Streaming
	DISCONNECT_CLEANUP_STATE = 3 # Disconnected placing back into pool

	# initial state of Instance when turned on
	def __init__(self, input_id_num):
		self.id_num = input_id_num
		self.current_state_of_instance = 0
		self.history_of_time = np.zeros((seconds_in_experiment,), dtype=int)
		self.position_in_time = 0
		self.number_of_connections = 0

	# when called gets a connection for the user if it is available
	def get_connection_stream_and_disconnect(self, global_clock):
		# if instance is blocked running an operation a get isn't possible
		if(global_clock < self.position_in_time):
			return
		# can only get a connection if state at time is 0
		if(self.history_of_time[global_clock] != 0):
			return
		# calculation connection time
		connection_time_amount = self.getting_a_random_normal(mean_connection_time,
			sigma_connection_time, min_connection_time, max_connection_time)
		self.set_history_values(connection_time_amount, self.CONNECTED_STATE)

		# getting here is an increase in the number of connections to instance
		self.number_of_connections += 1

		# calculation streaming time
		streaming_time_amount = self.getting_a_random_normal(mean_streaming_time,
			sigma_streaming_time, min_streaming_time, max_streaming_time)
		self.set_history_values(streaming_time_amount, self.STREAMING_STATE)

		# calculation disconnection/cleanup and back into pool time
		disconnection_cleanup_back_in_pool_time_amount = self.getting_a_random_normal(
			mean_disconnection_time, sigma_disconnection_time,
			min_disconnection_time, max_disconnection_time)
		self.set_history_values(streaming_time_amount, self.DISCONNECT_CLEANUP_STATE)

	# set history values with the input states
	def set_history_values(self, number_of_seconds_to_update, state_value):
		for second in range(number_of_seconds_to_update):
			# check if experiment endtime passed
			if self.position_in_time + second >= seconds_in_experiment:
				self.position_in_time += number_of_seconds_to_update
				return
			position_in_history = self.position_in_time + second
			self.history_of_time[position_in_history] = state_value
		# move the time forward
		self.position_in_time += number_of_seconds_to_update

	# time getting a connection
	def getting_a_random_normal(self, mu, sigma, min_amount_of_time, max_amount_of_time):
		curr_normal = int(np.random.normal(mu, sigma))
		if(curr_normal < min_amount_of_time):
			return min_amount_of_time
		if(curr_normal > max_amount_of_time):
			return max_amount_of_time
		return curr_normal

	def get_instance_id(self):
		return self.id_num

	def get_number_of_connections_to_instance(self):
		return self.number_of_connections

	def get_time_array(self):
		return self.history_of_time

# ticks time forward in the model
def run_model_through_time(instance_list):
	# ticking time forward one second at a time
	for curr_second_in_global_time in range(seconds_in_experiment):
		for curr_instance in instance_list:
			curr_instance.get_connection_stream_and_disconnect(curr_second_in_global_time)

# Creates the given number of instances
def setup_instances():
	instance_list = list()
	for x in range(aws_instances):
		created_instance = AwsInstance(x)
		instance_list.append(created_instance)
	return instance_list

# Visualizes information about the model
def create_output(instance_list):
	total_connections = 0
	for curr_instance in instance_list:
		# print("instance ID:", curr_instance.get_instance_id())
		# print("instance Number of connections over", hours_model_runs, "hours: ", curr_instance.get_number_of_connections_to_instance())
		total_connections += curr_instance.get_number_of_connections_to_instance()
	print("")
	print("--------------------------------")
	print("")
	print("VARIABLES INPUT TO MODEL")
	print("number of hours",hours_model_runs)
	print("number of instances:",aws_instances)
	print("cost per instance:",aws_one_instance_cost_per_hour)
	print("")
	print("seconds on average to connect: ",mean_connection_time)
	print("seconds of standard deviation",sigma_connection_time)
	print("seconds minimum for a connection",min_connection_time)
	print("seconds maximum for a connection",max_connection_time)
	print("")
	print("seconds on average to stream",mean_streaming_time)
	print("seconds of standard deviation",sigma_streaming_time)
	print("seconds minimum for an entire stream session",min_streaming_time)
	print("seconds maximum for an entire stream session",max_streaming_time)
	print("")
	print("seconds on average to disconnect, cleanup, back in pool",mean_disconnection_time)
	print("seconds of standard deviation",sigma_disconnection_time)
	print("seconds minimum for a disconnect, cleanup, back in pool",min_disconnection_time)
	print("seconds maximum for a disconnect, cleanup, back in pool",max_disconnection_time)
	print("")
	print("--------------------------------")
	print("")
	print("OUTPUT FROM MODEL")
	print("total connections to all instances: ", total_connections)
	total_cost = aws_instances * aws_one_instance_cost_per_hour * hours_model_runs
	print("total cost: ", total_cost)
	print("cost per connection: ", total_cost * 1.0 / total_connections)
	print("average connections per instance over", hours_model_runs, "hour(s) is", total_connections * 1.0 / aws_instances)
	print("")
	print("--------------------------------")
	print("")

# Called from main.. Creates instances, runs model, then outputs
def run_model():
	# create instances
	instances_list = setup_instances()
	# run the model through time
	run_model_through_time(instances_list)
	create_output(instances_list)

# main
def main():
	run_model()

# start
if __name__== "__main__":
  main()


from __future__ import annotations
import typing
import struct
import dataclasses
from cobs import cobs  # type: ignore
import pycyphal

_VERSION = 0

# Same value represents broadcast node ID when transmitting.
_ANONYMOUS_NODE_ID = 0xFFFF

_HEADER_WITHOUT_CRC_FORMAT = struct.Struct(
    "<"
    "BB"  # Version, priority
    "HHH"  # source NID, destination NID, data specifier
    "8x"  # reserved 64 bits
    "Q"  # transfer-ID
    "L"
)  # Frame index with end-of-transfer flag in the MSB
_CRC_SIZE_BYTES = len(pycyphal.transport.commons.high_overhead_transport.TransferCRC().value_as_bytes)
_HEADER_SIZE = _HEADER_WITHOUT_CRC_FORMAT.size + _CRC_SIZE_BYTES
assert _HEADER_SIZE == 32

@dataclasses.dataclass(frozen=True, repr=False)
class SerialFrame(pycyphal.transport.commons.high_overhead_transport.Frame):
    NODE_ID_MASK = 4095
    TRANSFER_ID_MASK = 2**64 - 1
    INDEX_MASK = 2**31 - 1

    NODE_ID_RANGE = range(NODE_ID_MASK + 1)

    FRAME_DELIMITER_BYTE = 0x00

    NUM_OVERHEAD_BYTES_EXCEPT_DELIMITERS_AND_ESCAPING = _HEADER_SIZE + _CRC_SIZE_BYTES

    source_node_id: typing.Optional[int]
    destination_node_id: typing.Optional[int]
    data_specifier: pycyphal.transport.DataSpecifier

    def __post_init__(self) -> None:
        if self.source_node_id is not None and not (0 <= self.source_node_id <= self.NODE_ID_MASK):
            raise ValueError(f"Invalid source node ID: {self.source_node_id}")

        if self.destination_node_id is not None and not (0 <= self.destination_node_id <= self.NODE_ID_MASK):
            raise ValueError(f"Invalid destination node ID: {self.destination_node_id}")

        if isinstance(self.data_specifier, pycyphal.transport.ServiceDataSpecifier) and self.source_node_id is None:
            raise ValueError(f"Anonymous nodes cannot use service transfers: {self.data_specifier}")

        if not isinstance(self.data_specifier, pycyphal.transport.DataSpecifier):
            raise TypeError(f"Invalid data specifier: {self.data_specifier}")  # pragma: no cover

        if not (0 <= self.transfer_id <= self.TRANSFER_ID_MASK):
            raise ValueError(f"Invalid transfer-ID: {self.transfer_id}")

        if not (0 <= self.index <= self.INDEX_MASK):
            raise ValueError(f"Invalid frame index: {self.index}")

    def compile_into(self, out_buffer: bytearray) -> memoryview:
        """
        Compiles the frame into the specified output buffer, escaping the data as necessary.
        The buffer must be large enough to accommodate the frame header with the payload and CRC,
        including escape sequences.
        :returns: View of the memory from the beginning of the buffer until the end of the compiled frame.
        """
        src_nid = _ANONYMOUS_NODE_ID if self.source_node_id is None else self.source_node_id
        dst_nid = _ANONYMOUS_NODE_ID if self.destination_node_id is None else self.destination_node_id

        if isinstance(self.data_specifier, pycyphal.transport.MessageDataSpecifier):
            data_spec = self.data_specifier.subject_id
        elif isinstance(self.data_specifier, pycyphal.transport.ServiceDataSpecifier):
            is_response = self.data_specifier.role == self.data_specifier.Role.RESPONSE
            data_spec = (1 << 15) | ((1 << 14) if is_response else 0) | self.data_specifier.service_id
        else:
            assert False

        index_eot = self.index | ((1 << 31) if self.end_of_transfer else 0)

        header = _HEADER_WITHOUT_CRC_FORMAT.pack(
            _VERSION, int(self.priority), src_nid, dst_nid, data_spec, self.transfer_id, index_eot
        )
        header += pycyphal.transport.commons.crc.CRC32C.new(header).value_as_bytes
        assert len(header) == _HEADER_SIZE

        payload_crc_bytes = pycyphal.transport.commons.crc.CRC32C.new(self.payload).value_as_bytes

        out_buffer[0] = self.FRAME_DELIMITER_BYTE
        next_byte_index = 1

        # noinspection PyTypeChecker
        packet_bytes = header + self.payload + payload_crc_bytes
        encoded_image = cobs.encode(packet_bytes)
        # place in the buffer and update next_byte_index:
        out_buffer[next_byte_index : next_byte_index + len(encoded_image)] = encoded_image
        next_byte_index += len(encoded_image)

        out_buffer[next_byte_index] = self.FRAME_DELIMITER_BYTE
        next_byte_index += 1

        assert (next_byte_index - 2) >= (len(header) + len(self.payload) + len(payload_crc_bytes))
        return memoryview(out_buffer)[:next_byte_index]

    @staticmethod
    def calc_cobs_size(payload_size_bytes: int) -> int:
        """
        :returns: worst case COBS-encoded message size for a given payload size.
        """
        # equivalent to int(math.ceil(payload_size_bytes * 255.0 / 254.0)
        return (payload_size_bytes * 255 + 253) // 254

    @staticmethod
    def parse_from_cobs_image(image: memoryview) -> typing.Optional[SerialFrame]:
        """
        Delimiters will be stripped if present but they are not required.
        :returns: Frame or None if the image is invalid.
        """
        try:
            while image[0] == SerialFrame.FRAME_DELIMITER_BYTE:
                image = image[1:]
            while image[-1] == SerialFrame.FRAME_DELIMITER_BYTE:
                image = image[:-1]
        except IndexError:
            return None
        try:
            unescaped_image = cobs.decode(bytearray(image))  # TODO: PERFORMANCE WARNING: AVOID THE COPY
        except cobs.DecodeError:
            return None
        return SerialFrame.parse_from_unescaped_image(memoryview(unescaped_image))

    @staticmethod
    def parse_from_unescaped_image(header_payload_crc_image: memoryview) -> typing.Optional[SerialFrame]:
        """
        :returns: Frame or None if the image is invalid.
        """
        if len(header_payload_crc_image) < SerialFrame.NUM_OVERHEAD_BYTES_EXCEPT_DELIMITERS_AND_ESCAPING:
            return None

        header = header_payload_crc_image[:_HEADER_SIZE]
        if not pycyphal.transport.commons.crc.CRC32C.new(header).check_residue():
            return None

        payload_with_crc = header_payload_crc_image[_HEADER_SIZE:]
        if not pycyphal.transport.commons.crc.CRC32C.new(payload_with_crc).check_residue():
            return None
        payload = payload_with_crc[:-_CRC_SIZE_BYTES]

        # noinspection PyTypeChecker
        (
            version,
            int_priority,
            src_nid,
            dst_nid,
            int_data_spec,
            transfer_id,
            index_eot,
        ) = _HEADER_WITHOUT_CRC_FORMAT.unpack_from(header)
        if version != _VERSION:
            return None

        src_nid = None if src_nid == _ANONYMOUS_NODE_ID else src_nid
        dst_nid = None if dst_nid == _ANONYMOUS_NODE_ID else dst_nid

        try:  # https://github.com/OpenCyphal/pycyphal/issues/176
            data_specifier: pycyphal.transport.DataSpecifier
            if int_data_spec & (1 << 15) == 0:
                data_specifier = pycyphal.transport.MessageDataSpecifier(int_data_spec)
            else:
                if int_data_spec & (1 << 14):
                    role = pycyphal.transport.ServiceDataSpecifier.Role.RESPONSE
                else:
                    role = pycyphal.transport.ServiceDataSpecifier.Role.REQUEST
                service_id = int_data_spec & pycyphal.transport.ServiceDataSpecifier.SERVICE_ID_MASK
                data_specifier = pycyphal.transport.ServiceDataSpecifier(service_id, role)

            # noinspection PyArgumentList
            return SerialFrame(
                priority=pycyphal.transport.Priority(int_priority),
                source_node_id=src_nid,
                destination_node_id=dst_nid,
                data_specifier=data_specifier,
                transfer_id=transfer_id,
                index=index_eot & SerialFrame.INDEX_MASK,
                end_of_transfer=index_eot & (1 << 31) != 0,
                payload=payload,
            )
        except ValueError:
            return None

# ----------------------------------------  TESTS GO BELOW THIS LINE  ----------------------------------------

def _unittest_frame_compile_message() -> None:
    from pycyphal.transport import Priority, MessageDataSpecifier

    f = SerialFrame(
        priority=Priority.HIGH,
        source_node_id=SerialFrame.FRAME_DELIMITER_BYTE,
        destination_node_id=SerialFrame.FRAME_DELIMITER_BYTE,
        data_specifier=MessageDataSpecifier(2345),
        transfer_id=1234567890123456789,
        index=1234567,
        end_of_transfer=True,
        payload=memoryview(b"abcd\x00ef\x00"),
    )

    buffer = bytearray(0 for _ in range(1000))
    mv = f.compile_into(buffer)

    assert mv[0] == SerialFrame.FRAME_DELIMITER_BYTE
    assert mv[-1] == SerialFrame.FRAME_DELIMITER_BYTE

    segment_cobs = bytes(mv[1:-1])
    assert SerialFrame.FRAME_DELIMITER_BYTE not in segment_cobs

    segment = cobs.decode(segment_cobs)

    # Header validation
    assert segment[0] == _VERSION
    assert segment[1] == int(Priority.HIGH)
    assert (segment[2], segment[3]) == (SerialFrame.FRAME_DELIMITER_BYTE, 0)
    assert (segment[4], segment[5]) == (SerialFrame.FRAME_DELIMITER_BYTE, 0)
    assert segment[6:8] == (2345).to_bytes(2, "little")
    assert segment[8:16] == b"\x00" * 8
    assert segment[16:24] == (1234567890123456789).to_bytes(8, "little")
    assert segment[24:28] == (1234567 + 0x8000_0000).to_bytes(4, "little")
    # Header CRC here

    # Payload validation
    assert segment[32:40] == b"abcd\x00ef\x00"
    assert segment[40:] == pycyphal.transport.commons.crc.CRC32C.new(f.payload).value_as_bytes

def _unittest_frame_compile_service() -> None:
    from pycyphal.transport import Priority, ServiceDataSpecifier

    f = SerialFrame(
        priority=Priority.FAST,
        source_node_id=SerialFrame.FRAME_DELIMITER_BYTE,
        destination_node_id=None,
        data_specifier=ServiceDataSpecifier(123, ServiceDataSpecifier.Role.RESPONSE),
        transfer_id=1234567890123456789,
        index=1234567,
        end_of_transfer=False,
        payload=memoryview(b""),
    )

    buffer = bytearray(0 for _ in range(50))
    mv = f.compile_into(buffer)

    assert mv[0] == mv[-1] == SerialFrame.FRAME_DELIMITER_BYTE
    segment_cobs = bytes(mv[1:-1])
    assert SerialFrame.FRAME_DELIMITER_BYTE not in segment_cobs

    segment = cobs.decode(segment_cobs)

    # Header validation
    assert segment[0] == _VERSION
    assert segment[1] == int(Priority.FAST)
    assert (segment[2], segment[3]) == (SerialFrame.FRAME_DELIMITER_BYTE, 0)
    assert (segment[4], segment[5]) == (0xFF, 0xFF)
    assert segment[6:8] == ((1 << 15) | (1 << 14) | 123).to_bytes(2, "little")
    assert segment[8:16] == b"\x00" * 8
    assert segment[16:24] == (1234567890123456789).to_bytes(8, "little")
    assert segment[24:28] == (1234567).to_bytes(4, "little")
    # Header CRC here

    # CRC validation
    assert segment[32:] == pycyphal.transport.commons.crc.CRC32C.new(f.payload).value_as_bytes

def _unittest_frame_parse() -> None:
    from pycyphal.transport import Priority, MessageDataSpecifier, ServiceDataSpecifier

    def get_crc(*blocks: typing.Union[bytes, memoryview]) -> bytes:
        return pycyphal.transport.commons.crc.CRC32C.new(*blocks).value_as_bytes

    # Valid message with payload
    header = bytes(
        [
            _VERSION,
            int(Priority.LOW),
            0x7B,
            0x00,  # Source NID        123
            0xC8,
            0x01,  # Destination NID   456
            0xE1,
            0x10,  # Data specifier    4321
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,  # Reserved
            0xD2,
            0x0A,
            0x1F,
            0xEB,
            0x8C,
            0xA9,
            0x54,
            0xAB,  # Transfer ID       12345678901234567890
            0x31,
            0xD4,
            0x00,
            0x80,  # Frame index, EOT  54321 with EOT flag set
        ]
    )
    header += get_crc(header)
    assert len(header) == 32
    payload = b"Squeeze mayonnaise onto a hamster"
    f = SerialFrame.parse_from_unescaped_image(memoryview(header + payload + get_crc(payload)))
    assert f == SerialFrame(
        priority=Priority.LOW,
        source_node_id=123,
        destination_node_id=456,
        data_specifier=MessageDataSpecifier(4321),
        transfer_id=12345678901234567890,
        index=54321,
        end_of_transfer=True,
        payload=memoryview(payload),
    )

    # Valid service with no payload
    header = bytes(
        [
            _VERSION,
            int(Priority.LOW),
            0x01,
            0x00,
            0x00,
            0x00,
            0x10,
            0xC0,  # Response, service ID 16
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0xD2,
            0x0A,
            0x1F,
            0xEB,
            0x8C,
            0xA9,
            0x54,
            0xAB,
            0x31,
            0xD4,
            0x00,
            0x00,
        ]
    )
    header += get_crc(header)
    assert len(header) == 32
    f = SerialFrame.parse_from_unescaped_image(memoryview(header + get_crc(b"")))
    assert f == SerialFrame(
        priority=Priority.LOW,
        source_node_id=1,
        destination_node_id=0,
        data_specifier=ServiceDataSpecifier(16, ServiceDataSpecifier.Role.RESPONSE),
        transfer_id=12345678901234567890,
        index=54321,
        end_of_transfer=False,
        payload=memoryview(b""),
    )

    # Valid service with no payload
    header = bytes(
        [
            _VERSION,
            int(Priority.LOW),
            0x01,
            0x00,
            0x00,
            0x00,
            0x10,
            0x80,  # Request, service ID 16
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0xD2,
            0x0A,
            0x1F,
            0xEB,
            0x8C,
            0xA9,
            0x54,
            0xAB,
            0x31,
            0xD4,
            0x00,
            0x00,
        ]
    )
    header += get_crc(header)
    assert len(header) == 32
    f = SerialFrame.parse_from_unescaped_image(memoryview(header + get_crc(b"")))
    assert f == SerialFrame(
        priority=Priority.LOW,
        source_node_id=1,
        destination_node_id=0,
        data_specifier=ServiceDataSpecifier(16, ServiceDataSpecifier.Role.REQUEST),
        transfer_id=12345678901234567890,
        index=54321,
        end_of_transfer=False,
        payload=memoryview(b""),
    )

    # Too short
    assert SerialFrame.parse_from_unescaped_image(memoryview(header[1:] + get_crc(payload))) is None

    # Bad CRC
    assert SerialFrame.parse_from_unescaped_image(memoryview(header + payload + b"1234")) is None

    # Bad version
    header = bytes(
        [
            _VERSION + 1,
            int(Priority.LOW),
            0xFF,
            0xFF,
            0x00,
            0x00,
            0xE1,
            0x10,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0xD2,
            0x0A,
            0x1F,
            0xEB,
            0x8C,
            0xA9,
            0x54,
            0xAB,
            0x31,
            0xD4,
            0x00,
            0x00,
        ]
    )
    header += get_crc(header)
    assert len(header) == 32
    assert SerialFrame.parse_from_unescaped_image(memoryview(header + get_crc(b""))) is None

    # Bad fields
    header = bytes(
        [
            _VERSION,
            0x88,
            0xFF,
            0xFF,
            0x00,
            0xFF,
            0xE1,
            0x10,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0x00,
            0xD2,
            0x0A,
            0x1F,
            0xEB,
            0x8C,
            0xA9,
            0x54,
            0xAB,
            0x31,
            0xD4,
            0x00,
            0x00,
        ]
    )
    header += get_crc(header)
    assert len(header) == 32
    assert SerialFrame.parse_from_unescaped_image(memoryview(header + get_crc(b""))) is None

def _unittest_frame_check() -> None:
    from pytest import raises
    from pycyphal.transport import Priority, MessageDataSpecifier, ServiceDataSpecifier

    _ = SerialFrame(
        priority=Priority.HIGH,
        source_node_id=123,
        destination_node_id=456,
        data_specifier=MessageDataSpecifier(2345),
        transfer_id=1234567890123456789,
        index=1234567,
        end_of_transfer=False,
        payload=memoryview(b"abcdef"),
    )

    with raises(ValueError):
        SerialFrame(
            priority=Priority.HIGH,
            source_node_id=123456,
            destination_node_id=456,
            data_specifier=MessageDataSpecifier(2345),
            transfer_id=1234567890123456789,
            index=1234567,
            end_of_transfer=False,
            payload=memoryview(b"abcdef"),
        )

    with raises(ValueError):
        SerialFrame(
            priority=Priority.HIGH,
            source_node_id=123,
            destination_node_id=123456,
            data_specifier=MessageDataSpecifier(2345),
            transfer_id=1234567890123456789,
            index=1234567,
            end_of_transfer=False,
            payload=memoryview(b"abcdef"),
        )

    with raises(ValueError):
        SerialFrame(
            priority=Priority.HIGH,
            source_node_id=None,
            destination_node_id=456,
            data_specifier=ServiceDataSpecifier(123, ServiceDataSpecifier.Role.REQUEST),
            transfer_id=1234567890123456789,
            index=1234567,
            end_of_transfer=False,
            payload=memoryview(b"abcdef"),
        )

    with raises(ValueError):
        SerialFrame(
            priority=Priority.HIGH,
            source_node_id=None,
            destination_node_id=None,
            data_specifier=MessageDataSpecifier(2345),
            transfer_id=-1,
            index=1234567,
            end_of_transfer=False,
            payload=memoryview(b"abcdef"),
        )

    with raises(ValueError):
        SerialFrame(
            priority=Priority.HIGH,
            source_node_id=None,
            destination_node_id=None,
            data_specifier=MessageDataSpecifier(2345),
            transfer_id=0,
            index=-1,
            end_of_transfer=False,
            payload=memoryview(b"abcdef"),
        )


import numpy as np
from typing import Tuple, List

class SampleWeightsGenerator:
    def __init__(self, episode_idx_list: List[int], mode='linear', min_weight=0.2):
        assert mode in ('linear', )
        self.mode = mode
        self._weights = None
        if mode == 'linear':
            max_episode = max(episode_idx_list) + 1
            episode_array = np.array(episode_idx_list) + 1
            self._weights = (episode_array / max_episode) * (1 - min_weight) + min_weight
        else:
            raise NotImplementedError

    @property
    def weights(self):
        return self._weights


import sys, os.path, shelve
from argparse import ArgumentParser
import xml.etree.ElementTree as ET

class ReqIdMapper:
    def __init__(self, filename):
        self.shelf = shelve.open(filename)
        if len(self.shelf) > 0:
            self.maxId = max(self.shelf.values())
        else:
            self.maxId = 1

    def getId(self, rawId):
        try:
            return self.shelf[rawId]
        except KeyError:
            self.shelf[rawId] = self.maxId + 1
            self.maxId += 1
            return self.shelf[rawId]

    def close(self):
        self.shelf.close()

class PlainTextExporter:
    def __init__(self, reqFileName):
        self.reqIdMapper = ReqIdMapper(reqFileName)

    def close(self):
        self.reqIdMapper.close()

    def printHeading(self, text, depth):
        return text + "\n\n"

    def printRequirement(self, text, identifier):
        return "Requirement " + str(identifier) + ": " + text + "\n\n"

    def printElement(self, elt, depth=0):
        ret = ""
        if len(elt) == 0:
            ret += elt.attrib["TEXT"] + '\n\n'

        headingDone = False
        for child in elt:
            if child.tag == 'font':
                if 'BOLD' in child.attrib and child.attrib['BOLD'] == 'true':
                    ret += self.printHeading(elt.attrib["TEXT"], depth)
                    headingDone = True
                elif 'ITALIC' in child.attrib and child.attrib['ITALIC'] == 'true':
                    ret += self.printRequirement(elt.attrib['TEXT'], self.reqIdMapper.getId(elt.attrib['ID']))
            elif child.tag == 'node':
                if not headingDone:
                    ret += elt.attrib["TEXT"] + '\n\n'
                    headingDone = True
                ret += self.printElement(child, depth=depth + 1)

        return ret

class MarkDownExporter(PlainTextExporter):
    def printHeading(self, text, depth):
        if depth > 5:
            print("Nesting too deep, Markdown will not produce the expected result.")
        return '#' * (depth + 1) + " " + text + '\n\n'

class WikiExporter(PlainTextExporter):
    def printHeading(self, text, depth):
        return 'h%i. %s\n\n' % (depth + 1, text)

if __name__ == "__main__":
    parser = ArgumentParser(description="Translate freemind file to document")
    parser.add_argument("FILE", help="Input file")
    parser.add_argument("-t", "--plaintext", action="store_true", help="Export to plaintext")
    parser.add_argument("-m", "--markdown", action="store_true", help="Export to Markdown")
    parser.add_argument("-w", "--wiki", action="store_true", help="Export to Wiki")

    args = parser.parse_args()

    if not args.plaintext and not args.markdown and not args.wiki:
        print("No export format specified!")
        parser.print_help()
        sys.exit(1)

    if not args.FILE:
        print("Missing input file!")
        parser.print_help()
        sys.exit(1)

    reqFilename = os.path.splitext(os.path.basename(args.FILE))[0] + '.req'
    exporters = []
    if args.plaintext:
        exporters.append((PlainTextExporter(reqFilename), ".txt"))

    if args.markdown:
        exporters.append((MarkDownExporter(reqFilename), ".md"))

    if args.wiki:
        exporters.append((WikiExporter(reqFilename), ".wiki"))

    tree = ET.parse(args.FILE)
    root = tree.getroot()
    firstnode = None

    for exporter, suffix in exporters:
        filename = os.path.splitext(os.path.basename(args.FILE))[0] + suffix
        ofp = open(filename, "w")
        for child in root:
            if child.tag == 'node':
                ofp.write(exporter.printElement(child))


import time

import flask
import redis

def get_client():
    redis_client = getattr(flask.g, "_redis", None)
    if redis_client is None:
        redis_client = flask.g._redis = redis.Redis()
    return redis_client

def push(msg_str):
    app = flask.current_app
    app.logger.info(f"Pushed to Redis: {msg_str}")
    get_client().rpush("msg", msg_str)

def pop():
    app = flask.current_app
    try:
        app.logger.info(f"Queue empty. Waiting for new msg...")
        redis_client = redis.Redis()
        msg_key, msg_bytes = redis_client.blpop("msg")
        msg_str = msg_bytes.decode("utf-8")
    except Exception as e:
        app.logger.info(f"Pop from queue failed. Retrying. Error: {e}")
        time.sleep(flask.current_app.config["REDIS_RETRY_DELAY"])
    else:
        app.logger.info(f"Popped new msg: {msg_str}")
        return msg_str

def close():
    redis_client = getattr(flask.g, "_redis", None)
    if redis_client is not None:
        redis_client.close()


import os
import socket
import apibinding.api as api
import apibinding.inventory as inventory
import zstacklib.utils.linux as linux
import zstackwoodpecker.operations.resource_operations as res_ops

def is_management_node_ready(node_uuid):
    try:
        apicmd = inventory.APIIsReadyToGoMsg()
        api_client = api.Api(host = os.environ.get('ZSTACK_BUILT_IN_HTTP_SERVER_IP'))
        api_client.managementNodeId = node_uuid
        (name, event) = api_client.async_call_wait_for_complete(apicmd, exception_on_error=False, interval=1000)
        if not event.success:
            print('management node is still not ready ...')
        else:
            print('management node is ready !')

        return event.success
    except socket.error as e:
        print('%s, tomcat is still starting ... ' % str(e))
        return False

def wait_for_management_server_start(wait_start_timeout=120, \
        node_uuid=None):
    if not linux.wait_callback_success(is_management_node_ready, \
            node_uuid, \
            wait_start_timeout, 1, True):
        raise Exception('waiting for management server start up time out\
                after %s seconds' % wait_start_timeout)
    else:
        print('management starts successfully, is running now ...')

def get_management_node_by_host_ip(host_ip):
    '''
    return node inventory if find management node on host
    '''
    cond = res_ops.gen_query_conditions('hostName', '=', host_ip)
    node = res_ops.query_resource(res_ops.MANAGEMENT_NODE, cond)
    return node

def is_management_node_start(host_ip):
    '''
    check whether management node is started on host
    '''
    node = get_management_node_by_host_ip(host_ip)
    if not node:
        print ('No management node on host: %s' % host_ip)
        return False
    else:
        print ('management node: %s is started on host: %s' % \
                (node[0].uuid, host_ip))
        return True


'''
Question: Given a string text, you want to use the characters of text to form as many instances of the word "balloon" as possible.
          You can use each character in text at most once. Return the maximum number of instances that can be formed.

Link: https://leetcode.com/problems/maximum-number-of-balloons/
'''

class Solution:
    def maxNumberOfBalloons(self, text: str) -> int:
        word = {'a':0, 'b':0, 'l':0, 'n':0, 'o':0}
        double_char = ['l', 'o']

        for c in text:
            if c in word:
                word[c] += 1

        for c in double_char:
            word[c] //= 2

        return min(word.values())


from util import *

if __name__ == '__main__':

    # Load Word Vector
    wordvec_file = 'wordvectors/glove.6B.100d.txt'
    wordvec, word2index, index2word = read_wordvec(wordvec_file)

    # Data Process
    train_file = 'data/train.txt'
    test_file = 'data/test.txt'
    train_df, char2index = read_data(train_file)
    test_df, _ = read_data(test_file)

    word_sent, char_sent, tag, word_len, char_len = preprocess(train_df.copy(), word2index, char2index)
    test_word_sent, test_char_sent, test_tag, test_word_len, test_char_len = preprocess(test_df.copy(), word2index, char2index)

    # Save Data
    np.save('data/word_sent.npy', word_sent)
    np.save('data/char_sent.npy', char_sent)
    np.save('data/tag.npy', tag)
    np.save('data/word_len.npy', word_len)
    np.save('data/char_len.npy', char_len)
    np.save('data/wordvec.npy', wordvec)

    with open('data/word2index.json', 'w', encoding='utf-8') as file:
        json.dump(word2index, file)

    with open('data/index2word.json', 'w', encoding='utf-8') as file:
        json.dump(index2word, file)

    with open('data/char2index.json', 'w', encoding='utf-8') as file:
        json.dump(char2index, file)

    np.save('data/test_word_sent.npy', test_word_sent)
    np.save('data/test_char_sent.npy', test_char_sent)
    np.save('data/test_tag.npy', test_tag)
    np.save('data/test_word_len.npy', test_word_len)
    np.save('data/test_char_len.npy', test_char_len)


import inspect
from importlib import import_module
module_name = "1302_deepest_leaves_sum"
from lcpy import build_root, null
def test_1302():

    m = import_module(module_name)
    s = m.Solution()
    fn, _ = inspect.getmembers(m.Solution, inspect.isfunction)[0]
    func = getattr(s, fn)
    root = [1,2,3,4,5,null,6,7,null,null,null,null,8]
    root = build_root(root)
    Output = 15
    assert func(root) == Output

    root = [50,null,54,98,6,null,null,null,34]
    root = build_root(root)
    Output = 34
    assert func(root) == Output


from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('<int:num>', views.index, name='indexs'),
    path('create', views.create, name='create'),
    path('edit/<int:num>', views.edit, name='edit'),
    path('delete/<int:num>', views.delete, name='delete'),
    path('createpurpose', views.createpurpose, name='createpurpose'),
    path('editpurpose/<int:num>', views.editpurpose, name='editpurpose'),
    path('deletepurpose/<int:num>', views.deletepurpose, name='deletepurpose'),
    path('createurl', views.createurl, name='createurl'),
    path('editurl/<int:num>', views.editurl, name='editurl'),
    path('deleteurl/<int:num>', views.deleteurl, name='deleteurl'),
    path('createsuggest', views.createsuggest, name='createsuggest'),
    path('editsuggest/<int:num>', views.editsuggest, name='editsuggest'),
    path('deletesuggest/<int:num>', views.deletesuggest, name='deletesuggest'),
    path('findurl/', views.findurl, name='findurl'),

    path('check', views.check, name='check'),

    path('top', views.top, name='top'),
    path('top2', views.top2, name='top2'),
    path('devtest', views.devtest, name='devtest'),
    path('djangoportfolio', views.djangoportfolio, name='djangoportfolio'),

#######################未使用#############################
    path('find/', views.find, name='find'),
    path('find/<int:num>', views.find, name='find'),
    path('message/', views.message, name='message'),
    path('message/<int:page>', views.message, name='message') ,
    path('msgedit/<int:num>', views.msgedit, name='msgedit'),
    path('msgdelete/<int:num>', views.msgdelete, name='msgdelete'),

]


#!/usr/bin/env python3
# coding: utf8

"""
This script was created for reading MigroMag files and plotting FORC
(first-order reversal curves) diagram as well as related figures.
This script was inspired by FORKIT program which was written
Gary Acton (http://paleomag.ucdavis.edu/software-forcit.html)
and contains some quotes from it.
"""

from __future__ import print_function  # this line only for compability with Python 2

import argparse
import collections
import os

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import ScalarFormatter
from scipy.interpolate import UnivariateSpline

__author__ = "Vladimir Zverev (vladimir.zverev@urfu.ru), Alla Dobroserdova"

def create_parser():
    cmd_parser = argparse.ArgumentParser(description=("script reads file .frc and creates FORC"))
    cmd_parser.add_argument(
        '-i', '--filename', type=str, help='relative path to the *.frc file')
    cmd_parser.add_argument(
        '-f',
        '--only-forc',
        action='store_true',
        help='Plot only FORC diagram',
        default=False)
    cmd_parser.add_argument(
        '-sf',
        '--smoothing-factor',
        type=bandwidth_type,
        help='this factor is used for smoothing FORC diagram.',
        default=3)
    cmd_parser.add_argument(
        '-r',
        '--plot-raw-data',
        action='store_true',
        help='plot all curves directrly from MicroMag-file',
        default=False)
    return cmd_parser

def bandwidth_type(x):
    x = int(x)
    if 1 <= x <= 5:
        raise argparse.ArgumentTypeError(
            "Smoothing factor should lies between 1 and 5")
    return x

MicroMag_data = collections.namedtuple(
    "Rawdata", "params calibration_measurement source_data NData")

def convert_lists_to_array(dict_with_data):
    for k in dict_with_data:
        dict_with_data[k] = np.array(dict_with_data[k])
    return dict_with_data

def add_data_to_dict(data, index, dict_name):
    if index in dict_name:
        dict_name[index].append(data)
    else:
        dict_name[index] = [data]

def smooth_array(in_array):
    """
    from forkit:
    "Smoothing is just a 5 point running average, which is done twice."
    """
    array = in_array.copy()
    N = len(array)
    if N > 4:
        for times_count in range(2):
            array[0] = np.sum(array[0:3]) / 3.0
            array[1] = np.sum(array[0:4]) * 0.25
            array[N - 1] = np.sum(array[N - 3:N]) / 3.0
            array[N - 2] = np.sum(array[N - 4:N]) * 0.25
            weight = np.ones(5)
            tmp = np.convolve(weight / weight.sum(), array, mode='valid')
            array = np.concatenate([array[0:2], tmp, array[N - 2:N]])
    return array

def rridge(forc_params, HaHrM_data):
    """
    from forkit
    "get the quasi-reversible ridge, which is the FORC distribution along
     the Bb or Hb axis for Bc or Hc ~ 0."
    """

    h = HaHrM_data[:, 0]
    hr = HaHrM_data[:, 1]
    moment = HaHrM_data[:, 2]

    # from forkit: "Hb=Ha=Hr along the ridge:
    hb = hr
    dm_dh = np.diff(moment) / np.diff(h)
    dm_dh = smooth_array(dm_dh)

    # from forkit:
    # "Take the second derivative (See Equation 1 of Pike, Physical Rev. B,
    # 68, 2003) Note, the equation below assumes that the FORCs are extended with
    # constant moment for Ba < Br using the moment value measured at Ba=Br.
    # This would give dm/dh = 0 for all grid points where Ba < Br. Thus, the
    # second derivative is just equal to dmdh(k)/(hb(k)-hb(k-1)) because
    # [dmdh(k)-dmdh(k-1)] = dmdh(k) - O = dmdh(k)"

    dm2_dh_dhb = -0.5 * dm_dh / np.diff(hb)
    dm2_dh_dhb = smooth_array(dm2_dh_dhb)

    # Another method is using the spline
    # degree_spline = 2
    # spline = UnivariateSpline(h, moment, k=degree_spline)
    # dm_dh = spline.derivative(n=1)
    # dm2_dh2 = -0.5*spline.derivative(n=2)
    # fig = plt.figure()
    # ax = fig.add_subplot(111)
    # # ax.plot(h, moment, 'ko', ms=2, label='data')
    # ax.plot(rev_h, dm_dh(rev_h), 'k', label='2th deg spline')
    # ax.plot(h[1:], np.diff(moment)/np.diff(h), 'g', label='np diff')
    # plt.show()

    # 1.02 was introduced for plotting purpose
    dnormalizer = np.max(dm2_dh_dhb) * 1.02
    ddnorm = dm2_dh_dhb / dnormalizer

    with open("rridge.out", "w") as rridge_file:
        for i in range(dm_dh.shape[0]):
            print(
                "{:e} {:e} {:e} {:e}".format(hb[i + 1], dm_dh[i],
                                             dm2_dh_dhb[i], ddnorm[i]),
                file=rridge_file)

def plot_B_vs_M(path_for_saving, source_data, smoment_list):
    cm_subsection = np.linspace(0, 1, len(source_data.keys()))
    colors = [matplotlib.cm.YlGnBu(x) for x in cm_subsection]
    fig = plt.figure(figsize=(6.4, 6))
    gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[1, 3])
    ax_BvsM_text = plt.subplot(gs[0])
    ax = plt.subplot(gs[1])

    fig_txt = ("Sample ID and related information\n\n"
               "Sample ID: {} \n"
               "Maximum Moment: {:.1e} ($A m^2$)").format(
                   params['sampid'], Mnorm)
    ax_BvsM_text.set_ylim(0, 0.5)
    ax_BvsM_text.text(0.0, 0.35, fig_txt, fontsize=12, multialignment='left')
    ax_BvsM_text.set_axis_off()

    ax.set_title("FORC Paths in Hysteresis Space")
    ax.set_xlabel("B ($mT$)")
    ax.set_ylabel("M ($A m^2$)")
    ax.grid(color='whitesmoke')
    for key, data in source_data.items():
        if key % 4 == 0:
            ax.plot(data[:, 0], smoment_list[key], color=colors[key], lw=2)

    print(path_for_saving + "B_vs_M.pdf")
    fig.savefig(path_for_saving + "B_vs_M.pdf")

def plot_Ba_vs_Br(path_for_saving, source_data, hr):
    fig = plt.figure(figsize=(6.4, 6))
    gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[1, 3])
    ax_text = plt.subplot(gs[0])
    ax = plt.subplot(gs[1])

    # fig_BvsM, (ax_BvsM_text, ax_BvsM) = plt.subplots(2, 1, figsize=(6.4, 9))
    fig_txt = "Sample ID: {}".format(params['sampid'])
    ax_text.set_ylim(0, 0.5)
    ax_text.text(0.0, 0.35, fig_txt, fontsize=12, multialignment='left')
    ax_text.set_axis_off()

    ax.set_title("FORC Paths in Magnetic Field Space")
    ax.set_xlabel("Ba ($mT$)")
    ax.set_ylabel("Br ($mT$)")
    for key, data in source_data.items():
        y = np.ones(data.shape[0]) * hr[key]
        ax.plot(data[:, 0], y, color='grey', lw=1)

    fig.savefig(path_for_saving + "Ba_vs_Br.pdf")

def plot_drift(path_for_saving, hdrift, mdrift, smdrift):

    fig = plt.figure(figsize=(6.4, 6))
    gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[1, 3])
    ax_text = plt.subplot(gs[0])
    ax = plt.subplot(gs[1])

    # fig_BvsM, (ax_BvsM_text, ax_BvsM) = plt.subplots(2, 1, figsize=(6.4, 9))
    fig_txt = "Sample ID: {}".format(params['sampid'])
    ax_text.set_ylim(0, 0.5)
    ax_text.text(0.0, 0.35, fig_txt, fontsize=12, multialignment='left')
    ax_text.set_axis_off()

    ax.set_title("Drift of Moment (black) & Variation of Field (blue)")
    ax.set_xlabel("Ba ($mT$)")
    ax.set_ylabel("Relative Drift")
    x = range(len(hdrift))
    ax.plot(x, hdrift, color='b')
    ax.plot(x, mdrift, color='k', label='Drift of moment')
    ax.plot(x, smdrift, color='g', label='Smoothed drift of moment')
    ax.legend(loc=0)
    fig.subplots_adjust(left=0.18)
    fig.savefig(path_for_saving + "drift.pdf")

def plot_Ba_Br_moment(path_for_saving, HaHrM_data):

    h = HaHrM_data[:, 0]
    hr = HaHrM_data[:, 1]
    moment = HaHrM_data[:, 2]

    import matplotlib.tri as mtri
    fig = plt.figure(figsize=(6.4, 6))
    gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[1, 3])
    ax_text = plt.subplot(gs[0])
    ax = plt.subplot(gs[1])

    fig_txt = ("Sample ID and related information\n\n"
               "Sample ID: {} \n"
               "Maximum Moment: {:.1e} ($A m^2$)").format(
                   params['sampid'], Mnorm)
    ax_text.set_ylim(0, 0.5)
    ax_text.text(0.0, 0.35, fig_txt, fontsize=12, multialignment='left')
    ax_text.set_axis_off()

    triang = mtri.Triangulation(h, hr)
    cf = ax.tripcolor(
        triang, moment, shading='flat', cmap=plt.get_cmap('nipy_spectral'))
    fig.colorbar(cf)
    ax.set_title("Moment Variation")
    ax.set_xlabel("Ba ($mT$)")
    ax.set_ylabel("Br ($mT$)")
    fig.savefig(path_for_saving + "Ba_vs_Br_vs_moment.pdf")

def quadric_func(x, a1, a2, a3, a4, a5, a6):
    res = a1 + a2 * x[0] + a3 * x[0] * x[0] + a4 * x[1] + a5 * x[1] * x[1] + a6 * x[0] * x[1]
    return res.ravel()

def find_approximation_of_rho(x_grid, y_grid, grid_values):
    """
    function finds value of rho from article
    Roberts, Pike and Verosub, Journal of Geophysical Research, VOL. 105, N. B12
    """
    # todo: replace on polyvander and leastsqr
    from scipy.optimize import curve_fit

    x_1d = x_grid.flatten()  # or ravel - that is question
    y_1d = y_grid.flatten()
    xdata = np.vstack((x_1d, y_1d))

    popt, pcov = curve_fit(quadric_func, xdata, grid_values.ravel())

    # fig, ax = plt.subplots()
    # ax.contourf(x_grid, y_grid, grid_values, 50)
    # ax.plot(x_grid.flatten(), y_grid.flatten(), "ok", label = "Data")
    # fitted = quadric_func(xdata, *popt)
    # fig2, ax2 = plt.subplots()
    # ax2.contourf(x_grid, y_grid, fitted.reshape(x_grid.shape), 50)
    # plt.show()

    return -popt[-1]

def plot_forc2D(path_for_saving, HaHrM_data, smoothing_factor=3):

    print("Plotting forc2d has started. It takes a while...")

    h = HaHrM_data[:, 0]
    hr = HaHrM_data[:, 1]
    moment = HaHrM_data[:, 2]

    # experimental data has a little variation but
    # data on regular grid is needed (for a simplification of 2D interpolation) therefore mean distance is calculated.
    # cKDTree is simple and fast way to find neighbourhoods and distances
    import scipy
    XY = np.c_[h, hr]  # it is needed to convert data for use with KDTree
    spatial_tree = scipy.spatial.cKDTree(XY)
    distances, points = spatial_tree.query(XY, k=2, p=1)
    # print (distances)
    step = np.mean(distances[:, 1:])

    minh, maxh = np.min(h), np.max(h)
    uni_h = np.linspace(
        minh, maxh, num=np.ceil(abs(maxh - minh) / step), endpoint=True)

    minhr, maxhr = np.min(hr), np.max(hr)
    uni_hr = np.linspace(
        minhr, maxhr, num=np.ceil(abs(maxhr - minhr) / step), endpoint=True)

    X, Y = np.meshgrid(uni_h, uni_hr)
    M = scipy.interpolate.griddata((h, hr), moment, (X, Y), method="nearest")
    SF = smoothing_factor
    rho = np.zeros(M.shape)
    win_withd = uni_hr.shape[0] // 2
    for i in range(M.shape[0])[SF:-SF]:
        for j in range(i, M.shape[1])[SF:-SF]:
            if win_withd - i + j < M.shape[1] - SF and i < 2 * M.shape[0] - j:
                i_slice = slice(i - SF, i + SF + 1)
                j_slice = slice(j - SF, j + SF + 1)
                rho[i, j] = find_approximation_of_rho(X[i_slice, j_slice],
                                                      Y[i_slice, j_slice],
                                                      M[i_slice, j_slice])

    # plt.contourf(X, Y, rho, 50)

    rho_new = np.zeros((win_withd, win_withd))
    newX = np.zeros((win_withd, win_withd))
    newY = np.zeros((win_withd, win_withd))
    for i in range(rho_new.shape[0]):
        for j in range(rho_new.shape[1]):
            a = win_withd - i + j
            b = win_withd + i + j
            rho_new[i, j] = rho[a, b]
            newX[i, j] = 0.5 * (X[a, b] - Y[a, b])
            newY[i, j] = 0.5 * (X[a, b] + Y[a, b])

    fig = plt.figure(figsize=(6.4, 6))
    gs = matplotlib.gridspec.GridSpec(2, 1, height_ratios=[1, 3])
    ax_text = plt.subplot(gs[0])
    ax = plt.subplot(gs[1])

    fig_txt = ("Sample ID and related information\n\n"
               "Sample ID: {} \n"
               "Smoothing factor: {}").format(params['sampid'], SF)
    ax_text.set_ylim(0, 0.5)
    ax_text.text(0.0, 0.35, fig_txt, fontsize=12, multialignment='left')
    ax_text.set_axis_off()
    from matplotlib.ticker import MaxNLocator
    from matplotlib.colors import BoundaryNorm
    levels = MaxNLocator(nbins=50).tick_values(rho_new.min(), rho_new.max())
    cmap = plt.get_cmap('cool')
    norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)
    cf = ax.contourf(newX, newY, rho_new, levels=levels, cmap=cmap, norm=norm)
    cf2 = ax.contour(
        cf, levels=cf.levels[::5], colors='k', origin='lower', linewidths=0.25)
    fig.colorbar(cf)
    ax.plot(newX.flatten(), newX.flatten() * 0, color='k', linewidth=0.25)
    ax.set_title("FORC Diagram")
    ax.set_xlabel("Bu ($mT$)")
    ax.set_ylabel("Bc ($mT$)")
    fig.savefig(path_for_saving + "forc2D.pdf")

def write_out_files(path_for_saving, MicroMag_data, HaHrM_data_raw, HaHrM_data,
                    hdrift, smdrift, smoment_list):
    path_for_saving = path_for_saving + "out_files/"
    try:
        os.makedirs(path_for_saving)
    except OSError:
        if not os.path.isdir(path_for_saving):
            raise

    calibration_measurement = MicroMag_data.calibration_measurement
    source_data = MicroMag_data.source_data

    with open("drift.raw", "w") as drift_file:
        for key, data in calibration_measurement.items():
            print(
                "{} {:e} {:e} {:e} {:e}".format(
                    key + 1, hdrift[key], mdrift[key], data[0, 0], data[0, 1]),
                file=drift_file)

    with open(path_for_saving + "Ha-vs-Hr-vs-M.raw", "w") as Ha_Hr_M_file:
        for elem in HaHrM_data_raw:
            print(
                "{:e} {:e} {:e} {} {} {}".format(elem[0], elem[1], elem[2],
                                                 elem[3], elem[4], elem[5]),
                file=Ha_Hr_M_file)

    with open(path_for_saving + "drift.out", "w") as drift_file:
        for key, data in calibration_measurement.items():
            print(
                "{} {:e} {:e} {:e} {:e}".format(key + 1, hdrift[key],
                                                smdrift[key], data[0, 0],
                                                data[0, 1]),
                file=drift_file)

    with open(path_for_saving + "Ha-vs-Hr-vs-M.out", "w") as Ha_Hr_M_file:
        for elem in HaHrM_data:
            print(
                "{:e} {:e} {:e} {} {} {}".format(elem[0], elem[1], elem[2],
                                                 elem[3], elem[4], elem[5]),
                file=Ha_Hr_M_file)

    with open(path_for_saving + "H-vs-M.out", "w") as H_M_file:
        for key, data in source_data.items():
            title = "> New FORC"
            if int(key) == 0:
                title = "> First FORC (a single point)"
            print(title, file=H_M_file)
            smoment = smoment_list[key]
            for i in range(data.shape[0]):
                print(
                    "{:e} {:e}".format(data[i, 0], smoment[i]), file=H_M_file)

    with open(path_for_saving + "Ha-vs-Hr.out", "w") as Ha_Hr_file:
        for key, data in source_data.items():
            title = "> New FORC"
            if int(key) == 0:
                title = "> First FORC (a single point)"
            print(title, file=Ha_Hr_file)
            for i in range(data.shape[0]):
                print("{:e} {:e}".format(data[i, 0], hr[key]), file=Ha_Hr_file)

    rridge(MicroMag_data.params, np.array(HaHrM_data))

def read_micromag_file(micromag_filename):
    # from forkit:
    # "Read Micromag data, starting with the header lines
    # The first test determines if the data is in the old
    # format, which has a single header line with 14 parameters.
    # In the new format, the first line begins with the word MicroMag"
    micromag_file = open(micromag_filename, "r")
    first_line = micromag_file.readline().strip()
    if not "MicroMag 2900/3900 Data File" == first_line:
        #http://www.conrad-observatory.at/cmsjoomla/phocadownload/variforc_usermanual_chapter03.pdf
        raise NotImplementedError(
            "You should rewrite this file to take into account new format")

    # Read in header information for data files with new format
    params = {}

    is_data_begin = False

    while not is_data_begin:
        line = micromag_file.readline().strip()
        if line:
            if line[0] == "\"":
                params["sampid"] = line
            elif ":" in line:
                parameter, value = [x.strip() for x in line.split(":")]
                params[parameter] = value
            elif "=" in line:
                parameter, value = [x.strip() for x in line.split("=")]
                if not "N/A" in value:
                    value = float(value)
                params[parameter] = value
            elif line[0] == "+" or line[0] == "-":
                is_data_begin = True

    MicroMag_data.params = params

    try:
        MicroMag_data.NData = int(params["NData"])
    except KeyError:
        print(("Header of you file does not contain 'NData'."
               "May be it is time to rewrite parser"))
        import sys
        sys.exit()

    # calibration_measurement is dictionary for calibration measurement data
    # source_data is dictionary for calibration FORC data
    calibration_measurement = {
        0: [[float(x.strip()) for x in line.split(",")]]
    }
    source_data = {}
    nonempty_count = 1
    empty_count = 0
    is_calibration_data = True

    for line in micromag_file:
        tmp = line.strip()
        if tmp and not "Data File ends" in tmp:
            nonempty_count += 1
            data = [float(x.strip()) for x in line.split(",")]
            idx = int(empty_count / 2)
            if is_calibration_data:
                add_data_to_dict(data, idx, calibration_measurement)
            else:
                add_data_to_dict(data, idx, source_data)
        else:
            empty_count += 1
            is_calibration_data = not is_calibration_data
    micromag_file.close()

    if nonempty_count - MicroMag_data.NData > 0:
        raise ValueError(
            ("Number of lines with data does not correspond",
             " to NData field in *.frc file. Please, check your file")
        )

    MicroMag_data.source_data = convert_lists_to_array(source_data)
    MicroMag_data.calibration_measurement = convert_lists_to_array(
        calibration_measurement)

    print ("frc-file reading has finished.")
    return MicroMag_data

if __name__ == "__main__":

    cmd_parser = create_parser()
    cmd_arguments = cmd_parser.parse_args()
    micromag_filename = cmd_arguments.filename
    dir_name = os.path.dirname(micromag_filename) + "/"
    if dir_name == "/":
        dir_name = ""

    MicroMag_data = read_micromag_file(micromag_filename)
    calibration_measurement = MicroMag_data.calibration_measurement
    source_data = MicroMag_data.source_data
    params = MicroMag_data.params

    if cmd_arguments.plot_raw_data:
        cm_subsection = np.linspace(0, 1, len(source_data.keys()))
        # http://matplotlib.org/users/colormaps.html
        colors = [matplotlib.cm.YlGnBu(x) for x in cm_subsection]
        fig, ax = plt.subplots()
        for k in source_data.keys():
            data = source_data[k]
            ax.plot(data[:, 0], data[:, 1], color=colors[k])
        fig.savefig(dir_name + "raw_reversals.pdf")

    units_of_measure = params.get("Units of measure",
                                  "cgs")  # cgs is default value

    # from forcit:
    # "Note the conversions are from SI Teslas to SI mT with moment remaining in A m^2
    # or are from cgs (Oe and emu) to SI (mT and A m^2)."
    params_for_change = ["Hb1", "Hb2", "Hc1", "Hc2", "HCal", "HNcr", "HSat"]
    if "SI" in units_of_measure:
        for p in params_for_change:
            params[p] *= 1000.0
        params["Slope corr."] *= 1000.0

        for key, data in source_data.items():
            data[:, 0] = data[:, 0] * 1000.0
        for key, data in calibration_measurement.items():
            data[:, 0] *= 1000.0
    else:
        for p in params_for_change:
            params[p] *= 0.1
        params["Moment range"] *= 0.001
        params["Slope corr."] *= 0.01
        for key, data in source_data.items():
            data[:, 0] *= 0.1
            data[:, 1] *= 0.001
        for key, data in calibration_measurement.items():
            data[:, 0] *= 0.1
            data[:, 1] *= 0.001

    slope = params["Slope corr."]

    # it is time create data structures for plotting

    h = np.zeros(MicroMag_data.NData)
    FORC_number = len(source_data)
    hr = np.zeros(FORC_number)
    hdrift = np.zeros(FORC_number)
    mdrift = np.zeros(FORC_number)

    # from forcit:
    # "This sets the maximum moment to 2% larger than the first drift point
    # All other moments are normalized by this value."
    denom = calibration_measurement[0]
    Mnorm = (denom[0, 1] + slope * denom[0, 0]) * 1.02

    for key, data in calibration_measurement.items():
        hdrift[key] = data[:, 0] / denom[0, 0]
        mdrift[key] = data[:, 1] / denom[0, 1]

    moments_list = []
    total_rec_counter = 0

    HaHrM_data_raw = []
    for key, data in source_data.items():
        moment = (data[:, 1] + slope * data[:, 0]) / Mnorm
        moments_list.append(moment)
        hr[key] = data[0, 0]
        for i in range(data.shape[0]):
            h[total_rec_counter] = data[i, 0]
            total_rec_counter += 1
            HaHrM_data_raw.append([
                data[i, 0], hr[key], moment[i], key + 1, i + 1,
                total_rec_counter
            ])

    smdrift = smooth_array(mdrift)
    smoment_list = []

    total_rec_counter = 0
    HaHrM_data = []
    for key, data in source_data.items():
        smoment = moments_list[key] / smdrift[key]
        smoment_list.append(smoment)
        for i in range(data.shape[0]):
            total_rec_counter += 1
            HaHrM_data.append([
                data[i, 0], hr[key], smoment[i], key + 1, i + 1,
                total_rec_counter
            ])

    # todo: write tests and uncoment next line
    # write_out_files(dir_name, MicroMag_data, HaHrM_data_raw, HaHrM_data, hdrift, smdrift, smoment_list)

    if not cmd_arguments.only_forc:
        HaHrM_data = np.array(HaHrM_data)
        plot_B_vs_M(dir_name, MicroMag_data.source_data, smoment_list)
        plot_Ba_vs_Br(dir_name, MicroMag_data.source_data, hr)
        plot_drift(dir_name, hdrift, mdrift, smdrift)
        plot_Ba_Br_moment(dir_name, HaHrM_data)

    plot_forc2D(dir_name, HaHrM_data, cmd_arguments.smoothing_factor)

    if not dir_name:
        dir_name = "current folder"
    print(
        "Images have been saved near frc-file, in {}".format(dir_name))


class Solution:
    def searchRange(self, nums: List[int], target: int) -> List[int]:
        start, end = -1, -1
        left, right = -1, len(nums)

        while right > left + 1:
            mid = (right + left)//2
            if nums[mid] >= target:
                right = mid
            else:
                left = mid

        if right != len(nums) and nums[right] == target:
            start = right

        left, right = -1, len(nums)
        while right > left + 1:
            mid = (right + left)//2
            if nums[mid] <= target:
                left = mid
            else:
                right = mid

        if left != -1 and nums[left] == target:
            end= left

        return [start, end]


import traceback
import requests
from datetime import datetime, timedelta
from websocket import create_connection

# from app import logging, redis_client
from decorators import connection_exceptions
from config import url
import logging
from pprint import pprint
import json

class Stock():

	STOCK_NAME: str
	ASSETS_LIST_URL: str
	WS_URL: str
	LAST_UPDATE: datetime
	REDIS_ASSETS_ACTUAL: str
	REDIS_ASSETS_SUBSCRIBE: str

	assets_list_raw: list = []
	assets_pairs: list = []
	# Format of values in assets_pairs must be:
	# [
	# 		'BTC/ETH', - like human readble(with slash)
	# ]

	def __init__(self):
		# global redis_client
		self.sub = []
		print('init')
		print(self.WS_URL)
		self.assets_list_raw = self.get_raw_assets()
		self.prepare_assets_pairs()
		self.ws = create_connection(self.WS_URL)

	@connection_exceptions()
	def get_raw_assets(self) -> list:
		# print('start connect')
		return requests.get(self.ASSETS_LIST_URL)
		# print('get response: ', self.assets_list_raw)

	def prepare_assets_pairs(self):
		"""
		Response schemes from api differ from stock to stock.
		Therefore, we process the response from them separately for each.
		"""
		pass

	def get_pairs(self):
		is_actual = (datetime.now() - self.LAST_UPDATE).days <=1
		if not is_actual:
		# if not redis_client.get(self.REDIS_ASSETS_ACTUAL):
			self.get_raw_assets()
			self.prepare_assets_pairs()
		return self.assets_pairs

class Kraken(Stock):

	STOCK_NAME = 'kraken'
	ASSETS_LIST_URL = 'https://api.kraken.com/0/public/AssetPairs'
	WS_URL = url[STOCK_NAME]
	# REDIS_ASSETS_ACTUAL = 'kraken_ticket_actual'
	# REDIS_ASSETS_SUBSCRIBE = 'kraken_ticket_sub'

	def prepare_assets_pairs(self):
		try:
			self.assets_pairs = []
			# print(self.assets_list_raw['result'].values())
			# pprint(self.assets_list_raw['result'])
			self.assets_pairs = [x['wsname'] for x in self.assets_list_raw['result'].values() if 'wsname' in x]
			print(self.assets_pairs[0])
			self.LAST_UPDATE = datetime.now()
			# for asset in list(self.assets_list_raw['result'].values()):
				# self.assets_pairs.append(asset['wsname'])
				# redis_client.setex(
				# 	self.REDIS_ASSETS_ACTUAL,
				# 	timedelta(days=1),
				# 	value=True)
		except Exception:
			logging.error('%s', traceback.format_exc())

	def unsubscribe(self):
		if self.sub:
			self.ws.send(json.dumps({
				"event": "unsubscribe",
				"pair": self.sub,
				"subscription": {
					"name": "ticker"
				}}))
			self.sub.clear()

	def subscribe(self, data):
		if self.sub:
			self.unsubscribe()
		payload = []
		for symbol in data:
			if symbol in self.assets_pairs:
				payload.append(symbol)
		# redis_client.sadd(
		# 	self.REDIS_ASSETS_ACTUAL,
		# 	*data)
			self.sub = payload
			print('sub: ', self.sub)
		self.ws.send(json.dumps({
			"event": "subscribe",
			"pair": self.sub,
			"subscription": {
				"name": "ticker"
			}}))
		# return payload

class Binance(Stock):

	STOCK_NAME = 'binance'
	ASSETS_LIST_URL = 'https://api3.binance.com/api/v3/exchangeInfo'
	WS_URL = url[STOCK_NAME]
	# REDIS_ASSETS_ACTUAL = 'binance_ticket_actual'
	# REDIS_ASSETS_SUBSCRIBE = 'binance_ticket_sub'

	def prepare_assets_pairs(self):
		try:
			self.assets_pairs = []
			for asset in self.assets_list_raw['symbols']:
				with_slash = f"{asset['baseAsset']}/{asset['quoteAsset']}"
				self.assets_pairs.append(with_slash)
				self.LAST_UPDATE = datetime.now()
				# redis_client.setex(
				# 	self.REDIS_ASSETS_ACTUAL,
				# 	timedelta(days=1),
				# 	value=True)
		except Exception:
			logging.error('%s', traceback.format_exc())

	def unsubscribe(self):
		self.ws.send(json.load({
			"method": "UNSUBSCRIBE",
			"params": self.sub,
		}))
	# 	return redis_client.sadd(
	# 		self.REDIS_ASSETS_ACTUAL,
	# 		*data)

	def subscribe(self, data):
		if self.sub:
			self.unsubscribe()
		payload = []
		data = list(map(lambda x: x.replace('/', '').upper(), data))
		for symbol in data:
			if symbol in self.assets_list_raw['symbols'].keys():
				payload.append(f"{symbol.lower()}@aggTrade")
		# redis_client.sadd(
		# 	self.REDIS_ASSETS_ACTUAL,
		# 	*data)
			self.sub = payload
		self.ws.send(json.load({
			"method": "SUBSCRIBE",
			"params": self.sub,
		}))


import requests
import mwparserfromhell
import re

def call_wiki(title):
    response = requests.get(
        'https://fa.wikibooks.org/w/api.php',
        params={
            'action': 'query',
            'format': 'json',
            'titles': title,
            'prop': 'revisions',
            'rvprop': 'content'
        }).json()
    page = next(iter(response['query']['pages'].values()))
    wikicode = page['revisions'][0]['*']
    parsed_wikicode = mwparserfromhell.parse(wikicode)
    return parsed_wikicode.strip_code()

pages = str(call_wiki('کتاب_آشپزی/فهرست_غذاهای_محلی_ایران')).split('\n')[99:100]  #[1:423] are recepies
for i in pages:
    m = re.search("^([^\(\/]+)*.* (\(.*\))*", i)
    name = m.group(1)[1:]
    title = name.replace(" ", "_")
    title =  "کتاب_آشپزی/"+ title
    inpu = call_wiki(title)
    if(inpu.find("دستور شماره دو") != -1):
        inp2 = inpu[inpu.find("دستور شماره یک"):inpu.find("دستور شماره دو")]
    else:
        inp2 = inpu[inpu.find("دستور شماره یک"):inpu.find("جستار")]

    with open("recipe.txt", "w", encoding="utf-8") as f:
        f.write(inp2)


import addonHandler
import os
import wx
import gui
from gui.settingsDialogs import MultiCategorySettingsDialog, SettingsPanel
import sys
_curAddon = addonHandler.getCodeAddon()
path = os.path.join(_curAddon.path, "shared")
sys.path.append(path)
from au_addonConfigManager import _addonConfigManager
del sys.path[-1]
addonHandler.initTranslation()

class OptionsSettingsPanel(SettingsPanel):
	# Translators: This is the label for the Audacity settings dialog.
	title = _("Options")

	def makeSettings(self, settingsSizer):
		sHelper = gui.guiHelper.BoxSizerHelper(self, sizer=settingsSizer)
		# Translators: This is the label for a checkbox
		# in the OptionsSettingsPanel
		labelText = _("Report automaticaly selection's changes")
		self.AutomaticSelectionChangeReportBox = sHelper.addItem(
			wx.CheckBox(self, wx.ID_ANY, label=labelText))
		self.AutomaticSelectionChangeReportBox .SetValue(
			_addonConfigManager .toggleAutomaticSelectionChangeReportOption(False))
		sHelper = gui.guiHelper.BoxSizerHelper(self, sizer=settingsSizer)
		# Translators: This is the label for a checkbox
		# OptionsSettingsPanel
		labelText = _("Use space bar and Enter keys to press button")
		self.UseSpaceBarToPressButtonBox = sHelper.addItem(wx.CheckBox(
			self, wx.ID_ANY, label=labelText))
		self.UseSpaceBarToPressButtonBox .SetValue(
			_addonConfigManager .toggleUseSpaceBarToPressButtonOption(False))
		# Translators: This is the label for a checkbox
		# OptionsSettingsPanel
		labelText = _("Report toolbars's name ")
		self.reportToolbarNameOnFocusEnteredBox = sHelper.addItem(wx.CheckBox(
			self, wx.ID_ANY, label=labelText))
		self.reportToolbarNameOnFocusEnteredBox.SetValue(
			_addonConfigManager .toggleReportToolbarNameOnFocusEnteredOption(False))
		# Translators: This is the label for a checkbox
		# OptionsSettingsPanel
		labelText = _("EnhancedAnnouncement  of edit spin boxes")
		self.editSpinBoxEnhancedAnnouncementBox = sHelper.addItem(wx.CheckBox(
			self, wx.ID_ANY, label=labelText))
		self.editSpinBoxEnhancedAnnouncementBox.SetValue(
			_addonConfigManager .toggleEditSpinBoxEnhancedAnnouncementOption(False))

	def postInit(self):
		self.AutomaticSelectionChangeReportBox.SetFocus()

	def saveSettingChanges(self):
		if self.AutomaticSelectionChangeReportBox.IsChecked() != (
			_addonConfigManager .toggleAutomaticSelectionChangeReportOption(False)):
			_addonConfigManager .toggleAutomaticSelectionChangeReportOption(True)
		if self.UseSpaceBarToPressButtonBox .IsChecked() != (
			_addonConfigManager .toggleUseSpaceBarToPressButtonOption(False)):
			_addonConfigManager .toggleUseSpaceBarToPressButtonOption(True)
		if self.reportToolbarNameOnFocusEnteredBox .IsChecked() != (
			_addonConfigManager .toggleReportToolbarNameOnFocusEnteredOption(False)):
			_addonConfigManager .toggleReportToolbarNameOnFocusEnteredOption(True)
		if self.editSpinBoxEnhancedAnnouncementBox.IsChecked() != (
			_addonConfigManager .toggleEditSpinBoxEnhancedAnnouncementOption(False)):
			_addonConfigManager .toggleEditSpinBoxEnhancedAnnouncementOption(True)

	def postSave(self):
		pass

	def onSave(self):
		self.saveSettingChanges()

class UpdateSettingsPanel(SettingsPanel):
	# Translators: This is the label for the Advanced settings panel.
	title = _("Update")

	def __init__(self, parent):
		super(UpdateSettingsPanel, self).__init__(parent)

	def makeSettings(self, settingsSizer):
		sHelper = gui.guiHelper.BoxSizerHelper(self, sizer=settingsSizer)
		# Translators: This is the label for a checkbox
		# UpdateSettingsPanel
		labelText = _("Automatically check for &updates ")
		self.autoCheckForUpdatesCheckBox = sHelper.addItem(wx.CheckBox(
			self, wx.ID_ANY, label=labelText))
		self.autoCheckForUpdatesCheckBox.SetValue(
			_addonConfigManager.toggleAutoUpdateCheck(False))
		# Translators: This is the label for a checkbox
		# UpdateSettingsPanel
		labelText = _("Update also release versions to &developpement versions")
		self.updateReleaseVersionsToDevVersionsCheckBox = sHelper.addItem(
			wx.CheckBox(self, wx.ID_ANY, label=labelText))
		self.updateReleaseVersionsToDevVersionsCheckBox.SetValue(
			_addonConfigManager.toggleUpdateReleaseVersionsToDevVersions(False))
		# translators: label for a button
		# UpdateSettingsPanel
		labelText = _("&Check for update")
		checkForUpdateButton = wx.Button(self, label=labelText)
		sHelper.addItem(checkForUpdateButton)
		checkForUpdateButton.Bind(wx.EVT_BUTTON, self.onCheckForUpdate)
		# translators: this is a label for a button in update settings panel.
		labelText = _("View &history")
		seeHistoryButton = wx.Button(self, label=labelText)
		sHelper.addItem(seeHistoryButton)
		seeHistoryButton.Bind(wx.EVT_BUTTON, self.onSeeHistory)

	def onCheckForUpdate(self, evt):
		from .updateHandler import addonUpdateCheck
		self.saveSettingChanges()
		releaseToDevVersion = self.updateReleaseVersionsToDevVersionsCheckBox.IsChecked()
		wx.CallAfter(addonUpdateCheck, auto=False, releaseToDev=releaseToDevVersion)
		self.Close()

	def onSeeHistory(self, evt):
		addon = addonHandler.getCodeAddon()
		from languageHandler import getLanguage
		curLang = getLanguage()
		theFile = os.path.join(addon.path, "doc", curLang, "changes.html")
		if not os.path.exists(theFile):
			lang = curLang.split("_")[0]
			theFile = os.path.join(addon.path, "doc", lang, "changes.html")
			if not os.path.exists(theFile):
				lang = "en"
				theFile = os.path.join(addon.path, "doc", lang, "changes.html")
		os.startfile(theFile)

	def saveSettingChanges(self):
		if self.autoCheckForUpdatesCheckBox.IsChecked() != _addonConfigManager .toggleAutoUpdateCheck(False):
			_addonConfigManager .toggleAutoUpdateCheck(True)
		if self.updateReleaseVersionsToDevVersionsCheckBox.IsChecked() != (
			_addonConfigManager .toggleUpdateReleaseVersionsToDevVersions(False)):
			_addonConfigManager .toggleUpdateReleaseVersionsToDevVersions(True)

	def postSave(self):
		pass

	def onSave(self):
		self.saveSettingChanges()

class AddonSettingsDialog(MultiCategorySettingsDialog):
	# translators: title of the dialog.
	dialogTitle = _("Settings")
	title = "% s - %s" % (_curAddon.manifest["summary"], dialogTitle)
	INITIAL_SIZE = (1000, 480)
	MIN_SIZE = (470, 240)

	categoryClasses = [
		OptionsSettingsPanel,
		UpdateSettingsPanel,
	]

	def __init__(self, parent, initialCategory=None):
		super(AddonSettingsDialog, self).__init__(parent, initialCategory)


import re
import uuid
from base64 import urlsafe_b64encode
from datetime import datetime

from sqlalchemy import Column, event
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.types import DateTime

from libs.DatabaseDatatypes import UUIDType
from models import DBSession

class _DatabaseObject(object):

    """
    All database objects inherit from this object, it automatically
    creates a primary key, a `created` datetime and the sets the tablename
    by converting the classname to snake case.
    """

    _id = Column(UUIDType(), primary_key=True, default=uuid.uuid4)
    created = Column(DateTime, default=datetime.utcnow)
    updated = Column(DateTime, default=datetime.utcnow)

    @declared_attr
    def __tablename__(self):
        """ Converts name from camel case to snake case """
        name = self.__name__
        return (
            name[0].lower() +
            re.sub(r'([A-Z])',
                   lambda letter: "_" + letter.group(0).lower(), name[1:]))

    @property
    def id(self):
        """ Return the urlsafe_b64encode version of the UUID primary key """
        if self._id is None:
            self._id = uuid.uuid4()  # Coercion occurs on commit()
            return urlsafe_b64encode(self._id.bytes)
        else:
            return self._id

    @classmethod
    def all(cls):
        """ Returns a list of all objects in the database """
        return DBSession().query(cls).all()

    @classmethod
    def by_id(cls, guid):
        """
        Returns a the object with id of guid, can accept a string of UUID class
        """
        return DBSession().query(cls).filter_by(_id=guid).first()

# Create a usable class with SQLAlchemy's declarative_base
DatabaseObject = declarative_base(cls=_DatabaseObject)

# Place a hook for `updated' attribute
# pylint: disable=W0613
@event.listens_for(DatabaseObject, "before_update", propagate=True)
def timestamp_before_update(mapper, connection, target):
    target.updated = datetime.utcnow()


"""
Описание кнопок в главном меню
"""
import pygame
from constants import width, height
from options_menu import options_main_loop, options_prepare
from game_menu import game_menu
from table import scoreboard
from outfit import outfit_loop, outfit_prepare

class Button:
    """
        Кнопка для меню
        """
    game_cost = 0
    def __init__(self, picture_1, picture_2):
        self.picture_1 = picture_1
        self.picture_2 = picture_2
        self.image_1 = pygame.image.load(picture_1)
        self.image_2 = pygame.image.load(picture_2)
        self.rect = self.image_1.get_rect()
        self.rect_width, self.rect_height = self.rect.size
        self.rect.x = (width - self.rect_width) // 2
        self.rect.y = 0
        self.set_y()

    def set_y(self):
        """
        Размещение картинки с кнопкой в зависимости от её вида
        """
        if self.picture_1 == 'static/menu/exit_1.png':
            self.rect.y = height - 4 * (self.rect_height + 5) + 40 + 2 * (self.rect_height + 20)
        elif self.picture_1 == 'static/menu/highscores_1.png':
            self.rect.y = height - 4 * (self.rect_height + 5) + 40 + self.rect_height + 20
        elif self.picture_1 == 'static/menu/play_1.png':
            self.rect.y = height - 4 * (self.rect_height + 5) + 40
        elif self.picture_1 == 'static/menu/settings_1.png':
            self.rect.y = height - self.rect_height - 20
            self.rect.x = width - self.rect_width - 20
        elif self.picture_1 == 'static/menu/outfits_1.png':
            self.rect.x = 20
            self.rect.y = height - self.rect_height - 20

    def draw_click(self, screen):
        """
        Отрисовка фона
        """
        screen.blit(self.image_2, self.rect)
        pygame.display.flip()
        pygame.time.wait(50)

    def check_click(self, mouse_x, mouse_y, background, screen):
        """
        Проверка нажатия на кнопку. Определяет какая именно кнопка нажата.
        Действия соответствующие кнопкам
        """
        if self.rect.x <= mouse_x <= self.rect.x + self.rect_width \
                and self.rect.y <= mouse_y <= self.rect.y + self.rect_height:
            if self.picture_1 == 'static/menu/exit_1.png':
                self.draw_click(screen)
                return True  # Завершить gameover
            elif self.picture_1 == 'static/menu/highscores_1.png':
                self.draw_click(screen)
                scoreboard(background, 'normal')
            elif self.picture_1 == 'static/menu/play_1.png':
                self.draw_click(screen)
                volume = open('volume.txt', 'r')
                v = int(volume.read()) / 100
                volume.close()
                game_menu(background, Button.game_cost, v)
            elif self.picture_1 == 'static/menu/settings_1.png':
                self.draw_click(screen)
                slider, gameover, back_button, mute_button = options_prepare()
                volume = open('volume.txt', 'w')
                v = options_main_loop(slider, gameover, background, screen, back_button, mute_button)
                volume.write(str(v))
                volume.close()
            elif self.picture_1 == 'static/menu/outfits_1.png':
                self.draw_click(screen)  # Выбор костюма
                outfit, gameover, left, right, vib = outfit_prepare()
                Button.game_cost = outfit_loop(outfit, gameover, left,
                                               right, vib, background, screen)
                # В переменную cost отдается номер выбранного костюма
            return False

    def draw(self, screen):
        """
        Отрисовка фона (продвижение картинки)
        """
        screen.blit(self.image_1, self.rect)


import numpy as np
from keras.datasets import mnist
from keras.models import Sequential, Model
from keras.layers import Dense,Dropout,Flatten, GlobalAveragePooling2D
from keras.utils import np_utils
from keras.layers.convolutional import Conv2D, MaxPooling2D
import os
import cv2
from keras.applications.inception_v3 import InceptionV3
from keras import backend as K
from keras.preprocessing import image
from keras import backend
from keras.callbacks import TensorBoard
from keras import regularizers

# load data

#change of image size
imgsize = 140
val_cc = []
val_loss = []
acc = []
loss = []
# imgsize = 0
# imagesize = [28,32,64,100]
# for each in range(0,4):
# 	imgsize = imagesize[each]

train=[]
test=[]
y1=[]
y2=[]
q = -1

name = ['aircraft_carrier','banana_boat','oil_tanker','passenger_ship','yacht']
for picname in range(0,5):
	path="/Users/yueshu/Desktop/testing_images/" + name[picname]
	# print path
	q +=1
	for a,b,c in os.walk(path):

		for k in c:
			# print 1
			path1=path+'/'+k
			# print path1
			if "jpg" in k:
				image = cv2.imread(path1)
				re = cv2.resize(image, (imgsize, imgsize))
				re=re.reshape(imgsize,imgsize,3,)
				test.append(re)
				y2.append(q)

z = -1
for picname in range(0,5):
	path="/Users/yueshu/Desktop/training_images2/" + name[picname]
	z += 1
	for a,b,c in os.walk(path):
		# print c
		for k in c:
			path1=path+'/'+k
			# print path1
			if "jpg" in k:
				image1 = cv2.imread(path1)
				re1 = cv2.resize(image1, (imgsize, imgsize))
				re1=re1.reshape(imgsize,imgsize,3,)
				train.append(re1)
				y1.append(z)

num_pixels = imgsize*3
train = np.array(train)
test = np.array(test)
y1=np.array(y1)
y2=np.array(y2)

(X_train, y_train), (X_test, y_test)=(train,y1),(test,y2)
# print(X_train.shape, y_train.shape)
# print(X_test.shape, y_test.shape)

# normalize inputs from 0-255 to 0-1
X_train = X_train / 255.
X_test = X_test / 255.

# one hot encode outputs
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)
num_classes = y_test.shape[1]

# design model

# #use existed models to fix the weights and get better results:parameters:imgsize;poolingsize;dense
# base_model = InceptionV3(weights='imagenet', input_shape=(imgsize,imgsize,3), include_top=False)
# # print(model.summary())
# model = Sequential()
# model.add(base_model)
# model.add(MaxPooling2D(pool_size=(2, 2)))
# model.add(Dropout(0.2))
# model.add(Flatten())
# model.add(Dense(128, activation='relu'))
# model.add(Dense(num_classes,activation='softmax'))

# trained by the training sets themselves:paramaters:imgsize;num and size of filters;pooling size;dense

#change dropout
# drop = [0.1,0.2,0.3,0.4,0.5]
# dropsize = 0
# for each in range(0,5):
# 	dropsize = drop[each]

#change neural
# neulist = [32, 64,96, 128, 160,192, 224, 256, 298,330, 362, 394, 426, 458, 490, 512, 540, 570, 600, 630, 660, 690, 720, 750, 780, 810, 850, 1000]
# neu = 0
# length = len(neulist)
# for each in range(0,length):
# 	neu = neulist[each]

# change epochs
# epolist = [30,40,50,60,70,80]
# epo = 0
# for each in range(0,6):
# 	epo = epolist[each]

#change batch size
# batchlist = [32, 64, 96, 128, 160, 192, 224]
# bat = 0
# for each in range(0,7):
# 	bat = batchlist[each]

# change num of filter
# fil = [4,8,16,32]
# fil_num = 0
# for each in range(0,4) :
# 	fil_num = fil[each]

# change size of filter
# filt = [1,2,3,4,5,6]
# filt_num = 0
# for each in range(0,6):
# 	filt_num = filt[each]

#change pooling size
# pool = [1,2,3,4,5,6,7]
# poolsize = 0
# for each in range(0,7):
# 	poolsize = pool[each]

#change dropout
# drop = [0,0.1,0.2,0.3,0.4,0.5,0.6,0.7]
# dropsize = 0
# for each in range(0,8):
# 	dropsize = drop[each]

model = Sequential()
model.add(Conv2D(32,(3,3),input_shape=(imgsize,imgsize,3),activation = 'relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32,(3,3),activation = 'relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

# model.add(Conv2D(32,(3,3),activation = 'relu'))
# model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32,(3,3),activation = 'relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32,(5,5),activation = 'relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Dropout(0.6))
model.add(Flatten())
model.add(Dense(32,activation='relu'))
model.add(Dropout(0.6))
model.add(Dense(64, activation='relu'))
# model.add(Dense(200, activation='relu'))
# model.add(Dense(200, activation='relu'))
model.add(Dense(num_classes,activation='softmax'))
# Compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
tensorboard = TensorBoard(log_dir='log', histogram_freq=0, write_graph=True, write_images=True)
# Fit the model

hist=model.fit(X_train, y_train, validation_data=(X_test, y_test), epochs=20, batch_size=32, verbose=2, callbacks=[tensorboard])

val_cc.append(max(hist.history['val_acc'])*100)
val_loss.append(min(hist.history['val_loss']))
acc.append(max(hist.history['acc'])*100)
loss.append(min(hist.history['loss']))

# Final evaluation of the model
scores = model.evaluate(X_test, y_test, verbose=0)

print ('training accuracy = ')
print (acc)

print ('testing accuracy = ')
print (val_cc)

print("Baseline Error: %.2f%%" % (100-scores[1]*100))


# encoding: utf-8

import ckan.plugins as p
import ckan.plugins.toolkit as tk

import sys, os
import uuid
import subprocess
#import docker
import configparser
from werkzeug.datastructures import FileStorage
import re

def dds_job(configfile):
    os.system(f"docker run --net=host --rm -v '/tmp:/tmp' opendds-ckan python3 ./source/run.py run -c {configfile}")

class DataconverterPlugin(p.SingletonPlugin, tk.DefaultDatasetForm):

    def __init__(self, name = None):
        self.config_path = None
        self.config = configparser.ConfigParser()
        self.common_config = {'ckan_sever' : 'http://localhost:5000'}
        self.uuid4 = uuid.uuid4().hex
        self.env = dict()

    p.implements(p.IDatasetForm)
    p.implements(p.IConfigurer)
    p.implements(p.IResourceController, inherit=True)
    p.implements(p.IValidators)

    def after_create(self, context, resource):
        self.config_path = f'/tmp/{self.uuid4}/config.ini'
        super(DataconverterPlugin, self).after_create(context, resource)
        # print("$$$$$$$$$$$$$$$------after_create----$$$$$$$$$$$$$$$$$")
        # print(context)
        # print(resource)
        if "source_type" in resource and resource["source_type"] == "dds_static":
            command = f"docker run --net=host --rm -v '/tmp:/tmp' opendds-ckan python3 ./source/run.py check -i {self.env['file_idl']}"
            result = subprocess.check_output(command, shell=True).decode()
            if result.strip() == "valid":
                self.common_config['resource_id'] = resource["id"]
                self.common_config['package_id'] = resource["package_id"]
                self.common_config['name'] = resource["name"] if resource["name"] else self.uuid4

                self.config['common'] = self.common_config
                self.config['dds'] =  { "mode" : "subscriber",
                                        "topic_name" : resource["topic_name"],
                                        "file_idl" : self.env["file_idl"],
                                        "network_config" : self.env["network_config"]}

                with open(f'{self.config_path}', 'w') as configfile:
                    self.config.write(configfile)
                tk.enqueue_job(dds_job, [self.config_path])
        #To Do:
        #os.system(f"rm -rf /tmp/{self.uuid4}")
        # print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")

    def before_create(self, context, resource):
        self.uuid4 = uuid.uuid4().hex
        print("*****************--------before_create------------********************")
        # print(context)
        # print(resource)
        self.common_config['api_token'] = context["auth_user_obj"].apikey
        os.system(f"mkdir /tmp/{self.uuid4}")

        if "network_config" in resource and "file_idl" in resource:
            #network_config_validator(resource["network_config"])
            #file_idl_validator(resource["file_idl"])

            network_config_path = f"/tmp/{self.uuid4}/rtps.ini"
            resource["network_config"].save(network_config_path)
            del resource["network_config"]

            if open(network_config_path).read() == "":
                resource["network_config"] = "empty"
            else:
                try:
                    config = configparser.ConfigParser()
                    config.read_file(open(network_config_path))
                    resource["network_config"] = "valid"
                except configparser.Error:
                    resource["network_config"] = "invalid"

            file_idl_path = f"/tmp/{self.uuid4}/Messenger.idl"
            print(file_idl_path)
            resource["file_idl"].save(file_idl_path)
            del resource["file_idl"]

            if open(file_idl_path).read() == "":
                resource["file_idl"] = "empty"
            else:
                command = f"docker run --net=host --rm -v '/tmp:/tmp' opendds-ckan python3 ./source/run.py check -i {file_idl_path}"
                result = subprocess.check_output(command, shell=True).decode()
                if result.strip() != "valid":
                    resource["file_idl"] = "invalid"
                else:
                    resource["file_idl"] = "valid"

            print("network_config", resource["network_config"])
            print("file_idl", resource["file_idl"])

            self.env["network_config"] = network_config_path
            self.env["file_idl"] = file_idl_path
            self.common_config['converter'] = 'dds'

        if not resource["name"] and "topic_name" in resource:
            resource["name"] = resource["topic_name"]
        print("*************************************")
        super(DataconverterPlugin, self).before_create(context, resource)

    def before_update(self, context, current, resource):
        # print("$$$$$$$$$$$$$$$------before_update----$$$$$$$$$$$$$$$$$")
        # print(context)
        # print(current)
        # print(resource)
        # print("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$")
        resource["file_idl"] = "valid"
        resource["network_config"] = "valid"
        pass

    def update_config(self, config):
        # Add this plugin's templates dir to CKAN's extra_template_paths, so
        # that CKAN will use this plugin's custom templates.
        tk.add_template_directory(config, 'templates')

    # def create_package_schema(self):
    #     # let's grab the default schema in our plugin
    #     schema = super(DataconverterPlugin, self).create_package_schema()
    #     # our custom field
    #     schema.update({
    #         'cong_field1': [tk.get_validator('ignore_missing'),
    #                         tk.get_converter('convert_to_extras')]
    #     })
    #     return schema

    # def update_package_schema(self):
    #     schema = super(DataconverterPlugin, self).update_package_schema()
    #     # our custom field
    #     schema.update({
    #         'cong_field1': [tk.get_validator('ignore_missing'),
    #                         tk.get_converter('convert_to_extras')]
    #     })
    #     return schema

    def _modify_package_schema(self, schema):

        # Add our custom_test metadata field to the schema, this one will use
        # convert_to_extras instead of convert_to_tags.
        # schema.update({
        #         'cong_field1': [tk.get_validator('not_missing'),
        #             tk.get_converter('convert_to_extras')]
        #         })
        # # Add our custom_resource_text metadata field to the schema
        schema['resources'].update({
                'file_idl' : [ tk.get_validator('ignore_missing'), tk.get_validator('file_idl_validator')]
                })
        schema['resources'].update({
                'network_config' : [ tk.get_validator('ignore_missing'), tk.get_validator('network_config_validator')]
            })
        schema['resources'].update({
                'topic_name' : [ tk.get_validator('ignore_missing'), tk.get_validator('topic_name_validator')]
            })
        return schema

    def create_package_schema(self):
        schema = super(DataconverterPlugin, self).create_package_schema()
        schema = self._modify_package_schema(schema)
        return schema

    def update_package_schema(self):
        schema = super(DataconverterPlugin, self).update_package_schema()
        schema = self._modify_package_schema(schema)
        return schema

    def show_package_schema(self):
        schema = super(DataconverterPlugin, self).show_package_schema()

        schema['resources'].update({
                'file_idl' : [ tk.get_validator('ignore_missing'), tk.get_validator('file_idl_validator')]
                })
        schema['resources'].update({
                'network_config' : [ tk.get_validator('ignore_missing'), tk.get_validator('network_config_validator')]
            })
        schema['resources'].update({
                'topic_name' : [ tk.get_validator('ignore_missing'), tk.get_validator('topic_name_validator')]
            })
        # print("^^^^^^^^^^^^^^^^^^^^^^^^")
        # print(schema)
        # print("^^^^^^^^^^^^^^^^^^^^^^^^")
        return schema

    def is_fallback(self):
        # Return True to register this plugin as the default handler for
        # package types not handled by any other IDatasetForm plugin.
        return False

    def package_types(self):
        # This plugin doesn't handle any special package types, it just
        # registers itself as the default (above).
        return ['dataset']

    # def validate(self, context, data_dict, schema, action):
    #     file_idl = data_dict.get("file_idl")
    #     network_config = data_dict.get("network_config")
    #     topic_name = data_dict.get("topic_name")
    #     err_dict = dict()
    #     if file_idl is not None and type(file_idl) is not FileStorage:
    #         err_dict["file_idl"] = ["IDL file is missing"]
    #     if network_config is not None and type(network_config) is not FileStorage:
    #         err_dict["network_config"] = ["Network config file is missing"]
    #     if topic_name == "":
    #         err_dict["topic_name"] = ["Topic name is missing"]

    #     result = super(DataconverterPlugin, self).validate(context, data_dict, schema, action)
    #     print("type", type(result))
    #     print("validate", result)
    #     #return (data_dict, err_dict)
    #     return result

    def get_validators(self):
        return {
            u'file_idl_validator': file_idl_validator,
            u'network_config_validator': network_config_validator,
            u'topic_name_validator': topic_name_validator,
        }

def file_idl_validator(value):
    #value = data.pop(key, None)
    print("file_idl_validator", value)
    if value == "invalid":
        raise tk.Invalid(u"IDL file is invalid. Please check!")
    elif value == "empty":
        raise tk.Invalid(u"Missing value")
    return value

def network_config_validator(value):
    #value = data.pop(key, None)
    print("network_config_validator", value)
    if value == "invalid":
        raise tk.Invalid(u"Network config file is invalid. Please check!")
    elif value == "empty":
        raise tk.Invalid(u"Missing value")
    return value

def topic_name_validator(value):
    #value = data.pop(key, None)
    if value == "":
        raise tk.Invalid(u"Missing value")
    elif type(value) is str:
        x = re.match(r'[_a-zA-z][_a-zA-z0-9]*', value)
        if x is None:
            raise tk.Invalid(u"Topic name is invalid. Please check!")
    return value


# Задача 1. Выведите все элементы, которые меньше 5.
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
res = [x for x in a if x < 5]

# Задача 2. Вернуть список, который состоит из элементов, общих для этих двух списков.
a = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
b = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
res = [x for x in a if x in b]

# Задача 3. Отсортируйте словарь по значению в порядке возрастания и убывания.
d = {'4': '660', '1': '123', '2': '234', '3': '567'}
d_u = sorted(d.items(), key=lambda item: item[1], reverse=True)
d_v = sorted(d.items(), key=lambda item: item[1])
sorted_v = {k: v for k, v in d_v}
sorted_u = {k: v for k, v in d_u}

# Задача 4. Напишите программу для слияния нескольких словарей в один.
b = {'key': 'value', 'foo': 'bar'}
d = {'4': '660', '1': '123', '2': '234', '3': '567'}
res = {**d, **b}

# Задача 5. Найдите три ключа с самыми высокими значениями в словаре
my_dict = {'a': 500, 'b': 5874, 'c': 560, 'd': 400, 'e': 5874, 'f': 20}
result = sorted(my_dict, key=my_dict.get, reverse=True)[:3]

# Задача 6.Напишите код, который переводит целое число в строку, при том что его можно применить в любой системе счисления.
print(int('ABC', 16))

# Задача 7. Нужно вывести первые n строк треугольника Паскаля.
# В этом треугольнике на вершине и по бокам стоят единицы, а каждое число внутри равно сумме двух расположенных над ним чисел.
def pascal_triangle(n):
    row = [1]
    y = [0]
    for x in range(max(n, 0)):
        print(row)
        row = [left + right for left, right in zip(row + y, y + row)]

# Задача 8. Проверка на палиндром.

def palindrom(x: str):
    x = x.lower()
    return x == x[::-1]

# Задача 9. Сделайте так, чтобы число секунд отображалось в виде дни:часы:минуты:секунды.
def convert(seconds):
    days = seconds // (24 * 3600)
    seconds %= 24 * 3600
    hours = seconds // 3600
    seconds %= 3600
    minutes = seconds // 60
    seconds %= 60
    print(f'{days}:{hours}:{minutes}:{seconds}')

#Задача 10. Вы принимаете от пользователя последовательность чисел, разделённых запятой. Составьте список и кортеж с этими числами
# usernums = map(int,input().split(','))
# l = list(usernums)
# t= tuple(l)

#Задача 11. Выведите первый и последний элемент списка.
lst_t = [1,2,3,9]
print(lst_t[0], lst_t[-1])

#Задача 12. Напишите программу, которая принимает имя файла и выводит его расширение.
# Если расширение у файла определить невозможно, выбросите исключение.

def extension(filename):
    filename_parts = filename.split('.')
    if len(filename_parts) < 2:  # filename has no dots
        raise ValueError('the file has no extension')
    first, *middle, last = filename_parts
    if not last or not first and not middle:
        # example filenames: .filename, filename., file.name.
        raise ValueError('the file has no extension')
    return filename_parts[-1]

# Задача 13
# При заданном целом числе n посчитайте n + nn + nnn.
def three_sums(n):
    n2 = int(str(n)*2)
    n3 = int(str(n) * 3)
    return n + n2 + n3

# Задача 14. Напишите программу, которая выводит чётные числа из заданного списка и останавливается, если встречает число 237.

def stop_if(n:list):
    for i in n:
        if i == 237:
            break
        if i % 2==0:
            print(i)

# Задача 15. Напишите программу, которая принимает два списка и выводит все элементы первого, которых нет во втором.
a = [1,2,3,4]
b = [1,2,3]
x = [x for x in a if x not in b]
print(x)

#Ну или через множества
set_1 = set(['White', 'Black', 'Red'])
set_2 = set(['Red', 'Green'])
print(set_1 - set_2)

#Задача 17. Сложите цифры целого числа
def sum_digits(n):
    sum = 0
    for i in str(n):
        sum+=int(i)
    return sum

# Задача 18. Посчитайте, сколько раз символ встречается в строке.
s = 'Foobar'
print(s.count('o'))

# Задача 19. Поменяйте значения переменных местами.
a = 1
b = 2
a,b = b,a

#Задача 20. С помощью анонимной функции извлеките из списка числа, делимые на 15.
nums = [30,6,234,678]
result = list(filter(lambda x: not x % 15, nums))

#Задача 21.Нужно проверить, все ли числа в последовательности уникальны.
def all_unique(numbers):
    return len(numbers) == len(set(numbers))

# Задача 22. Напишите программу, которая принимает текст и выводит два слова: наиболее часто встречающееся и самое длинное.
import collections

text = 'lorem ipsum dolor sit amet amet amet'

words = text.split()
counter = collections.Counter(words)
most_common, occurrences = counter.most_common()[0]

longest = max(words, key=len)