from itertools import groupby
from operator import itemgetter
import copy
import json

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.db import transaction
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

import requests

from client.models import Zone, ZoneRecord
from client.pdns import PowerDnsClient

def pdns_client(accounts):
    return PowerDnsClient(
        accounts=accounts,
        server=settings.POWERDNS['server'],
        hostname=settings.POWERDNS['hostname'],
        port=settings.POWERDNS['port'],
        api_key=settings.POWERDNS['api-key'],
    )

def user_groups(user):
    if user.is_superuser:
        return None
    else:
        return [str(group) for group in user.groups.all()]

def denied_response():
    response = Response()
    response.status_code = 403
    return response

def database_record_to_pdns_record(record):
    return {'disabled': False, 'name': record.rr_name, 'type': record.rr_type, 'ttl': record.rr_ttl, 'content': record.rr_content}

class ZonesListView(APIView):
    allowed_methods = ['GET', 'POST']
    permission_classes = (IsAuthenticated,)

    def get(self, request, *args, **kwargs):
        zones = pdns_client(accounts=user_groups(request.user)).get_zones()
        return Response(zones)

class ZoneView(APIView):
    allowed_methods = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH']
    permission_classes = (IsAuthenticated,)

    def get(self, request, pk):
        zone = pdns_client(accounts=user_groups(request.user)).get_zone(pk)

        if not zone:
            return denied_response()

        return Response(zone)

    def put(self, request, pk):
        import pprint; pprint.pprint(json.dumps(request.data))

        client = pdns_client(accounts=user_groups(request.user))
        put_data = copy.copy(request.data)
        server_zone = client.get_zone(pk)

        if not server_zone:
            return denied_response()

        server_records = server_zone['records']
        modifications = [record for record in put_data['records'] if 'modification' in record and record['modification'] in ('created', 'updated', 'deleted')]

        key = itemgetter('name', 'type')
        server_rrsets = {
            k: list(v) for k,v in groupby(sorted(server_records, key=key), key=key)
        }

        patched_rrsets = {}

        for modification in modifications:
            if modification['type'].lower() == 'soa':
                modification['name'] = server_zone['name']

            if modification['modification'] == 'updated':
                original_rrset_key = (modification['original']['name'], modification['original']['type'])
                server_rrsets[original_rrset_key].remove(modification['original'])
                patched_rrsets[original_rrset_key] = server_rrsets[original_rrset_key]

            new_rrset_key = (modification['name'], modification['type'])
            new_rrset = patched_rrsets.get(new_rrset_key, server_rrsets.get(new_rrset_key, []))
            new_rr = {k:v for k,v in modification.iteritems() if k not in ('original', 'modification')}

            if 'disabled' not in new_rr:
                new_rr['disabled'] = False

            if modification['modification'] == 'deleted':
                new_rrset.remove(new_rr)
            else:
                new_rrset.append(new_rr)

            patched_rrsets[new_rrset_key] = new_rrset

        patch_request_data = {
            'rrsets': [
                {
                    'name': k[0],
                    'type': k[1],
                    'changetype': 'REPLACE',
                    'records': v,
                } for k, v in patched_rrsets.iteritems()
            ]
        }

        patch_request = client.patch_zone(pk, patch_request_data)

        if patch_request: # succeeded
            with transaction.atomic():
                database_zone = Zone(zone_name=patch_request['id'], user=request.user, comment=request.data['commitMessage'])
                database_zone.save()
                ZoneRecord.objects.bulk_create(
                    [ZoneRecord(zone=database_zone, rr_name=record['name'], rr_type=record['type'], rr_ttl=record['ttl'], rr_content=record['content']) for record in patch_request['records']]
                )

        patch_response = Response(patch_request)
        return patch_response

class UserView(APIView):
    allowed_methods = ['GET']
    permission_classes = (IsAuthenticated,)

    def get(self, request):
        return Response({
            'username': request.user.username,
            'groups': user_groups(request.user),
        })

class ZoneRevisionListView(APIView):
    allowed_methods = ['GET']
    permission_classes = (IsAuthenticated,)

    def get(self, request, pk):
        if any([pk == zone['id'] for zone in pdns_client(accounts=user_groups(request.user)).get_zones()]):
            revisions = Zone.objects.filter(zone_name=pk).order_by('-created')
            return Response(
                [{'id': revision.id, 'user': revision.user.username, 'created': revision.created, 'comment': revision.comment} for revision in revisions]
            )
        else:
            return denied_response()

class ZoneRevisionView(APIView):
    allowed_methods = ['GET']
    permission_classes = (IsAuthenticated,)

    def get(self, request, zone_id, pk):
        revision_zone = Zone.objects.get(pk=pk)
        server_zone = pdns_client(accounts=user_groups(request.user)).get_zone(revision_zone.zone_name)
        diff_records = []

        if server_zone is None:
            return denied_response()

        revision_records = [database_record_to_pdns_record(record) for record in revision_zone.records.all()]

        for revision_record in revision_records:
            if revision_record not in server_zone['records'] and revision_record['type'].lower() != 'soa':
                revision_record['modification'] = 'created'
                diff_records.append(revision_record)

        for server_record in server_zone['records']:
            if server_record not in revision_records and server_record['type'].lower() != 'soa':
                server_record['modification'] = 'deleted'
            diff_records.append(server_record)

        return Response(diff_records)

class ClientView(TemplateView):
    template_name = "client/client.html"

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ClientView, self).dispatch(*args, **kwargs)


"""
https://leetcode.com/problems/reverse-subarray-to-maximize-array-value/
"""

class Solution:
    def maxValueAfterReverse(self, nums: list[int]) -> int:
        """
        See https://leetcode.com/problems/reverse-subarray-to-maximize-array-value/discuss/489882/O(n)-Solution-with-explanation for more details.
        """
        minAB, maxCD, totalSum = float('inf'), float('-inf'), 0
        for a, b in zip(nums, nums[1:]):
            totalSum += abs(a - b)
            maxCD = max(min(a, b), maxCD)
            minAB = min(max(a, b), minAB)

        # Calculate change after reverse from minAB to maxCD
        delta = max(0, (maxCD - minAB) << 1)

        # Checking boundaries.
        for a, b in zip(nums, nums[1:]):
            low = -abs(a - b) + abs(nums[0] - b)
            high = -abs(a - b) + abs(nums[-1] - a)
            delta = max(low, high, delta)

        return totalSum + delta


# -*- coding: utf8 -*-
# Programa: Examen II Parcial // clase vehiculo
# Autor: Akdiel Callejas Amador
# Fecha 13/03/20

import datetime
ultimo_id = 0

class Vehiculo:
    """ se encarga de la cración de un objeto tipo Vehículo """

    def __init__(self, numero_placa, marca="", model="",tipo_vehiculo="" ):
        """ crea un objeto tipo vehiculo en base a los parametros datos. """
        global ultimo_id
        ultimo_id += 1
        self.id_vehiculo = ultimo_id
        self.placa_vehiculo = numero_placa
        self.marca_vehiculo = marca
        self.modelo_vehiculo = model
        if tipo_vehiculo == "automovil" or tipo_vehiculo == "automóvil" or tipo_vehiculo== "motocicleta":
            self.tipo_vehiculo = tipo_vehiculo
        else:
            print("el tipo de vehívulo no es es aceptado o es incorrecto.")
        self.hora_ingreso_vehiculo = datetime.datetime.now()
        self.estado_vehiculo = True


from __future__ import unicode_literals

from django.db import models
import datetime

# Create your models here.
class Notices(models.Model):
	sender_name=models.CharField(max_length=30)
	sender_department=models.CharField(max_length=30)
	post_on=models.DateTimeField()
	content=models.CharField(max_length=250)

class Target(models.Model):
	Departments=(
		   ('Computer Science','CS'),
		   ('Computer Engineering','CE'),
		   ('Civil Engineering','Civil'),
		   ('Electrical and Electronics Engineering','EE'),
		   ('Environment Engineering','ENE'),
		   ('Chemical Engineering','CHE'),
		   ('Mechanical Engineering','ME'),
		   ('Geomatics Engineering','GE'),
		   ('Biotechnology','BT'),
		   ('Pharmacy','BP'),
		   ('Environment Science','ES'),
		   ('Applied Physics','AP'),
		   ('Human Biology','HB'),
		   ('Law','Law')

		)
	Semesters=(
			('First','1st'),
			('Second','2nd'),
			('Third','3rd'),
			('Fourth','4th'),
			('Fifth','5th'),
			('Sixth','6th'),
			('Seventh','7th'),
			('Eighth','8th'),
			('Ninth','9th'),
			('Tenth','10th'),

		)

	notice=models.ForeignKey(Notices)
	department=models.CharField(choices=Departments,max_length=20)
	semester=models.CharField(choices=Semesters,max_length=20)


from artmaps.maps.models import Location
from artmaps.maps.models import Gallery
from artmaps.maps.models import Show
from artmaps.maps.models import Event
from django.contrib import admin

class LocationAdmin(admin.ModelAdmin):
	list_display = ('nickname', 'address1', 'city', 'state', 'zipcode', 'url')

class ShowAdmin(admin.ModelAdmin):
	list_display = ('name', 'gallery', 'opening_date')
	list_filter = ['opening_date', 'gallery']
	search_fields = ['name', 'artist', 'description']
	fields = ['gallery','name', 'image', 'thumbnail', 'description',
		  'start_date', 'end_date', 'opening_date', 'time_info',
		  'pick', 'artist']

class EventAdmin(admin.ModelAdmin):
	list_display = ('title', 'gallery', 'event_type', 'date')
	list_filter = ['date', 'gallery', 'event_type']
	search_fields = ['title', 'description']

admin.site.register(Location, LocationAdmin)
admin.site.register(Gallery)
admin.site.register(Show, ShowAdmin)
admin.site.register(Event, EventAdmin)


import os

import maya.OpenMaya as OpenMaya
import maya.OpenMayaMPx as OpenMayaMPx
import maya.OpenMayaAnim as OpenMayaAnim

import maya.cmds as cmds
import maya.mel as mel

kPluginCmdName = 'manageSkinCluster'

# --------------------------------------------------------------------------------
# argument flags
# --------------------------------------------------------------------------------

helpFlag = '-h'
helpFlagLong = '-help'

fileFlag = '-f'
fileFlagLong = '-file'

modeFlag = '-m'
modeFlagLong = '-mode'

orderFlag = '-ro'
orderFlagLong = '-reverseOrder'

exclusiveFlag = '-ex'
exclusiveFlagLong = '-exclusive'

helpText = ''
helpText += '\n Description: The command exports and imports the selected skinCluster to/from a file.'
helpText += '\n'
helpText += '\n Flags: manageSkinCluster   -h    -help          <n/a>       this message'
helpText += '\n                            -m    -mode          <int>       write (default=0) or read (1)'
helpText += '\n                            -ro   -reverseOrder  <int>       from file (default=0) or reversed (1)'
helpText += '\n                            -f    -file          <string>    the file name for the skinCluster weight data'
helpText += '\n                            -ex   -exclusive     <int>       stores the weight for each influence to a separate file'
helpText += '\n'
helpText += '\n Usage:   Execute the command with the following arguments:'
helpText += '\n Execute: manageSkinCluster -m <mode> -f <file name>;';

# --------------------------------------------------------------------------------
# command
# --------------------------------------------------------------------------------

