from django.contrib import admin
from django.contrib.auth import get_user_model
from hijack.contrib.admin import HijackUserAdminMixin
from django.db.models import ForeignKey, IntegerField, F, Sum
from django.db.models.expressions import Value, Case, When, Subquery, OuterRef, ExpressionWrapper
from django.db.models.functions import Coalesce, Least
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from import_export import resources, fields
from import_export.admin import ImportExportActionModelAdmin, ExportActionMixin
from import_export.results import RowResult
from import_export.widgets import ForeignKeyWidget

from api.crud import get_ongoing_semester, get_negative_hours, SumSubquery
from sport.models import Student, MedicalGroup, StudentStatus, Semester, Sport, Attendance, Debt, FitnessTestGrading, \
    FitnessTestResult, Enroll
from sport.signals import get_or_create_student_group
from .inlines import ViewAttendanceInline, AddAttendanceInline, ViewMedicalGroupHistoryInline
from .site import site
from .utils import user__role, DefaultFilterMixIn

class FitnessTestExcerciseInline(admin.TabularInline):
    model = FitnessTestResult
    extra = 0

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'semester':
            kwargs['initial'] = get_ongoing_semester()
            return db_field.formfield(**kwargs)
        return super().formfield_for_foreignkey(
            db_field, request, **kwargs
        )

class HoursFilter(admin.SimpleListFilter):
    title = 'hours'
    parameter_name = 'hours'

    def lookups(self, request, model_admin):
        return (
            ('less', 'Less -60'),
            ('-31', 'From -60 to -31'),
            ('-1', 'From -30 to -1'),
            ('29', 'From 0 to 29'),
            ('more', 'More 30')
        )

    def queryset(self, request, queryset):
        value = self.value()
        if value == 'less':
            return queryset.filter(complex_hours__lt=-60)
        if value == '-31':
            return queryset.filter(complex_hours__lt=-30).filter(complex_hours__gte=-60)
        if value == '-1':
            return queryset.filter(complex_hours__lt=0).filter(complex_hours__gte=-30)
        if value == '29':
            return queryset.filter(complex_hours__lt=30).filter(complex_hours__gte=0)
        elif value == 'more':
            return queryset.filter(complex_hours__gte=30)
        return queryset

class StudentResource(resources.ModelResource):
    medical_group = fields.Field(
        column_name="medical_group",
        attribute="medical_group",
        widget=ForeignKeyWidget(MedicalGroup, "name"),
    )

    student_status = fields.Field(
        column_name="student_status",
        attribute="student_status",
        widget=ForeignKeyWidget(StudentStatus, "name"),
    )

    sport = fields.Field(
        column_name="sport",
        attribute="sport",
        widget=ForeignKeyWidget(Sport, "name"),
    )

    complex_hours = fields.Field(attribute='complex_hours', readonly=True)

    def get_or_init_instance(self, instance_loader, row):
        student_group = get_or_create_student_group()
        user_model = get_user_model()
        user, _ = user_model.objects.get_or_create(
            email=row["email"],
            defaults={
                "first_name": row.get("first_name"),
                "last_name": row.get("last_name"),
            },
        )

        student_model_fields = [
            f.name
            for f in Student._meta.fields
            if not isinstance(f, ForeignKey)
        ]

        student_import_fields = row.keys() & student_model_fields

        student, student_created = Student.objects.get_or_create(
            user=user,
            defaults=dict([
                (key, row[key])
                for key in student_import_fields
            ])
        )
        if student_created:
            user.groups.add(student_group)

        return student, student_created

    class Meta:
        model = Student
        fields = (
            "user",
            "user__email",
            "user__first_name",
            "user__last_name",
            "enrollment_year",
            "course",
            "has_QR",
            "telegram",
            "is_online",
        )
        export_order = (
            "user",
            "user__email",
            "user__first_name",
            "user__last_name",
            "enrollment_year",
            "course",
            "has_QR",
            "medical_group",
            "student_status",
            "is_online",
            'sport',
            'complex_hours',
            "telegram",
        )
        import_id_fields = ("user",)
        skip_unchanged = False
        report_skipped = True
        raise_errors = False

    def import_row(self, row, instance_loader, **kwargs):
        # overriding import_row to ignore errors and skip rows that fail to import
        # without failing the entire import
        import_result = super().import_row(row, instance_loader, **kwargs)
        if import_result.import_type == RowResult.IMPORT_TYPE_ERROR:
            # Copy the values to display in the preview report
            import_result.diff = [
                None,
                row.get('email'),
                row.get('first_name'),
                row.get('last_name'),
                row.get('medical_group'),
                row.get('enrollment_year'),
                row.get('course'),
                row.get('has_QR'),
                row.get('telegram'),
            ]
            # Add a column with the error message
            import_result.diff.append(mark_safe(
                f'''Errors:
{''.join([f'
{err.error}
' for err in import_result.errors])}
'''
            ))
            # clear errors and mark the record to skip
            import_result.errors = []
            import_result.import_type = RowResult.IMPORT_TYPE_SKIP

        return import_result

@admin.register(Student, site=site)
class StudentAdmin(HijackUserAdminMixin, ImportExportActionModelAdmin, DefaultFilterMixIn):
    default_filters = ['student_status__id__exact=0']
    resource_class = StudentResource

    def get_fields(self, request, obj=None):
        if obj is None:
            return (
                "user",
                "medical_group",
                "enrollment_year",
                "course",
                "student_status",
                "telegram",
            )
        return (
            "user",
            "gender",
            "has_QR",
            "is_online",
            "medical_group",
            "enrollment_year",
            "course",
            "sport",
            "student_status",
            "telegram" if obj.telegram is None or len(
                obj.telegram) == 0 else ("telegram", "write_to_telegram"),
            "comment",
        )

    autocomplete_fields = (
        "user",
    )

    search_fields = (
        "user__first_name",
        "user__last_name",
        "user__email",
        "telegram",
    )

    list_filter = (
        "course",
        "enrollment_year",
        "is_online",
        "medical_group",
        'student_status',
        'sport',
        'has_QR',
        HoursFilter
    )

    list_display = (
        "__str__",
        user__role,
        "has_QR",
        "is_online",
        "course",
        "medical_group",
        "sport",
        "complex_hours",
        "student_status",
        "write_to_telegram",
    )

    readonly_fields = (
        "write_to_telegram",
    )

    def write_to_telegram(self, obj):
        return None if obj.telegram is None else \
            format_html(
                '{}',
                obj.telegram[1:],
                obj.telegram
            )

    def complex_hours(self, obj: Student):
        return obj.complex_hours
    complex_hours.admin_order_field = 'complex_hours'

    ordering = (
        "user__first_name",
        "user__last_name"
    )

    inlines = (
        ViewMedicalGroupHistoryInline,
        ViewAttendanceInline,
        AddAttendanceInline,
        FitnessTestExcerciseInline
    )

    # https://stackoverflow.com/a/66730984
    def change_view(self, request, object_id, form_url='', extra_context=None):
        try:
            obj = self.model.objects.get(pk=object_id)
        except self.model.DoesNotExist:
            pass
        else:
            if obj.medical_group.name == 'Medical checkup not passed':
                self.inlines = (ViewAttendanceInline,)
        return super().change_view(request, object_id, form_url, extra_context)

    def get_queryset(self, request):
        qs = super().get_queryset(request)

        qs = qs.annotate(_debt=Coalesce(
            SumSubquery(Debt.objects.filter(semester_id=get_ongoing_semester().pk,
                                            student_id=OuterRef("pk")), 'debt'),
            0
        ))
        qs = qs.annotate(_ongoing_semester_hours=Coalesce(
            SumSubquery(Attendance.objects.filter(
                training__group__semester_id=get_ongoing_semester().pk, student_id=OuterRef("pk")), 'hours'),
            0
        ))
        qs = qs.annotate(complex_hours=ExpressionWrapper(
            F('_ongoing_semester_hours') - F('_debt'), output_field=IntegerField()
        ))

        return qs

    def get_hijack_user(self, obj):
        return obj.user

    def delete_sport(self, request, queryset):
        queryset.update(sport=None)
        Enroll.objects.filter(student__in=queryset, group__semester=get_ongoing_semester()).delete()
    delete_sport.short_description = 'Deselect sport type and group'

    def increase_course(self, request, queryset):
        queryset.filter(student_status_id=0, course__gte=4).update(course=None, student_status_id=3)
        queryset.filter(student_status_id=0, course__lte=3).update(course=F('course') + 1)

    actions = [ExportActionMixin.export_admin_action, delete_sport, increase_course]

    list_select_related = (
        "user",
        "medical_group",
    )


import os
import time
from mpi4py import MPI
if __name__=="__main__":
    comm = MPI.COMM_WORLD
    my_rank = comm.Get_rank()
    num_procs = comm.Get_size()

    SLURM_NTASKS=os.environ["SLURM_NTASKS"]
    SLURM_PROCID=os.environ["SLURM_PROCID"]

    processor_name=MPI.Get_processor_name()

    if my_rank == 0:
        print("This is process 0 (name: %s). We have %d processes."%(processor_name, num_procs))
        for other_rank in range(1,num_procs):
            comm.send(
                obj="Hello %d"%(other_rank),
                dest=other_rank,
                tag=0
            )

        for other_rank in range(1,num_procs):
            data = comm.recv(
                source=other_rank,
                tag=0
            )
            print(data)
    else:
        data = comm.recv(
            source=0,
            tag=0
        )
        assert data.startswith("Hello ")
        comm.send(
            obj="Process %d (name: %s) reporting for duty."%(my_rank,processor_name),
            dest=0,
            tag=0
        )
    print("Process %d going to sleep"%(my_rank))
    time.sleep(20)


#!/usr/bin/python
import rospy
from std_msgs.msg import String
from sensor_msgs.msg import Joy
import numpy as np
from serial import Serial
from lin_deltaz_utils import move_to_xyz_pos
import numpy as np
import linear_actuator_pb2
from time import sleep
from singlearm_ros.msg import MoveFingersAction, MoveFingersActionResult
import actionlib

BTN_Y_INDEX = 3
BTN_B_INDEX = 1

