#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import (absolute_import, division, print_function,
                        unicode_literals)
from future.builtins import *  # NOQA @UnusedWildImport

import inspect
import io
import os
import unittest
import warnings

from obspy import UTCDateTime, read_events
from obspy.io.ndk.core import (ObsPyNDKException, _parse_date_time, _is_ndk,
                               _read_ndk)

class NDKTestCase(unittest.TestCase):
    """
    Test suite for obspy.io.ndk
    """
    def setUp(self):
        self.path = os.path.dirname(os.path.abspath(inspect.getfile(
            inspect.currentframe())))
        self.datapath = os.path.join(self.path, "data")

    def test_read_single_ndk(self):
        """
        Test reading a single event from an NDK file and comparing it to a
        QuakeML file that has been manually checked to contain all the
        information in the NDK file.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")
        cat = _read_ndk(filename)

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        self.assertEqual(cat, ref_cat)

    def test_read_multiple_events(self):
        """
        Tests the reading of multiple events in one file. The file has been
        edited to test a variety of settings.
        """
        filename = os.path.join(self.datapath, "multiple_events.ndk")
        cat = _read_ndk(filename)

        self.assertEqual(len(cat), 6)

        # Test the type of moment tensor inverted for.
        self.assertEqual([i.focal_mechanisms[0].moment_tensor.inversion_type
                          for i in cat],
                         ["general", "zero trace", "double couple"] * 2)

        # Test the type and duration of the moment rate function.
        self.assertEqual(
            [i.focal_mechanisms[0].moment_tensor.source_time_function.type
             for i in cat],
            ["triangle", "box car"] * 3)
        self.assertEqual(
            [i.focal_mechanisms[0].moment_tensor.source_time_function.duration
             for i in cat],
            [2.6, 7.4, 9.0, 1.8, 2.0, 1.6])

        # Test the type of depth setting.
        self.assertEqual([i.preferred_origin().depth_type for i in cat],
                         ["from moment tensor inversion", "from location",
                          "from modeling of broad-band P waveforms"] * 2)

        # Check the solution type.
        for event in cat[:3]:
            self.assertIn("Standard",
                          event.focal_mechanisms[0].comments[0].text)
        for event in cat[3:]:
            self.assertIn("Quick",
                          event.focal_mechanisms[0].comments[0].text)

    def test_is_ndk(self):
        """
        Test for the the _is_ndk() function.
        """
        valid_files = [os.path.join(self.datapath, "C200604092050A.ndk"),
                       os.path.join(self.datapath, "multiple_events.ndk")]
        invalid_files = []
        for filename in os.listdir(self.path):
            if filename.endswith(".py"):
                invalid_files.append(os.path.join(self.path, filename))
        self.assertGreater(len(invalid_files), 0)

        for filename in valid_files:
            self.assertTrue(_is_ndk(filename))
        for filename in invalid_files:
            self.assertFalse(_is_ndk(filename))

    def test_reading_using_obspy_plugin(self):
        """
        Checks that reading with the read_events() function works correctly.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")
        cat = read_events(filename)

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        self.assertEqual(cat, ref_cat)

    def test_reading_from_string_io(self):
        """
        Tests reading from StringIO.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")
        with open(filename, "rt") as fh:
            file_object = io.StringIO(fh.read())

        cat = read_events(file_object)
        file_object.close()

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        self.assertEqual(cat, ref_cat)

    def test_reading_from_bytes_io(self):
        """
        Tests reading from BytesIO.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")
        with open(filename, "rb") as fh:
            file_object = io.BytesIO(fh.read())

        cat = read_events(file_object)
        file_object.close()

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        self.assertEqual(cat, ref_cat)

    def test_reading_from_open_file_in_text_mode(self):
        """
        Tests reading from an open file in text mode.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")
        with open(filename, "rt") as fh:
            cat = read_events(fh)

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        self.assertEqual(cat, ref_cat)

    def test_reading_from_open_file_in_binary_mode(self):
        """
        Tests reading from an open file in binary mode.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")
        with open(filename, "rb") as fh:
            cat = read_events(fh)

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        self.assertEqual(cat, ref_cat)

    def test_reading_the_same_file_twice_does_not_raise_a_warnings(self):
        """
        Asserts that reading the same file twice does not raise a warning
        due to resource identifier already in use.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")
        cat_1 = read_events(filename)

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            cat_2 = read_events(filename)

        self.assertEqual(len(w), 0)
        self.assertEqual(cat_1, cat_2)

        filename = os.path.join(self.datapath, "multiple_events.ndk")
        cat_1 = read_events(filename)

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            cat_2 = read_events(filename)

        self.assertEqual(len(w), 0)
        self.assertEqual(cat_1, cat_2)

    def test_is_ndk_for_file_with_invalid_date(self):
        """
        Tests the _is_ndk function for a file with invalid date.
        """
        self.assertFalse(_is_ndk(os.path.join(self.datapath,
                                              "faulty_invalid_date.ndk")))

    def test_is_ndk_for_file_with_invalid_latitude(self):
        """
        Tests the _is_ndk function a file with an invalid latitude.
        """
        self.assertFalse(_is_ndk(os.path.join(self.datapath,
                                              "faulty_invalid_latitude.ndk")))

    def test_is_ndk_for_file_with_infeasible_latitude(self):
        """
        Tests the _is_ndk function a file with an unfeasible latitude.
        """
        self.assertFalse(_is_ndk(os.path.join(
            self.datapath, "faulty_infeasible_latitude.ndk")))

    def test_reading_file_with_multiple_errors(self):
        """
        Tests reading a file with multiple errors.
        """
        filename = os.path.join(self.datapath, "faulty_multiple_events.ndk")

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            cat = read_events(filename)

        self.assertEqual(len(w), 6)
        self.assertIn("Invalid time in event 2", str(w[0]))
        self.assertIn("Unknown data type", str(w[1]))
        self.assertIn("Moment rate function", str(w[2]))
        self.assertIn("Unknown source type", str(w[3]))
        self.assertIn("Unknown type of depth", str(w[4]))
        self.assertIn("Invalid CMT timestamp", str(w[5]))

        # One event should still be available.
        self.assertEqual(len(cat), 1)

    def test_reading_from_string(self):
        """
        Tests reading from a string.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        with io.open(filename, "rt") as fh:
            data = fh.read()

        self.assertTrue(_is_ndk(data))
        cat = _read_ndk(data)

        self.assertEqual(cat, ref_cat)

    def test_reading_from_bytestring(self):
        """
        Tests reading from a byte string.
        """
        filename = os.path.join(self.datapath, "C200604092050A.ndk")

        reference = os.path.join(self.datapath, "C200604092050A.xml")
        ref_cat = read_events(reference)

        with io.open(filename, "rb") as fh:
            data = fh.read()

        self.assertTrue(_is_ndk(data))
        cat = _read_ndk(data)

        self.assertEqual(cat, ref_cat)

    def test_missing_lines(self):
        """
        Tests the raised warning if an event has less then 5 lines.
        """
        with open(os.path.join(self.datapath, "multiple_events.ndk"), "rt") \
                as fh:
            lines = [_i.rstrip() for _i in fh.readlines()]

        # Assemble anew and skip last line.
        data = io.StringIO("\n".join(lines[:-1]))

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter("always")
            cat = read_events(data)

        data.close()

        self.assertEqual(len(w), 1)
        self.assertIn("Not a multiple of 5 lines", str(w[0]))
        # Only five events will have been read.
        self.assertEqual(len(cat), 5)

    def test_reading_event_with_faulty_but_often_occurring_timestamp(self):
        """
        The timestamp "O-00000000000000" is not valid according to the NDK
        definition but occurs a lot in the GCMT catalog thus we include it
        here.
        """
        filename = os.path.join(self.datapath, "faulty_cmt_timestamp.ndk")

        cat = read_events(filename)

        self.assertEqual(len(cat), 1)
        comments = cat[0].focal_mechanisms[0].comments
        self.assertIn("CMT Analysis Type: Unknown", comments[0].text)
        self.assertIn("CMT Timestamp: O-000000000", comments[1].text)

    def test_raise_exception_if_no_events_in_file(self):
        """
        The parser is fairly relaxed and will skip invalid files. This test
        assures that an exception is raised if every event has been skipped.
        """
        with open(os.path.join(self.datapath, "C200604092050A.ndk"), "rt") \
                as fh:
            lines = [_i.rstrip() for _i in fh.readlines()]

        # Assemble anew and skip last line.
        data = io.StringIO("\n".join(lines[:-1]))

        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            self.assertRaises(ObsPyNDKException, read_events, data)

    def test_parse_date_time_function(self):
        """
        Tests the _parse_date_time() function.
        """
        # Simple tests for some valid times.
        date, time = "1997/11/03", "19:17:33.8"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(1997, 11, 3, 19, 17, 33, int(8E5)))
        date, time = "1996/11/20", "19:42:56.1"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(1996, 11, 20, 19, 42, 56, int(1E5)))
        date, time = "2005/01/01", "01:20:05.4"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2005, 1, 1, 1, 20, 5, int(4E5)))
        date, time = "2013/03/01", "03:29:46.8"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2013, 3, 1, 3, 29, 46, int(8E5)))
        date, time = "2013/03/02", "07:53:43.8"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2013, 3, 2, 7, 53, 43, int(8E5)))

        # Some more tests for 60s. The tested values are all values occurring
        # in a big NDK test file.
        date, time = "1998/09/27", "00:57:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(1998, 9, 27, 0, 58))
        date, time = "2000/12/22", "16:29:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2000, 12, 22, 16, 30))
        date, time = "2003/06/19", "23:04:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2003, 6, 19, 23, 5))
        date, time = "2005/06/20", "02:32:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2005, 6, 20, 2, 33))
        date, time = "2006/03/02", "17:16:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2006, 3, 2, 17, 17))
        date, time = "2006/05/26", "10:25:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2006, 5, 26, 10, 26))
        date, time = "2006/08/20", "13:34:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2006, 8, 20, 13, 35))
        date, time = "2007/04/20", "00:30:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2007, 4, 20, 0, 31))
        date, time = "2007/07/02", "00:54:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2007, 7, 2, 0, 55))
        date, time = "2007/08/27", "17:11:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2007, 8, 27, 17, 12))
        date, time = "2008/09/24", "01:36:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2008, 9, 24, 1, 37))
        date, time = "2008/10/05", "10:44:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2008, 10, 5, 10, 45))
        date, time = "2009/04/17", "04:09:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2009, 4, 17, 4, 10))
        date, time = "2009/06/03", "14:30:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2009, 6, 3, 14, 31))
        date, time = "2009/07/20", "10:44:60.0"
        self.assertEqual(_parse_date_time(date, time),
                         UTCDateTime(2009, 7, 20, 10, 45))