class transferSkinCluster(OpenMayaMPx.MPxCommand):

    def __init__( self ):
        OpenMayaMPx.MPxCommand.__init__(self)

    def doIt( self, args ):
        modeArg = 0
        fileName = ''
        orderArg = 0
        exclusiveArg = 0

        # parse the arguments.
        argData = OpenMaya.MArgDatabase(self.syntax(), args)

        if argData.isFlagSet(helpFlag):
            self.setResult(helpText)
            return()

        if argData.isFlagSet(modeFlag):
            modeArg = argData.flagArgumentDouble(modeFlag, 0)
        if argData.isFlagSet(orderFlag):
            orderArg = argData.flagArgumentDouble(orderFlag, 0)
        if argData.isFlagSet(exclusiveFlag):
            exclusiveArg = argData.flagArgumentDouble(exclusiveFlag, 0)
        if argData.isFlagSet(fileFlag):
            fileName = argData.flagArgumentString(fileFlag, 0)
        else:
            OpenMaya.MGlobal.displayError(kPluginCmdName + ' needs file name flag.')
            return();

        if fileName == '':
            OpenMaya.MGlobal.displayError(kPluginCmdName + ' file name is not specified.')
            return()

        if modeArg < 0 or modeArg > 1:
            OpenMaya.MGlobal.displayError(kPluginCmdName + ' mode needs to be set to either 0 for \'write\' or 1 for \'read\'.')
            return()

        start = cmds.timerX()
        msgString = ''

        result = 0
        if modeArg == 0:
            result = self.writeWeights(fileName, exclusiveArg)
            msgString = 'exported to '
        else:
            result = self.readWeights(fileName, orderArg)
            msgString = 'imported from '

        doneTime = cmds.timerX(startTime = start)
        if result == 1:
            OpenMaya.MGlobal.displayInfo('transferSkinCluster command took %.02f seconds' % doneTime)
            OpenMaya.MGlobal.displayInfo('Weights ' + msgString + '\'' + fileName + '\'')

    # --------------------------------------------------------------------------------
    # write the weights file
    # --------------------------------------------------------------------------------

    def writeWeights( self, fileName, exclusive ):

        # get the current selection
        skinClusterNode = cmds.ls(sl = True, fl = True)
        if len(skinClusterNode) != 0:
                skinClusterNode = skinClusterNode[0]
        else:
            OpenMaya.MGlobal.displayError('Select a skinCluster node to export.')
            return(-1)

        # check if it's a skinCluster
        if cmds.nodeType(skinClusterNode) != 'skinCluster':
            OpenMaya.MGlobal.displayError('Selected node is not a skinCluster.')
            return(-1)

        # get the MFnSkinCluster
        sel = OpenMaya.MSelectionList()
        OpenMaya.MGlobal.getActiveSelectionList(sel)
        skinClusterObject = OpenMaya.MObject()
        sel.getDependNode(0, skinClusterObject)
        skinClusterFn = OpenMayaAnim.MFnSkinCluster(skinClusterObject)

        # get the influence objects
        infls = cmds.skinCluster(skinClusterNode, q = True, inf = True)
        if len(infls) == 0:
            OpenMaya.MGlobal.displayError('No influence objects found for skinCluster %s.' % skinClusterNode)
            return(-1)

        # get the connected shape node
        shape = cmds.skinCluster(skinClusterNode, q = True, g = True)[0]
        if len(shape) == 0:
            OpenMaya.MGlobal.displayError('No connected shape nodes found.')
            return(-1)

        # get the dag path of the shape node
        cmds.select(shape, r = True)
        sel = OpenMaya.MSelectionList()
        OpenMaya.MGlobal.getActiveSelectionList(sel)
        shapeDag = OpenMaya.MDagPath()
        sel.getDagPath(0, shapeDag)
        # create the geometry iterator
        geoIter = OpenMaya.MItGeometry(shapeDag)

        # create a pointer object for the influence count of the MFnSkinCluster
        infCount = OpenMaya.MScriptUtil()
        infCountPtr = infCount.asUintPtr()
        OpenMaya.MScriptUtil.setUint(infCountPtr, 0)

        value = OpenMaya.MDoubleArray()

        #----------------------------------------------------
        # default export to a single skin weights file
        #----------------------------------------------------
        if not exclusive:
            try:
                weightFile = open(fileName, 'wb')
            except:
                OpenMaya.MGlobal.displayError('A file error has occured for file \'' + fileName + '\'.')
                return(-1)

            # write all influences and the shape node to the file
            for i in range(0, len(infls), 1):
                weightFile.write(infls[i] + " ")
            weightFile.write(shape + '\n')

            weightFile.write(skinClusterNode + '\n')

            # write the attributes of the skinCluster node to the file
            result = cmds.getAttr(skinClusterNode + ".normalizeWeights")
            weightFile.write('-nw %s ' % result)
            result = cmds.getAttr(skinClusterNode + ".maxInfluences")
            weightFile.write('-mi %s ' % result)
            result = cmds.getAttr(skinClusterNode + ".dropoff")[0][0]
            weightFile.write('-dr %s\n' % result)

            # get the skinCluster weights
            while geoIter.isDone() == False:
                skinClusterFn.getWeights(shapeDag, geoIter.currentItem(), value, infCountPtr)
                for j in range(0, len(infls)):
                    if value[j] > 0:
                        lineArray = [geoIter.index(), infls[j], j, value[j]]
                        weightFile.write(str(lineArray) + '\n')
                geoIter.next()
            weightFile.close()

        # ------------------------------------
        # custom export to individual files
        # ------------------------------------
        else:
            cmds.skinCluster(skinClusterNode, e = True, fnw = True);
            dataPath = '%s/%s' % (fileName, skinClusterNode)
            if not os.path.exists(dataPath):
                try:
                    os.makedirs(dataPath)
                except:
                    OpenMaya.MGlobal.displayError('Unable to create export directory \'' + dataPath + '\'.')
                    return(-1)

            for j in range(0, len(infls)):
                fileName = '%s/%s.bsw' % (dataPath, infls[j])
                try:
                    weightFile = open(fileName, 'wb')
                except:
                    OpenMaya.MGlobal.displayError('A file error has occured for file \'' + fileName + '\'.')
                    return(-1)
                geoIter.reset()

                while geoIter.isDone() == False:
                    skinClusterFn.getWeights(shapeDag, geoIter.currentItem(), value, infCountPtr)
                    line = str(geoIter.index()) + ' ' + str(value[j]) + '\n'
                    weightFile.write(line)
                    geoIter.next()
                weightFile.close()
        return(1)

    # --------------------------------------------------------------------------------
    # read the weights file
    # --------------------------------------------------------------------------------

    @staticmethod
    def getSkinCluster(_transform):
        """
        Find a SkinCluster from a transform
        Returns the skinCluster node
        """
        result = []
        if not (cmds.objExists(_transform)):
            return result
        validList = mel.eval('findRelatedDeformer("' + str(_transform) + '")')
        if validList is None:
            return result
        for elem in validList:
            if cmds.nodeType(elem) == 'skinCluster':
                result.append(elem)
        cmds.select(result, r=True)
        result_node = cmds.ls(sl=1)

        if len(result_node) > 1:
            return str(result_node)
        else:
            try:
                return str(result_node[0])
            except IndexError:
                return False

    def readWeights(self, fileName, reverseOrder):
        # open the file for reading
        try:
            weightFile = open(fileName, 'rb')
        except:
            OpenMaya.MGlobal.displayError('A file error has occured for file \'' + fileName + '\'.')
            return(-1)

        weightData = weightFile.read()
        weightLines = weightData.split('\n')
        weightFile.close()

        normalization = 1

        # variables for writing a range of influences
        weightString = ''
        inflStart = -1
        inflEnd = -1
        setCount = 0
        writeData = 0

        # --------------------------------------------------------------------------------
        # the first line contains the joints and skin shape
        # --------------------------------------------------------------------------------
        objects = weightLines[0]
        items = objects.split(' ')
        shape = items[len(items) - 1]

        # --------------------------------------------------------------------------------
        # the second line contains the name of the skin cluster
        # --------------------------------------------------------------------------------
        skinClusterName = weightLines[1]

        # --------------------------------------------------------------------------------
        # the third line contains the values for the skin cluster
        # --------------------------------------------------------------------------------
        objects = objects.split(' ')
        if reverseOrder == 1:
            objects = objects[::-1]
            objects.pop(0)
            objects.append(shape)

        # check for the version
        # up to Maya 2012 the bind method flag is not available
        version = mel.eval('getApplicationVersionAsFloat()')
        bindMethod = '-bm 0 '
        if version < 2013:
            bindMethod = '-ih '

        # create the new skinCluster
        original_skinCls = self.getSkinCluster(shape)
        if original_skinCls is not False:
            try:
                cmds.skinCluster(cmds.listRelatives(shape, parent=1)[0], e=1, ub=1)
            except:
                pass

        # select the influences and the skin shape
        try:
            cmds.select(objects, r = True)
        except:
            weightFile.close()
            return()
        newSkinCluster = mel.eval('newSkinCluster \"-tsb ' + bindMethod + weightLines[2] + '-omi true -rui false\"')[0]
        cmds.rename(newSkinCluster, skinClusterName)

        # get the current normalization and store it
        # it will get re-applied after applying all the weights
        normalization = cmds.getAttr(skinClusterName + '.nw')
        # turn off the normalization to correctly apply the stored skin weights
        cmds.setAttr((skinClusterName + '.nw'), 0)
        # pruning the skin weights to zero is much faster
        # than iterating through all components and setting them to 0
        cmds.skinPercent(skinClusterName, shape, prw = 100, nrm = 0)

        # allocate memory for the number of components to set
        weights = eval(weightLines[len(weightLines) - 2])
        # get the index of the last component stored in the weight list
        maxIndex = weights[0]
        cmds.select(skinClusterName, r = True)
        cmdString = 'setAttr -s ' + str(maxIndex + 1) + ' \".wl\"'
        OpenMaya.MGlobal.executeCommand(cmdString)

        # --------------------------------------------------------------------------------
        # apply the weight data
        # --------------------------------------------------------------------------------

        # timer for timing the read time without the smooth binding
        #start = cmds.timerX()

        for l in range(3, len(weightLines) - 1):
            weights = eval(weightLines[l])
            weightsNext = ''
            # also get the next line for checking if the component changes
            # but only if it's not the end of the list
            if l < len(weightLines) - 2:
                weightsNext = eval(weightLines[l + 1])
            else:
                weightsNext = weights
                writeData = 1

            compIndex = weights[0]

            # --------------------------------------------------------------------------------
            # construct the setAttr string
            # i.e. setAttr -s 4 ".wl[9].w[0:3]"  0.0003 0.006 0.496 0.496
            # --------------------------------------------------------------------------------

            # start a new range
            if inflStart == -1:
                inflEnd = inflStart = weights[2]
            else:
                # if the current component is the next in line
                if inflEnd == weights[2] - 1:
                    inflEnd = weights[2]
                # if influences were dropped because of zero weight
                else:
                    # fill the weight string inbetween with zeros
                    for x in range(inflEnd + 1, weights[2]):
                        weightString += '0 '
                        setCount += 1
                    inflEnd = weights[2]

            # add the weight to the weight string
            weightString += str(weights[3]) + ' '
            # increase the number of weights to be set
            setCount += 1

            # if the next line is for the next index set the weights
            if compIndex != weightsNext[0]:
                writeData = 1

            if writeData == 1:
                # decide if a range or a single influence index is written
                rangeString = ':' + str(inflEnd)
                if inflEnd == inflStart:
                    rangeString = ''

                cmdString = 'setAttr -s ' + str(setCount) + ' \".weightList[' + str(compIndex) + '].weights[' + str(inflStart) + rangeString + ']\" ' + weightString
                OpenMaya.MGlobal.executeCommand(cmdString)

                # reset and start over
                inflStart = inflEnd = -1
                writeData = 0
                setCount = 0
                weightString = ''

        cmds.setAttr((skinClusterName + '.nw'), normalization)

        if original_skinCls is not False:
            cmds.rename(skinClusterName,  str(original_skinCls))

        #doneTime = cmds.timerX(startTime = start)
        #OpenMaya.MGlobal.displayInfo('%.02f seconds' % doneTime)

        return(1)