class DeltaZ:
    def __init__(self):
        rospy.init_node("linear_delta_node")
        self.publish_deltaZ = False
        self.vertical_control = False

        self.trials_to_collect = 0
        self.pub = rospy.Publisher("/grasp_startstop", String, queue_size=10)
        self.joy_sub = rospy.Subscriber("/joy", Joy, self.joy_callback)
        self.delta_actionserver = actionlib.SimpleActionServer(
            "move_fingers",
            MoveFingersAction,
            execute_cb=self.run_command,
            auto_start=False,
        )
        self.delta_actionserver.start()
        self.clf_pub = rospy.Publisher("/classifier_commands", String, queue_size=10)
        self.record_pub = rospy.Publisher("/record_trial", String, queue_size=10)
        self.arduino = Serial("/dev/ttyACM1", 57600)
        self.delta_message = linear_actuator_pb2.lin_actuator()
        self.delta_message.id = 1
        self.pinch = False
        self.rub = False
        self.is_pinch = rospy.get_param("/app/grasp_type") == "norub"
        self.is_rub = rospy.get_param("/app/grasp_type") == "vertrub"

        self.no_of_rubs = 2

    def execute_open(self):
        rospy.loginfo("Opening gripper")
        y_offset = rospy.get_param("/app/y_offset")
        push_force = rospy.get_param("/app/push_force")
        base_pos = np.array([-push_force, y_offset, 3, push_force, y_offset, 3])
        move_to_xyz_pos(base_pos, self.delta_message, self.arduino)
        sleep(0.5)

    def execute_close(self):
        rospy.loginfo("Closing gripper")
        y_offset = rospy.get_param("/app/y_offset")
        push_force = rospy.get_param("/app/push_force")
        base_pos = np.array([push_force, y_offset, 3, -push_force, 0, 3])
        sleep(0.1)
        rospy.loginfo("calling close")
        move_to_xyz_pos(base_pos, self.delta_message, self.arduino)
        self.clf_pub.publish("start")  # start classifier
        sleep(0.5)
        self.clf_pub.publish("end")  # start classifier

    def execute_robustify_grasp(self):
        rospy.loginfo("Adjusting gripper")
        y_offset = rospy.get_param("/app/y_offset")
        push_force = rospy.get_param("/app/push_force")

        base_pos = np.array([1.9, y_offset, 3, -0.5, 0, 3])
        move_to_xyz_pos(base_pos, self.delta_message, self.arduino)

        z_in = 3.8
        poses = [
            np.array([-1.0, y_offset, z_in, -0.5, 0, 3]),  # scoop bottom finger
            np.array([push_force, y_offset, z_in, -push_force, 0, z_in + 0.1]),
            np.array([push_force, y_offset, z_in, -push_force, 0, z_in]),
            np.array([push_force, y_offset, 3, -push_force, 0, 3]),
        ]
        for i in range(2):
            for pose in poses:
                move_to_xyz_pos(pose, self.delta_message, self.arduino)

    def execute_pinch(self):
        self.pub.publish("start")
        self.record_pub.publish("start_%s_%f_%f_%d" % ("pinch", 0, 0, 0))
        sleep(1)
        push_force = rospy.get_param("/app/push_force")

        y_offset = rospy.get_param("/app/y_offset")

        base_pos = np.array([push_force, y_offset, 3, -push_force, 0, 3])
        final_pos = np.array([-push_force, y_offset, 3, push_force, 0, 3])

        if rospy.get_param("/app/random_grasp_pos") == 1:
            stop = False
            while not stop:
                yrand, xrand = np.random.uniform(
                    low=-0.75, high=0.75, size=2
                )  # changed from 1
                rand_base_pos = base_pos + np.array([0, yrand, xrand, 0, yrand, xrand])
                finger1_norm = np.linalg.norm(rand_base_pos[:3] - final_pos[:3])
                finger2_norm = np.linalg.norm(rand_base_pos[3:] - final_pos[3:])
                stop = finger1_norm > 0.1 and finger2_norm > 0.1
            rospy.loginfo(rand_base_pos)
        else:
            rand_base_pos = base_pos

        rospy.loginfo("Pinching")
        move_to_xyz_pos(rand_base_pos, self.delta_message, self.arduino)
        self.clf_pub.publish("start")  # start classifier
        sleep(1.0)
        self.clf_pub.publish("end")  # end classifier

        rospy.loginfo("Releasing")
        rospy.loginfo(final_pos)
        move_to_xyz_pos(final_pos, self.delta_message, self.arduino)

        sleep(0.1)
        self.record_pub.publish("stop")
        self.pub.publish("stop")
        sleep(1)

    def execute_rub(self, is_vert_rub=True, time_per=0.2):

        push_force = rospy.get_param("/app/push_force")
        is_finger1 = rospy.get_param("/app/is_finger_1")

        if is_vert_rub:
            z1 = 3.8
            z2 = 1.8
            if is_finger1:
                rub_start_xyz = [push_force, 0, z1, -push_force, 0, 3]
                rub_end_xyz = [push_force, 0, z2, -push_force, 0, 3]
            else:
                rub_start_xyz = [push_force, 0, 3, -push_force, 0, z1]
                rub_end_xyz = [push_force, 0, 3, -push_force, 0, z2]

        else:  # horizontal rub
            y1 = 2
            y2 = -2
            if is_finger1:
                rub_start_xyz = [push_force, y1, 3, -push_force, 0, 3]
                rub_end_xyz = [push_force, y2, 3, -push_force, 0, 3]
            else:
                rub_start_xyz = [push_force, 0, 3, -push_force, y1, 3]
                rub_end_xyz = [push_force, 0, 3, -push_force, y2, 3]

        move_to_xyz_pos([1.5, 0, 3, -1.5, 0, 3.8], self.delta_message, self.arduino)
        for i in range(self.no_of_rubs):
            move_to_xyz_pos(rub_start_xyz, self.delta_message, self.arduino)
            sleep(time_per)
            move_to_xyz_pos(rub_end_xyz, self.delta_message, self.arduino)
            sleep(time_per)
        move_to_xyz_pos([-1.5, 0, 3, 1.5, 0, 3], self.delta_message, self.arduino)
        sleep(1)

    def execute_dbg(self):
        """
        After a grasp we want to move the fingers slightly forward in order to get a much better grasp of the cloth.
        """
        rospy.loginfo("Moving gripper forward")
        y_offset = rospy.get_param("/app/y_offset")
        push_force = rospy.get_param("/app/push_force")
        z_forward = 1
        push_force_reduce = 1.7
        final_pose = np.array(
            [
                push_force - push_force_reduce,
                y_offset,
                3,
                -(push_force - push_force_reduce),
                0,
                3,
            ]
        )
        move_to_xyz_pos(final_pose, self.delta_message, self.arduino)
        sleep(0.1)
        final_pose = np.array(
            [
                push_force - push_force_reduce,
                y_offset,
                3 + z_forward,
                push_force,
                0,
                3 + z_forward,
            ]
        )
        move_to_xyz_pos(final_pose, self.delta_message, self.arduino)
        sleep(0.1)
        final_pose = np.array(
            [push_force, y_offset, 3 + z_forward, -(push_force), 0, 3 + z_forward]
        )
        self.clf_pub.publish("start")  # start classifier
        sleep(0.5)
        self.clf_pub.publish("end")  # start classifier

    def execute_moveforward(self):
        """
        After a grasp we want to move the fingers slightly forward in order to get a much better grasp of the cloth.
        """
        rospy.loginfo("Moving gripper forward")
        y_offset = rospy.get_param("/app/y_offset")
        push_force = rospy.get_param("/app/push_force")
        z_forward = 1
        push_force_reduce = 1
        final_pose = np.array(
            [push_force - push_force_reduce, y_offset, 3, -(push_force), 0, 3]
        )
        move_to_xyz_pos(final_pose, self.delta_message, self.arduino)
        sleep(0.1)
        final_pose = np.array(
            [push_force - push_force_reduce, y_offset, 3, -push_force, 0, 3 + z_forward]
        )
        move_to_xyz_pos(final_pose, self.delta_message, self.arduino)
        sleep(0.1)
        final_pose = np.array([push_force, y_offset, 3, -push_force, 0, 3])
        move_to_xyz_pos(final_pose, self.delta_message, self.arduino)
        self.clf_pub.publish("start")  # start classifier
        sleep(1)
        self.clf_pub.publish("end")  # start classifier

    def joy_callback(self, data):
        if data.buttons[BTN_B_INDEX] != 1:
            return

        self.collection_mode = rospy.get_param("/app/collection_mode")
        self.num_auto_trials = rospy.get_param("/app/num_auto_trials")
        self.trials_to_collect = (
            self.num_auto_trials if self.collection_mode == "auto" else 1
        )

        while self.trials_to_collect > 0:
            if self.is_pinch:
                self.execute_pinch()
                self.trials_to_collect -= 1
                if self.trials_to_collect == 0:
                    self.pinch = False
            elif self.is_rub:
                self.execute_open()
                self.execute_close()
                self.execute_rub(is_vert_rub=True)
                self.execute_open()
                self.trials_to_collect -= 1
                if self.trials_to_collect == 0:
                    self.rub = False
            else:
                rospy.logerr("neither pinch nor rub command sent to linear delta")
                raise NotImplementedError

    def run_command(self, msg):
        command = msg.command.data
        if "dbg_" in command:
            command = command.replace("dbg_", "")
            debug = True
        else:
            debug = False

        rospy.loginfo("Delta action command received: %s" % command)

        if debug:
            self.record_pub.publish("start_%s_%f_%f_%d" % ("command", 0, 0, 0))
            sleep(0.5)

        if command == "open":
            self.execute_open()
        elif command == "close":
            self.execute_close()
        elif command == "robustify":
            self.execute_robustify_grasp()
        elif command == "pinch":
            self.execute_pinch()
        elif command == "vertrub":
            self.execute_rub(is_vert_rub=True)
        elif command == "horzrub":
            self.execute_rub(is_vert_rub=False)
        elif command == "moveforward":
            self.execute_moveforward()
        else:
            rospy.logerr("unrecognized command sent to linear delta: %s" % command)
            raise NotImplementedError

        if debug:
            sleep(0.5)
            self.record_pub.publish("stop")

        result = MoveFingersActionResult()
        self.delta_actionserver.set_succeeded(result)

if __name__ == "__main__":
    dz = DeltaZ()
    rospy.spin()


from detective_game import *
from sheet import *
login()
get_username()
from detective_game import NAME
print ("Hello " + (NAME) + "!")
time.sleep(1)
read_storyline()
time.sleep(8)
ask_to_begin()
read_story_1()
time.sleep(3)
read_question_1()
time.sleep(3)
ans_question_1()
read_story_2()
time.sleep(5)
read_question_2()
time.sleep(3)
ans_question_2()
read_story_3()
time.sleep(5)
read_question_3()
time.sleep(3)
ans_question_3()
time.sleep(3)
read_story_4()
time.sleep(5)
read_question_4()
time.sleep(3)
ans_question_4()
read_story_5()
time.sleep(5)
read_question_5()
time.sleep(3)
ans_question_5()
read_story_6()
time.sleep(5)
read_question_6()
time.sleep(3)
ans_question_6()
read_story_7()
time.sleep(5)
read_question_7()
time.sleep(3)
ans_question_7()

status = 'unkown'
"""Status is used to determine whether suspiscion was raised enough
for you to be arrested or free,
the if statement below takes the sus level
 and assignes status the correct value based on your sus level"""

from sheet import *

def update_sheet():
    row = [(NAME), (status), (sus)]
    index = 2
    RESULTS.insert_row(row, index)
from detective_game import sus
if sus >= 3:
    print('You have been brought in for further quesitioning. You raised the suspiscions of the detective')
    status = 'arrested'
    update_sheet()
    begin = input('Would you like to try again? \n 1 = Yes, 2 = No \n')
    if begin == '1':
        pass
    elif begin == '2':
        print('Okay, maybe next time! Goodbye')
        exit()
    else:
        print('Invalid entry please select option 1 or 2')
        ask_to_begin()
else:
    print('The detective left without his suspiscion being raised enough to bring you in. Congrats ' + (NAME) + '!')
    status = 'free'
    update_sheet()


"""The Functions Module contains functions that are either used by probability
or that are used for manipulating Node Elements.

@author Nicholas Cottrell
@author Justyn Diaz
@date 2021-04-05
"""

from .Elements import Node
from itertools import product

def normalize(arr: list) -> list:
    """Normalizes a list of numbers based on the sum of all its values
    """
    total = sum(arr)
    return list(map(lambda x: x / total, arr))

def Not(probability: float) -> float:
    """Probabilistic not function.
    @param probability a float number that represents the probability of a
    fact being true.
    @returns a float probability of a fact not being true.
    """
    return 1 - probability

def get_node(label: str, arr: list) -> Node:
    """This function gets the node that belongs to the given label
    in a given array
    @param label the label of the element desired
    @param arr the list of nodes to search for
    @returns the Node with the given label or None if it is not present
    """
    for i in arr:
        if i.key == label:
            return i
    return None

def get_roots(element: Node) -> set:
    """ Gets the roots of a given node
    @param element the element that you want to get
    @returns the set that contains all roots to the given element
    """
    results = set()
    if len(element.get_dependencies()) == 0:
        return set(element)  # return itself because it is itself a root
    for i in element.get_dependencies():
        if len(i.get_dependencies()) == 0:
            # if the element being checked has no dependencies, then it is a root
            results.add(i)
        else:
            # if not, ask the element what its roots are
            results.update(get_roots(i))
    return results

def get_history(element: Node) -> set:
    """ This function gets all of the dependencies of the given node, and
    the dependencies of those all the way to the roots
    @param element the node that you want to get the entire history of
    @returns a set of all the nodes that the element remotely depends on
    """
    results = set(element.get_dependencies())
    for elm in element.get_dependencies():
        results.update(get_history(elm))
    return results

def __enum(target: Node, *given: Node, **observed: bool) -> list:
    # Get given variable that enumerate all gets probability for
    spackage = get_history(target)
    spackage.update(given)
    # include everything up to roots
    for i in given:
        spackage.update(get_history(i))

    # convert back to list to keep indexes
    package = list(spackage)

    # making table of conditions
    conditions = [[True, False] for a in package]

    # Changing boolean sets based on observed
    for key in observed.keys():
        if get_node(key, package):
            conditions[package.index(get_node(key, package))] = [observed[key]]
    iters = list(product(*conditions))
    sum_vals = [1 for a in iters]

    for conditional in range(len(sum_vals)):
        for node in range(len(package)):
            # making dict to get what values both have in common
            pstate = spackage.intersection(package[node].get_dependencies())
            state = dict()
            for s in pstate:
                state[s.key] = iters[conditional][package.index(s)]

            pval = float()
            if (len(pstate) == 0):
                pval = package[node]()[0]
            else:
                pval = package[node](**state)[0]
            if not iters[conditional][node]:
                pval = Not(pval)

            sum_vals[conditional] *= pval

        # Getting dictionary differences for the given variable
        pstate = spackage.intersection(target.get_dependencies())
        state = dict()
        for s in pstate:
            state[s.key] = iters[conditional][package.index(s)]

        sum_vals[conditional] *= target(**state)[0]
    return sum_vals