def suite():
    return unittest.makeSuite(NDKTestCase, "test")

if __name__ == "__main__":
    unittest.main(defaultTest="suite")


import megengine as mge
import megengine.functional as F
import megengine.module as M
from .net_continous import Actor, Critic, ActorCritic

class ActorDDPG(Actor):
    def __init__(self, *args):
        super().__init__(*args)

    def get_losses(self, inputs):
        critic_net = inputs['critic_net']
        batch = inputs['batch']
        actor_inputs = {'obs' : mge.Tensor(batch.obs) }

        actions, hidden = self.network_forward(actor_inputs)
        critic_inputs = {'obs' : mge.Tensor(batch.obs), 'act' : actions}
        actor_loss = - critic_net.network_forward(critic_inputs).mean()

        return {
            'actor_loss' : actor_loss,
        }

class CriticDDPG(Critic):
    def __init__(self, *args):
        super().__init__(*args)

    def get_losses(self, inputs):
        batch = inputs['batch']
        net_inputs = {
            'obs': mge.Tensor(batch.obs),
            'act': mge.Tensor(batch.act)
        }
        weight = getattr(batch, "weight", 1.0)
        current_q = self.network_forward(net_inputs).flatten()
        target_q = batch.returns.flatten()
        td = current_q - target_q
        critic_loss = (F.pow(td, 2) * weight).mean()
        inputs['batch'].weight = td

        return {
            'critic_loss' : critic_loss,
        }

ActorCriticDDPG = ActorCritic


import pygame
from .base import BaseState

class Gameplay(BaseState):
    def __init__(self):
        super(Gameplay, self).__init__()
        self.rect = pygame.Rect((0, 0), (80, 80))
        self.rect.center = self.screen_rect.center
        self.next_state = "GAME_OVER"

    def get_event(self, event):
        if event.type == pygame.QUIT:
            self.quit = True
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_UP:
                self.rect.move_ip(0, -10)
            if event.key == pygame.K_DOWN:
                self.rect.move_ip(0, 10)
            if event.key == pygame.K_LEFT:
                self.rect.move_ip(-10, 0)
            if event.key == pygame.K_RIGHT:
                self.rect.move_ip(10, 0)
            if event.key == pygame.K_SPACE:
                self.done = True

    def draw(self, surface):
        surface.fill(pygame.Color("black"))
        pygame.draw.rect(surface, pygame.Color("blue"), self.rect)