# --------------------------------------------------------------------------------
# define the syntax, needed to make it work with mel and python
# --------------------------------------------------------------------------------

# creator
def cmdCreator():
    return OpenMayaMPx.asMPxPtr(transferSkinCluster())

def syntaxCreator():
    syn = OpenMaya.MSyntax()
    syn.addFlag(helpFlag, helpFlagLong);
    syn.addFlag(fileFlag, fileFlagLong, OpenMaya.MSyntax.kString);
    syn.addFlag(modeFlag, modeFlagLong, OpenMaya.MSyntax.kLong);
    syn.addFlag(orderFlag, orderFlagLong, OpenMaya.MSyntax.kLong);
    syn.addFlag(exclusiveFlag, exclusiveFlagLong, OpenMaya.MSyntax.kLong);
    return syn

# initialization
def initializePlugin( mobject ):
    mplugin = OpenMayaMPx.MFnPlugin(mobject, 'Audrey Deschamps-Brower', '1.00')
    try:
        mplugin.registerCommand(kPluginCmdName, cmdCreator, syntaxCreator)
    except:
        sys.stderr.write('Failed to register command: %s\n' % kPluginCmdName)
        raise

def uninitializePlugin( mobject ):
    mplugin = OpenMayaMPx.MFnPlugin(mobject)
    try:
        mplugin.deregisterCommand(kPluginCmdName)
    except:
        sys.stderr.write( 'Failed to unregister command: %s\n' % kPluginCmdName )
        raise


# Once the player enters the Teleporter Device they are
# immediately relocated to the closest NetherPortal
# NOTE: these XYZ coordinates are unique to my MC server world

from mcpi.minecraft import Minecraft
import time

def teleport():

    mc.postToChat("BINGO!")
    mc.player.setPos(-453, 4, -255)

if __name__ == "__main__":
    mc = Minecraft.create()

    while True:
        pos = mc.player.getPos()
        x = pos.x
        y = pos.y
        z = pos.z

        if x<-426 and x>-427 and y==4 and z<-199 and z>-200:
            teleport()


import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# 線形関数の定義
def linear_func(x, a, b):
    return a * x + b

# データ数
n = 100

# xの範囲
x_min, x_max = 0, 10

# 誤差の範囲
error_range = 0.5

# xの配列を生成
x_values = np.linspace(x_min, x_max, n)

# 2つのランダムな誤差を含むyの配列を生成
y1_values = 3 * x_values + 5 + np.random.uniform(-error_range, error_range, n)
y2_values = 4 * x_values + 7 + np.random.uniform(-error_range, error_range, n)

# 最小二乗法でパラメータを決定
params1, _ = curve_fit(linear_func, x_values, y1_values)
params2, _ = curve_fit(linear_func, x_values, y2_values)

# 最小二乗法で求めたパラメータを表示
print("Line 1: a = {:.3f}, b = {:.3f}".format(params1[0], params1[1]))
print("Line 2: a = {:.3f}, b = {:.3f}".format(params2[0], params2[1]))

# 相対スケールと相対切片を計算
relative_scale = params2[0] / params1[0]
relative_intercept = params2[1] - params1[1]

print("Relative scale:", relative_scale)
print("Relative intercept:", relative_intercept)

# 新しい配列を生成
new_y1_values = relative_scale * y1_values + relative_intercept

sum1=sum(np.power(y1_values-y2_values,2.0))
sum2=sum(np.power(new_y1_values-y2_values,2.0))
print(sum1,sum2)
# プロット
plt.plot(x_values, y1_values, 'o', label='Original Line 1')
plt.plot(x_values, y2_values, 'o', label='Original Line 2')
plt.plot(x_values, new_y1_values, 'o', label='Transformed Line 1')
plt.legend()
plt.savefig("test.png")


#!/usr/bin/env python3
import argparse
import concurrent.futures
import os
import time
import random
from concurrent.futures import ThreadPoolExecutor

import requests

from tqdm import tqdm

user_agents = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
    "Mozilla/5.0 (Windows NT 5.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.2; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.90 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36",
    "Mozilla/4.0 (compatible; MSIE 9.0; Windows NT 6.1)",
    "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)",
    "Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 6.2; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; Trident/5.0)",
    "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)",
    "Mozilla/5.0 (Windows NT 6.1; Win64; x64; Trident/7.0; rv:11.0) like Gecko",
    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)",
    "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)",
    "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)",
]
visitvsco = {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "en-US,en;q=0.9",
    "Connection": "keep-alive",
    "Host": "vsco.co",
    "Upgrade-Insecure-Requests": "1",
    "User-Agent": random.choice(user_agents),
}

visituserinfo = {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "en-US,en;q=0.9",
    "Connection": "keep-alive",
    "Host": "vsco.co",
    "Referer": "https://vsco.co/bob/images/1",
    "User-Agent": random.choice(user_agents),
}

media = {
    "Accept": "*/*",
    "Accept-Encoding": "gzip, deflate",
    "Accept-Language": "en-US,en;q=0.9",
    "Connection": "keep-alive",
    "Host": "vsco.co",
    "Referer": "https://vsco.co/bob/images/1",
    "User-Agent": random.choice(user_agents),
    "X-Client-Build": "1",
    "X-Client-Platform": "web",
}