def enumeration_all(target: Node = None, *given: Node, **observed: bool) -> float:
    """Returns the absolute probability of a node given certain environment variables.
    @param target the node that you want to get the whole probability of its success.
    @param given nodes that are given to have been used in finding the targets
    probability.
    @param observed a dictionary of values acting as the probabilities that are
    a constant chance.
    @returns a probability value of that target being true in any circumstance
    based on observed truths.
    """
    # contingency if variables is empty
    if not target:
        return 1
    return sum(__enum(target, *given, **observed))

def enumeration_ask(target: Node = None, *vars: Node, **evidence: bool) -> list:
    """Ask for all potential probabilities of a given node being true and asks
    for that distribution.
    @param target the node that you want to get the whole probability of its success.
    @param vars nodes that are given to have been used in finding the targets
    probability.
    @param evidence a dictionary of values acting as the probabilities that are
    a constant chance.
    @returns a normalized distribution of the given variable.
    """
    return normalize(__enum(target, *vars, **evidence))


import torch
import math
import torch.nn as nn
import torch.functional as F
from matplotlib import pyplot as plt
from torchvision import transforms

def expand_split_svbrdf(input_svbrdf):
    # input_svbrdf: [N, 9, H, W], 2, 3, 1, 3; between [-1,1]
    splited = input_svbrdf.split(1, dim=-3)

    diffuse = map_to_img(torch.cat(splited[2:5], dim=-3))  # [8,3,H,W], [0,1]
    roughness_scalar = map_to_img(torch.cat(splited[5:6], dim=-3))  # [8,1,H,W], [0,1]
    specular = map_to_img(torch.cat(splited[6:9], dim=-3))  # [8,3,H,W], [0,1]

    roughness_shape = [1, 3, 1, 1]
    roughness = roughness_scalar.repeat(roughness_shape)

    normals_xy = torch.cat(splited[0:2], dim=-3)  # [8,2,H,W], [-1,1]
    # normals_x, normals_y = torch.split(normals_xy.mul(3.0), 1, dim=-3)
    normals_x, normals_y = torch.split(normals_xy, 1, dim=-3)  # [-1,1]
    normals_z = torch.ones_like(normals_x)
    normals = torch.cat([normals_x, normals_y, normals_z], dim=-3)
    norm = torch.sqrt(torch.sum(torch.pow(normals, 2.0), dim=-3, keepdim=True))
    normals = torch.div(normals, norm)  # norm, [N, 3, H, W], [-1,1]
    normals = map_to_img(normals)

    # 4*[N,3,H,W], between [0,1]
    return normals, diffuse, roughness, specular

def split_svbrdf(input_svbrdf):
    # input_svbrdf: [N, 12, H, W], between [0,1]
    splited = input_svbrdf.split(1, dim=-3)

    normals = torch.cat(splited[0:3], dim=-3)  # [8,3,H,W], [0,1]
    diffuse = torch.cat(splited[3:6], dim=-3)  # [8,3,H,W], [0,1]
    roughness = torch.cat(splited[6:9], dim=-3)  # [8,3,H,W], [0,1]
    specular = torch.cat(splited[9:12], dim=-3)  # [8,3,H,W], [0,1]

    return normals, diffuse, roughness, specular

def expand_svbrdf(input_svbrdf):
    # input_svbrdf: [N, 9, H, W], 2, 3, 1, 3; between [-1,1]
    normals, diffuse, roughness, specular = expand_split_svbrdf(input_svbrdf)
    # [N,12,H,W], between [0,1]
    expanded = torch.cat([normals, diffuse, roughness, specular], dim=-3)

    return expanded

def generate_normalized_random_direction(count):
    # def generate_normalized_random_direction(count=5, min_eps=0.001, max_eps=0.05):
    theta = torch.Tensor(count, 1).uniform_(1.0/6.0, 1.0/4.0)*math.pi
    phi = torch.Tensor(count, 1).uniform_(0.0, 1.0)*math.pi
    z = torch.cos(theta)
    xy = torch.sin(theta)
    x = xy * torch.cos(phi)
    y = xy * torch.sin(phi)
    return torch.cat([x, y, z], dim=-1)

def generate_distance():
    distance = torch.Tensor(1).uniform_(6, 8)
    # distance = torch.Tensor(1).uniform_(8, 10)
    return torch.sqrt(distance)

to_img = transforms.ToPILImage()
to_tensor = transforms.ToTensor()
scale_trans = transforms.Resize([288, 288])

def map_to_img(x):
    return x/2.0 + 0.5

def de_map(x):
    return 2.0*x - 1.0

def displayimg(t):
    img = to_img(t)
    plt.imshow(img)
    plt.show()

def displaybrdf(t):
    # t: [12,H,W]
    C_total, H, W = t.shape
    t = t.reshape(4, 3, H, W)  # [3,4,H,W]
    normals = t[0]
    albedo = t[1]
    roughness = t[2]
    specular = t[3]
    img = torch.cat([normals, albedo, roughness, specular], dim=-1)
    img = to_img(img.reshape(3, H, W*4))
    plt.imshow(img)
    plt.show()


from tkinter import *
import threading
from tkinter.filedialog import askopenfilename
#from tkFileDialog import askopenfilename

class VendBulkCustomerDelGUI:

    def __init__(self, deletefunc):
        """
            Constructor for the GUI. The delete function passed is the entry
            function in the calling class/module to bind to the delete button.
        """

        self.__deletefunc = deletefunc
        self.root = Tk()
        self.root.geometry("700x500")
        self.root.call('tk','scaling', 2.0)
        #self.root.geometry("650x450")
        self.root.minsize(650,450)
        #self.root.resizable(0,0)
        self.root.title("Vend Bulk Customer Delete")
        self.root.pack_propagate(0)
        header = Label(self.root, text="Bulk Customer Delete", bd=1, font="San-Serif 18 bold", bg="#41B04B", fg="white")
        header.pack(side=TOP, anchor=W, fill=X)

        # container for the main widgets
        mainFrame = Frame(self.root)
        mainFrame.pack(padx=20, pady=10)

        self.__loadUserInputs__(mainFrame)
        self.__loadButtons__(mainFrame)
        self.__loadCsvControl__(mainFrame)
        self.__loadCheckListControl__(mainFrame)
        self.__loadMessageControls__(mainFrame)

        self.root.geometry("650x450")

    def __loadUserInputs__(self, mainFrame):
        """
            Loads the user input controls onto the given parent frame
        """
        lblStorePrefix = Label(mainFrame, text="Store Prefix:", font="Helvetica 14 bold")
        lblStorePrefix.grid(row=1, column=0, sticky=E)

        lblToken = Label(mainFrame, text="Token:", font="Helvetica 14 bold")
        lblToken.grid(row=2, column=0, sticky=E)

        lblCsv = Label(mainFrame, text="CSV File:", font="Helvetica 14 bold")
        #lblCsv.grid(row=3, column=0, sticky=E)

        #textboxes
        self.txtPrefix = Entry(mainFrame)
        self.txtToken = Entry(mainFrame)
        self.txtPrefix.grid(row=1,column=1, sticky=W)
        self.txtToken.grid(row=2,column=1, sticky=W)

        csvframe = Frame(mainFrame)
        self.txtCsv = Entry(csvframe)

        #self.txtCsv.pack(side=LEFT)
        #self.btnOpenCsvDialog.pack()
        #csvframe.grid(row=3,column=1, sticky=W)

    def __loadButtons__(self, mainFrame):
        """
            Loads the button controls onto the given parent frame
        """
        btnframe = Frame(mainFrame)
        self.btnDelCust = Button(btnframe, text="Delete Customers", command=self.startThread)
        self.btnDelCust.pack(side=RIGHT, padx=5)
        self.btnReset = Button(btnframe, text="Reset", command=self.reset)
        self.btnReset.pack()
        btnframe.grid(row=4, column=1, padx=5)

    def __loadCsvControl__(self, mainFrame):
        """
            Loads the CSV file controls onto the given parent frame
        """
        self.csvList = []
        self.csvFileDict = {}
        self.csvListbox = Listbox(mainFrame, listvariable=self.csvList, width=25, bd=0.5, selectmode='single')

        #csvHeader.grid(row=0, column=2)
        self.csvListbox.grid(row=1, column=2, rowspan=3, padx=10)

        csvFrame = Frame(mainFrame, padx=10)

        csvHeader = Label(csvFrame, text="CSV Files", font="Helvetica 14 bold")
        csvHeader.pack(side=LEFT)

        csvFrame.grid(row=4, column=2, sticky=E)
        self.btnOpenCsvDialog = Button(csvFrame, text="+", font="Helvetica 14 bold", command=self.openFile, width=3)
        self.btnOpenCsvDialog.pack(side=LEFT)
        self.btnDeleteFile = Button(csvFrame, text="-", font="Helvetica 14 bold", command=self.deleteFileFromList, width=3)
        self.btnDeleteFile.pack()

    def __loadCheckListControl__(self, mainFrame):
        """
            Loads the check list controls onto the given parent frame
        """
        checklistFrame = Frame(mainFrame, width=200, height=200, bd=1)
        #Label(mainFrame, text="Checklist", font="Helvetica 14 bold").grid(row=0, column=3)
        checklistFrame.grid(row=3, column=1)

        self.paConfirmation = BooleanVar()
        self.tokenExpiry = BooleanVar()
        self.chkPaConfirm = Checkbutton(checklistFrame, text="PA Confirmation", variable=self.paConfirmation)
        self.chkPaConfirm.grid(row=1, sticky=W)
        self.chkTokenExpiry = Checkbutton(checklistFrame, text="Token Expiry Set", variable=self.tokenExpiry)
        self.chkTokenExpiry.grid(row=2, sticky=W)

    def __loadMessageControls__(self, mainFrame):
        """
            Loads the status/result message controls onto the given parent frame
        """
        self.statusMsg = StringVar()
        self.lblStatus = Label(self.root, textvariable=self.statusMsg, bd=1, relief=SUNKEN, anchor=W, bg="#3A4953", fg="white", font="Helvetica 14 italic")
        self.lblStatus.pack(side=BOTTOM, fill=X)

        resultFrame = Frame(mainFrame)
        resultFrame.grid(row=5,column=0, columnspan=3, rowspan=4)

        self.resultText = StringVar()
        resultLabel = Message(resultFrame, textvariable=self.resultText,font="Helvetica 16", width=500)
        resultLabel.pack(pady=15)

    def reset(self):
        """
            Function to reset the state of the GUI.
        """
        self.setStatus("")
        self.setReadyState()
        self.txtToken.delete(0,END)
        self.txtPrefix.delete(0,END)
        self.paConfirmation.set(0)
        self.tokenExpiry.set(0)
        del self.csvList[:]
        self.csvListbox.delete(0,END)
        self.csvFileDict = {}
        self.setResult("")

    def deleteFileFromList(self):
        """
            Function to delete the selected file from the CSV listbox as well
            as the corresponding list variable and dictionary.
        """
        selected = self.csvListbox.curselection()

        if selected:
            self.csvListbox.delete(selected[0])
            self.csvFileDict.pop(self.csvList[selected[0]], None)
            del self.csvList[selected[0]]

    def entriesHaveValues(self):
        """
            Returns true/false whether the required input values have been
            provided
        """
        return (len(self.txtPrefix.get().strip()) > 0) and (len(self.txtToken.get().strip()) > 0) and (len(self.csvList) > 0)

    def startThread(self):
        """
            Main function to start the thread to the provided function of the
            controller that creates/calls this class.
        """
        self.setStatus("")
        self.setDeletingState()
        thr = threading.Thread(target=self.__deletefunc, args=(), kwargs={})

        thr.start()
        #self.setReadyState()

    def isChecklistReady(self):
        """ Returns whether the checklist is completed. """
        return self.tokenExpiry.get() and self.paConfirmation.get()

    def openFile(self):
        """
            When the + button is clicked to add CSV files, opens the file opener
            dialog to retrieve the file.
        """
        filepath = askopenfilename(parent=self.root)
        tempArr = filepath.split("/")

        filename = tempArr[len(tempArr)-1]

        if self.csvFileDict.get(filename, None) is not None:
            self.setStatus("{0} has been added already.".format(filename))
            return

        self.csvFileDict[filename] = filepath
        self.csvList.append(filename)

        self.csvListbox.insert(END, filename)

    def setStatus(self, msg):
        """ Sets the status message to the provided string. """
        self.statusMsg.set(msg)

    def setResult(self, msg):
        """ Sets the result variable to the given string. """
        self.resultText.set(msg)

    def setDeletingState(self):
        """ Sets all the controls to disabled state to prevent any multi-clicks"""
        self.btnReset.config(state=DISABLED)
        self.btnDelCust.config(state=DISABLED)
        self.btnOpenCsvDialog.config(state=DISABLED)
        self.btnDeleteFile.config(state=DISABLED)
        self.txtToken.config(state=DISABLED)
        self.txtPrefix.config(state=DISABLED)
        self.chkPaConfirm.config(state=DISABLED)
        self.chkTokenExpiry.config(state=DISABLED)
        self.root.update()

    def setReadyState(self):
        """ Resets all controls back to normal state."""
        self.btnReset.config(state=NORMAL)
        self.btnDelCust.config(state=NORMAL)
        self.btnOpenCsvDialog.config(state=NORMAL)
        self.btnDeleteFile.config(state=NORMAL)
        self.txtToken.config(state=NORMAL)
        self.txtPrefix.config(state=NORMAL)
        self.chkPaConfirm.config(state=NORMAL)
        self.chkTokenExpiry.config(state=NORMAL)
        self.root.update()

    def main(self):
        """ Main loop for this GUI. """
        self.root.mainloop()