import json
from flask import Flask, request
from LocationSKU import LocationSKU
from sqlalchemy import create_engine

from sqlalchemy.orm import sessionmaker

app = Flask(__name__)
engine = create_engine('sqlite:///C:/Users/vihar/demo.db', echo=False)

def get_filter_condition(args):
    form = args.to_dict()
    filters = []
    for col in form:
        filter_expression = (getattr(LocationSKU, col) == form[col])
        filters.append(filter_expression)
    return filters

@app.route("/location_details/", methods=['GET', 'POST', 'PUT', 'DELETE'])
def get_locations():
    if request.method == 'GET':
        args = request.args
    if request.method == 'POST':
        args = request.form
    filter_condition = get_filter_condition(args)
    Session = sessionmaker()
    Session.configure(bind=engine)
    session = Session()
    res = session.query(LocationSKU).filter(*filter_condition).all()
    output = []
    for r in res:
        del r.__dict__['_sa_instance_state']
        output.append(r.__dict__)
    return json.dumps(output)

@app.route("/delete_sku/", methods=['GET', 'DELETE'])
def delete_sku():
    args = request.args
    filter_condition = get_filter_condition(args)
    Session = sessionmaker()
    Session.configure(bind=engine)
    session = Session()
    session.query(LocationSKU).filter(*filter_condition).delete()
    session.commit()
    return "Record removed successfully"

@app.route("/add_sku/", methods=['PUT', 'OPTIONS'])
def add_sku():
    print(request.method)
    args = request.args
    Session = sessionmaker()
    Session.configure(bind=engine)
    session = Session()
    new = LocationSKU(args['SKU'], args['Name'], args['Location'], args['Department'], args['Category'], args['SubCategory'])
    session.add(new)
    session.commit()
    return "Record added successfully"

if '__main__' == __name__:
    app.run(debug=True)


import os

def menu():
    print("\nAGENDA TABAJARA")
    print("1 - CADASTRAR")
    print("2 - LISTAR")
    print("3 - CONSULTAR")
    print("4 - DELETAR")
    print("0 - SAIR")
    opcao = int(input("Qual a sua opção? "))
    return opcao

def cadastrar(contatos):
    nome = input("Digite o nome: ")
    idade = int(input("Digite a idade: "))
    telefone = input("Digite o telefone: ")
    contatos[nome] = {'idade': idade, 'telefone': telefone}

def listar(contatos):
    for nome, info in contatos.items():
        print(f"{nome} - Idade: {info['idade']} - Telefone: {info['telefone']}")

def consultar(contatos):
    nome = input("Digite o nome do contato: ")
    if nome in contatos:
        print(f"{nome} - Idade: {contatos[nome]['idade']} - Telefone: {contatos[nome]['telefone']}")
    else:
        print("Contato não encontrado.")

def deletar(contatos):
    nome = input("Digite o nome do contato que deseja deletar: ")
    if nome in contatos:
        del contatos[nome]
        print(f"Contato {nome} deletado com sucesso.")
    else:
        print("Contato não encontrado.")

def main():
    contatos_iniciais = {
        "Ana": {"idade": 25, "telefone": "1111-1111"},
        "Bruno": {"idade": 30, "telefone": "2222-2222"},
        "Carla": {"idade": 23, "telefone": "3333-3333"},
        "Diego": {"idade": 45, "telefone": "4444-4444"},
        "Eliana": {"idade": 34, "telefone": "5555-5555"},
        "Fernando": {"idade": 40, "telefone": "6666-6666"},
        "Gustavo": {"idade": 29, "telefone": "7777-7777"},
        "Helena": {"idade": 31, "telefone": "8888-8888"},
        "Igor": {"idade": 19, "telefone": "9999-9999"},
        "Julia": {"idade": 27, "telefone": "0000-0000"},
    }

    contatos = contatos_iniciais.copy()

    while True:
        opcao = menu()
        os.system('cls')
        if opcao == 0:
            break
        elif opcao == 1:
            cadastrar(contatos)
        elif opcao == 2:
            listar(contatos)
        elif opcao == 3:
            consultar(contatos)
        elif opcao == 4:
            deletar(contatos)
        else:
            print("Opção inválida. Tente novamente.")
        os.system('pause')

if __name__ == "__main__":
    main()


"""Test parsing corridor configurations."""
import pytest
from srctools import Property as Keyvalues
from srctools.dmx import Element, Attribute, ValueType

from config.corridors import Direction, GameMode, Orient, Config, UIState

# Two sets of sample instance names, for testing parsing.
CORR_SEL = [
    'instances/bee2/some_selected_1.vmf',
    'instances/bee2/some_selected_2.vmf',
    'instances/bee2/some_selected_3.vmf'
]
CORR_UNSEL = [
    'instances/bee2/some_unsel_1.vmf',
    'instances/bee2/some_unsel_2.vmf',
]

def test_conf_parse_kv1() -> None:
    """Test parsing keyvalues1 configs."""
    kv = Keyvalues.root(
        Keyvalues('Corridors', [
            Keyvalues('selected', 'instances/bee2/some_selected_1.vmf'),
            Keyvalues('unselected', 'instances/bee2/some_unsel_1.vmf'),
            Keyvalues('unselected', 'instances/bee2/some_unsel_2.vmf'),
            Keyvalues('selected', 'instances/bee2/some_selected_2.vmf'),
            Keyvalues('selected', 'instances/bee2/some_selected_3.vmf'),
        ])
    )
    assert Config.parse_kv1(kv, 1) == Config(selected=CORR_SEL, unselected=CORR_UNSEL)

    with pytest.raises(AssertionError):  # Check version 2 is not allowed.
        Config.parse_kv1(kv, 2)

def test_conf_export_kv1() -> None:
    """Test exporting keyvalues1 configs."""
    kv = Config(selected=CORR_SEL, unselected=CORR_UNSEL).export_kv1()

    assert len(kv) == 1
    corr = kv.find_key('Corridors')
    assert len(corr) == 5

    # We don't care how these are interspersed.
    selected = [prop.value for prop in corr.find_all('selected')]
    unselected = [prop.value for prop in corr.find_all('unselected')]

    assert selected == CORR_SEL
    assert unselected == CORR_UNSEL