class Scraper(object):
    def __init__(self, username):
        self.username = username
        self.session = requests.Session()
        self.session.get(
            "https://vsco.co/content/Static/userinfo?callback=jsonp_%s_0"
            % (str(round(time.time() * 1000))),
            headers=visituserinfo,
        )
        self.uid = self.session.cookies.get_dict()["vs"]
        path = os.path.join(os.getcwd(), self.username)
        # If the path doesn't exist, then create it
        if not os.path.exists(path):
            os.makedirs(path)
        os.chdir(path)
        self.path = path
        self.newSiteId()
        self.buildJSON()
        self.totalj = 0
        self.imagelist = []

    def newSiteId(self):
        """
        Gets the unique id used per vsco user, it can be found in the cookies
        :params: none
        :return: returns the site id of a user in case you were curious
        """
        res = self.session.get(
            "https://vsco.co/ajxp/%s/2.0/sites?subdomain=%s" % (self.uid, self.username)
        )
        self.siteid = res.json()["sites"][0]["id"]
        self.sitecollectionid = res.json()["sites"][0]["site_collection_id"]
        return self.siteid

    def buildJSON(self):
        """
        Creates the urls used to grab json data for a user
        :params: none
        :return: returns the main media url by default
        """
        self.mediaurl = "https://vsco.co/ajxp/%s/2.0/medias?site_id=%s" % (
            self.uid,
            self.siteid,
        )
        self.journalurl = "https://vsco.co/ajxp/%s/2.0/articles?site_id=%s" % (
            self.uid,
            self.siteid,
        )
        self.collectionurl = "https://vsco.co/ajxp/%s/2.0/collections/%s/medias?" % (
            self.uid,
            self.sitecollectionid,
        )
        return self.mediaurl

    def getCollection(self):
        """
        Downloads the collection posts from the user
        :params: none
        :return: none
        """
        self.imagelist = []
        path = os.path.join(os.getcwd(), "collection")
        if not os.path.exists(path):
            os.makedirs(path)
        os.chdir(path)
        self.getCollectionList()
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
            future_to_url = {
                executor.submit(self.download_img_normal, lists): lists
                for lists in self.imagelist
            }
            for future in tqdm(
                    concurrent.futures.as_completed(future_to_url),
                    total=len(self.imagelist),
                    desc="Downloading collection posts of %s" % self.username,
                    unit=" posts",
            ):
                liste = future_to_url[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print("%r crashed %s" % (liste, exc))
        os.chdir("..")

    def getCollectionList(self):
        """
        Starts setting up to download the collection

        Does magical stuff with the concurrent future
        :params: none
        :return: none
        """
        self.pbar = tqdm(
            desc="Finding new collection posts of %s" % self.username, unit=" posts"
        )
        with ThreadPoolExecutor(max_workers=5) as executor:
            future_to_url = {
                executor.submit(self.makeCollectionList, num): num for num in range(5)
            }
            for future in concurrent.futures.as_completed(future_to_url):
                num = future_to_url[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print("%r crashed %s" % (num, exc))
        self.pbar.close()

    def makeCollectionList(self, num):
        """
        Determines what file type a media item is, then appends the correct url
        :params: num - this does some magic, no idea why it works or why I did it
        :return: a boolean on whether the list was successfully made
        """
        num += 1
        z = self.session.get(
            self.collectionurl,
            params={"size": 100, "page": num},
            headers=media,
        ).json()["medias"]

        count = len(z)
        while count > 0:
            for url in z:
                if (
                        "%s.jpg" % str(url["upload_date"])[:-3] in os.listdir()
                        or "%s.mp4" % str(url["upload_date"])[:-3] in os.listdir()
                ):
                    continue
                if url["is_video"] is True:
                    self.imagelist.append(
                        [
                            "https://%s" % url["video_url"],
                            str(url["upload_date"])[:-3],
                            True,
                        ]
                    )
                    self.pbar.update()
                else:
                    self.imagelist.append(
                        [
                            "https://%s" % url["responsive_url"],
                            str(url["upload_date"])[:-3],
                            False,
                        ]
                    )
                    self.pbar.update()
            num += 5
            z = self.session.get(
                self.collectionurl,
                params={"size": 100, "page": num},
                headers=media,
            ).json()["medias"]
            count = len(z)
        return True

    def getJournal(self):
        """
        Downloads the journal posts from the user
        :params: none
        :return: none
        """
        self.getJournalList()
        self.progbarj = tqdm(
            total=self.totalj,
            desc="Downloading journal posts of %s" % self.username,
            unit=" posts",
        )
        for x in self.works:
            path = os.path.join(os.getcwd(), x[0])
            if not os.path.exists(path):
                os.makedirs(path)
            os.chdir(path)
            x.pop(0)
            with ThreadPoolExecutor(max_workers=5) as executor:
                future_to_url = {
                    executor.submit(self.download_img_journal, part): part for part in x
                }
                for future in concurrent.futures.as_completed(future_to_url):
                    part = future_to_url[future]
                    try:
                        data = future.result()
                    except Exception as exc:
                        print("%r crashed %s" % (part, exc))
            os.chdir(os.path.normpath(os.getcwd() + os.sep + os.pardir))
        self.progbarj.close()

    def getJournalList(self):
        """
        Opens initial journal data of a user and creates the journal folder

        Then it does some magical bs, I made this years ago no idea how it works

        :params: none
        :return: none
        """
        self.works = []
        self.jour_found = self.session.get(
            self.journalurl, params={"size": 10000, "page": 1}, headers=media
        ).json()["articles"]
        self.pbarjlist = tqdm(
            desc="Finding new journal posts of %s" % self.username, unit=" posts"
        )
        for x in self.jour_found:
            self.works.append([x["permalink"]])
        path = os.path.join(os.getcwd(), "journal")
        if not os.path.exists(path):
            os.makedirs(path)
        os.chdir(path)
        with ThreadPoolExecutor(max_workers=5) as executor:
            future_to_url = {
                executor.submit(self.makeListJournal, len(self.jour_found), val): val
                for val in range(len(self.jour_found))
            }
            for future in concurrent.futures.as_completed(future_to_url):
                val = future_to_url[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print("%r crashed %s" % (val, exc))
        self.pbarjlist.close()

    def makeListJournal(self, num, loc):
        """
        Makes the list of all journal entries on the users page
        :params: num, loc
        :return: a boolean on whether the journal media was able to be grabbed
        """
        for item in self.jour_found[loc]["body"]:
            if item["type"] == "image":
                if os.path.exists(
                        os.path.join(os.getcwd(), self.jour_found[loc]["permalink"])
                ):
                    if "%s.jpg" % str(item["content"][0]["id"]) in os.listdir(
                            os.path.join(os.getcwd(), self.jour_found[loc]["permalink"])
                    ):
                        continue
                self.works[loc].append(
                    [
                        "https://%s" % item["content"][0]["responsive_url"],
                        item["content"][0]["id"],
                        "img",
                    ]
                )
            elif item["type"] == "video":
                if os.path.exists(
                        os.path.join(os.getcwd(), self.jour_found[loc]["permalink"])
                ):
                    if "%s.mp4" % str(item["content"][0]["id"]) in os.listdir(
                            os.path.join(os.getcwd(), self.jour_found[loc]["permalink"])
                    ):
                        continue
                self.works[loc].append(
                    [
                        "https://%s" % item["content"][0]["video_url"],
                        item["content"][0]["id"],
                        "vid",
                    ]
                )
            elif item["type"] == "text":
                if os.path.exists(
                        os.path.join(os.getcwd(), self.jour_found[loc]["permalink"])
                ):
                    if "%s.txt" % str(item["content"]) in os.listdir(
                            os.path.join(os.getcwd(), self.jour_found[loc]["permalink"])
                    ):
                        continue
                self.works[loc].append([item["content"], "txt"])
            self.totalj += 1
            self.pbarjlist.update()
        return True

    def download_img_journal(self, lists):
        """
        Downloads the journal media in specified ways depending on the type of media

        Since Journal items can be text files, images, or videos, I had to make 3
        different ways of downloading

        :params: lists - No idea why I named it this, but it's a media item
        :return: a boolean on whether the journal media was able to be downloaded
        """
        if lists[1] == "txt":
            with open("%s.txt" % str(lists[0]), "w") as f:
                f.write(lists[0])
        if lists[2] == "img":
            if "%s.jpg" % lists[1] in os.listdir():
                return True
            with open("%s.jpg" % str(lists[1]), "wb") as f:
                f.write(requests.get(lists[0], stream=True).content)

        elif lists[2] == "vid":
            if "%s.mp4" % lists[1] in os.listdir():
                return True
            with open("%s.mp4" % str(lists[1]), "wb") as f:
                for chunk in requests.get(lists[0], stream=True).iter_content(
                        chunk_size=1024
                ):
                    if chunk:
                        f.write(chunk)
        self.progbarj.update()
        return True

    def getImages(self):
        """
        Makes a list of all media items in a page

        I clearly recall straight copy pasting the concurrent futures thing from stack
        overflow. Still have no idea how it works

        :params: none
        :return: none
        """
        self.imagelist = []
        self.getImageList()
        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
            future_to_url = {
                executor.submit(self.download_img_normal, lists): lists
                for lists in self.imagelist
            }
            for future in tqdm(
                    concurrent.futures.as_completed(future_to_url),
                    total=len(self.imagelist),
                    desc="Downloading posts of %s" % self.username,
                    unit=" posts",
            ):
                liste = future_to_url[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print("%r crashed %s" % (liste, exc))

    def getImageList(self):
        """
        tqdm is a great library isn't it

        :params: none
        :return: none
        """
        self.pbar = tqdm(desc="Finding new posts of %s" % self.username, unit=" posts")
        with ThreadPoolExecutor(max_workers=5) as executor:
            future_to_url = {
                executor.submit(self.makeImageList, num): num for num in range(5)
            }
            for future in concurrent.futures.as_completed(future_to_url):
                num = future_to_url[future]
                try:
                    data = future.result()
                except Exception as exc:
                    print("%r crashed %s" % (num, exc))
        self.pbar.close()

    def makeImageList(self, num):
        """
        At this point I'm only doing these comments out of a general sense I should comment
        all these functions after that one PR did it

        Don't ask me how it works, frankly I'm surprised it does

        :params: num - I remember looking at this after starting to merge the prs and wondering why I did num += 5. Still couldn't tell you.
        :return: a boolean on whether the journal media was able to be grabbed
        """
        num += 1
        z = self.session.get(
            self.mediaurl, params={"size": 100, "page": num}, headers=media
        ).json()["media"]
        count = len(z)
        while count > 0:
            for url in z:
                if (
                        "%s.jpg" % str(url["upload_date"])[:-3] in os.listdir()
                        or "%s.mp4" % str(url["upload_date"])[:-3] in os.listdir()
                ):
                    continue
                if url["is_video"] is True:
                    self.imagelist.append(
                        [
                            "https://%s" % url["video_url"],
                            str(url["upload_date"])[:-3],
                            True,
                        ]
                    )
                    self.pbar.update()
                else:
                    self.imagelist.append(
                        [
                            "https://%s" % url["responsive_url"],
                            str(url["upload_date"])[:-3],
                            False,
                        ]
                    )
                    self.pbar.update()
            num += 5
            z = self.session.get(
                self.mediaurl,
                params={"size": 100, "page": num},
                headers=media,
            ).json()["media"]
            count = len(z)
        return True

    def download_img_normal(self, lists):
        """
        This function makes sense at least

        The if '%s.whatever' sections are to skip downloading the file again if it's already been downloaded

        At the time I wrote this, I only remember seeing that images and videos were the only things allowed

        So I didn't write an if statement checking for text files, so this would just skip it I believe if it ever came up
        and return True

        :params: lists - My naming sense was beat. lists is just a media item.
        :return: a boolean on whether the media item was downloaded successfully
        """
        if lists[2] is False:
            if "%s.jpg" % lists[1] in os.listdir():
                return True
            with open("%s.jpg" % str(lists[1]), "wb") as f:
                f.write(requests.get(lists[0], stream=True).content)
        else:
            if "%s.mp4" % lists[1] in os.listdir():
                return True
            with open("%s.mp4" % str(lists[1]), "wb") as f:
                for chunk in requests.get(lists[0], stream=True).iter_content(
                        chunk_size=1024
                ):
                    if chunk:
                        f.write(chunk)
        return True

    def run_all(self):
        """
        This runs all of the operations on a user's profile,
        it gets the images, the collection, and the journal entries
        :params: none
        :return: none
        """
        self.getImages()
        self.getCollection()
        self.getJournal()

def parser():
    """Returns the parser arguments
    :params: none
    :return: parser.parse_args() object
    """
    parser = argparse.ArgumentParser(
        description="Scrapes a specified users VSCO Account"
    )
    parser.add_argument(
        "username",
        type=str,
        help="VSCO user to scrape or file name to read usernames off of. Filename feature works with -m, -mc, -mj, and -a only",
    )
    parser.add_argument(
        "-s", "--siteId", action="store_true", help="Grabs VSCO siteID for user"
    )
    parser.add_argument(
        "-i", "--getImages", action="store_true", help="Get the pictures of the user"
    )
    parser.add_argument(
        "-j",
        "--getJournal",
        action="store_true",
        help="Get the journal images of the user",
    )
    parser.add_argument(
        "-c",
        "--getCollection",
        action="store_true",
        help="Get the collection images of the user",
    )
    parser.add_argument(
        "-m", "--multiple", action="store_true", help="Scrape multiple users"
    )
    parser.add_argument(
        "-mj",
        "--multipleJournal",
        action="store_true",
        help="Scrape multiple users journal",
    )
    parser.add_argument(
        "-mc",
        "--multipleCollection",
        action="store_true",
        help="Scrape multiple users collection",
    )
    parser.add_argument(
        "-a",
        "--all",
        action="store_true",
        help="Scrape multiple users journals and images",
    )
    return parser.parse_args()

def main():
    args = parser()

    if args.siteId:
        scraper = Scraper(args.username)
        print(scraper.newSiteId())

    if args.getImages:
        scraper = Scraper(args.username)
        scraper.getImages()

    if args.getJournal:
        scraper = Scraper(args.username)
        scraper.getJournal()

    if args.getCollection:
        scraper = Scraper(args.username)
        scraper.getCollection()

    if args.multiple:
        y = []
        vsco = os.getcwd()
        with open(args.username, "r") as f:
            for x in f:
                y.append(x.replace("\n", ""))
        for z in y:
            try:
                os.chdir(vsco)
                Scraper(z).getImages()
                print()
            except:
                print("%s crashed" % z)
                pass

    if args.multipleJournal:
        y = []
        vsco = os.getcwd()
        with open(args.username, "r") as f:
            for x in f:
                y.append(x.replace("\n", ""))
        for z in y:
            try:
                os.chdir(vsco)
                Scraper(z).getJournal()
                print()
            except:
                print("%s crashed" % z)
                pass

    if args.multipleCollection:
        y = []
        vsco = os.getcwd()
        with open(args.username, "r") as f:
            for x in f:
                y.append(x.replace("\n", ""))
        for z in y:
            try:
                os.chdir(vsco)
                Scraper(z).getCollection()
                print()
            except:
                print("%s crashed" % z)
                pass

    if args.all:
        y = []
        vsco = os.getcwd()
        with open(args.username, "r") as f:
            for x in f:
                y.append(x.replace("\n", ""))
        for z in y:
            try:
                os.chdir(vsco)
                Scraper(z).run_all()
                print()
            except:
                print("%s crashed" % z)
                pass

if __name__ == "__main__":
    main()


"""
* 벨만-포드 알고리즘 : 그래프에서 시작 정점으로부터 다른 정점까지의 최단 경로를 찾기 위한 알고리즘.
1. 음수 가중치가 있는 그래프의 시작 정점에서 다른 정점까지의 최단 거리를 구할 수 있다.
2. 음수 사이클 존재의 여부를 알 수 있다.

"""
def bellman_ford(start):
    distances = [1e9 for _ in range(n+1)]
    distances[start] = 0

    for check in range(n): # 모든 정점에 대해서 자신의 정점까지의 거리가 적은 것으로 갱신되는 것을 정점 개수만큼 반복
        for now_n in range(1, n+1): # 지점
            for next_d, next_n in adj[now_n]:
                next_d += distances[now_n]
                if next_d < distances[next_n]:
                    distances[next_n] = next_d
                    # 계속 줄어들어 n번째까지 값이 갱신되다면 "음의 싸이클"이 존재하므로 출발하였을 때보다 시간이 되돌아가 있게 된다.
                    if check == n-1:
                        return False
    return True

for _ in range(int(input())):
    n, m, w = map(int, input().split())
    adj = [[] for _ in range(n + 1)]
    for _ in range(m):
        s, e, d = map(int, input().split())
        adj[s].append((d, e))
        adj[e].append((d, s))

    for _ in range(w):
        s, e, d = map(int, input().split())
        adj[s].append((-d, e))

    print("NO") if bellman_ford(1) else print("YES")


import geometry
import torchvision
import util

from pytorch_prototyping import pytorch_prototyping

import torch
from torch import nn

def init_recurrent_weights(self):
    for m in self.modules():
        if type(m) in [nn.GRU, nn.LSTM, nn.RNN]:
            for name, param in m.named_parameters():
                if 'weight_ih' in name:
                    nn.init.kaiming_normal_(param.data)
                elif 'weight_hh' in name:
                    nn.init.orthogonal_(param.data)
                elif 'bias' in name:
                    param.data.fill_(0)

def lstm_forget_gate_init(lstm_layer):
    for name, parameter in lstm_layer.named_parameters():
        if not "bias" in name: continue
        n = parameter.size(0)
        start, end = n // 4, n // 2
        parameter.data[start:end].fill_(1.)

def clip_grad_norm_hook(x, max_norm=10):
    total_norm = x.norm()
    total_norm = total_norm ** (1 / 2.)
    clip_coef = max_norm / (total_norm + 1e-6)
    if clip_coef < 1:
        return x * clip_coef

class DepthSampler(nn.Module):
    def __init__(self):
        super().__init__()

    def forward(self,
                xy,
                depth,
                cam2world,
                intersection_net,
                intrinsics):
        self.logs = list()

        batch_size, _, _ = cam2world.shape

        intersections = geometry.world_from_xy_depth(xy=xy, depth=depth, cam2world=cam2world, intrinsics=intrinsics)

        depth = geometry.depth_from_world(intersections, cam2world)

        if self.training:
            print(depth.min(), depth.max())

        return intersections, depth

class Raymarcher(nn.Module):
    def __init__(self,
                 num_feature_channels,
                 raymarch_steps):
        super().__init__()

        self.n_feature_channels = num_feature_channels
        self.steps = raymarch_steps

        hidden_size = 16
        self.lstm = nn.LSTMCell(input_size=self.n_feature_channels,
                                hidden_size=hidden_size)

        self.lstm.apply(init_recurrent_weights)
        lstm_forget_gate_init(self.lstm)

        self.out_layer = nn.Linear(hidden_size, 1)
        self.counter = 0

    def forward(self,
                cam2world,
                phi,
                uv,
                intrinsics):
        batch_size, num_samples, _ = uv.shape
        log = list()

        ray_dirs = geometry.get_ray_directions(uv,
                                               cam2world=cam2world,
                                               intrinsics=intrinsics)

        initial_depth = torch.zeros((batch_size, num_samples, 1)).normal_(mean=0.05, std=5e-4).cuda()
        init_world_coords = geometry.world_from_xy_depth(uv,
                                                         initial_depth,
                                                         intrinsics=intrinsics,
                                                         cam2world=cam2world)

        world_coords = [init_world_coords]
        depths = [initial_depth]
        states = [None]

        for step in range(self.steps):
            v = phi(world_coords[-1])

            state = self.lstm(v.view(-1, self.n_feature_channels), states[-1])

            if state[0].requires_grad:
                state[0].register_hook(lambda x: x.clamp(min=-10, max=10))

            signed_distance = self.out_layer(state[0]).view(batch_size, num_samples, 1)
            new_world_coords = world_coords[-1] + ray_dirs * signed_distance

            states.append(state)
            world_coords.append(new_world_coords)

            depth = geometry.depth_from_world(world_coords[-1], cam2world)

            if self.training:
                print("Raymarch step %d: Min depth %0.6f, max depth %0.6f" %
                      (step, depths[-1].min().detach().cpu().numpy(), depths[-1].max().detach().cpu().numpy()))

            depths.append(depth)

        if not self.counter % 100:
            # Write tensorboard summary for each step of ray-marcher.
            drawing_depths = torch.stack(depths, dim=0)[:, 0, :, :]
            drawing_depths = util.lin2img(drawing_depths).repeat(1, 3, 1, 1)
            log.append(('image', 'raycast_progress',
                        torch.clamp(torchvision.utils.make_grid(drawing_depths, scale_each=False, normalize=True), 0.0,
                                    5),
                        100))

            # Visualize residual step distance (i.e., the size of the final step)
            fig = util.show_images([util.lin2img(signed_distance)[i, :, :, :].detach().cpu().numpy().squeeze()
                                    for i in range(batch_size)])
            log.append(('figure', 'stopping_distances', fig, 100))
        self.counter += 1

        return world_coords[-1], depths[-1], log

class DeepvoxelsRenderer(nn.Module):
    def __init__(self,
                 nf0,
                 in_channels,
                 input_resolution,
                 img_sidelength):
        super().__init__()

        self.nf0 = nf0
        self.in_channels = in_channels
        self.input_resolution = input_resolution
        self.img_sidelength = img_sidelength

        self.num_down_unet = util.num_divisible_by_2(input_resolution)
        self.num_upsampling = util.num_divisible_by_2(img_sidelength) - self.num_down_unet

        self.build_net()

    def build_net(self):
        self.net = [
            pytorch_prototyping.Unet(in_channels=self.in_channels,
                                     out_channels=3 if self.num_upsampling <= 0 else 4 * self.nf0,
                                     outermost_linear=True if self.num_upsampling <= 0 else False,
                                     use_dropout=True,
                                     dropout_prob=0.1,
                                     nf0=self.nf0 * (2 ** self.num_upsampling),
                                     norm=nn.BatchNorm2d,
                                     max_channels=8 * self.nf0,
                                     num_down=self.num_down_unet)
        ]

        if self.num_upsampling > 0:
            self.net += [
                pytorch_prototyping.UpsamplingNet(per_layer_out_ch=self.num_upsampling * [self.nf0],
                                                  in_channels=4 * self.nf0,
                                                  upsampling_mode='transpose',
                                                  use_dropout=True,
                                                  dropout_prob=0.1),
                pytorch_prototyping.Conv2dSame(self.nf0, out_channels=self.nf0 // 2, kernel_size=3, bias=False),
                nn.BatchNorm2d(self.nf0 // 2),
                nn.ReLU(True),
                pytorch_prototyping.Conv2dSame(self.nf0 // 2, 3, kernel_size=3)
            ]

        self.net += [nn.Tanh()]
        self.net = nn.Sequential(*self.net)

    def forward(self, input):
        batch_size, _, ch = input.shape
        input = input.permute(0, 2, 1).view(batch_size, ch, self.img_sidelength, self.img_sidelength)
        out = self.net(input)
        return out.view(batch_size, 3, -1).permute(0, 2, 1)


'''
Created on Jan 14, 2017

@author: User
'''
import string
import itertools
import operator
#word = input("Enter text: ")
def most_common(word):
    keyVal = {}
    if len(word) > 3 and len(word) < 10000:
        for i in word:
            keyVal[i] = word.count(i)
        sortedKeyVal = sorted(keyVal.items(), key = lambda x:x[1], reverse=True)
        #you also do. Make you you import the operator module before you do this
        #sortedKeyVal = sorted(keyVal.items(), key = operator.itemgetter(1), reverse=True) #change the itemgetter to zero to sort with the keys
    for key, value in itertools.islice(sortedKeyVal, 3):
        print(key, value)

#most_common(word)

def most_common2(word):
    diction = {}
    for char in word:
        diction[char] = word.count(char)
    sorted_dict = sorted(diction.items(), key=operator.itemgetter(1), reverse=True)
    keys = list(diction.keys())
    keys.sort()

    sorted_dict = dict(sorted_dict)
    limit = 0
    while len(sorted_dict) > 0:
        highest_count = 0
        highest_word = ""
        position = 0
        for x in range(len(keys)):
            if sorted_dict[keys[x]] > highest_count:
                highest_count = sorted_dict[keys[x]]
                highest_word = keys[x]
                position = x
        del sorted_dict[highest_word]
        del keys[position]
        print(highest_word+" %d" % highest_count)
        limit += 1
        if limit > 2:
            break

most_common(input("Enter a string\n"))


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri May 27 13:47:15 2022

@author: tomasnotenson
"""
from scipy.fft import fft, ifft, fftfreq, fft2, ifft2
import numpy as np
from numba import jit
import matplotlib.pyplot as plt
from qutip import *
from time import time
from tqdm import tqdm # customisable progressbar decorator for iterators
from cmath import phase
from scipy.stats import skew
import seaborn as sns; sns.set_theme()
plt.rcParams.update({
"text.usetex": True,
"font.family": "sans-serif",
"font.sans-serif": ["Helvetica"], "font.size": 24})

@jit(nopython=True, parallel=True, fastmath = True)#, cache=True)#(cache=True)#(nopython=True)
def FF(N, x1 = 0, p1 = 0):
    FF = np.zeros((N,N),dtype=np.complex_)
    for i in range(N):
        for j in range(N):
            FF[i,j]=np.exp(-1j*2*np.pi*(i + x1)*(j + p1)/N)*np.sqrt(1/N)
    return FF

@jit#(nopython=True, parallel=True, fastmath = True)#, cache=True)#(nopython=True)
def UU(K, N, op = 'P', x1 = 0, p1 = 0):
    UU = np.zeros((N,N),dtype=np.complex_)
    MM = np.zeros((N,N),dtype=np.complex_)
    F = FF(N)
    Keff = K/(4*np.pi**2)

    if op == 'X':

        for i in range(N):
                for j in range(N):
                    UU[i,j]=F[i,j]*np.exp(-1j*2*np.pi*N*Keff*np.cos(2*np.pi*(i + x1)/N))#/N
                    MM[i,j]=np.conjugate(F[j,i])*np.exp(-1j*np.pi*(i + p1)**2/N)
    elif op == 'P'  :
        for i in range(N):
                for j in range(N):
                    UU[i,j]=np.exp(-1j*2*np.pi*N*Keff*np.cos(2*np.pi*(i + x1)/N))*np.conjugate(F[j,i])
                    MM[i,j]=np.exp(-1j*np.pi*(i + p1)**2/N)*F[i,j]

    U = MM@UU
    U = np.matrix(U)
    return U

def fV(N):
    V = 0
    for j in range(N):
        V += basis(N,(j+1)%N)*basis(N,j).dag()
    return V

@jit#(nopython=True, parallel=True, fastmath = True)
def fV_numpy(N):
    V = np.zeros((N,N), dtype=np.complex_)
    I = np.identity(N)
    for j in range(N):
        V += np.outer(I[:,(j+1)%N],I[j,:])
    V = np.matrix(V)
    return V #np.matrix(V)
# print(V(N))

def fU(N, qs):
    U = 0
    tau = np.exp(2j*np.pi/N)
    for j in range(N):
        U += basis(N,j)*basis(N,j).dag()*tau**(qs[j])
    return U

@jit#(nopython=True, parallel=True, fastmath = True)
def fU_numpy(N, qs):
    U = np.zeros((N,N), dtype=np.complex_)
    tau = np.exp(2j*np.pi/N)
    I = np.identity(N)
    for j in range(N):
        U += np.outer(I[:,j],I[j,:])*tau**(qs[j])
    U = np.matrix(U)
    return U #np.matrix(U)

# Calcultes r parameter in the 10% center of the energy "ener" spectrum. If plotadjusted = True, returns the magnitude adjusted to Poisson = 0 or WD = 1
def r_chaometer(ener,plotadjusted):
    ra = np.zeros(len(ener)-2)
    #center = int(0.1*len(ener))
    #delter = int(0.05*len(ener))
    for ti in range(len(ener)-2):
        ra[ti] = (ener[ti+2]-ener[ti+1])/(ener[ti+1]-ener[ti])
        ra[ti] = min(ra[ti],1.0/ra[ti])
    ra = np.mean(ra)
    if plotadjusted == True:
        ra = (ra -0.3863) / (-0.3863+0.5307)
    return ra

def diagU_r(U_sub):
    ener = np.linalg.eigvals(U_sub)
    # ener = np.sort(ener)
    fases = [phase(en) for en in ener]
    fases = np.sort(fases)
    # histo_level_spacing(fases)
    r_normed = r_chaometer(fases, plotadjusted=True)
    return r_normed

# def expand_in_basis(state, base, formato='qutip'):
#     if formato=='qutip':
#         # print(type(state), type(base[0])) # chequeo los types
#         assert type(state) == type(base[0]), 'r u sure this is a Qobj?' # aviso cuando no son Qobj
#         # prueba = (base[0].dag()*state).full()[0][0]
#         # print(prueba, prueba.shape)
#         coefs = np.array([(base[i].dag()*state).full()[0][0] for i in range(len(base))], dtype=np.complex_) # coeficientes del estado a expandir en la base elegida
#         norm = np.linalg.norm(coefs) # norma del estado en esa base
#         print(coefs.shape)
#         res = Qobj(coefs)
#         return res
#     elif formato=='numpy':
#         coefs = np.array([np.sum(np.conj(base[i])*state) for i in range(len(base))], dtype=np.complex_) # coeficientes del estado a expandir en la base elegida
#         print(coefs.shape)
#         # print('norma expansion', norm) # chequeo las normas
#         return coefs#/norm # devuelvo el estado expandido en la base

@jit
def IPR(state, tol = 0.0001):
    if (np.linalg.norm(state)-1) > tol:
        print(np.linalg.norm(state))
    # state = state.full()
    pi = np.abs(state) # calculo probabilidades
    IPR = np.sum(pi**2)/np.sum(pi)**2 # calculo el IPR
    return IPR # devuelvo el IPR

def normalize(array):# normalizo valores entre 0 y 1
    return (array - min(array))/(max(array)-min(array)) # devuelvo la variable normalizada

@jit
def coherent_state_Augusto(N, q0, p0, lim_suma=4, norma=True):#, cuasiq=0
    state = np.zeros((N), dtype=np.complex_) # creo el estado como array de ceros
    cte = np.power(2/N,4) # cte de norm. 1
    coefq = np.exp(np.pi/(2*N)*(q0**2+p0**2)) # cte de norm. 2
    for q in range(N): #calculo el coeficiente para cada q
        coefsnu = np.zeros((2*lim_suma+1), dtype=np.complex_) # creo un array de ceros
        for i,nu in enumerate(np.arange(-lim_suma,lim_suma+1)):
            # print('q',q,', nu',nu)
            coefnu = np.exp(-np.pi/N*(nu*N-(q0-q))**2-1j*2*np.pi/N*p0*(nu*N-q+q0/2))
            coefsnu[i] = coefnu # lo voy llenando con los términos de la sumatoria
        coef = np.sum(coefsnu) # hago la sumatoria
        state[q] = coef # agrego el coeficiente para el q fijo
    if norma:
        nrm = np.linalg.norm(state) # calculo la norma
        # inrm = cte*coefq
        # print('norm state', nrm) # chequeo la norma del estado
        return state/nrm # devuelvo el estado normalizado como numpy darray
    else:
        return state

@jit
def base_coherente_Augusto(N, Nstates):
    base = np.zeros((N,Nstates**2), dtype=np.complex_)
    paso = N/Nstates
    for q in tqdm(range(Nstates), desc='q coherent basis'):
        for p in range(Nstates):
            # indice
            i=q+p*Nstates
            #centros

            q0=q*paso
            p0=p*paso
            # estado coherente
            # print(i, 'de ',Nstates**2)
            b = Qobj(coherent_state_Augusto(N, q0, p0, lim_suma=4))
            # print(np.linalg.norm(b))
            base[:,i] = np.array(b).flatten()
    return base

@jit
def base_integrable(N, K=0):
    U = UU(K, N)
    e, evec = np.linalg.eig(U)
    return evec

@jit
def ovrlp(a,b):
    adag = np.conj(a)
    res = np.inner(adag,b)
    return res

@jit
def projectr(b):
    bdag = np.conj(b)
    res = np.outer(bdag,b)
    return res

@jit
def mtrx_element(M,a,b):
    adag = np.matrix(np.conj(a))
    bp = np.matrix(b).T
    # print(adag.shape, M.shape, bp.shape)
    res = adag@M@bp
    return res[0,0]

def coherent_coef(q, N, q0, p0, lim_suma=4):
    coefsnu = np.zeros((2*lim_suma+1), dtype=np.complex_) # creo un array de ceros
    for i,nu in enumerate(np.arange(-lim_suma,lim_suma+1)):
        # print('q',q,', nu',nu)
        coefnu = np.exp(-np.pi/N*(nu*N-(q0-q))**2-1j*2*np.pi/N*p0*(nu*N-q+q0/2))
        coefsnu[i] = coefnu # lo voy llenando con los términos de la sumatoria
    coef = np.sum(coefsnu) # hago la sumatoria
    return coef

def coherent_Fcoef(p, N, q0, p0, lim_suma=4):
    b = coherent_state_Augusto(N, q0, p0, lim_suma=4, norma=False)
    M = len(b)
    bf = fft(b)*1/np.sqrt(M)
    return bf[p]

def state2kirk(phi,ndim,tip=0,tiq=0):

# !
# ! constructs the kirkwood representation of the pure state vector phi
# !
# ! on entry phi(j)=<j|phi> in the coordinate rep. (unchanged on exit)
# ! on exit rho(k,n) containd the Kirkwood rep. rho(k,n)=<k|rho|n>/<k|n>
# ! normalization is such that sum_{k,n}=1
    n = len(phi)
    # print('n',n)
    # assert n<15000, 'n too big'

    cunit=2*1j*np.pi/n

    # work = np.zeros(n, dtype=np.complex_)

    work = phi*np.exp(-cunit*tip*np.arange(n))

    M = len(work)
    workf = fft(work)*1/np.sqrt(M)
    # workf = workf#*2.0/M#[:M//2]

    # print('work',len(workf))
    # print('phi',len(phi))
    rho = np.zeros((ndim, ndim), dtype=np.complex_)
    for k in range(n):
       for i in range(n):
           # print('k,i',k,i)
           rho[k,i]=workf[k]*np.conj(phi[i])*np.exp(cunit*i*(k+tip))
           # acá me queda la duda si tengo que usar workf (fft) o work
    # !rho[k,i]=<k|phi><phi|i>/<k|i>
    # print('termina hus')
    return rho

# @jit
def kirk2hus(n,rho):
# ! assumes workfft has been initialized by prop_init
# ! computes the Husimi distribution from the Kirkwood array
# ! on input rho is the kirkwood matrix matrix  <k|rho|n>/<k/n> (unchanged)
# ! on output hus is the real array <p,q|rho|p,q> discretized
# ! on a phase space grid (n*nr) x (n*nr)
# ! nr (even) is chosen by the program to provide nice smooth plots
# ! and passed on to the plotting program
# ! for N>50 nr=2 is appropriate
# ! when rho is a pure state this is the Husimi distribution

    hus = np.zeros((n,n), dtype=np.complex_)
    aim = 1j*2*np.pi/n    #!2*i*pi/n

# !      if(n>ndim+1)stop 'dimension of map too large in kirk2hus'
    nr=2
    if(n<4): nr=20
    elif(n<6): nr=16
    elif(n<10): nr=10
    elif(n<20): nr=8
    elif(n<40): nr=6
    elif(n<80): nr=4
    # elif(n*nr>nhus):
        # print('nhus=',nhus)
        # print('n*nr=',n*nr)
    # assert n*nr<nhus, f'dimension of hus too large in kirk2hus n*nr={n*nr} >= nhus={nhus}'

    nnr2=n*nr/2
    for ik in range(n):
        for ip in range(n):
            hus[ik,ip] = rho[ik,ip]

    M = len(hus)
    husf = ifft2(hus)*M
    # husf = husf#*2/M

# !  hus now contains the N*N generating function
    hus = np.zeros((n*nr, n*nr), dtype=np.complex_)
    for iq in range(n*nr):
        for ip in range(n*nr):
            hus[iq,ip]=husf[iq%n,ip%n]
    # print('\n\npaso el primer loop de n*nr')
    for iq in range(n*nr):
        for ip in range(n*nr):
            exp1 = np.exp(-0.5*np.pi/n*((nnr2-iq)**2+(nnr2-ip)**2))
            exp2 = np.exp(0.5*aim*(((ip-nnr2)*(iq-nnr2))%(2*n)))
            hus[iq,ip]=hus[iq,ip]*exp1*exp2

# !  hus now contains the p,q fourier components of the husimi function
    M = len(hus)
    husfif = fft2(hus)*1/M
    # husfif = husfif#*2/M
    for ip in range(n*nr):
        for iq in range(n*nr):
            husfif[ip,iq]=husfif[ip,iq]*(-1)**(ip+iq)/(n*n*nr)    #!normalization
    # print('algo')
# !  hus is the husimi on a grid refined by nr
# ! notice that first index is momentum and second is coordinate!
    return husfif

def kirk2hus_Tomi(n, rho):
    nr=2
    if(n<4): nr=20
    elif(n<6): nr=16
    elif(n<10): nr=10
    elif(n<20): nr=8
    elif(n<40): nr=6
    elif(n<80): nr=4

    hus = np.zeros((n*nr, n*nr), dtype=np.complex_)
    for iq in range(n*nr):
        for ip in range(n*nr):
            b = coherent_state_Augusto(N, q0, p0, lim_suma=4, norma=False)
            M = len(b)
            bf = fft(b)*1/np.sqrt(M)

            hus[iq,ip]=mtrx_element(rho,bf,b)

    return hus

def plot_Husimi(state):
    n = len(state)
    print(n)
    # nhus = int(5*n)
    # print('llego')
    rho = state2kirk(state, n)
    hus = kirk2hus(n, rho)
    # hus /= np.sum(np.abs(hus))
    hus = np.abs(hus)#**2
    print('shape', hus.shape)
    ax = sns.heatmap(hus)
    return

def flattenear(vec):
    return np.array(vec).flatten()

# @jit
def IPR_Husimi(state, tol = 0.0001):
    # print('entra')
    n = len(state)
    # nhus = int(5*n)
    # print('llego')
    rho = state2kirk(state, n)
    hus = kirk2hus(n, rho)
    hus /= np.sum(np.abs(hus))
    aux = IPR(np.abs(hus), tol)
    return aux

#%% cargo husimi de Fortran (Nacho) y la ploteo
# husimi_fortran = np.loadtxt('/home/tomasnotenson/Escritorio/Caos_y_control_cuantico/Repo github/Nacho/husimi.dat')

# plt.figure(figsize=(10,10))
# sns.heatmap(husimi_fortran)
# plt.savefig('heatmap_Husimi_autoestado_Nacho_hecho_en_Fortran.png', dpi=80)
#%%

nqubits = 6;
N = 200#2**nqubits#11
# hbar = 1/(2*np.pi*N)
nr=2
if(N<4): nr=20
elif(N<6): nr=16
elif(N<10): nr=10
elif(N<20): nr=8
elif(N<40): nr=6
elif(N<80): nr=4

Nstates= np.int32(nr*N)#N/2)  #% numero de estados coherentes de la base

# # armo la base coherente
# start_time = time()
# base = base_coherente_Augusto(N,Nstates)
# # base = base_integrable(N)
# print('Duration: ', time()-start_time)

# # seed
# np.random.seed(0)

# # defino 2 estados complejos random
# a=np.random.random(N)+np.random.random(N)*1j
# norm=np.linalg.norm(a)
# an = a/norm
# # a = Qobj(a/norm)

# # defino la identidad
# Idenn = np.zeros([N,N], dtype=np.complex_)
# # Iden = Qobj(Idenn)

# # est_a = np.zeros(Nstates**2, dtype=np.complex_)
# est_an = np.zeros(Nstates**2, dtype=np.complex_)

# for q in tqdm(range(Nstates), desc='q loop'):
#     for p in range(Nstates):
#         # indice
#         i=q+p*Nstates
#         #centros

#         q0=q*paso
#         p0=p*paso
#         # estado coherente
#         # print(i, 'de ',Nstates**2)
#         bn = base[:,i]
#         # b = Qobj(bn)

#         # expando los estados a y b en la base de estados coherentes
#         # overlap entre el estado a y el coherente centrado en q0 y p0
#         # est_a[i] = a.overlap(b)
#         est_an[i] = ovrlp(an,bn)

#         # sumo el proyector asociado a ese estado coherente
#         # ident1 = b.proj()
#         ident1n = projectr(bn)
#         Idenn = Idenn+ident1n
#         # Iden = Iden+ident1

# # calculo las normas y el overlap tomando los elementos de matriz de la...
# # ... identidad calculada a partir de los proyectores de la base coherente
# # nor1=Iden.matrix_element(a,a)
# nor1n=mtrx_element(Idenn,an,an)
# %%

# K = 0.2533*4*(np.pi**2)
# U = UU(K, N)
# e,evec = np.linalg.eig(U)

# index = 43

# state = flattenear(evec[:,index])

# # plt.figure(figsize=(10,10))
# # plot_Husimi_Tomi(state)
# # plt.savefig('heatmap_Husimi_autoestado_Tomi.png', dpi=80)

# plt.figure(figsize=(10,10))
# plot_Husimi(state)
# plt.savefig('heatmap_Husimi_autoestado_Nacho_hecho_en_python.png', dpi=80)

#%%
Kpaso = 0.05
Ks = np.arange(0,10.1,Kpaso)#

# norma = np.sqrt(nor1n)
IPR_means = np.zeros((len(Ks)))
rs = np.zeros((len(Ks)))

for k,K in tqdm(enumerate(Ks), desc='K loop'):
    IPRs = np.zeros((N))
    U = UU(K, N)
    ev, evec = np.linalg.eig(U)
    # r = diagU_r(U)
    # rs[k] = r

    for j in tqdm(range(evec.shape[1]), desc='vec loop'):
        vec = flattenear(evec[:,j])
        # est_vec = np.zeros(Nstates**2, dtype=np.complex_)
        # for q in range(Nstates):
        #     for p in range(Nstates):
        #         # indice
        #         i=q+p*Nstates
        #         #centros

        #         q0=q*paso
        #         p0=p*paso
        #         # estado coherente
        #         # print(i, 'de ',Nstates**2)
        #         # b = Qobj(base[:,i])
        #         b = base[:,i]

        #         # expando los estados a y b en la base de estados coherentes
        #         # overlap entre el estado a y el coherente centrado en q0 y p0
        #         # est_vec[i] = vec.overlap(b) #Iden.matrix_element(b,vec)#
        #         est_vec[i] = ovrlp(b,vec)#mtrx_element(Idenn,b,vec)#

        # aux = IPR_Husimi(est_vec/norma)
        # print('\nvec',vec.shape)
        # print('\n\n\n\n\n')
        aux = IPR_Husimi(vec)
        IPRs[j] = aux

    IPR_means[k] = np.mean(IPRs)

np.savez(f'IPR_Husimi_vs_Ks_Kmin{min(Ks)}_Kmax{max(Ks)}_Kpaso{Kpaso}_N{N}_coherent_basis_grid{Nstates}x{Nstates}_numpy.npz', IPR_means = 1/IPR_means, rs = rs)#integrable_K0
#%%
y_IPR = normalize(1/IPR_means)

plt.figure(figsize=(16,8))
plt.title(f'IPR rutinas Nacho')
plt.plot(Ks, y_IPR, '-b', lw=1.5)
# plt.plot(Kx, r_normed, '-r', lw=1.5, label='r')
# plt.plot(Ks, 1-r_one, '-g', lw=1.5, label='1-r paridad +1')
plt.xlabel(r'$K$')
plt.ylabel('IPR')
# plt.ylim(0,1)
# plt.xlim(-0.2,max(times)+0.2)
plt.grid(True)
# plt.legend(loc = 'best')


# coding: utf-8

import types
import numpy as np
from numpy.linalg import solve
from scipy.misc import comb
from .system import AbstractSystem

class StateSpace(AbstractSystem):
    '''state space

    F: transition matrix
    G: noise transition matrix
    H: observation matrix
    Q: transition covariance
    R: observation covariance
    '''

    def __init__(self, F, G, H, Q=np.ones, R=np.ones, offset=np.zeros,
                 initial_state=np.zeros, initial_covariance=np.ones):

        params = self.sample_params(
            F, G, H, Q, R, offset,
            initial_state, initial_covariance)

        self.set_params(params)

    def set_params(self, params):
        self.F = params['F']
        self.G = params['G']
        self.H = params['H']
        self.Q = params['Q']
        self.R = params['R']
        self.state = params['state']
        self.covariance = params['covariance']
        self.offset = params['offset']
        self.n_dim_state = params['n_dim_state']
        self.n_dim_observe = params['n_dim_observe']

    def sample_params(self, F, G, H, Q=np.ones, R=np.ones,
                      offset=np.zeros,
                      initial_state=np.zeros,
                      initial_covariance=np.ones):
        n_dim_state = F.shape[0]
        n_dim_observe = H.shape[0]

        def isfunction(x):
            return (isinstance(x, types.FunctionType) or
                    isinstance(x, types.BuiltinFunctionType))

        if isfunction(Q):
            Q = np.diag(Q(G.shape[1]))

        if isfunction(R):
            R = np.diag(R(n_dim_observe))

        if isfunction(offset):
            offset = offset(n_dim_observe)[:, None]

        if isfunction(initial_state):
            initial_state = initial_state(n_dim_state)[:, None]

        if isfunction(initial_covariance):
            initial_covariance = np.diag(initial_covariance(n_dim_state))

        return {'F': F, 'G': G, 'H': H, 'Q': Q, 'R': R,
                'offset': offset,
                'state': initial_state,
                'covariance': initial_covariance,
                'n_dim_state': n_dim_state,
                'n_dim_observe': n_dim_observe}

    def compose(self, ss):
        F = compose_matrix(self.F, ss.F)
        G = compose_matrix(self.G, ss.G)
        H = np.concatenate([self.H, ss.H], axis=1)
        Q = compose_matrix(self.Q, ss.Q)
        R = (self.R + ss.R) / 2
        offset = np.max(np.concatenate([self.offset, ss.offset], axis=1),
                        axis=1)[:, None]
        state = np.concatenate([self.state, ss.state])
        return StateSpace(F, G, H, Q, R, offset, state)

    def __add__(self, other):
        return self.compose(other)

    def get_params(self):
        return {'F': self.F, 'G': self.G, 'H': self.H,
                'Q': self.Q, 'R': self.R,
                'offset': self.offset,
                'state': self.state,
                'covariance': self.covariance,
                'n_dim_state': self.n_dim_state,
                'n_dim_observe': self.n_dim_observe}

    def save(self, filename):
        params = self.get_params()
        np.save(filename, params)

    def load(self, filename):
        params = np.load(filename)[()]
        self.set_params(params)

    def copy(self):
        F = self.F.copy()
        G = self.G.copy()
        H = self.H.copy()
        Q = self.Q.copy()
        R = self.R.copy()
        offset = self.offset.copy()
        state = self.state.copy()
        return StateSpace(F, G, H, Q, R, offset, state)

    def predict(self, pure=False):
        x = self.state
        V = self.covariance

        next_x = self.F @ x
        next_V = self.F @ V @ self.F.T + self.G @ self.Q @ self.G.T

        if pure:
            next_ss = self.copy()
            next_ss.state = next_x
            next_ss.covariance = next_V
            return next_ss
        else:
            self.state = next_x
            self.covariance = next_V
            return None

    def update(self, d, pure=False):
        x = self.state
        y = d - self.offset
        V = self.covariance
        I = np.identity(V.shape[0])

        # K = V @ self.H.T @ inv(self.H @ V @ self.H.T + self.R)
        K = V @ solve((self.H @ V @ self.H.T + self.R).T, (self.H.T).T).T
        next_x = x + K @ (y - self.H @ x)
        next_V = (I - K @ self.H) @ V

        if pure:
            next_ss = self.copy()
            next_ss.state = next_x
            next_ss.covariance = next_V
            return next_ss
        else:
            self.state = next_x
            self.covariance = next_V
            return None

    def observe(self, covariance=True):
        mean = self.H @ self.state + self.offset
        if not covariance:
            return mean
        else:
            V = self.covariance
            cov = self.H @ V @ self.H.T + self.R
            return mean, cov

class Trend(StateSpace):
    def __init__(self, k, dim=1):
        c = np.array([(-1) ** ((i + 1) % 2) * comb(k, i)
                      for i in range(1, k + 1)])[None, :]
        F = np.concatenate([c, time_shift(k)])
        G = np.zeros([k, 1])
        G[0, 0] = 1
        H = np.zeros([1, k])
        H[0, 0] = 1
        super().__init__(F, G, H)

class Period(StateSpace):
    def __init__(self, period):
        p = period - 1
        c = np.array([-1 for i in range(0, p)])[None, :]
        F = np.concatenate([c, time_shift(p)])
        G = np.zeros([p, 1])
        G[0, 0] = 1
        H = np.zeros([1, p])
        H[0, 0] = 1
        super().__init__(F, G, H)

def compose_matrix(A, B):
    rA, cA = A.shape
    rB, cB = B.shape
    Z1 = np.zeros([rA, cB])
    Z2 = np.zeros([rB, cA])
    return np.concatenate([np.concatenate([A, Z1], axis=1),
                           np.concatenate([Z2, B], axis=1)])

def time_shift(dim, shift=1):
    return np.concatenate([np.identity(dim - shift),
                           np.zeros([dim - shift, shift])],
                          axis=1)

def expand_matrix_dim(M, dim=1):
    r, c = M.shape
    expanded = np.zeros([dim * r, dim * c])
    for d in range(dim):
        expanded[d::dim, d::dim] = M
    return expanded

def expand_vector_dim(M, dim=1):
    r, c = M.shape
    expanded = np.zeros([dim * r, c])
    for d in range(dim):
        expanded[d::dim, :] = M
    return expanded

def expand_ss_dim(ss, dim=1):
    F = expand_matrix_dim(ss.F, dim)
    G = expand_matrix_dim(ss.G, dim)
    H = expand_matrix_dim(ss.H, dim)
    Q = expand_matrix_dim(ss.Q, dim)
    R = expand_matrix_dim(ss.R, dim)
    state = expand_vector_dim(ss.state, dim)
    offset = expand_vector_dim(ss.offset, dim)
    return StateSpace(F, G, H, Q, R, offset, state)


from discord.ext import commands
import discord
from utils import get_config, guild_exists
import time

class Client(commands.Bot):
    def __init__(self, prefix):
        super().__init__(command_prefix=prefix)
        self.help_command = None

    async def on_ready(self):
        print(f'{self.user} is connected and ready active on time: {int(time.time())}')
        await self.change_presence(activity=discord.Game(name="ping me for help!"))

    async def on_guild_join(self, guild):
        guild_id = str(guild.id)
        guild_exists(guild_id)

    async def on_message(self, message):
        """ensures bot does not respond to itself"""
        if message.author.id == self.user.id:
            return
        ctx = await self.get_context(message)
        if message.content == f"<@!{self.user.id}>" or message.content == f"<@{self.user.id}":
            return await ctx.invoke(self.get_command('help'))

        elif message.content == f"shutdown <@!{self.user.id}>" and message.author.id in get_config()['has_access']:
            await ctx.send("Shutting down.")
            print("Manual shut down intiated.")
            quit()

        # elif message.author.id == ctx.guild.owner.id and message.content == "happy bday to me":
        #     return await ctx.send("happy brday")
        # :D dated 8/9/2020, for 8/10/2020. cheers to me!

        # if ping bot, run help command
        await self.process_commands(message)


"""
1. 修改指定index数据
2. revers()
3. sort() reverse= Ture 降序 false 升序（默认）
"""
name_list = ['TOM', 'Lily', 'ROSE']
# 1
name_list[1] = 'LILY'
print(name_list)
# 2
list1 = [1, 3, 2, 5, 4, 9, 7]
list1.reverse()
print(list1)
# 3 sort()
list1.sort(key=None, reverse=True)  # key用于dictionary
print(list1)


# Создайте программу для игры с конфетами человек против человека.
# Условие задачи: На столе лежит 2021 конфета. Играют два игрока делая ход друг после друга.
# Первый ход определяется жеребьёвкой. За один ход можно забрать не более чем 28 конфет.
# Все конфеты оппонента достаются сделавшему последний ход.
# Сколько конфет нужно взять первому игроку, чтобы забрать все конфеты у своего конкурента?
# Добавьте игру против бота
# Подумайте, как наделить бота "интеллектом"
from random import choice

mode = int(input("Play with bot 1 - yes, 0 - no: "))

player_1 = input("Enter first player name: ")
player_2 = "Bot" if mode == 1 else input("Enter second player name: ")

p_move = player_1 if mode == 1 else choice([player_1, player_2])
candies = 174

while True:
    print(f"Remaining candies: {candies}")
    num = int(input(f"{p_move} move: "))
    if num < 1 or num > 28:
        print("You should take candies in range from 1 to 28!")
        continue
    candies -= num
    p_move = player_1 if p_move == player_2 else player_2
    if candies < 28:
        print(f"{p_move} - winner!")
        break

    if mode == 0:
        continue

    print(f"Remaining candies: {candies}")
    print(f"{p_move} move: {29 - num}")
    candies -= 29 - num
    p_move = player_1 if p_move == player_2 else player_2
    if candies < 28:
        print(f"{p_move} - winner!")
        break

# Рассчитать выигрышную стратегию (а значит наделить бота интеллектом) можно только:
# 1. если бот ходит всегда вторым (то есть если нет жеребьевки)
# 2. если количество всех конфет кратно максимальному числу конфет,
#    которые можно взять из кучи, плюс один (то есть 28 + 1 = 29, число 2021 не делится нацело на 29)
# При игре с ботом я включил эти условия.


# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def reverseBetween(self, head, m, n):
        """
        :type head: ListNode
        :type m: int
        :type n: int
        :rtype: ListNode
        """
        dum = ListNode()
        dum.next = head
        pre = dum

        for i in range(m - 1):
            pre = pre.next

        cur = pre.next

        for i in range(n - m):
            next = cur.next
            cur.next = next.next
            next.next = pre.next
            pre.next = next

        return dum.next


def AplusB(a,b):

    return a+b
result=AplusB(1,2)
print(result)
print(AplusB(10,12))

def circle(r):
    return r**2*3.14
print(circle(4))

a=2
def main():
    print(a)
main()
print(a)

circle3=lambda r,pi:r**2*pi
print(circle3(3,3.14))

def change(a):
    a=10

b=2
change(b)#2->a,a=2->a=10
print(b)

c=[1,2,3]
def change2(x):
    x.append([1,2,3])
change2(c)
print(c)

b='123'
b=123


import socket

def server_program():
    host = socket.gethostname()
    port = 5000
    serv = socket.socket()
    serv.bind((host, port))
    serv.listen(100)
    conn, address = serv.accept()
    print(f"Connection from: {address}")
    storage_name = input("Please write storage name: ")
    conn.send(storage_name.encode())
    res = conn.recv(1024).decode()
    # print('Received from client: ' + res)
    print(res)
    command = input(">>> ")
    # while command.lower().strip() != 'exit':
    while True:
        conn.send(command.encode())
        result = conn.recv(1024).decode()
        if not result:
            break
        # print('Received from client: ' + result)
        print(result)
        command = input(">>> ")
    conn.close()

if __name__ == '__main__':
    server_program()


# AUTHOR    = Avi Mehenwal
# DATE      = 11th-August-2014
# PURPOSE   = How to detect if a windows machine is running IPV6

import socket

def isIPV6():
    ipv6 = True
    try:
        s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
    except:
        ipv6 = False
    return ipv6

if __name__ == "__main__":
    c = isIPV6()
    print(c)


import json as _json
import datetime
import dateutil.parser
import decimal
import sys

__all__ = ['json', 'instead_json']

CONVERTERS = {
    'datetime': {
        'type': datetime.datetime,
        'parser': dateutil.parser.parse,
        'format': lambda x: x.isoformat(),
    },
    'date': {
        'type': datetime.date,
        'parser': dateutil.parser.parse,
        'format': lambda x: x.isoformat(),
    },
    'decimal': {
        'type': decimal.Decimal,
        'parser': decimal.Decimal,
        'format': str,
    },
}

class MyJSONEncoder(_json.JSONEncoder):
    def default(self, obj):
        for tn in CONVERTERS:
            config = CONVERTERS[tn]
            if isinstance(obj, config['type']):
                return {"val": config['format'](obj), "_spec_type": tn}
        return super(MyJSONEncoder, self).default(obj)

def object_hook(obj):
    _spec_type = obj.get('_spec_type')
    if not _spec_type:
        return obj

    if _spec_type in CONVERTERS:
        return CONVERTERS[_spec_type]['parser'](obj['val'])
    else:
        raise Exception('Unknown {}'.format(_spec_type))

class json(object):
    @staticmethod
    def dumps(data, **kwargs):
        kwargs['cls'] = kwargs.get('cls') or MyJSONEncoder
        return _json.dumps(data, **kwargs)

    @staticmethod
    def loads(thing, **kwargs):
        kwargs['object_hook'] = kwargs.get('object_hook') or object_hook
        return _json.loads(thing, **kwargs)

    @classmethod
    def __getattribute__(cls, item):
        if item in {'dumps', 'loads'}:
            return super(json, cls).__getattribute__(item)
        else:
            return getattr(_json, item)

def instead_json():
    sys.modules['json'] = json


import os

ROOT_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..')

def apath(*relative_dirs):
    """ Takes a relative path (the the repository's root) and return
    its absolute path.

    :returns: absolute filesystem path
    """
    return os.path.join(ROOT_DIR, *relative_dirs)

APP_DIR = apath('psi')
MIGRATION_DIR = apath('psi', 'migrations')


#!/usr/bin/python3
"""Stabilizer streaming receiver and parsers"""

import argparse
import asyncio
import logging
import struct
from collections import namedtuple
from dataclasses import dataclass

import numpy as np

from . import DAC_VOLTS_PER_LSB

logger = logging.getLogger(__name__)

Trace = namedtuple("Trace", "values scale label")

def wrap(wide):
    """Wrap to 32 bit integer"""
    return wide & 0xffffffff

class AdcDac:
    """Stabilizer default striming data format"""
    format_id = 1

    def __init__(self, header, body):
        self.header = header
        self.body = body

    def batch_count(self):
        """Return the number of batches in the frame"""
        return self.size() // (4 * 2 * self.header.batch_size)

    def size(self):
        """Return the data size of the frame in bytes"""
        return len(self.body)

    def to_mu(self):
        """Return the raw data in machine units"""
        data = np.frombuffer(self.body, "<i2")
        data = data.reshape(-1, 4, self.header.batch_size)
        data = data.swapaxes(0, 1).reshape(4, -1)
        # convert DAC offset binary to two's complement
        data[2:] ^= np.int16(0x8000)
        return data

    def to_si(self):
        """Convert the raw data to SI units"""
        data = self.to_mu() * DAC_VOLTS_PER_LSB
        return {
            "adc": data[:2],
            "dac": data[2:],
        }

    def to_traces(self):
        """Convert the raw data to labelled Trace instances"""
        data = self.to_mu()
        return [
            Trace(data[0], scale=DAC_VOLTS_PER_LSB, label='ADC0'),
            Trace(data[1], scale=DAC_VOLTS_PER_LSB, label='ADC1'),
            Trace(data[2], scale=DAC_VOLTS_PER_LSB, label='DAC0'),
            Trace(data[3], scale=DAC_VOLTS_PER_LSB, label='DAC1')
        ]

class StabilizerStream(asyncio.DatagramProtocol):
    """Stabilizer streaming receiver protocol"""
    # The magic header half-word at the start of each packet.
    magic = 0x057B
    header_fmt = struct.Struct("<HBBI")
    header = namedtuple("Header", "magic format_id batch_size sequence")
    parsers = {
        AdcDac.format_id: AdcDac,
    }

    @classmethod
    async def open(cls, local_addr, maxsize=1):
        """Open a UDP socket and start receiving frames"""
        loop = asyncio.get_running_loop()
        transport, protocol = await loop.create_datagram_endpoint(
            lambda: cls(maxsize), local_addr=local_addr)
        return transport, protocol

    def __init__(self, maxsize):
        self.queue = asyncio.Queue(maxsize)

    def connection_made(self, _transport):
        logger.info("Connection made (listening)")

    def connection_lost(self, _exc):
        logger.info("Connection lost")

    def datagram_received(self, data, _addr):
        header = self.header._make(self.header_fmt.unpack_from(data))
        if header.magic != self.magic:
            logger.warning("Bad frame magic: %#04x, ignoring", header.magic)
            return
        try:
            parser = self.parsers[header.format_id]
        except KeyError:
            logger.warning("No parser for format %s, ignoring", header.format_id)
            return
        frame = parser(header, data[self.header_fmt.size:])
        if self.queue.full():
            old = self.queue.get_nowait()
            logger.debug("Dropping frame: %#08x", old.header.sequence)
        self.queue.put_nowait(frame)

async def measure(stream, duration):
    """Measure throughput and loss of stream reception"""
    @dataclass
    class _Statistics:
        expect = None
        received = 0
        lost = 0
        bytes = 0
    stat = _Statistics()

    async def _record():
        while True:
            frame = await stream.queue.get()
            if stat.expect is not None:
                stat.lost += wrap(frame.header.sequence - stat.expect)
            batch_count = frame.batch_count()
            stat.received += batch_count
            stat.expect = wrap(frame.header.sequence + batch_count)
            stat.bytes += frame.size()
            # test conversion
            # frame.to_si()

    try:
        await asyncio.wait_for(_record(), timeout=duration)
    except asyncio.TimeoutError:
        pass

    logger.info("Received %g MB, %g MB/s", stat.bytes/1e6,
            stat.bytes/1e6/duration)

    sent = stat.received + stat.lost
    if sent:
        loss = stat.lost/sent
    else:
        loss = 1
    logger.info("Loss: %s/%s batches (%g %%)", stat.lost, sent, loss*1e2)
    return loss

async def main():
    """Test CLI"""
    parser = argparse.ArgumentParser(description="Stabilizer streaming demo")
    parser.add_argument("--port", type=int, default=9293,
                        help="Local port to listen on")
    parser.add_argument("--host", default="0.0.0.0",
                        help="Local address to listen on")
    parser.add_argument("--maxsize", type=int, default=1,
                        help="Frame queue size")
    parser.add_argument("--duration", type=float, default=1.,
                        help="Test duration")
    args = parser.parse_args()

    logging.basicConfig(level=logging.INFO)
    _transport, stream = await StabilizerStream.open(
        (args.host, args.port), args.maxsize)
    await measure(stream, args.duration)

if __name__ == "__main__":
    asyncio.run(main())


# RMIT University Vietnam
# Course: COSC2429 Introduction to Programming
# Semester: 2022C
# Assignment: Individual - Timed Programming Lab Test 1 (25%)
# Author: Phan Nhat Minh (s3978598)
# Created date: 19/11/2022
# Last modified date: 19/11/2022
# IDE: Pycharm 2022.2.3 (Professional Edition)
# Python version: 3.11
# Question: 2

# function to find the factorial of a positive integer number
def factorial(n):
    """
    This function calculate the factorial of an integer number
    :param n: an integer input from user
    :return: the factorial of the integer n
    """
    fact = 1
    for i in range(1, n+1):
        fact = fact * i
    return fact

# main program
a = int(input("Enter an integer number: "))
# check the property of the input number
if a < 0:   # if a < 0 there is not factorial
    print("Factorial does not exist for negative number")
elif a == 0:    # if a = 0 then factorial = 1
    print(" The factorial of 0 is 1")
else:   # if a > 0 then call the function to calculate the factorial of a
    print("The factorial of ", str(a), " is ", str(factorial(a)))