import scrapy
from scrapy_dangdang_03.items import ScrapyDangdang03Item

class DangSpider(scrapy.Spider):
    name = "dang"
    #如果是多页下载的话那么必须要调整的是allowed_domains的范围  一般情况下只写域名
    allowed_domains = ["category.dangdang.com"]
    start_urls = ["http://category.dangdang.com/cp01.01.02.00.00.00.html"]
    # http://category.dangdang.com/cp01.01.02.00.00.00.html
    # http://category.dangdang.com/pg2-cp01.01.02.00.00.00.html

    str_url = 'http://category.dangdang.com/cp01.01.02.00.00.00.html'
    page = 1

    def parse(self, response):

        # pipelines 下载数据
        # item    定义数据结构
        # src = '//ul[@id="component_59"]/li//img/@src'
        # name = '//ul[@id="component_59"]/li//img/@alt'
        # price = '//ul[@id="component_59"]/li//p[@class="price"]/span[1]/text()
        # 所有的seletor的对象 都可以再次调用xpath方法
        li_list = response.xpath('//ul[@id="component_59"]/li')

        for li in li_list:
            src = li.xpath('.//img/@data-original').extract_first()
            # 第一张图片和其他图片的src地址不一样
            src = src or li.xpath('.//img/@src').extract_first()

            name = li.xpath('.//img/@alt').extract_first()
            price = li.xpath('.//p[@class="price"]/span[1]/text()').extract_first()
            # 获取一个book就将book交给pipelines下载
            yield ScrapyDangdang03Item(src = src,name = name,price = price)
            # print(src,name,price)

        if self.page < 20:
            self.page += 1
            url = self.str_url.replace('cp', f'pg{self.page}-cp') if self.page > 1 else self.str_url
            print(f'这是循环网址：{url}')

            # 怎么去调用parse方法
            # scrapy . Request就是scrpay的get请求url就是请求地址
            # callback是你要执行的那个函数注意不需要加()
            yield scrapy.Request(url=url,callback=self.parse)


from heapq import heappop, heappush
import sys
input = sys.stdin.readline

n = int(input())
q = []
for _ in range(n):
    x = int(input())
    if x == 0 and q:
        print(heappop(q))
    elif x == 0 and not q:
        print(0)
    else:
        heappush(q, x)


import torch
from torch import nn
from torch.nn import functional as F
from torch import optim

@torch.jit.script
def gaussian(x, centers, widths):
    return torch.exp((-(x - centers)**2) / (2 * widths**2))

@torch.jit.script
def triangular(x, lefts, centers, rights, zero):
    return torch.fmax(
        torch.fmin(
            (x - lefts) / (centers - lefts), (rights - x) / (rights - centers)
        ),
        zero,
    )

@torch.jit.script
def difference_of_sigmoid(x, lefts, rights):
    return F.sigmoid(x - lefts) - F.sigmoid(x - rights)

class AnfisLayer(nn.Module):
    """
        Module for an AnfisLayer in PyTorch
    """
    def __init__(self,
            in_dim,
            n_rules=8,
            membership_type="Gaussian",
            normal_dis_factor=2.0,
            order=1,
            normalize_rules=True,
        ):
        """
            in_dim:                  The number of inputs for the AnfisLayer*
            n_rules:                 The number of rules for each input
            membership_type:         The type of rule to use for the AnfisLayer
            normal_dis_factor:       What to multiply the original position of the rules
            order:                   The order of the AnfisLayer. 0 means no additional parameters or biases are used.
                                     1 means there are additional parameters and biases multiplied and added to the input
            normalize_rules:         Whether to normalize the rules or not. If encountering NaNs or infs, try
                                     not normalizing the rules as it may lead to numerical instability

            *NOTE: The number of input dimensions will match the number of output dimensions.
                   This is because the AnfisLayer will be used at the end of the network. If you want to
                   to have the number of inputs be different than the number of outputs, use another
                   layer before the AnfisLayer to increase the complexity of the network.
        """
        super(AnfisLayer, self).__init__()

        # Membership functions
        if membership_type == "Gaussian":
            # Means (centers) and Standard Deviation (widths)
            self.register_parameter("centers", nn.Parameter(torch.randn(in_dim, n_rules) * normal_dis_factor))
            self.register_parameter("widths", nn.Parameter(torch.rand(in_dim, n_rules) * normal_dis_factor))

            self.membership_function = self.gaussian_membership_function
        elif membership_type == "Triangular":
            # Centers (centers), and left/right points (center +/- width)
            self.register_parameter("centers", nn.Parameter(torch.randn(in_dim, n_rules) * normal_dis_factor))
            self.register_parameter("left_widths", nn.Parameter(torch.rand(in_dim, n_rules) * normal_dis_factor))
            self.register_parameter("right_widths", nn.Parameter(torch.rand(in_dim, n_rules) * normal_dis_factor))
            self.register_buffer("common_zero", torch.tensor(0.0))

            self.membership_function = self.triangular_membership_function
        elif membership_type == "Difference of Sigmoid":
            self.register_parameter("lefts", nn.Parameter(torch.randn(in_dim, n_rules) * normal_dis_factor))
            self.register_parameter("rights", nn.Parameter(self.lefts.clone() + torch.rand(in_dim, n_rules)))

            self.membership_function = self.difference_of_sigmoid_membership_function
        else:
            # TODO: Add in other membership functions
            raise NotImplementedError(f"AnfisLayer with membership type <{self.membership_type}> is not supported")
            return -1

        if order == 0:
            pass
        elif order == 1:
            # Learning parameters
            # Jang paper
            self.register_parameter("params", nn.Parameter(torch.randn(in_dim, n_rules) * normal_dis_factor))
            self.register_parameter("biases", nn.Parameter(torch.randn(in_dim, n_rules) * normal_dis_factor))

        # Setup the members for later referencing
        self.membership_type = membership_type
        self.n_rules = n_rules
        self.normalize_rules = normalize_rules
        self.in_dim = in_dim
        self.order = order

    def gaussian_membership_function(self, x):
        return torch.exp((-(x - self.centers)**2) / (2 * self.widths**2))

    def triangular_membership_function(self, x):
        batch_size = x.shape[0]
        # Get right/left points of the triangles
        # (batch_size, in_dim, n_rules)
        lefts = (self.centers - self.left_widths).expand(batch_size, -1, -1)
        rights = (self.centers + self.right_widths).expand(batch_size, -1, -1)
        centers = self.centers.expand(batch_size, -1, -1)

        # Perform the membership function
        # (batch_size, in_dim, n_rules)
        return triangular(x, lefts, centers, rights, self.common_zero)

    def difference_of_sigmoid_membership_function(self, x):
        return difference_of_sigmoid(x, self.lefts, self.rights)

    def forward(self, x):
        # Expand for broadcasting with rules
        # (batch_size, in_dim, n_rules)
        x = x.unsqueeze(-1).expand(-1, -1, self.n_rules)

        # Fuzzification
        # (batch_size, in_dim, n_rules)
        membership = self.membership_function(x)

        # Normalization
        # (batch_size, in_dim, n_rules)
        # If the rules are going to be normalized
        if self.normalize_rules:
            rule_evaluation = membership / membership.sum(dim=-1, keepdim=True)
        else:
            rule_evaluation = membership

        # Multiply the input by the learnable parameters and add the biases
        # (batch_size, in_dim, n_rules)
        if self.order == 0:
            defuzz = rule_evaluation
        elif self.order == 1:
            defuzz = x * self.params + self.biases

        # Multiply the rules by the fuzzified input
        # (batch_size, in_dim, n_rules)
        output = rule_evaluation * defuzz

        # Sum the rules
        # (batch_size, in_dim)
        return output.sum(dim=-1)

    def __repr__(self):
        repr_str = super(AnfisLayer, self).__repr__()[:-2] + f"(in_features={self.in_dim}, out_features={self.in_dim})\n"
        repr_str += f"  (n_rules): {self.n_rules}\n"

        if self.membership_type == "Gaussian":
            repr_str += f"  (centers): {self.centers.shape, self.centers.dtype}\n"
            repr_str += f"  (widths): {self.widths.shape, self.widths.dtype}\n"
        elif self.membership_type == "Triangular":
            repr_str += f"  (centers): {self.centers.shape, self.centers.dtype}\n"
            repr_str += f"  (left_widths): {self.left_widths.shape, self.left_widths.dtype}\n"
            repr_str += f"  (right_widths): {self.right_widths.shape, self.right_widths.dtype}\n"

        if self.order == 1:
            repr_str += f"  (learnable_params): {self.params.shape, self.params.dtype}\n"
            repr_str += f"  (learnable_biases): {self.biases.shape, self.biases.dtype}\n)"

        return repr_str


import logging
import time
import os
from typing import Dict
from typing import List

import boto3
import neo4j

from cartography.intel.aws.redshift import get_redshift_cluster_data, transform_redshift_cluster_data
from cartography.intel.aws.jsonwrappers.service_enum import AWSServices

import cartography.intel.aws.jsonwrappers.json_utils as json_utils
from cartography.util import timeit

logger = logging.getLogger(__name__)
json_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))

@timeit
def _attach_ec2_security_groups(neo4j_session: neo4j.Session, cluster: Dict,
                                aws_update_tag: int, redshift_dict: dict) -> None:
    for group in cluster.get('VpcSecurityGroups', []):
        relationship_details = {
            'to_id': group['VpcSecurityGroupId'], 'from_id': cluster['arn'],
            'to_label': 'EC2SecurityGroup', 'from_label': 'RedshiftCluster',
            'type': 'MEMBER_OF_EC2_SECURITY_GROUP'
        }

        json_utils.add_relationship(relationship_details, redshift_dict, aws_update_tag)

@timeit
def _attach_iam_roles(neo4j_session: neo4j.Session, cluster: Dict,
                      aws_update_tag: int, redshift_dict: dict) -> None:
    for role in cluster.get('IamRoles', []):
        relationship_details = {
            'to_id': role['IamRoleArn'], 'from_id': cluster['arn'],
            'to_label': 'AWSPrincipal', 'from_label': 'RedshiftCluster', 'type': 'STS_ASSUMEROLE_ALLOW'
        }

        json_utils.add_relationship(relationship_details, redshift_dict, aws_update_tag)

@timeit
def _attach_aws_vpc(neo4j_session: neo4j.Session, cluster: Dict, aws_update_tag: int, redshift_dict: dict) -> None:
    if cluster.get('VpcId'):
        relationship_details = {
            'to_id': cluster['VpcId'], 'from_id': cluster['arn'],
            'to_label': 'AWSVpc', 'from_label': 'RedshiftCluster', 'type': 'MEMBER_OF_AWS_VPC '
        }
        json_utils.add_relationship(relationship_details, redshift_dict, aws_update_tag)