def test_conf_parse_dmx() -> None:
    """Test parsing dmx configs."""
    elem = Element('CorrConfig', 'DMElement')
    elem['selected'] = CORR_SEL
    elem['unselected'] = CORR_UNSEL

    assert Config.parse_dmx(elem, 1) == Config(selected=CORR_SEL, unselected=CORR_UNSEL)

def test_conf_export_dmx() -> None:
    """Test exporting DMX configs."""
    elem = Config(selected=CORR_SEL, unselected=CORR_UNSEL).export_dmx()
    assert len(elem) == 2
    assert list(elem['selected'].iter_string()) == CORR_SEL
    assert list(elem['unselected'].iter_string()) == CORR_UNSEL

@pytest.mark.parametrize('mode', GameMode)
@pytest.mark.parametrize('orient', Orient)
@pytest.mark.parametrize('direction', Direction)
def test_ui_parse_kv1(mode: GameMode, orient: Orient, direction: Direction) -> None:
    """Test parsing keyvalues1 UI state."""
    kv = Keyvalues('Corridor', [
        Keyvalues('mode', mode.value),
        Keyvalues('orient', orient.value),
        Keyvalues('direction', direction.value),
        Keyvalues('width', '272'),
        Keyvalues('height', '849'),
    ])
    assert UIState.parse_kv1(kv, 1) == UIState(
        last_mode=mode, last_orient=orient, last_direction=direction,
        width=272, height=849,
    )

    with pytest.raises(AssertionError):  # Check version 2 is not allowed.
        UIState.parse_kv1(kv, 2)

@pytest.mark.parametrize('mode', GameMode)
@pytest.mark.parametrize('orient', Orient)
@pytest.mark.parametrize('direction', Direction)
def test_ui_export_kv1(mode: GameMode, orient: Orient, direction: Direction) -> None:
    """Test exporting keyvalues1 UI state."""
    kv = UIState(
        last_mode=mode, last_orient=orient, last_direction=direction,
        width=272, height=849,
    ).export_kv1()
    assert len(kv) == 5
    assert kv['mode'] == mode.value
    assert kv['orient'] == orient.value
    assert kv['width'] == '272'
    assert kv['height'] == '849'

@pytest.mark.parametrize('mode', GameMode)
@pytest.mark.parametrize('orient', Orient)
@pytest.mark.parametrize('direction', Direction)
def test_ui_parse_dmx(mode: GameMode, orient: Orient, direction: Direction) -> None:
    """Test parsing dmx UI state."""
    elem = Element('UIState', 'DMEElement')
    elem['mode'] = mode.value
    elem['orient'] = orient.value
    elem['direction'] = direction.value
    elem['width'] = 272
    elem['height'] = 849

    assert UIState.parse_dmx(elem, 1) == UIState(
        last_mode=mode, last_orient=orient, last_direction=direction,
        width=272, height=849,
    )

    with pytest.raises(AssertionError):  # Check version 2 is not allowed.
        UIState.parse_dmx(elem, 2)

@pytest.mark.parametrize('mode', GameMode)
@pytest.mark.parametrize('orient', Orient)
@pytest.mark.parametrize('direction', Direction)
def test_ui_export_dmx(mode: GameMode, orient: Orient, direction: Direction) -> None:
    """Test exporting dmx UI state."""
    elem = UIState(
        last_mode=mode, last_orient=orient, last_direction=direction,
        width=272, height=849,
    ).export_dmx()
    assert len(elem) == 5
    assert elem['mode'].val_string == mode.value
    assert elem['orient'].val_string == orient.value
    assert elem['width'].val_int == 272
    assert elem['height'].val_int == 849


from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('IOT_data_2.csv')

print(data)

plt.xlabel("pressure")
plt.ylabel("id")

#train data 및 test data 나누기
x = data[["pressure"]]
y = data[["id"]]
x_train, x_test, y_train, y_test = train_test_split(x,y,train_size=0.8, test_size=0.2)

#예측 모델 생성
lr = LinearRegression()
lr.fit(x_train,y_train)

#정확도 측정
accuracy = lr.score(x_train,y_train)
print(accuracy)

#예측값 구하기
y_predicted = lr.predict(x_test)
mse = mean_squared_error(y_test, y_predicted)
print(mse)
print('w : ',lr.coef_,lr.intercept_)

#산포도 구해보기
plt.scatter(y_test,y_predicted, alpha=0.5)
plt.show()

21-1 산업인공지능개론/과제/산업현장의 IoT데이터 수집 및 예측 분석 결과/10W-1.py


import cmd
import traceback

from commands.compact import CompactCommand
from commands.get import GetCommand
from commands.incr import IncrCommand
from commands.incrby import IncrbyCommand
from commands.set import SetCommand
from commands.delete import DelCommand

class Karn(cmd.Cmd):
    """Simple command processor example."""
    prompt = '(karn) '

    # For Multi line processing
    multi_mode = False
    multi_commands_queue = []

    # For compact processing
    command_history = []

    def do_GET(self, arg):
        op = self.run(GetCommand, arg)
        if op:
            print(op)

    def do_SET(self, arg):
        op = self.run(SetCommand, arg)
        if op:
            print(op)

    def do_DEL(self, arg):
        op = self.run(DelCommand, arg)
        if op:
            print(op)

    def do_INCR(self, arg):
        op = self.run(IncrCommand, arg)
        if op:
            print(op)

    def do_INCRBY(self, arg):
        op = self.run(IncrbyCommand, arg)
        if op:
            print(op)

    def do_MULTI(self, arg):
        self.multi_mode = True

    def do_EXEC(self, arg):
        self.multi_mode = False
        for command in self.multi_commands_queue:
            self.onecmd(command)
        self.multi_commands_queue = []

    def do_DISCARD(self, arg):
        self.multi_mode = False
        self.multi_commands_queue = []

    def do_COMPACT(self, arg):
        op = self.run(CompactCommand, self.command_history)
        if op:
            print(op)

    def do_EXIT(self, arg):
        return True

    def run(self, command_class, arg):
        command = command_class(arg)
        self.command_history.append({
            'cmd': str(command),
            'arg': arg
        })

        try:
            command.validate()
            if self.multi_mode:
                self.multi_commands_queue.append(f'{command} {arg}')
            else:
                return command.execute()
        except Exception as e:
            print(traceback.format_exc())
            return f'(error) {e}'