@timeit
def load_redshift_cluster_data(
        neo4j_session: neo4j.Session, clusters: List[Dict], region: str,
        current_aws_account_id: str, aws_update_tag: int, redshift_dict: dict) -> None:

    entities = redshift_dict['entities']
    for cluster in clusters:
        entities[cluster['arn']] = {
            'identity': cluster['arn'],
            'labels': ['RedshiftCluster'],
            'Region': region,
            'firstseen': int(time.time()),
            'lastupdated': aws_update_tag
        }

        entities[cluster['arn']].update(cluster)

        # add relationship with AWSAccount
        relationship_details = {
            'to_id': cluster['arn'], 'from_id': current_aws_account_id,
            'to_label': 'RedshiftCluster', 'from_label': 'AWSAccount', 'type': 'RESOURCE'
        }
        json_utils.add_relationship(relationship_details, redshift_dict, aws_update_tag)

        _attach_ec2_security_groups(neo4j_session, cluster, aws_update_tag, redshift_dict)
        _attach_iam_roles(neo4j_session, cluster, aws_update_tag, redshift_dict)
        _attach_aws_vpc(neo4j_session, cluster, aws_update_tag, redshift_dict)

@timeit
def sync_redshift_clusters(
        neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, region: str,
        current_aws_account_id: str, aws_update_tag: int, redshift_dict: dict) -> None:
    data = get_redshift_cluster_data(boto3_session, region)
    transform_redshift_cluster_data(data, region, current_aws_account_id)
    load_redshift_cluster_data(neo4j_session, data, region, current_aws_account_id, aws_update_tag, redshift_dict)

@timeit
def sync(neo4j_session: neo4j.Session, boto3_session: boto3.session.Session, regions: List[str],
         current_aws_account_id: str, update_tag: int, common_job_parameters: Dict) -> None:

    redshift_dict = {
        'entities': {},
        'relationships': []
    }

    for region in regions:
        logger.info("Syncing Redshift clusters for region '%s' in account '%s'.", region, current_aws_account_id)
        sync_redshift_clusters(neo4j_session, boto3_session, region, current_aws_account_id, update_tag, redshift_dict)

    """
    Any properties to be omitted or overriden should be done in the following dictionaries
    Note: None key value means for all instead of a specific label
    override_properties = {
        # for all
        None: {
            'arn': 'changed'
        }
        # for label specific
        'RedshiftCluster': {
            'db_name': 'something'
        }
    }
    remove_properties = {
        # for all
        None: ['db_name', 'arn', ...]
        # for label specific
        'RedshiftCluster': ['encrypted', ...]
    }
    """
    excluded_props = {
        None: [
            'IamRoles', 'AquaConfiguration', 'ClusterNodes', 'VpcSecurityGroups', 'ClusterParameterGroups'
        ]
    }
    json_utils.exclude_properties(redshift_dict, excluded_props)
    json_utils.override_properties(redshift_dict, properties={})

    # write to json files
    json_utils.create_folder(AWSServices.REDSHIFT.value, current_aws_account_id)

    json_utils.write_relationship_to_json(redshift_dict, AWSServices.REDSHIFT.value, current_aws_account_id)
    redshift_list = list(redshift_dict['entities'].values())
    json_utils.write_to_json(redshift_list, 'redshift.json', AWSServices.REDSHIFT.value, current_aws_account_id)


import numpy as np
import index_sum
# layer1_1
layer1_1_1similar = np.load("./cal_similar/layer1_1_1similar.npy",allow_pickle=True)
layer1_1_1similar = layer1_1_1similar.tolist()
layer1_1_1index = np.load("./cal_similar/layer1_1_1index.npy",allow_pickle=True)
layer1_1_1index = layer1_1_1index.tolist()
layer1_1_1norm = np.load("./cal_similar/layer1_1_1norm.npy",allow_pickle=True)
layer1_1_1norm = layer1_1_1norm.tolist()
# layer1_2
layer1_1_2similar = np.load("./cal_similar/layer1_1_2similar.npy",allow_pickle=True)
layer1_1_2similar = layer1_1_2similar.tolist()
# print('similar1_1',similar1_1)
layer1_1_2index = np.load("./cal_similar/layer1_1_2index.npy",allow_pickle=True)
layer1_1_2index = layer1_1_2index.tolist()
layer1_1_2norm = np.load("./cal_similar/layer1_1_2norm.npy",allow_pickle=True)
layer1_1_2norm = layer1_1_2norm.tolist()

layer1_2_1similar = np.load("./cal_similar/layer1_2_1similar.npy",allow_pickle=True)
layer1_2_1similar = layer1_2_1similar.tolist()
layer1_2_1index = np.load("./cal_similar/layer1_2_1index.npy",allow_pickle=True)
layer1_2_1index = layer1_2_1index.tolist()
layer1_2_1norm = np.load("./cal_similar/layer1_2_1norm.npy",allow_pickle=True)
layer1_2_1norm = layer1_2_1norm.tolist()

layer1_2_2similar = np.load("./cal_similar/layer1_2_2similar.npy",allow_pickle=True)
layer1_2_2similar = layer1_2_2similar.tolist()
layer1_2_2index = np.load("./cal_similar/layer1_2_2index.npy",allow_pickle=True)
layer1_2_2index = layer1_2_2index.tolist()
layer1_2_2norm = np.load("./cal_similar/layer1_2_2norm.npy",allow_pickle=True)
layer1_2_2norm = layer1_2_2norm.tolist()

layer1_3_1similar = np.load("./cal_similar/layer1_3_1similar.npy",allow_pickle=True)
layer1_3_1similar = layer1_3_1similar.tolist()
layer1_3_1index = np.load("./cal_similar/layer1_3_1index.npy",allow_pickle=True)
layer1_3_1index = layer1_3_1index.tolist()
layer1_3_1norm = np.load("./cal_similar/layer1_3_1norm.npy",allow_pickle=True)
layer1_3_1norm = layer1_3_1norm.tolist()

layer1_3_2similar = np.load("./cal_similar/layer1_3_2similar.npy",allow_pickle=True)
layer1_3_2similar = layer1_3_2similar.tolist()
layer1_3_2index = np.load("./cal_similar/layer1_3_2index.npy",allow_pickle=True)
layer1_3_2index = layer1_3_2index.tolist()
layer1_3_2norm = np.load("./cal_similar/layer1_3_2norm.npy",allow_pickle=True)
layer1_3_2norm = layer1_3_2norm.tolist()

layer1_3_3similar = np.load("./cal_similar/layer1_3_3similar.npy",allow_pickle=True)
layer1_3_3similar = layer1_3_3similar.tolist()
layer1_3_3index = np.load("./cal_similar/layer1_3_3index.npy",allow_pickle=True)
layer1_3_3index = layer1_3_3index.tolist()
layer1_3_3norm = np.load("./cal_similar/layer1_3_3norm.npy",allow_pickle=True)
layer1_3_3norm = layer1_3_3norm.tolist()

layer2_1_1similar = np.load("./cal_similar/layer2_1_1similar.npy",allow_pickle=True)
layer2_1_1similar = layer2_1_1similar.tolist()
# print('similar1_1',similar1_1)
layer2_1_1index = np.load("./cal_similar/layer2_1_1index.npy",allow_pickle=True)
layer2_1_1index = layer2_1_1index.tolist()
layer2_1_1norm = np.load("./cal_similar/layer2_1_1norm.npy",allow_pickle=True)
layer2_1_1norm = layer2_1_1norm.tolist()
# layer1_2
layer2_1_2similar = np.load("./cal_similar/layer2_1_2similar.npy",allow_pickle=True)
layer2_1_2similar = layer2_1_2similar.tolist()
# print('similar1_1',similar1_1)
layer2_1_2index = np.load("./cal_similar/layer2_1_2index.npy",allow_pickle=True)
layer2_1_2index = layer2_1_2index.tolist()
layer2_1_2norm = np.load("./cal_similar/layer2_1_2norm.npy",allow_pickle=True)
layer2_1_2norm = layer2_1_2norm.tolist()

layer2_2_1similar = np.load("./cal_similar/layer2_2_1similar.npy",allow_pickle=True)
layer2_2_1similar = layer2_2_1similar.tolist()
layer2_2_1index = np.load("./cal_similar/layer2_2_1index.npy",allow_pickle=True)
layer2_2_1index = layer2_2_1index.tolist()
layer2_2_1norm = np.load("./cal_similar/layer2_2_1norm.npy",allow_pickle=True)
layer2_2_1norm = layer2_2_1norm.tolist()

layer2_2_2similar = np.load("./cal_similar/layer2_2_2similar.npy",allow_pickle=True)
layer2_2_2similar = layer2_2_2similar.tolist()
layer2_2_2index = np.load("./cal_similar/layer2_2_2index.npy",allow_pickle=True)
layer2_2_2index = layer2_2_2index.tolist()
layer2_2_2norm = np.load("./cal_similar/layer2_2_2norm.npy",allow_pickle=True)
layer2_2_2norm = layer2_2_2norm.tolist()

layer2_3_1similar = np.load("./cal_similar/layer2_3_1similar.npy",allow_pickle=True)
layer2_3_1similar = layer2_3_1similar.tolist()
layer2_3_1index = np.load("./cal_similar/layer2_3_1index.npy",allow_pickle=True)
layer2_3_1index = layer2_3_1index.tolist()
layer2_3_1norm = np.load("./cal_similar/layer2_3_1norm.npy",allow_pickle=True)
layer2_3_1norm = layer2_3_1norm.tolist()

layer2_3_2similar = np.load("./cal_similar/layer2_3_2similar.npy",allow_pickle=True)
layer2_3_2similar = layer2_3_2similar.tolist()
layer2_3_2index = np.load("./cal_similar/layer2_3_2index.npy",allow_pickle=True)
layer2_3_2index = layer2_3_2index.tolist()
layer2_3_2norm = np.load("./cal_similar/layer2_3_2norm.npy",allow_pickle=True)
layer2_3_2norm = layer2_3_2norm.tolist()

layer2_4_1similar = np.load("./cal_similar/layer2_4_1similar.npy",allow_pickle=True)
layer2_4_1similar = layer2_4_1similar.tolist()
layer2_4_1index = np.load("./cal_similar/layer2_4_1index.npy",allow_pickle=True)
layer2_4_1index = layer2_4_1index.tolist()
layer2_4_1norm = np.load("./cal_similar/layer2_4_1norm.npy",allow_pickle=True)
layer2_4_1norm = layer2_4_1norm.tolist()

layer2_4_2similar = np.load("./cal_similar/layer2_4_2similar.npy",allow_pickle=True)
layer2_4_2similar = layer2_4_2similar.tolist()
layer2_4_2index = np.load("./cal_similar/layer2_4_2index.npy",allow_pickle=True)
layer2_4_2index = layer2_4_2index.tolist()
layer2_4_2norm = np.load("./cal_similar/layer2_4_2norm.npy",allow_pickle=True)
layer2_4_2norm = layer2_4_2norm.tolist()

layer2_4_3similar = np.load("./cal_similar/layer2_4_3similar.npy",allow_pickle=True)
layer2_4_3similar = layer2_4_3similar.tolist()
layer2_4_3index = np.load("./cal_similar/layer2_4_3index.npy",allow_pickle=True)
layer2_4_3index = layer2_4_3index.tolist()
layer2_4_3norm = np.load("./cal_similar/layer2_4_3norm.npy",allow_pickle=True)
layer2_4_3norm = layer2_4_3norm.tolist()

layer3_1_1similar = np.load("./cal_similar/layer3_1_1similar.npy",allow_pickle=True)
layer3_1_1similar = layer3_1_1similar.tolist()
layer3_1_1index = np.load("./cal_similar/layer3_1_1index.npy",allow_pickle=True)
layer3_1_1index = layer3_1_1index.tolist()
layer3_1_1norm = np.load("./cal_similar/layer3_1_1norm.npy",allow_pickle=True)
layer3_1_1norm = layer3_1_1norm.tolist()
# layer1_2
layer3_1_2similar = np.load("./cal_similar/layer3_1_2similar.npy",allow_pickle=True)
layer3_1_2similar = layer3_1_2similar.tolist()
layer3_1_2index = np.load("./cal_similar/layer3_1_2index.npy",allow_pickle=True)
layer3_1_2index = layer3_1_2index.tolist()
layer3_1_2norm = np.load("./cal_similar/layer3_1_2norm.npy",allow_pickle=True)
layer3_1_2norm = layer3_1_2norm.tolist()