import sqlite3
import random

conn = sqlite3.connect('pokemon.db')
db = conn.cursor()

class Pokemon():
    """
    A class used to represent a Pokemon

    ...

    Attributes
    ----------
    name : str
        The name of the pokemon creature
    level : int
        The power level of a pokemon. ranges from 1 to 100
    pokemon_type1 : str
        The primary Type given to a pokemon
    pokemon_type2 : str
        The secondary type for a given pokemon.
    base_hp : int
        The base health points for a given pokemon
    base_attack : int
        THe base physical attack value for a given pokemon
    base_defense : int
        The base physical defense value for a given pokemon
    base_spatk : int
        The base special attack value for a given pokemon
    base_spdef : int
        The base special defense value for a given pokemon
    base_speed : int
        The base speed value for a given pokemon(used to determine which pokemon attacks first)
    fainted : bool
        A flag used to determine if a pokemon can continue combat(default is False)

    Methods
    -------
    pokemon_weak_resist(type1,type2)
        Produces two list containing information on a pokemon's weakness and resistances
    level_up()
        Increases the level and stats of a pokemon
    decrease_hp(amount)
        lowers a pokemons current health points value by amount provided
    increase_hp(amount)
        increases a pokemons current health point value by amount provided
    revive()
        restores the health points of a pokemon that is fainted
    user_attack(attacker,opponent,*pokemon)
        THe active user uses this method for there pokemon to attack each other. Using a *args in the case of multiple pokemon being attacked
    ai_attack(attacker,opponent,*pokemon)
        during comabt this is called to simulate a second trainer giving commands to their pokemon
    move_selection(num, text)
        used to keep player choice within its proper boundary
    learn_move(name, power, damage_type)
        used to update instance attribute 'moves' with new moves determined by trainer
    pokemon_alive()
        changes a pokemons fainted state if their health point is <= 0
    get_hp()
        returns the current health points of a pokemon
    get_fainted()
        returns a pokemons current fainted state

    """
    def __init__(self, name, level, pokemon_type1, pokemon_type2, base_hp, base_attack, base_defense, base_spatk, base_spdef, base_speed, fainted=False):
        #Database Provided
        '''
        Parameters
        ----------
        name : str
            The name of the pokemon creature
        level : int
            The power level of a pokemon. ranges from 1 to 100
        pokemon_type1 : str
            The primary Type given to a pokemon
        pokemon_type2 : str
            The secondary type for a given pokemon.
        base_hp : int
            The base health points for a given pokemon
        base_attack : int
            THe base physical attack value for a given pokemon
        base_defense : int
            The base physical defense value for a given pokemon
        base_spatk : int
            The base special attack value for a given pokemon
        base_spdef : int
            The base special defense value for a given pokemon
        base_speed : int
            The base speed value for a given pokemon(used to determine which pokemon attacks first)
        fainted : bool
            A flag used to determine if a pokemon can continue combat(default is False)

        '''
        self.name = name
        self.level = level
        self.pokemon_type1 = pokemon_type1
        self.pokemon_type2 = pokemon_type2
        self.base_hp = base_hp
        self.base_attack = base_attack
        self.base_defense = base_defense
        self.base_spatk = base_spatk
        self.base_spdef = base_spdef
        self.base_speed = base_speed

        self.maximum_hp = base_hp
        self.current_hp = base_hp
        self.fainted = fainted

        #_pokemon_weakness
        self.weakness = []
        #_pokemon_resistance
        self.resistance = []

        #FIX: create a function that adds move to a pokemon. [limt being no more that 4 moves]
        self.moves = [{"name":"Tackle", "damage": 35, "damage_type": "Normal"}]
        self.maximum_level = 100

    def __str__(self):
        all_moves = ""
        for move in self.moves:
            all_moves = all_moves + move["name"]+"|"+ "Power:"+ str(move["damage"])+"\n"

        return f"Pokemon Name: {self.name.capitalize()}\nHP: {self.current_hp}/{self.maximum_hp}\nLevel: {self.level} \nType1: {self.pokemon_type1}\nType2: {self.pokemon_type2}\n----------\nWeakness:\n{self.weakness}\n----------\nResistance:\n{self.resistance}\n----------\nMoves:\n{all_moves}"

    def __repr__(self):
        return f"Pokemon({self.name},{self.level},{self.pokemon_type1},{self.pokemon_type2},{self.base_hp},{self.base_attack},{self.base_defense},{self.base_spatk},{self.base_defense},{self.base_speed})"

    def _pokemon_resistance(self, type1, type2):
        db.execute('SELECT resistance, immune FROM pokemon_resistance WHERE type= :type',{'type':type1 })
        type1_resistance = db.fetchall()

        for resist in type1_resistance:
            self.resistance.append({'type': resist[0], 'multiplier': .5})

        if type1 != type2:
            db.execute('SELECT resistance, immune FROM pokemon_resistance WHERE type= :type',{'type':type2 })
            type2_resistance = db.fetchall()

            temp = 0
            for resist2 in type2_resistance:
                for i in range(0,len(self.resistance)):

                    if resist2[0] == self.resistance[i]['type']:
                        self.resistance[i]['multiplier']*=.5
                        temp = i
                        break

                if resist2[0] != self.resistance[temp]['type']:
                    if resist2[1] == "YES":
                        self.resistance.append({'type': resist2[0], 'multiplier': 0})
                    else:
                        self.resistance.append({'type': resist2[0], 'multiplier': .5})

    def _pokemon_weakness(self, type1, type2):
        db.execute('SELECT weakness FROM pokemon_type WHERE type= :type',{'type':type1 })
        type1_weakness = db.fetchall()

        for item in type1_weakness:
            self.weakness.append({'type': item[0], 'multiplier': 2})

        if type1 != type2:
            db.execute('SELECT weakness FROM pokemon_type WHERE type= :type',{'type':type2 })
            type2_weakness = db.fetchall()

            #Making sure that any overlapping weaknesses are stacked instead of showing up 2x
            temp = 0
            for typei in type2_weakness:
                for i in range(0,len(self.weakness)):

                    if typei[0] == self.weakness[i]['type']:
                        self.weakness[i]['multiplier']*=2

                        temp = i
                        break

                if typei[0] != self.weakness[temp]['type']:
                    self.weakness.append({'type': typei[0], 'multiplier': 2})

    def pokemon_weak_resist(self, type1, type2):
        self._pokemon_weakness(type1,type2)
        self._pokemon_resistance(type1, type2)

        #Removing all false weaknesses
        for value in range(0,len(self.resistance)):
            for val in self.weakness:
                if self.resistance[value]['type']  == val['type']:
                    temp = self.weakness[self.weakness.index(val)]['multiplier']
                    self.weakness[self.weakness.index(val)]['multiplier']*=self.resistance[value]['multiplier']
                    self.resistance[value]['multiplier']*=temp

        modified_weakness = [weakness for weakness in self.weakness if weakness['multiplier'] >= 2]
        self.weakness = modified_weakness

        modified_resistance = [resistance for resistance in self.resistance if resistance['multiplier'] <= .5]
        self.resistance = modified_resistance

    def level_up(self):
        if self.level < self.maximum_level:
            self.level+=1
            #simplistic approach
            hp_base = random.randint(5,10)
            self.base_hp+=hp_base
            self.maximum_hp+=hp_base

            self.base_attack+= random.randint(3,4)
            self.base_defense+= random.randint(3,4)
            self.base_spatk+= random.randint(3,4)
            self.base_spdef+= random.randint(3,4)
            self.base_speed+= random.randint(3,4)
            print(f"{self.name} has gained a level")

        else:
            print("{pokemon} level  is already maxed and will not go any higher")

    def decrease_hp(self,amount):
        if self.fainted is False:

            if self.current_hp - amount <= 0:
                self.fainted = True
                self.current_hp = 0
            else:
                self.current_hp-=amount
                return print(f"{self.name}'s HP has been reduced to {self.current_hp}/{self.maximum_hp}")

        print(f"Your pokemon {self.name} has fainted")

    def increase_hp(self,amount):
        if self.current_hp == self.maximum_hp:
            return f"Your {self.name} HP is already full \n"
        elif self.current_hp == 0:
            self.fainted = True
            return f"You can not use health point items on your Fainted {self.name} \n"
        elif (self.current_hp + amount) > self.maximum_hp:
            self.current_hp = self.maximum_hp
            return f"{self.name} has been healed to full hp \n"
        else:
            self.current_hp += amount
            return f"Your {self.name} has been healed by {amount}. Current HP is {self.current_hp}/{self.maximum_hp} \n"

    def revive(self):
        if self.fainted is True:
            self.current_hp = int(self.maximum_hp/2)
            return f"Your pokemon {self.name} has been revived"
        else:
            return "The item revive has no effect on pokemon not fainted"

    def user_attack(self,attacker, opponent,*pokemons):
        for i, move in enumerate(self.moves, start=1):
            print(f"{i}) Move Name: { move['name']} Power:{move['damage']}")

        move_number = self.move_selection(len(self.moves),f"What move would you want {self.name.title()} to use?: \n")

        # print(self.moves[move_number-1]["damage"])
        for pokemon in pokemons:
            #for Super Effective Moves 2x
            if self.moves[move_number-1]["damage_type"] in pokemon.weakness:
                print(f"{attacker.name}'s {self.name} attacks {opponent.name}'s {pokemon.name} for {self.moves[move_number-1]['damage'] * 2} damage")
                pokemon.decrease_hp(self.moves[move_number-1]["damage"] * 2)

            #for resistance .5 or.25
            elif self.moves[move_number-1]["damage_type"] in pokemon.resistance:
                index = pokemon.resistance.index(self.moves[move_number-1]["damage_type"].upper())
                print(f"{attacker.name}'s {self.name} attacks {opponent.name}'s {pokemon.name} for {self.moves[move_number-1]['damage'] * pokemon.resistance[index]['multiplier']} damage")
                pokemon.decrease_hp(self.moves[move_number-1]["damage"] * pokemon.resistance[index]['multiplier'] )

            #for Normal Damage 1x
            else:
                print(f"{attacker.name}'s {self.name} attacks {opponent.name}'s {pokemon.name} for {self.moves[move_number-1]['damage']} damage")
                pokemon.decrease_hp(self.moves[move_number-1]["damage"])

    def ai_attack(self, attacker, opponent,*pokemons):
        for pokemon in pokemons:
            #for Super Effective Moves 2x
            if self.moves[0]["damage_type"] in pokemon.weakness:
                print(f"**{attacker.name}'s {self.nam.title()} attacks {opponent.name}'s {pokemon.name.title()} for {self.moves[0]['damage'] * 2} damage**\n")
                pokemon.decrease_hp(self.moves[0]["damage"] * 2)

            # for resistance .25x .5x
            elif self.moves[0]["damage_type"] in pokemon.resistance:
                index = pokemon.resistance.index(self.moves[0]["damage_type"].upper())
                print(f"{attacker.name}'s {self.name.title()} attacks {opponent.name}'s {pokemon.name.title()} for {self.moves[0]['damage'] * pokemon.resistance[index]['multiplier']} damage")
                pokemon.decrease_hp(self.moves[0]["damage"] * pokemon.resistance[index]['multiplier'] )

            #for Normal Damage 1x
            else:
                print(f"{attacker.name}'s {self.name.title()} attacks {opponent.name}'s {pokemon.name.title()} for {self.moves[0]['damage']} damage")
                pokemon.decrease_hp(self.moves[0]["damage"])

    def move_selection(self,num, text):
        lst = list(range(1,num+1))
        answer= 0
        while answer not in lst:
            try:
                answer = int(input(text))

                if answer not in range(1,num+1):
                    raise ValueError
                break
            except ValueError:
                print('Select a valid Number')

        return answer

    #-----------------------------------NEEDS WORK--------------------------------
    def learn_move(self, name, power, damage_type):
        for move in self.moves:
            if name == move["name"]:
                print("your pokemon already knows this move")
                return

        self.moves.append({"name": name, "damage": power, "damage_type": damage_type})
    #-------------------------------------------------------------------------------

    def pokemon_alive(self):
        if self.current_hp <= 0:
            self.fainted = True
        else:
            self.get_hp()

    def get_hp(self):
        return self.current_hp

    def get_max_hp(self):
        return self.maximum_hp

    def get_fainted(self):
        return self.fainted


"""
岛屿问题
"""

from queue import Queue

class MyCircularQueue(object):

    def __init__(self, k=100):
        """
        Initialize your data structure here. Set the size of the queue to be k.
        :type k: int
        """
        self.q = [None for i in range(k + 1)]
        self.head = 0
        self.tail = 0
        self.k = k

    def enQueue(self, value):
        """
        Insert an element into the circular queue. Return true if the operation is successful.
        :type value: int
        :rtype: bool
        """
        if self.isFull():
            return False
        else:
            self.tail = self.next_index(self.tail)
            self.q[self.tail] = value
            return True

    def deQueue(self):
        """
        Delete an element from the circular queue. Return true if the operation is successful.
        :rtype: bool
        """
        if self.isEmpty():
            return False
        else:
            self.head = self.next_index(self.head)
            return True

    def Front(self):
        """
        Get the front item from the queue.
        :rtype: int
        """
        if self.isEmpty():
            return -1
        else:
            next_head = self.next_index(self.head)
            return self.q[next_head]

    def Rear(self):
        """
        Get the last item from the queue.
        :rtype: int
        """
        if self.isEmpty():
            return -1
        else:
            res = self.q[self.tail]
            # self.tail = self.last_index(self.tail)
            return res

    def isEmpty(self):
        """
        Checks whether the circular queue is empty or not.
        :rtype: bool
        """
        return self.head == self.tail

    def isFull(self):
        """
        Checks whether the circular queue is full or not.
        :rtype: bool
        """
        return self.next_index(self.tail) == self.head

    def next_index(self, index):
        """
        """
        if index == self.k:
            return 0
        else:
            return index + 1

    def last_index(self, index):
        if index == 0:
            return self.k
        else:
            return index - 1

    def empty(self):
        return self.isEmpty()

    def get(self):
        res = self.Front()
        self.deQueue()
        return res

    def put(self, value):
        return self.enQueue(value)