layer3_2_1similar = np.load("./cal_similar/layer3_2_1similar.npy",allow_pickle=True)
layer3_2_1similar = layer3_2_1similar.tolist()
layer3_2_1index = np.load("./cal_similar/layer3_2_1index.npy",allow_pickle=True)
layer3_2_1index = layer3_2_1index.tolist()
layer3_2_1norm = np.load("./cal_similar/layer3_2_1norm.npy",allow_pickle=True)
layer3_2_1norm = layer3_2_1norm.tolist()

layer3_2_2similar = np.load("./cal_similar/layer3_2_2similar.npy",allow_pickle=True)
layer3_2_2similar = layer3_2_2similar.tolist()
layer3_2_2index = np.load("./cal_similar/layer3_2_2index.npy",allow_pickle=True)
layer3_2_2index = layer3_2_2index.tolist()
layer3_2_2norm = np.load("./cal_similar/layer3_2_2norm.npy",allow_pickle=True)
layer3_2_2norm = layer3_2_2norm.tolist()

layer3_3_1similar = np.load("./cal_similar/layer3_3_1similar.npy",allow_pickle=True)
layer3_3_1similar = layer3_3_1similar.tolist()
layer3_3_1index = np.load("./cal_similar/layer3_3_1index.npy",allow_pickle=True)
layer3_3_1index = layer3_3_1index.tolist()
layer3_3_1norm = np.load("./cal_similar/layer3_3_1norm.npy",allow_pickle=True)
layer3_3_1norm = layer3_3_1norm.tolist()

layer3_3_2similar = np.load("./cal_similar/layer3_3_2similar.npy",allow_pickle=True)
layer3_3_2similar = layer3_3_2similar.tolist()
layer3_3_2index = np.load("./cal_similar/layer3_3_2index.npy",allow_pickle=True)
layer3_3_2index = layer3_3_2index.tolist()
layer3_3_2norm = np.load("./cal_similar/layer3_3_2norm.npy",allow_pickle=True)
layer3_3_2norm = layer3_3_2norm.tolist()

layer3_4_1similar = np.load("./cal_similar/layer3_4_1similar.npy",allow_pickle=True)
layer3_4_1similar = layer3_4_1similar.tolist()
layer3_4_1index = np.load("./cal_similar/layer3_4_1index.npy",allow_pickle=True)
layer3_4_1index = layer3_4_1index.tolist()
layer3_4_1norm = np.load("./cal_similar/layer3_4_1norm.npy",allow_pickle=True)
layer3_4_1norm = layer3_4_1norm.tolist()

layer3_4_2similar = np.load("./cal_similar/layer3_4_2similar.npy",allow_pickle=True)
layer3_4_2similar = layer3_4_2similar.tolist()
layer3_4_2index = np.load("./cal_similar/layer3_4_2index.npy",allow_pickle=True)
layer3_4_2index = layer3_4_2index.tolist()
layer3_4_2norm = np.load("./cal_similar/layer3_4_2norm.npy",allow_pickle=True)
layer3_4_2norm = layer3_4_2norm.tolist()

layer3_5_1similar = np.load("./cal_similar/layer3_5_1similar.npy",allow_pickle=True)
layer3_5_1similar = layer3_5_1similar.tolist()
layer3_5_1index = np.load("./cal_similar/layer3_5_1index.npy",allow_pickle=True)
layer3_5_1index = layer3_5_1index.tolist()
layer3_5_1norm = np.load("./cal_similar/layer3_5_1norm.npy",allow_pickle=True)
layer3_5_1norm = layer3_5_1norm.tolist()

layer3_5_2similar = np.load("./cal_similar/layer3_5_2similar.npy",allow_pickle=True)
layer3_5_2similar = layer3_5_2similar.tolist()
layer3_5_2index = np.load("./cal_similar/layer3_5_2index.npy",allow_pickle=True)
layer3_5_2index = layer3_5_2index.tolist()
layer3_5_2norm = np.load("./cal_similar/layer3_5_2norm.npy",allow_pickle=True)
layer3_5_2norm = layer3_5_2norm.tolist()

layer3_6_1similar = np.load("./cal_similar/layer3_6_1similar.npy",allow_pickle=True)
layer3_6_1similar = layer3_6_1similar.tolist()
layer3_6_1index = np.load("./cal_similar/layer3_6_1index.npy",allow_pickle=True)
layer3_6_1index = layer3_6_1index.tolist()
layer3_6_1norm = np.load("./cal_similar/layer3_6_1norm.npy",allow_pickle=True)
layer3_6_1norm = layer3_6_1norm.tolist()

layer3_6_2similar = np.load("./cal_similar/layer3_6_2similar.npy",allow_pickle=True)
layer3_6_2similar = layer3_6_2similar.tolist()
layer3_6_2index = np.load("./cal_similar/layer3_6_2index.npy",allow_pickle=True)
layer3_6_2index = layer3_6_2index.tolist()
layer3_6_2norm = np.load("./cal_similar/layer3_6_2norm.npy",allow_pickle=True)
layer3_6_2norm = layer3_6_2norm.tolist()

layer3_6_3similar = np.load("./cal_similar/layer3_6_3similar.npy",allow_pickle=True)
layer3_6_3similar = layer3_6_3similar.tolist()
layer3_6_3index = np.load("./cal_similar/layer3_6_3index.npy",allow_pickle=True)
layer3_6_3index = layer3_6_3index.tolist()
layer3_6_3norm = np.load("./cal_similar/layer3_6_3norm.npy",allow_pickle=True)
layer3_6_3norm = layer3_6_3norm.tolist()

layer4_1_1similar = np.load("./cal_similar/layer4_1_1similar.npy",allow_pickle=True)
layer4_1_1similar = layer4_1_1similar.tolist()
layer4_1_1index = np.load("./cal_similar/layer4_1_1index.npy",allow_pickle=True)
layer4_1_1index = layer4_1_1index.tolist()
layer4_1_1norm = np.load("./cal_similar/layer4_1_1norm.npy",allow_pickle=True)
layer4_1_1norm = layer4_1_1norm.tolist()
# layer1_2
layer4_1_2similar = np.load("./cal_similar/layer4_1_2similar.npy",allow_pickle=True)
layer4_1_2similar = layer4_1_2similar.tolist()
# print('similar1_1',similar1_1)
layer4_1_2index = np.load("./cal_similar/layer4_1_2index.npy",allow_pickle=True)
layer4_1_2index = layer4_1_2index.tolist()
layer4_1_2norm = np.load("./cal_similar/layer4_1_2norm.npy",allow_pickle=True)
layer4_1_2norm = layer4_1_2norm.tolist()

layer4_2_1similar = np.load("./cal_similar/layer4_2_1similar.npy",allow_pickle=True)
layer4_2_1similar = layer4_2_1similar.tolist()
layer4_2_1index = np.load("./cal_similar/layer4_2_1index.npy",allow_pickle=True)
layer4_2_1index = layer4_2_1index.tolist()
layer4_2_1norm = np.load("./cal_similar/layer4_2_1norm.npy",allow_pickle=True)
layer4_2_1norm = layer4_2_1norm.tolist()

layer4_2_2similar = np.load("./cal_similar/layer4_2_2similar.npy",allow_pickle=True)
layer4_2_2similar = layer4_2_2similar.tolist()
layer4_2_2index = np.load("./cal_similar/layer4_2_2index.npy",allow_pickle=True)
layer4_2_2index = layer4_2_2index.tolist()
layer4_2_2norm = np.load("./cal_similar/layer4_2_2norm.npy",allow_pickle=True)
layer4_2_2norm = layer4_2_2norm.tolist()

layer4_3_1similar = np.load("./cal_similar/layer4_3_1similar.npy",allow_pickle=True)
layer4_3_1similar = layer4_3_1similar.tolist()
layer4_3_1index = np.load("./cal_similar/layer4_3_1index.npy",allow_pickle=True)
layer4_3_1index = layer4_3_1index.tolist()
layer4_3_1norm = np.load("./cal_similar/layer4_3_1norm.npy",allow_pickle=True)
layer4_3_1norm = layer4_3_1norm.tolist()

layer4_3_2similar = np.load("./cal_similar/layer4_3_2similar.npy",allow_pickle=True)
layer4_3_2similar = layer4_3_2similar.tolist()
layer4_3_2index = np.load("./cal_similar/layer4_3_2index.npy",allow_pickle=True)
layer4_3_2index = layer4_3_2index.tolist()
layer4_3_2norm = np.load("./cal_similar/layer4_3_2norm.npy",allow_pickle=True)
layer4_3_2norm = layer4_3_2norm.tolist()

layer4_3_3similar = np.load("./cal_similar/layer4_3_3similar.npy",allow_pickle=True)
layer4_3_3similar = layer4_3_3similar.tolist()
layer4_3_3index = np.load("./cal_similar/layer4_3_3index.npy",allow_pickle=True)
layer4_3_3index = layer4_3_3index.tolist()
layer4_3_3norm = np.load("./cal_similar/layer4_3_3norm.npy",allow_pickle=True)
layer4_3_3norm = layer4_3_3norm.tolist()

# layer1_1_1 (64 -> 56)
remain =[]
remove_total = []
cfg_before = []
cfg_before.append(64)
remain.append(64)
remove_total.append([])
layer1_1_1norm = np.sum(layer1_1_1norm, axis=(0,)) / 40
sum1, sum2, sum3 = index_sum.index_sum(layer1_1_1similar)
index1, index2, index3 = index_sum.index_cut(layer1_1_1index,sum1,sum2,sum3)
layer1_1_1remove = index_sum.remove_index1_1_1(sum1,index1,sum2,index2,sum3,index3,layer1_1_1norm)
# layer1_1_1remove =[]
print('layer1_1_1remove',layer1_1_1remove)
layer1_1_1remain = len(layer1_1_1norm) - len(layer1_1_1remove)
print('len(layer1_1_1remove)',len(layer1_1_1remove))
cfg_before.append(len(layer1_1_1norm))
remain.append(layer1_1_1remain)
remove_total.append(layer1_1_1remove)

# layer1_1_2 (64 -> 56)
layer1_1_2norm = np.sum(layer1_1_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer1_1_2similar)
index1, index2, index3 = index_sum.index_cut(layer1_1_2index,sum1,sum2,sum3)
layer1_1_2remove = index_sum.remove_index1_1_1(sum1,index1,sum2,index2,sum3,index3,layer1_1_2norm)
# layer1_1_2remove =[]
layer1_1_2remain = len(layer1_1_2norm) - len(layer1_1_2remove)
cfg_before.append(len(layer1_1_2norm))
remain.append(layer1_1_2remain)
remove_total.append(layer1_1_2remove)

# layer1_1_3 = layer1_3_3
#   (256 -> 248)
layer1_3_3norm = np.sum(layer1_3_3norm,axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer1_3_3similar)
index1,index2,index3 = index_sum.index_cut(layer1_3_3index,sum1,sum2,sum3)
layer1_3_3remove = index_sum.remove_index1_1_1(sum1,index1,sum2,index2,sum3,index3,layer1_3_3norm)
# layer1_3_3remove =[]
print('layer1_3_3remove',layer1_3_3remove)
layer1_3_3remain = len(layer1_3_3norm) - len(layer1_3_3remove)
cfg_before.append(len(layer1_3_3norm))
layer1_1_3remove=layer1_3_3remove
layer1_1_3remain=layer1_3_3remain
print('layer1_3_3remain',layer1_3_3remain)
remain.append(layer1_1_3remain)
remove_total.append(layer1_1_3remove)
cfg_before.append(len(layer1_3_3norm))
layer1_1_3remove=layer1_3_3remove
layer1_1_3remain=layer1_3_3remain
print('layer1_3_3remain',layer1_3_3remain)
remain.append(layer1_1_3remain)
remove_total.append(layer1_1_3remove)

# layer1_2_1 (64 -> 56)
layer1_2_1norm = np.sum(layer1_2_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer1_2_1similar)
index1, index2, index3 = index_sum.index_cut(layer1_2_1index,sum1,sum2,sum3)
layer1_2_1remove = index_sum.remove_index1_1_1(sum1,index1,sum2,index2,sum3,index3,layer1_2_1norm)
# layer1_2_1remove =[]
layer1_2_1remain = len(layer1_2_1norm) - len(layer1_2_1remove)