class Solution(object):

    def __init__(self):
        super(Solution, self).__init__()
        # self.q = Queue()
        self.q = MyCircularQueue()

    def _get_node_list(self, grid):
        """"""
        node_list = []
        i = 0
        for row in grid:
            j = 0
            for node in row:
                if node == '1':
                    node_list.append((i, j))
                j += 1
            i += 1
        return node_list

    def _get_arounds(self, node, grid):
        """获取周围的点"""
        try:
            k = grid[node[0]][node[1]]
        except Exception as e:
            k = '0'
        return k

    def _bfs(self, node, node_set, grid):
        """"""
        self.q.put(node)
        while not self.q.empty():
            node = self.q.get()
            round_list = [(node[0]+1, node[1]), (node[0]-1, node[1]), (node[0], node[1]+1), (node[0], node[1]-1)]
            for r_node in round_list:
                if r_node in node_set:
                    self.q.put(r_node)
                    node_set.remove(r_node)

    def numIslands(self, grid):
        """
        :type grid: List[List[str]]
        :rtype: int
        """
        node_set = set(self._get_node_list(grid))
        res = 0
        while len(node_set) > 0:
            res += 1
            node = node_set.pop()
            self._bfs(node, node_set, grid)
        return res

if __name__ == '__main__':

    x = """11110
11010
11000
00000"""
#     x = """11000
# 11000
# 00100
# 00011"""
    g = []
    for i in x.split('\n'):
        g.append(list(i))
    res = Solution().numIslands(g)
    print(res)


import torch

from torch_cluster import radius, radius_graph

from typing import Tuple

def torch_neighbor_list(data, rcut, self_interaction=True, num_workers=1, max_num_neighbors=1000):
    if 'pbc' in data:
        pbc = data.pbc
    else:
        pbc = torch.zeros(3, dtype=bool, device=data.pos.device)

    if torch.any(pbc):
        if 'cell' not in data:
            raise ValueError(f'Periodic systems need to have a unit cell defined')
        idx_i, idx_j, cell_shifts, self_interaction_mask = torch_neighbor_list_pbc(data, rcut, self_interaction=self_interaction, num_workers=num_workers, max_num_neighbors=max_num_neighbors)
    else:
        idx_i, idx_j, self_interaction_mask = torch_neighbor_list_no_pbc(data, rcut, self_interaction=self_interaction,
                                               num_workers=num_workers, max_num_neighbors=max_num_neighbors)
        cell_shifts = torch.zeros((idx_i.shape[0], 3), dtype=data.pos.dtype, device=data.pos.device)

    return idx_i, idx_j, cell_shifts, self_interaction_mask