cfg_before.append(len(layer1_2_1norm))
remain.append(layer1_2_1remain)
remove_total.append(layer1_2_1remove)

# layer1_2_2 (64 -> 56)
layer1_2_2norm = np.sum(layer1_2_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer1_2_2similar)
index1, index2, index3 = index_sum.index_cut(layer1_2_2index,sum1,sum2,sum3)
layer1_2_2remove = index_sum.remove_index1_1_1(sum1,index1,sum2,index2,sum3,index3,layer1_2_2norm)
# layer1_2_2remove =[]
layer1_2_2remain = len(layer1_2_2norm) - len(layer1_2_2remove)

cfg_before.append(len(layer1_2_2norm))
remain.append(layer1_2_2remain)
remove_total.append(layer1_2_2remove)

cfg_before.append(len(layer1_3_3norm))
layer1_2_3remove=layer1_3_3remove
layer1_2_3remain=layer1_3_3remain
# print('layer1_3_3remain',layer1_3_3remain)
remain.append(layer1_2_3remain)
remove_total.append(layer1_2_3remove)

# layer1_3_1 (64 -> 56)
layer1_3_1norm = np.sum(layer1_3_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer1_3_1similar)
index1, index2, index3 = index_sum.index_cut(layer1_3_1index,sum1,sum2,sum3)
layer1_3_1remove = index_sum.remove_index1_1_1(sum1,index1,sum2,index2,sum3,index3,layer1_3_1norm)
# layer1_3_1remove =[]
layer1_3_1remain = len(layer1_3_1norm) - len(layer1_3_1remove)
cfg_before.append(len(layer1_3_1norm))
remain.append(layer1_3_1remain)
remove_total.append(layer1_3_1remove)

# layer1_3_2 (64 -> 56)
layer1_3_2norm = np.sum(layer1_3_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer1_3_2similar)
index1, index2, index3 = index_sum.index_cut(layer1_3_2index,sum1,sum2,sum3)
layer1_3_2remove = index_sum.remove_index1_1_1(sum1,index1,sum2,index2,sum3,index3,layer1_3_2norm)
# layer1_3_2remove =[]
layer1_3_2remain = len(layer1_3_2norm) - len(layer1_3_2remove)
cfg_before.append(len(layer1_3_2norm))
remain.append(layer1_3_2remain)
remove_total.append(layer1_3_2remove)
# layer1_3_3  (256 -> 242)
cfg_before.append(len(layer1_3_3norm))
layer1_3_3remain = len(layer1_3_3norm) - len(layer1_3_3remove)
print('layer1_3_3remain',layer1_3_3remain)
remain.append(layer1_3_3remain)
remove_total.append(layer1_3_3remove)

# layer2_1_1  (128 -> 242)
layer2_1_1norm = np.sum(layer2_1_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_1_1similar)
index1, index2, index3 = index_sum.index_cut(layer2_1_1index,sum1,sum2,sum3)
layer2_1_1remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_1_1norm)
# layer2_1_1remove =[]

layer2_1_1remain = len(layer2_1_1norm) - len(layer2_1_1remove)

'''11'''
cfg_before.append(len(layer2_1_1norm))
remain.append(layer2_1_1remain)
remove_total.append(layer2_1_1remove)

# layer2_1_2  (128 -> 248)
layer2_1_2norm = np.sum(layer2_1_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_1_2similar)
index1, index2, index3 = index_sum.index_cut(layer2_1_2index,sum1,sum2,sum3)
layer2_1_2remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_1_2norm)
# layer2_1_2remove =[]
layer2_1_2remain = len(layer2_1_2norm) - len(layer2_1_2remove)
'''12'''
cfg_before.append(len(layer2_1_2norm))
remain.append(layer2_1_2remain)
remove_total.append(layer2_1_2remove)

# layer2_1_3
layer2_4_3norm = np.sum(layer2_4_3norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_4_3similar)
index1, index2, index3 = index_sum.index_cut(layer2_4_3index,sum1,sum2,sum3)
layer2_4_3remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_4_3norm)
# layer2_4_3remove =[]
layer2_4_3remain = len(layer2_4_3norm) - len(layer2_4_3remove)
'''13'''
cfg_before.append(len(layer2_4_3norm))
layer2_1_3remove=layer2_4_3remove
layer2_1_3remain=layer2_4_3remain
# print('layer2_1_3remain',layer2_1_3remain)
# input()
remain.append(layer2_1_3remain)
remove_total.append(layer2_1_3remove)
'''14'''
cfg_before.append(len(layer2_4_3norm))
layer2_1_3remove=layer2_4_3remove
layer2_1_3remain=layer2_4_3remain
print('layer2_1_3remain',layer2_1_3remain)
remain.append(layer2_1_3remain)
remove_total.append(layer2_1_3remove)

# layer2_2_1  (128 -> 248)
layer2_2_1norm = np.sum(layer2_2_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_2_1similar)
index1, index2, index3 = index_sum.index_cut(layer2_2_1index,sum1,sum2,sum3)
layer2_2_1remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_2_1norm)
# layer2_2_1remove =[]
layer2_2_1remain = len(layer2_2_1norm) - len(layer2_2_1remove)
'''15'''
cfg_before.append(len(layer2_2_1norm))
remain.append(layer2_2_1remain)
remove_total.append(layer2_2_1remove)

# layer2_2_2  (128 -> 248)
layer2_2_2norm = np.sum(layer2_2_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_2_2similar)
index1, index2, index3 = index_sum.index_cut(layer2_2_2index,sum1,sum2,sum3)
layer2_2_2remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_2_2norm)
# layer2_2_2remove =[]
layer2_2_2remain = len(layer2_2_2norm) - len(layer2_2_2remove)
cfg_before.append(len(layer2_2_2norm))
remain.append(layer2_2_2remain)
remove_total.append(layer2_2_2remove)

# layer2_2_3
cfg_before.append(len(layer2_4_3norm))
layer2_2_3remove=layer2_4_3remove
layer2_2_3remain=layer2_4_3remain
print('layer2_2_3remain',layer2_2_3remain)
remain.append(layer2_2_3remain)
remove_total.append(layer2_2_3remove)

# layer2_3_1  (128 -> 248)
layer2_3_1norm = np.sum(layer2_3_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_3_1similar)
index1, index2, index3 = index_sum.index_cut(layer2_3_1index,sum1,sum2,sum3)
layer2_3_1remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_3_1norm)
# layer2_3_1remove =[]
layer2_3_1remain = len(layer2_3_1norm) - len(layer2_3_1remove)
cfg_before.append(len(layer2_3_1norm))
remain.append(layer2_3_1remain)
remove_total.append(layer2_3_1remove)

# layer2_3_2  (128 -> 248)
layer2_3_2norm = np.sum(layer2_3_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_3_2similar)
index1, index2, index3 = index_sum.index_cut(layer2_3_2index,sum1,sum2,sum3)
layer2_3_2remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_3_2norm)
# layer2_3_2remove =[]
layer2_3_2remain = len(layer2_3_2norm) - len(layer2_3_2remove)
cfg_before.append(len(layer2_3_2norm))
remain.append(layer2_3_2remain)
remove_total.append(layer2_3_2remove)

#layer2_3_3
cfg_before.append(len(layer2_4_3norm))
layer2_3_3remove=layer2_4_3remove
layer2_3_3remain=layer2_4_3remain
print('layer2_3_3remain',layer2_3_3remain)
remain.append(layer2_3_3remain)
remove_total.append(layer2_3_3remove)

# layer2_4_1  (128 -> 248)
layer2_4_1norm = np.sum(layer2_4_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_4_1similar)
index1, index2, index3 = index_sum.index_cut(layer2_4_1index,sum1,sum2,sum3)
layer2_4_1remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_4_1norm)
# layer2_4_1remove =[]
layer2_4_1remain = len(layer2_4_1norm) - len(layer2_4_1remove)
cfg_before.append(len(layer2_4_1norm))
remain.append(layer2_4_1remain)
remove_total.append(layer2_4_1remove)

# layer2_4_2  (128 -> 248)
layer2_4_2norm = np.sum(layer2_4_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer2_4_2similar)
index1, index2, index3 = index_sum.index_cut(layer2_4_2index,sum1,sum2,sum3)
layer2_4_2remove = index_sum.remove_index2_1_1(sum1,index1,sum2,index2,sum3,index3,layer2_4_2norm)
# layer2_4_2remove =[]
layer2_4_2remain = len(layer2_4_2norm) - len(layer2_4_2remove)
cfg_before.append(len(layer2_4_2norm))
remain.append(layer2_4_2remain)
remove_total.append(layer2_4_2remove)

# layer2_4_3  (128 -> 248)
cfg_before.append(len(layer2_4_3norm))
remain.append(layer2_4_3remain)
remove_total.append(layer2_4_3remove)

# layer3_1_1  (128 -> 248)
layer3_1_1norm = np.sum(layer3_1_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_1_1similar)
index1, index2, index3 = index_sum.index_cut(layer3_1_1index,sum1,sum2,sum3)
layer3_1_1remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_1_1norm)
# layer3_1_1remove =[]
layer3_1_1remain = len(layer3_1_1norm) - len(layer3_1_1remove)
cfg_before.append(len(layer3_1_1norm))
remain.append(layer3_1_1remain)
remove_total.append(layer3_1_1remove)

# layer3_1_2  (128 -> 248)
layer3_1_2norm = np.sum(layer3_1_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_1_2similar)
index1, index2, index3 = index_sum.index_cut(layer3_1_2index,sum1,sum2,sum3)
layer3_1_2remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_1_2norm)
# layer3_1_2remove =[]
layer3_1_2remain = len(layer3_1_2norm) - len(layer3_1_2remove)
cfg_before.append(len(layer3_1_2norm))
remain.append(layer3_1_2remain)
remove_total.append(layer3_1_2remove)

# layer3_1_3
layer3_6_3norm = np.sum(layer3_6_3norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_6_3similar)
index1, index2, index3 = index_sum.index_cut(layer3_6_3index,sum1,sum2,sum3)
layer3_6_3remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_6_3norm)
# layer3_6_3remove =[]
layer3_6_3remain = len(layer3_6_3norm) - len(layer3_6_3remove)
cfg_before.append(len(layer3_6_3norm))
layer3_1_3remove = layer3_6_3remove
layer3_1_3remain = layer3_6_3remain
remain.append(layer3_1_3remain)
remove_total.append(layer3_1_3remove)

cfg_before.append(len(layer3_6_3norm))
layer3_1_3remove = layer3_6_3remove
layer3_1_3remain = layer3_6_3remain
remain.append(layer3_1_3remain)
remove_total.append(layer3_1_3remove)

# layer3_2_1  (128 -> 248)
layer3_2_1norm = np.sum(layer3_2_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_2_1similar)
index1, index2, index3 = index_sum.index_cut(layer3_2_1index,sum1,sum2,sum3)
layer3_2_1remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_2_1norm)
# layer3_2_1remove =[]
layer3_2_1remain = len(layer3_2_1norm) - len(layer3_2_1remove)
cfg_before.append(len(layer3_2_1norm))
remain.append(layer3_2_1remain)
remove_total.append(layer3_2_1remove)

# layer3_2_2  (128 -> 248)
layer3_2_2norm = np.sum(layer3_2_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_2_2similar)
index1, index2, index3 = index_sum.index_cut(layer3_2_2index,sum1,sum2,sum3)
layer3_2_2remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_2_2norm)
# layer3_2_2remove =[]
layer3_2_2remain = len(layer3_2_2norm) - len(layer3_2_2remove)
cfg_before.append(len(layer3_2_2norm))
remain.append(layer3_2_2remain)
remove_total.append(layer3_2_2remove)

# layer3_2_3
cfg_before.append(len(layer3_6_3norm))
layer3_2_3remove = layer3_6_3remove
layer3_2_3remain = layer3_6_3remain
remain.append(layer3_2_3remain)
remove_total.append(layer3_2_3remove)