@torch.jit.script
def compute_images(positions: torch.Tensor, cell: torch.Tensor, pbc: torch.Tensor, cutoff: float, batch: torch.Tensor, n_atoms: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
    cell = cell.view((-1, 3, 3)).to(torch.float64)
    pbc = pbc.view((-1, 3))
    reciprocal_cell = torch.linalg.inv(cell).transpose(2, 1)
    # print('reciprocal_cell: ', reciprocal_cell.device)
    inv_distances = reciprocal_cell.norm(2, dim=-1)
    # print('inv_distances: ', inv_distances.device)
    num_repeats = torch.ceil(cutoff * inv_distances).to(torch.long)
    num_repeats_ = torch.where(pbc, num_repeats, torch.zeros_like(num_repeats))
    # print('num_repeats_: ', num_repeats_.device)
    images, batch_images, shifts_expanded, shifts_idx_ = [], [], [], []
    for i_structure in range(num_repeats_.shape[0]):
        num_repeats = num_repeats_[i_structure]
        r1 = torch.arange(-num_repeats[0], num_repeats[0] + 1, device=cell.device, dtype=torch.long)
        r2 = torch.arange(-num_repeats[1], num_repeats[1] + 1, device=cell.device, dtype=torch.long)
        r3 = torch.arange(-num_repeats[2], num_repeats[2] + 1, device=cell.device, dtype=torch.long)
        shifts_idx = torch.cartesian_prod(r1, r2, r3)
        shifts = torch.matmul(shifts_idx.to(cell.dtype), cell[i_structure])
        pos = positions[batch == i_structure]
        shift_expanded = shifts.repeat(1, n_atoms[i_structure]).view((-1, 3))
        pos_expanded = pos.repeat(shifts.shape[0], 1)
        images.append(pos_expanded + shift_expanded)

        batch_images.append(i_structure*torch.ones(images[-1].shape[0], dtype=torch.int64, device=cell.device))
        shifts_expanded.append(shift_expanded)
        shifts_idx_.append(shifts_idx.repeat(1, n_atoms[i_structure]).view((-1, 3)))
    return (torch.cat(images, dim=0), torch.cat(batch_images, dim=0),
                torch.cat(shifts_expanded, dim=0), torch.cat(shifts_idx_, dim=0))

@torch.jit.script
def strides_of(v: torch.Tensor) -> torch.Tensor:
    strides = torch.zeros(v.shape[0]+1, dtype=torch.int64, device=v.device)
    strides[1:] = v
    strides = torch.cumsum(strides, dim=0)
    return strides

def torch_neighbor_list_no_pbc(data, rcut, self_interaction=True, num_workers=1, max_num_neighbors=1000):
    # assert data.n_atoms.shape[0] == 1, 'data should contain only one structure'

    edge_index = radius_graph(data.pos, rcut, batch=data.batch, max_num_neighbors = max_num_neighbors,
                        num_workers=num_workers, flow='target_to_source', loop=self_interaction)
    self_interaction_mask = edge_index[0] != edge_index[1]
    return edge_index[0], edge_index[1], self_interaction_mask

@torch.jit.script
def get_j_idx(edge_index: torch.Tensor, batch_images:torch.Tensor, n_atoms: torch.Tensor) -> torch.Tensor:
    # get neighbor index reffering to the list of original positions
    n_neighbors = torch.bincount(edge_index[0])
    strides = strides_of(n_atoms)
    n_reapeats = torch.zeros_like(n_atoms)
    for i_structure,(st,nd) in enumerate(zip(strides[:-1], strides[1:])):
        n_reapeats[i_structure] = torch.sum(n_neighbors[st:nd])
    n_atoms = torch.repeat_interleave(n_atoms, n_reapeats, dim=0)

    batch_i = torch.repeat_interleave(strides[:-1], n_reapeats, dim=0)

    n_images = torch.bincount(batch_images)
    strides_images = strides_of(n_images[:-1])
    images_shift = torch.repeat_interleave(strides_images, n_reapeats, dim=0)

    j_idx = torch.remainder(edge_index[1]-images_shift, n_atoms) + batch_i
    return j_idx

def torch_neighbor_list_pbc(data, rcut, self_interaction=True, num_workers=1, max_num_neighbors=1000):
    images, batch_images, shifts_expanded, shifts_idx = compute_images(data.pos, data.cell, data.pbc, rcut, data.batch, data.n_atoms)
    edge_index = radius(x=images, y=data.pos, r=rcut, batch_x=batch_images, batch_y=data.batch,
                        max_num_neighbors = max_num_neighbors,
                        num_workers = num_workers)

    j_idx = get_j_idx(edge_index,batch_images, data.n_atoms)

    # find self interactions
    is_central_cell = (shifts_idx[edge_index[1]] == 0).all(dim=1)
    mask = torch.cat([is_central_cell.view(-1,1), (edge_index[0] == j_idx).view(-1,1)], dim=1)
    self_interaction_mask = torch.logical_not(torch.all(mask,dim=1))

    if self_interaction:
        idx_i, idx_j = edge_index[0], j_idx
        cell_shifts = shifts_expanded[edge_index[1]]
    else:
        # remove self interaction
        idx_i, idx_j = edge_index[0][self_interaction_mask], j_idx[self_interaction_mask]
        cell_shifts = shifts_expanded[edge_index[1][self_interaction_mask]]

    return idx_i, idx_j, cell_shifts, self_interaction_mask

def wrap_positions(data, eps=1e-7):
    """Wrap positions to unit cell.

    Returns positions changed by a multiple of the unit cell vectors to
    fit inside the space spanned by these vectors.

    Parameters:

    data:
        torch_geometric.Data
    eps: float
        Small number to prevent slightly negative coordinates from being
        wrapped.

    """
    center=torch.tensor((0.5, 0.5, 0.5)).view(1, 3)
    assert data.n_atoms.shape[0] == 1, f"There should be only one structure, found: {data.n_atoms.shape[0]}"

    pbc = data.pbc.view(1,3)
    shift = center - 0.5 - eps

    # Don't change coordinates when pbc is False
    shift[torch.logical_not(pbc)] = 0.0

    # assert np.asarray(cell)[np.asarray(pbc)].any(axis=1).all(), (cell, pbc)

    cell = data.cell
    positions = data.pos

    fractional = torch.linalg.solve(cell.t(),
                                 positions.t()).t() - shift

    for i, periodic in enumerate(pbc.view(-1)):
        if periodic:
            fractional[:, i] = torch.remainder(fractional[:, i], 1.0)
            fractional[:, i] += shift[0, i]

    data.pos = torch.matmul(fractional, cell)


class Node:
    def __init__(self, data):
        self.data=data
        self.left=None
        self.right=None
def printTree(root):
    if root == None:
        return
    print(root.data, end= ":")
    if root.left != None:
        print("L", root.left.data, end=",")
    if root.right != None:

        print("R", root.right.data, end="")
    print()
    printTree(root.left)
    printTree(root.right)

def treeInput():
    rootData=int(input())
    if rootData == -1:
        return None
    root = Node(rootData)
    leftTree=treeInput()
    rightTree=treeInput()
    root.left=leftTree
    root.right=rightTree
    return root
def largestData(root):
    if root==None:
        return -1
    leftLargest=largestData(root.left)
    rightLargest=largestData(root.right)
    ans=max(leftLargest,rightLargest,root.data)
    return ans
def numLeafNodes(root):
    if root==None:
        return 0
    if root.left==None and root.right == None:
        return 1
    numLL=numLeafNodes(root.left)
    numLR=numLeafNodes(root.right)
    return numLL+numLR

def numNodes(root):
    if root==None:
        return 0
    leftCount=numNodes(root.left)
    rightCount=numNodes(root.right)
    return 1+leftCount+rightCount

def printDepthK(root, k):
    if root == None:
        return
    if k == 0:
        print(root.data)
        return
    printDepthK(root.left, k-1)
    printDepthK(root.right, k-1)

def printDepthKV2(root, k, d=0):
    if root == None:
        return
    if k==d:
        print(root.data)
        return
    printDepthKV2(root.left, k, d+1)
    printDepthKV2(root.right, k, d+1)
root=treeInput()
printTree(root)
print(largestData(root))
print(numLeafNodes(root))
printDepthK(root, 2)
printDepthKV2(root, 2)


import numpy as np
import matplotlib.pyplot as plt

a = [[1, 2], [3, 4]]
print(a)
b = []
for i in a:
    b.append(i.copy())
a[0][0] = 5
print(a)
print(b)