# layer3_3_1  (128 -> 248)
layer3_3_1norm = np.sum(layer3_3_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_3_1similar)
index1, index2, index3 = index_sum.index_cut(layer3_3_1index,sum1,sum2,sum3)
layer3_3_1remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_3_1norm)
# layer3_3_1remove =[]
layer3_3_1remain = len(layer3_3_1norm) - len(layer3_3_1remove)
cfg_before.append(len(layer3_3_1norm))
remain.append(layer3_3_1remain)
remove_total.append(layer3_3_1remove)

# layer3_3_2  (128 -> 248)
layer3_3_2norm = np.sum(layer3_3_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_3_2similar)
index1, index2, index3 = index_sum.index_cut(layer3_3_2index,sum1,sum2,sum3)
layer3_3_2remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_3_2norm)
# layer3_3_2remove =[]
layer3_3_2remain = len(layer3_3_2norm) - len(layer3_3_2remove)
cfg_before.append(len(layer3_3_2norm))
remain.append(layer3_3_2remain)
remove_total.append(layer3_3_2remove)

# layer3_3_3
cfg_before.append(len(layer3_6_3norm))
layer3_3_3remove = layer3_6_3remove
layer3_3_3remain = layer3_6_3remain
remain.append(layer3_3_3remain)
remove_total.append(layer3_3_3remove)

# layer3_4_1  (128 -> 248)
layer3_4_1norm = np.sum(layer3_4_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_4_1similar)
index1, index2, index3 = index_sum.index_cut(layer3_4_1index,sum1,sum2,sum3)
layer3_4_1remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_4_1norm)
# layer3_4_1remove =[]
layer3_4_1remain = len(layer3_4_1norm) - len(layer3_4_1remove)
cfg_before.append(len(layer3_4_1norm))
remain.append(layer3_4_1remain)
remove_total.append(layer3_4_1remove)

# layer3_4_2  (128 -> 248)
layer3_4_2norm = np.sum(layer3_4_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_4_2similar)
index1, index2, index3 = index_sum.index_cut(layer3_4_2index,sum1,sum2,sum3)
layer3_4_2remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_4_2norm)
# layer3_4_2remove =[]
layer3_4_2remain = len(layer3_4_2norm) - len(layer3_4_2remove)
cfg_before.append(len(layer3_4_2norm))
remain.append(layer3_4_2remain)
remove_total.append(layer3_4_2remove)

# layer3_4_3
cfg_before.append(len(layer3_6_3norm))
layer3_4_3remove = layer3_6_3remove
layer3_4_3remain = layer3_6_3remain
remain.append(layer3_4_3remain)
remove_total.append(layer3_4_3remove)

# layer3_5_1  (128 -> 248)
layer3_5_1norm = np.sum(layer3_5_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_5_1similar)
index1, index2, index3 = index_sum.index_cut(layer3_5_1index,sum1,sum2,sum3)
layer3_5_1remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_5_1norm)
# layer3_5_1remove =[]
layer3_5_1remain = len(layer3_5_1norm) - len(layer3_5_1remove)
cfg_before.append(len(layer3_5_1norm))
remain.append(layer3_5_1remain)
remove_total.append(layer3_5_1remove)

# layer3_5_2  (128 -> 248)
layer3_5_2norm = np.sum(layer3_5_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_5_2similar)
index1, index2, index3 = index_sum.index_cut(layer3_5_2index,sum1,sum2,sum3)
layer3_5_2remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_5_2norm)
# layer3_5_2remove =[]
layer3_5_2remain = len(layer3_5_2norm) - len(layer3_5_2remove)
cfg_before.append(len(layer3_5_2norm))
remain.append(layer3_5_2remain)
remove_total.append(layer3_5_2remove)

# layer3_5_3
cfg_before.append(len(layer3_6_3norm))
layer3_5_3remove = layer3_6_3remove
layer3_5_3remain = layer3_6_3remain
remain.append(layer3_5_3remain)
remove_total.append(layer3_5_3remove)

# layer3_6_1  (128 -> 248)
layer3_6_1norm = np.sum(layer3_6_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_6_1similar)
index1, index2, index3 = index_sum.index_cut(layer3_6_1index,sum1,sum2,sum3)
layer3_6_1remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_6_1norm)
# layer3_6_1remove =[]
layer3_6_1remain = len(layer3_6_1norm) - len(layer3_6_1remove)
cfg_before.append(len(layer3_6_1norm))
remain.append(layer3_6_1remain)
remove_total.append(layer3_6_1remove)

# layer3_6_2  (128 -> 248)
layer3_6_2norm = np.sum(layer3_6_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer3_6_2similar)
index1, index2, index3 = index_sum.index_cut(layer3_6_2index,sum1,sum2,sum3)
layer3_6_2remove = index_sum.remove_index3_1_1(sum1,index1,sum2,index2,sum3,index3,layer3_6_2norm)
# layer3_6_2remove =[]
layer3_6_2remain = len(layer3_6_2norm) - len(layer3_6_2remove)
cfg_before.append(len(layer3_6_2norm))
remain.append(layer3_6_2remain)
remove_total.append(layer3_6_2remove)

# layer3_6_3  (128 -> 248)
cfg_before.append(len(layer3_6_3norm))
remain.append(layer3_6_3remain)
remove_total.append(layer3_6_3remove)

# layer4_1_1  (128 -> 248)
layer4_1_1norm = np.sum(layer4_1_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer4_1_1similar)
index1, index2, index3 = index_sum.index_cut(layer4_1_1index,sum1,sum2,sum3)
layer4_1_1remove = index_sum.remove_index4_1_1(sum1,index1,sum2,index2,sum3,index3,layer4_1_1norm)
# layer4_1_1remove =[]
layer4_1_1remain = len(layer4_1_1norm) - len(layer4_1_1remove)
cfg_before.append(len(layer4_1_1norm))
remain.append(layer4_1_1remain)
remove_total.append(layer4_1_1remove)

# layer4_1_2  (128 -> 248)
layer4_1_2norm = np.sum(layer4_1_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer4_1_2similar)
index1, index2, index3 = index_sum.index_cut(layer4_1_2index,sum1,sum2,sum3)
layer4_1_2remove = index_sum.remove_index4_1_1(sum1,index1,sum2,index2,sum3,index3,layer4_1_2norm)
# layer4_1_2remove =[]
layer4_1_2remain = len(layer4_1_2norm) - len(layer4_1_2remove)
cfg_before.append(len(layer4_1_2norm))
remain.append(layer4_1_2remain)
remove_total.append(layer4_1_2remove)

#layer4_1_3
layer4_3_3norm = np.sum(layer4_3_3norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer4_3_3similar)
index1, index2, index3 = index_sum.index_cut(layer4_3_3index,sum1,sum2,sum3)
layer4_3_3remove = index_sum.remove_index4_1_1(sum1,index1,sum2,index2,sum3,index3,layer4_3_3norm)
# layer4_3_3remove =[]
layer4_3_3remain = len(layer4_3_3norm) - len(layer4_3_3remove)
cfg_before.append(len(layer4_3_3norm))
layer4_1_3remove = layer4_3_3remove
layer4_1_3remain = layer4_3_3remain
remain.append(layer4_1_3remain)
remove_total.append(layer4_1_3remove)

cfg_before.append(len(layer4_3_3norm))
layer4_1_3remove = layer4_3_3remove
layer4_1_3remain = layer4_3_3remain
remain.append(layer4_1_3remain)
remove_total.append(layer4_1_3remove)

# layer4_2_1  (128 -> 248)
layer4_2_1norm = np.sum(layer4_2_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer4_2_1similar)
index1, index2, index3 = index_sum.index_cut(layer4_2_1index,sum1,sum2,sum3)
layer4_2_1remove = index_sum.remove_index4_1_1(sum1,index1,sum2,index2,sum3,index3,layer4_2_1norm)
# layer4_2_1remove =[]
layer4_2_1remain = len(layer4_2_1norm) - len(layer4_2_1remove)
cfg_before.append(len(layer4_2_1norm))
remain.append(layer4_2_1remain)
remove_total.append(layer4_2_1remove)

# layer4_2_2  (128 -> 248)
layer4_2_2norm = np.sum(layer4_2_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer4_2_2similar)
index1, index2, index3 = index_sum.index_cut(layer4_2_2index,sum1,sum2,sum3)
layer4_2_2remove = index_sum.remove_index4_1_1(sum1,index1,sum2,index2,sum3,index3,layer4_2_2norm)
# layer4_2_2remove =[]
layer4_2_2remain = len(layer4_2_2norm) - len(layer4_2_2remove)
cfg_before.append(len(layer4_2_2norm))
remain.append(layer4_2_2remain)
remove_total.append(layer4_2_2remove)

# layer4_2_3
cfg_before.append(len(layer4_3_3norm))
layer4_2_3remove = layer4_3_3remove
layer4_2_3remain = layer4_3_3remain
remain.append(layer4_2_3remain)
remove_total.append(layer4_2_3remove)

# layer4_3_1  (128 -> 248)
layer4_3_1norm = np.sum(layer4_3_1norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer4_3_1similar)
index1, index2, index3 = index_sum.index_cut(layer4_3_1index,sum1,sum2,sum3)
layer4_3_1remove = index_sum.remove_index4_1_1(sum1,index1,sum2,index2,sum3,index3,layer4_3_1norm)
# layer4_3_1remove =[]
layer4_3_1remain = len(layer4_3_1norm) - len(layer4_3_1remove)
cfg_before.append(len(layer4_3_1norm))
remain.append(layer4_3_1remain)
remove_total.append(layer4_3_1remove)

# layer4_3_2  (128 -> 248)
layer4_3_2norm = np.sum(layer4_3_2norm, axis=(0,))
sum1, sum2, sum3 = index_sum.index_sum(layer4_3_2similar)
index1, index2, index3 = index_sum.index_cut(layer4_3_2index,sum1,sum2,sum3)
layer4_3_2remove = index_sum.remove_index4_1_1(sum1,index1,sum2,index2,sum3,index3,layer4_3_2norm)
# layer4_3_2remove =[]
layer4_3_2remain = len(layer4_3_2norm) - len(layer4_3_2remove)
cfg_before.append(len(layer4_3_2norm))
remain.append(layer4_3_2remain)
remove_total.append(layer4_3_2remove)

# layer4_3_3  (128 -> 248)
cfg_before.append(len(layer4_3_3norm))
remain.append(layer4_3_3remain)
remove_total.append(layer4_3_3remove)

# cfg_before.append(len(layer4_3_3norm))
# remain.append(layer4_3_3remain)
# remove_total.append(layer4_3_3remove)

print('cfg_before',cfg_before)
print('remain',remain)
# print(len(remain))
# #
remove_total = np.array(remove_total)
np.save("./layer_remove_index/remove_total.npy", remove_total)
remain = np.array(remain)
np.save("./layer_remove_index/remain.npy", remain)
cfg_before = np.array(cfg_before)
np.save("./layer_remove_index/cfg_before.npy", cfg_before)


from __future__ import print_function
import math

def quaternionTEuler(x, y, z, w):
   q0 = w
   q1 = x
   q2 = y
   q3 = z
   pitch = math.asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3
   roll = math.atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3
   yaw = math.atan2(2 * (q1*q2 + q0*q3), q0*q0 + q1*q1 - q2*q2 - q3*q3)* 57.3

   return pitch, roll, yaw

def eulerToQuaternion(pitch, roll, yaw):
    w = math.cos(yaw/2)*math.cos(roll/2)*math.cos(pitch/2)-math.sin(yaw/2)*math.sin(roll/2)*math.sin(pitch/2)
    x = math.cos(yaw/2)*math.cos(roll/2)*math.sin(pitch/2)+math.sin(yaw/2)*math.sin(roll/2)*math.cos(pitch/2)
    y = math.cos(yaw/2)*math.sin(roll/2)*math.cos(pitch/2)-math.sin(yaw/2)*math.cos(roll/2)*math.sin(pitch/2)
    z = math.sin(yaw/2)*math.cos(roll/2)*math.cos(pitch/2)+math.cos(yaw/2)*math.sin(roll/2)*math.sin(pitch/2)
    return w, x, y, z

def calAng(x, y, yaw, remainder):
    ang = round(math.degrees(math.atan2(y, x))-yaw, remainder)
    if ang > 180:
        return ang - 360
    elif ang < -180:
        return ang + 360
    else:
        return ang

def calDis(x, y, remainder, toCM=True):
    if toCM:
        return round(math.hypot(x, y)*100, remainder)
    else:
        return round(math.hypot(x, y), remainder)