# -*- coding: utf-8 -*-
"""
Created on Tue Nov 10 15:05:08 2020

@author: muska
"""

import pandas as pd
import sys

def topsis():
    def rankify(A):

        # Rank Vector
        R = [0 for x in range(len(A))]

        # Sweep through all elements
        # in A for each element count
        # the number of less than and
        # equal elements separately
        # in r and s.
        for i in range(len(A)):
            (r, s) = (1, 1)
            for j in range(len(A)):
                if j != i and A[j] > A[i]:
                    r += 1
                if j != i and A[j] == A[i]:
                    s += 1

            # Use formula to obtain rank
            R[i] = r + (s - 1) / 2

        # Return Rank Vector
        return R

    if len(sys.argv)==1 or len(sys.argv)>5:
        print("Error! Wrong number of arguments")
        print("4 parameters are required...")
        exit(0)

    arg = sys.argv[1]
    list1 = arg.split('.')
    extension = list1[1]
    if(extension != 'csv'):
        print("Invalid file extension!")
        exit(0)

    arg = sys.argv[4]
    list1 = arg.split('.')
    extension = list1[1]
    if(extension != 'csv'):
        print("Invalid file extension!")
        exit(0)

    try:
        df = pd.read_csv(sys.argv[1])
        col = df.columns
        if (len(col)<3):
            raise ValueError

        for i in range(1,df.shape[1]):
            if df.iloc[:,i].dtype=="float64":
                continue
            else:
                print("Columns should be of numeric type only")
                exit(0)

        weights = sys.argv[2].split(',')
        weights = [int(i) for i in weights]
        if (len(weights) != (len(col)-1)):
            raise ValueError

        impacts = sys.argv[3].split(',')
        for i in impacts:
            if i!='+' and i!='-':
                print("Impacts must be either + or -")
                exit(0)
        if (len(impacts) != (len(col)-1)):
            raise ValueError

        df_new = df.drop("Model", 1)
        df1 = df_new

        for j in range(df1.shape[1]):
            n = sum(df1.iloc[:,j]**2)**0.5
            for i in range(df1.shape[0]):
                df_new.iloc[i,j] = df_new.iloc[i,j]*weights[j]/n

        ideal_best = []
        ideal_worst = []
        for i in range(df1.shape[1]):
            if impacts[i]=='+':
                ideal_worst.append(min(df_new.iloc[:,i]))
                ideal_best.append(max(df_new.iloc[:,i]))
            else:
                ideal_worst.append(max(df_new.iloc[:,i]))
                ideal_best.append(min(df_new.iloc[:,i]))

        dib=(df_new-ideal_best)**2
        diw=(df_new-ideal_worst)**2
        s_plus = []
        s_minus = []
        for j in range(df1.shape[0]):
        	s_plus.append(sum(dib.iloc[j,:])**0.5)
        	s_minus.append(sum(diw.iloc[j,:])**0.5)

        s_total = []
        for i in range(len(s_plus)):
            s_total.append(s_plus[i]+s_minus[i])

        p = []
        for i in range(len(s_minus)):
            p.append(s_minus[i]/s_total[i])

        df["Topsis Score"] = p

        r = rankify(p)
        df["Rank"] = r

        df.to_csv(sys.argv[4])

    except ValueError:
        print("Atleast 3 columns should be there in the input file!!")
        print("Number of weights, number of impacts and number of columns must be same")
    except:
        print("Error!! No such file exists")

if __name__ == "__main__":
    topsis()


from discord.ext import commands
from notbot.context import Context, Module
from typing import Optional
from notbot.cogs.util.formatter import success_message, format_user_name

from notbot.services import get_settings_service

MODULE_NAME = "settings_module"

class SettingsModule(commands.Cog, Module):
    def __init__(self, context: Context):
        self.bot = context.get_bot()
        self.settings_service = get_settings_service(context)

    def get_name(self):
        return MODULE_NAME

    @commands.command(
        name="pprefix",
        description="""
    Sets or removes the personal prefix to interact with the bot.
    If the command is called without arguments, it will display your current personal prefix instead.
    """,
        usage="[personal_prefix|unset]",
    )
    async def pprefix(self, ctx, pprefix: Optional[str] = None):
        if pprefix == "unset":
            await self.settings_service.del_pprefix(ctx.author.id)
            await ctx.send(success_message("PPrefix removed"))
            return

        pprfx = await self.settings_service.get_pprefix(ctx.author.id)
        if pprefix is None and pprfx is None:
            raise commands.BadArgument("You do not have a personal prefix.")
        if pprefix is None and pprfx is not None:
            await ctx.send(
                f":information_source: Your personal prefix is **{'nothing' if pprfx == '' else pprfx}**"
            )
            return
        if pprefix is None:
            raise commands.BadArgument("You should specify a prefix.")
        if len(pprefix) > 5:
            raise commands.BadArgument("Personal prefix must be **1-5** characters.")
        await self.settings_service.set_pprefix(ctx.author.id, pprefix)
        if pprefix == "":
            pprefix = "nothing"
        await ctx.send(
            f"Set **{format_user_name(ctx.author)}**'s personal prefix to **{pprefix}**"
        )

def setup(bot):
    context: Context = bot.context

    module = context.get_module(MODULE_NAME)
    bot.add_cog(module)


class Node:

    def __init__(self, value):
        self.value = value
        self.next = None

class List:

    def __init__(self, node=None):
        self.head = node

    def clear(self):
        self.head = None

    def addToEnd(self, node):
        if self.head is None:
            self.head = node
        else:
            current = self.head
            while (current.next is not None):
                current = current.next
            current.next = node

    def addToBegin(self, node):
        if self.head is None:
            self.head = node
        else:
            node.next = self.head
            self.head = node

    def remove(self, position: int):
        current = self.head
        for i in range(position):
            current = current.next
        current.next = current.next.next

    def __str__(self):
        if self.head != None:
            current = self.head
            out =  str(current.value)+' '
            while current.next != None:
                current = current.next
                out += str(current.value) + " "
            return out
        return 'Список пуст'

Питон 1 лаба/List.py


name = input("You full name : \n \t \t =====> ").lower()
upper_name = name.title()
list_name = list(upper_name)
# Xóa khoảng trắng thừa
for i in range(len(list_name)):
    for j in range(len(list_name)):
        if list_name[j] == ' ' and list_name[j+1] == ' ':
            del list_name[j+1]
            break
print("\t \t Updated : ", end="")
print(''.join(list_name))
# có thể dùng split() để xóa khoảng trắng thừa , thay cho vòng lặp ở trên
# upper_char = name.title()
# print(*upper_char.split())


class Node:
    def __init__(self, value, left, right):
        self.value = value
        self.left = left
        self.right = right

def inorder(btree, path):
    if btree.left is not None:
        inorder(btree.left, path)
    path.append(btree.value)
    if btree.left is not None and btree.right is not None:
        print(btree.value)
    if btree.right is not None:
        inorder(btree.right, path)

elems = list(map(int, input().split()))[:-1]

binary_tree = Node(None, None, None)

for elem in elems:
    node = binary_tree
    inserted = False
    while not inserted:
        if node.value is None:
            node.value = elem
            inserted = True
        elif node.value == elem:
            inserted = True
        elif elem < node.value:
            if node.left is None:
                node.left = Node(elem, None, None)
                inserted = True
            else:
                node = node.left
        elif node.value < elem:
            if node.right is None:
                node.right = Node(elem, None, None)
                inserted = True
            else:
                node = node.right

path = []
inorder(binary_tree, path)


# blender script to create big fucking booster
# apply to booster3.blend

import bpy, bmesh
import importlib
import bfs
importlib.reload(bfs)

bfs.deselect()
bfs.deleteObjectNamed("booster top")
bfs.deleteObjectNamed("booster bottom")
bfs.deleteObjectNamed("x1")
bfs.deleteObjectNamed("x2")
bfs.deleteObjectNamed("space1")
bfs.deleteObjectNamed("space2")
bfs.deleteObjectNamed("flag1")
bfs.deleteObjectNamed("flag2")
bfs.deleteObjectNamed("logo1")
bfs.deleteObjectNamed("logo2")

booster = bfs.selectByName("booster5")
booster.hide = True

bpy.ops.object.duplicate()
bpy.context.scene.objects.active = bfs.getSelected()[0]
bpy.context.scene.objects.active.hide = False
bpy.context.scene.objects.active.name = 'booster'
booster = bpy.context.scene.objects.active

xPlug = bfs.findObject('x plug')
x1 = bfs.cookieCut(booster, xPlug, "x1", "BMESH")

bfs.selectActivate(xPlug)
xPlug.location.x *= -1
# rotation applies the location change to matrix_world
bpy.ops.transform.rotate(value=bfs.toRad(180), axis=(0.0, 0.0, 1.0))

x2 = bfs.cookieCut(booster, xPlug, "x2", "BMESH")

bfs.selectActivate(xPlug)
bpy.ops.transform.rotate(value=bfs.toRad(180), axis=(0.0, 0.0, 1.0))
xPlug.location.x *= -1

spacePlug = bfs.findObject('space plug')
space1 = bfs.cookieCut(booster, spacePlug, "space1", "BMESH")

bfs.selectActivate(spacePlug)
bpy.ops.transform.translate(value=(-9.0, 0.0, 0.0))
space2 = bfs.cookieCut(booster, spacePlug, "space2", "BMESH")
bfs.selectActivate(spacePlug)
bpy.ops.transform.translate(value=(9.0, 0.0, 0.0))

flagPlug = bfs.findObject('flag plug')
flag1 = bfs.cookieCut(booster, flagPlug, "flag1", "BMESH")
bfs.selectActivate(flagPlug)
bpy.ops.transform.translate(value=(-9.0, 0.0, 0.0))
flag2 = bfs.cookieCut(booster, flagPlug, "flag2", "BMESH")
bfs.selectActivate(flagPlug)
bpy.ops.transform.translate(value=(9.0, 0.0, 0.0))

logoPlug = bfs.findObject('logo plug')
logo1 = bfs.cookieCut(booster, logoPlug, "logo1", "BMESH")
bfs.selectActivate(logoPlug)
bpy.ops.transform.translate(value=(-9.0, 0.0, 0.0))
logo2 = bfs.cookieCut(booster, logoPlug, "logo2", "BMESH")
bfs.selectActivate(logoPlug)
bpy.ops.transform.translate(value=(9.0, 0.0, 0.0))

# calculate UVs
bfs.cylinderUV(flag1, flipZ=True, flipX=True)
bfs.cylinderUV(flag2, flipZ=True, flipX=True)
bfs.cylinderUV(logo1, flipZ=True, flipX=True)
bfs.cylinderUV(logo2, flipZ=True, flipX=True)
bfs.cylinderUV(space1, flipZ=True, flipX=True)
bfs.cylinderUV(space2, flipZ=True, flipX=True)
bfs.cylinderUV(x1, flipZ=True, flipX=True)
bfs.cylinderUV(x2, flipZ=True, flipX=True)

# split booster in 2
fusePlug = bfs.findObject('fuse plug')
bottom_booster = bfs.cookieCut(booster, fusePlug, "booster bottom", "BMESH")
booster.name = "booster top"


########################################################################
# $HeadURL$
# Author : Andrei Tsaregorodtsev
########################################################################
"""
  Utilities for managing DIRAC configuration:

  getCEsFromCS
  getUnusedGridCEs
  getUnusedGridSEs
  getSiteUpdates
  getSEUpdates
"""
__RCSID__ = "$Id$"

import re
import types
from DIRAC import gConfig, gLogger, S_OK
from DIRAC.Core.Utilities import List
from DIRAC.Core.Utilities.Grid import getBdiiCEInfo, getBdiiSEInfo, ldapService
from DIRAC.Core.Utilities.SitesDIRACGOCDBmapping import getDIRACSiteName, getDIRACSesForSRM
from DIRAC.ConfigurationSystem.Client.Helpers.Path import cfgPath
from DIRAC.Core.Utilities.Pfn import pfnparse
from DIRAC.ConfigurationSystem.Client.Helpers.Registry import getVOs, getVOOption

def getGridVOs():
  """ Get all the VOMS VO names served by this DIRAC service
  """
  voNames = []
  result = getVOs()
  if not result['OK']:
    return result
  else:
    vos = result['Value']
    for vo in vos:
      vomsVO = getVOOption( vo, "VOMSName" )
      if vomsVO:
        voNames.append( vomsVO )
  return S_OK( voNames )

def getCEsFromCS():
  """ Get all the CEs defined in the CS
  """

  knownCEs = []
  result = gConfig.getSections( '/Resources/Sites' )
  if not result['OK']:
    return result
  grids = result['Value']

  for grid in grids:
    result = gConfig.getSections( '/Resources/Sites/%s' % grid )
    if not result['OK']:
      return result
    sites = result['Value']

    for site in sites:
      opt = gConfig.getOptionsDict( '/Resources/Sites/%s/%s' % ( grid, site ) )['Value']
      ces = List.fromChar( opt.get( 'CE', '' ) )
      knownCEs += ces

  return S_OK( knownCEs )

def getSEsFromCS( protocol = 'srm' ):
  """ Get all the SEs defined in the CS
  """
  knownSEs = {}
  result = gConfig.getSections( '/Resources/StorageElements' )
  if not result['OK']:
    return result
  ses = result['Value']
  for se in ses:
    seSection = '/Resources/StorageElements/%s' % se
    result = gConfig.getSections( seSection )
    if not result['OK']:
      continue
    accesses = result['Value']
    for access in accesses:
      seProtocol = gConfig.getValue( cfgPath( seSection, access, 'Protocol' ), '' )
      if seProtocol.lower() == protocol.lower() or protocol == 'any':
        host = gConfig.getValue( cfgPath( seSection, access, 'Host' ), '' )
        knownSEs.setdefault( host, [] )
        knownSEs[host].append( se )
      else:
        continue

  return S_OK( knownSEs )

def getGridCEs( vo, bdiiInfo = None, ceBlackList = None ):
  """ Get all the CEs available for a given VO and having queues in Production state
  """
  knownCEs = set()
  if ceBlackList is not None:
    knownCEs = knownCEs.union( set( ceBlackList ) )

  ceBdiiDict = bdiiInfo
  if bdiiInfo is None:
    result = getBdiiCEInfo( vo )
    if not result['OK']:
      return result
    ceBdiiDict = result['Value']

  siteDict = {}
  for site in ceBdiiDict:
    siteCEs = set( ceBdiiDict[site]['CEs'].keys() )
    newCEs = siteCEs - knownCEs
    if not newCEs:
      continue

    ceFullDict = {}
    for ce in newCEs:
      ceDict = {}
      ceInfo = ceBdiiDict[site]['CEs'][ce]
      ceType = 'Unknown'
      ceDict['Queues'] = []
      for queue in ceInfo['Queues']:
        queueStatus = ceInfo['Queues'][queue].get( 'GlueCEStateStatus', 'UnknownStatus' )
        if 'production' in queueStatus.lower():
          ceType = ceInfo['Queues'][queue].get( 'GlueCEImplementationName', '' )
          ceDict['Queues'].append( queue )
      if not ceDict['Queues']:
        continue

      ceDict['CEType'] = ceType
      ceDict['GOCSite'] = site
      ceDict['CEID'] = ce
      systemName = ceInfo.get( 'GlueHostOperatingSystemName', 'Unknown' )
      systemVersion = ceInfo.get( 'GlueHostOperatingSystemVersion', 'Unknown' )
      systemRelease = ceInfo.get( 'GlueHostOperatingSystemRelease', 'Unknown' )
      ceDict['System'] = ( systemName, systemVersion, systemRelease )

      ceFullDict[ce] = ceDict

    siteDict[site] = ceFullDict

  result = S_OK( siteDict )
  result['BdiiInfo'] = ceBdiiDict
  return result

def getSiteUpdates( vo, bdiiInfo = None, log = None ):
  """ Get all the necessary updates for the already defined sites and CEs
  """

  def addToChangeSet( entry, changeSet ):
    _section, _option, value, new_value = entry
    if new_value and new_value != value:
      changeSet.add( entry )

  if log is None:
    log = gLogger

  ceBdiiDict = bdiiInfo
  if bdiiInfo is None:
    result = getBdiiCEInfo( vo )
    if not result['OK']:
      return result
    ceBdiiDict = result['Value']

  changeSet = set()
  gConfig.forceRefresh()

  for site in ceBdiiDict:
    result = getDIRACSiteName( site )
    if not result['OK']:
      continue
    siteNames = result['Value']
    for siteName in siteNames:
      siteSection = cfgPath( '/Resources', 'Sites', siteName.split('.')[0], siteName )
      result = gConfig.getOptionsDict( siteSection )
      if not result['OK']:
        continue
      siteDict = result['Value']
      # Current CS values
      coor = siteDict.get( 'Coordinates', 'Unknown' )
      mail = siteDict.get( 'Mail', 'Unknown' ).replace( ' ','' )
      description = siteDict.get( 'Description', 'Unknown' )

      longitude = ceBdiiDict[site].get( 'GlueSiteLongitude', '' ).strip()
      latitude = ceBdiiDict[site].get( 'GlueSiteLatitude', '' ).strip()

      # Current BDII value
      newcoor = ''
      if longitude and latitude:
        newcoor = "%s:%s" % ( longitude, latitude )
      newmail = ceBdiiDict[site].get( 'GlueSiteSysAdminContact', '' ).replace( 'mailto:', '' ).strip()
      newdescription = ceBdiiDict[site].get( 'GlueSiteDescription', '' ).strip()
      # Adding site data to the changes list
      addToChangeSet( ( siteSection, 'Coordinates', coor, newcoor ), changeSet )
      addToChangeSet( ( siteSection, 'Mail', mail, newmail ), changeSet )
      addToChangeSet( ( siteSection, 'Description', description, newdescription ), changeSet )

      ces = gConfig.getValue( cfgPath( siteSection, 'CE' ), [] )
      for ce in ces:
        ceSection = cfgPath( siteSection, 'CEs', ce )
        ceDict = {}
        result = gConfig.getOptionsDict( ceSection )
        if result['OK']:
          ceDict = result['Value']
        else:
          if ceBdiiDict[site]['CEs'].get( ce, None ):
            log.notice( "Adding new CE %s to site %s/%s" % (ce, siteName, site) )
        ceInfo = ceBdiiDict[site]['CEs'].get( ce, None )
        if ceInfo is None:
          ceType = ceDict.get( 'CEType', '')
          continue

        # Current CS CE info
        arch = ceDict.get( 'architecture', 'Unknown' )
        OS = ceDict.get( 'OS', 'Unknown' )
        si00 = ceDict.get( 'SI00', 'Unknown' )
        ceType = ceDict.get( 'CEType', 'Unknown' )
        ram = ceDict.get( 'HostRAM', 'Unknown' )
        submissionMode = ceDict.get( 'SubmissionMode', 'Unknown' )

        # Current BDII CE info
        newarch = ceBdiiDict[site]['CEs'][ce].get( 'GlueHostArchitecturePlatformType', '' ).strip()
        systemName = ceInfo.get( 'GlueHostOperatingSystemName', '' ).strip()
        systemVersion = ceInfo.get( 'GlueHostOperatingSystemVersion', '' ).strip()
        systemRelease = ceInfo.get( 'GlueHostOperatingSystemRelease', '' ).strip()
        newOS = ''
        if systemName and systemVersion and systemRelease:
          newOS = '_'.join( ( systemName, systemVersion, systemRelease ) )
        newsi00 = ceInfo.get( 'GlueHostBenchmarkSI00', '' ).strip()
        newCEType = 'Unknown'
        for queue in ceInfo['Queues']:
          queueDict = ceInfo['Queues'][queue]
          newCEType = queueDict.get( 'GlueCEImplementationName', '' ).strip()
          if newCEType:
            break
        if newCEType=='ARC-CE':
          newCEType = 'ARC'

        newSubmissionMode = None
        if newCEType in ['ARC','CREAM']:
          newSubmissionMode = "Direct"
        newRAM = ceInfo.get( 'GlueHostMainMemoryRAMSize', '' ).strip()

        # Adding CE data to the change list
        addToChangeSet( ( ceSection, 'architecture', arch, newarch ), changeSet )
        addToChangeSet( ( ceSection, 'OS', OS, newOS ), changeSet )
        addToChangeSet( ( ceSection, 'SI00', si00, newsi00 ), changeSet )
        addToChangeSet( ( ceSection, 'CEType', ceType, newCEType ), changeSet )
        addToChangeSet( ( ceSection, 'HostRAM', ram, newRAM ), changeSet )
        if submissionMode == "Unknown" and newSubmissionMode:
          addToChangeSet( ( ceSection, 'SubmissionMode', submissionMode, newSubmissionMode ), changeSet )

        queues = ceInfo['Queues'].keys()
        for queue in queues:
          queueSection = cfgPath( ceSection, 'Queues', queue )
          queueDict = {}
          result = gConfig.getOptionsDict( queueSection )
          if result['OK']:
            queueDict = result['Value']
          else:
            log.notice( "Adding new queue %s to CE %s" % (queue, ce) )
          queueInfo = ceInfo['Queues'][queue]
          queueStatus = queueInfo['GlueCEStateStatus']
          if queueStatus.lower() != "production":
            continue

          # Current CS queue info
          maxCPUTime = queueDict.get( 'maxCPUTime', 'Unknown' )
          si00 = queueDict.get( 'SI00', 'Unknown' )
          maxTotalJobs = queueDict.get( 'MaxTotalJobs', 'Unknown' )

          # Current BDII queue info
          newMaxCPUTime = queueInfo.get( 'GlueCEPolicyMaxCPUTime', '' )
          newSI00 = ''
          caps = queueInfo['GlueCECapability']
          if type( caps ) == type( '' ):
            caps = [caps]
          for cap in caps:
            if 'CPUScalingReferenceSI00' in cap:
              newSI00 = cap.split( '=' )[-1]

          # Adding queue info to the CS
          addToChangeSet( ( queueSection, 'maxCPUTime', maxCPUTime, newMaxCPUTime ), changeSet )
          addToChangeSet( ( queueSection, 'SI00', si00, newSI00 ), changeSet )
          if maxTotalJobs == "Unknown":
            newTotalJobs =  min( 1000, int( int( queueInfo.get( 'GlueCEInfoTotalCPUs', 0 ) )/2 ) )
            newWaitingJobs =  max( 2, int( newTotalJobs * 0.1 ) )
            newTotalJobs = str( newTotalJobs )
            newWaitingJobs = str( newWaitingJobs )
            addToChangeSet( ( queueSection, 'MaxTotalJobs', '', newTotalJobs ), changeSet )
            addToChangeSet( ( queueSection, 'MaxWaitingJobs', '', newWaitingJobs ), changeSet )

          # Updating eligible VO list
          VOs = set()
          if queueDict.get( 'VO', '' ):
            VOs = set( [ q.strip() for q in queueDict.get( 'VO', '' ).split( ',' ) if q ] )
          if not vo in VOs:
            VOs.add( vo )
            VOs = list( VOs )
            newVOs = ','.join( VOs )
            addToChangeSet( ( queueSection, 'VO', '', newVOs ), changeSet )

  return S_OK( changeSet )

def getGridSEs( vo, bdiiInfo = None, seBlackList = None ):
  """ Get all the SEs available for a given VO
  """
  seBdiiDict = bdiiInfo
  if bdiiInfo is None:
    result = getBdiiSEInfo( vo )
    if not result['OK']:
      return result
    seBdiiDict = result['Value']

  knownSEs = set()
  if seBlackList is not None:
    knownSEs = knownSEs.union( set( seBlackList ) )

  siteDict = {}
  for site in seBdiiDict:
    for gridSE in seBdiiDict[site]['SEs']:
      seDict = seBdiiDict[site]['SEs'][gridSE]

      #if "lhcb" in seDict['GlueSAName']:
      #  print '+'*80
      #  print gridSE
      #  for k,v in seDict.items():
      #    print k,'\t',v

      if not gridSE in knownSEs:
        siteDict.setdefault( site, {} )
        if type( seDict['GlueSAAccessControlBaseRule'] ) == types.ListType:
          voList = [ re.sub( '^VO:', '', s ) for s in seDict['GlueSAAccessControlBaseRule'] ]
        else:
          voList = [ re.sub( '^VO:', '', seDict['GlueSAAccessControlBaseRule'] ) ]
        siteDict[site][gridSE] = { 'GridSite': seDict['GlueSiteUniqueID'],
                                   'BackendType': seDict['GlueSEImplementationName'],
                                   'Description': seDict.get( 'GlueSEName', '-' ),
                                   'VOs': voList
                                 }

  result = S_OK( siteDict )
  result['BdiiInfo'] = seBdiiDict
  return result

def getGridSRMs( vo, bdiiInfo = None, srmBlackList = None, unUsed = False ):

  result = ldapService( serviceType = 'SRM', vo = vo )
  if not result['OK']:
    return result
  srmBdiiDict = result['Value']

  knownSRMs = set()
  if srmBlackList is not None:
    knownSRMs = knownSRMs.union( set( srmBlackList ) )

  siteSRMDict = {}
  for srm in srmBdiiDict:

    endPoint = srm.get( 'GlueServiceEndpoint', '')
    srmHost = ''
    if endPoint:
      result = pfnparse( endPoint )
      if not result['OK']:
        continue
      srmHost = result['Value']['Host']
    if not srmHost:
      continue

    if srmHost in knownSRMs:
      continue

    if unUsed:
      result = getDIRACSesForSRM( srmHost )
      if not result['OK']:
        return result
      diracSEs = result['Value']
      if diracSEs:
        # If it is a known SRM and only new SRMs are requested, continue
        continue
    site = srm.get( 'GlueForeignKey', '' ).replace( 'GlueSiteUniqueID=', '' )
    siteSRMDict.setdefault( site, {} )
    siteSRMDict[site][srmHost] = srm

  if bdiiInfo is None:
    result = getBdiiSEInfo( vo )
    if not result['OK']:
      return result
    seBdiiDict = result['Value']
  else:
    seBdiiDict = bdiiInfo

  srmSeDict = {}
  for site in siteSRMDict:
    srms = siteSRMDict[site].keys()
    for srm in srms:
      if seBdiiDict.get( site, {} ).get( 'SEs', {} ).get( srm, {} ):
        srmSeDict.setdefault( site, {} )
        srmSeDict[site].setdefault( srm, {} )
        srmSeDict[site][srm]['SRM'] = siteSRMDict[site][srm]
        srmSeDict[site][srm]['SE'] = seBdiiDict[site]['SEs'][srm]

  return S_OK( srmSeDict )

def getSRMUpdates( vo, bdiiInfo = None ):

  changeSet = set()

  def addToChangeSet( entry, changeSet ):
    _section, _option, value, new_value = entry
    if new_value and new_value != value:
      changeSet.add( entry )

  result = getGridSRMs( vo, bdiiInfo = bdiiInfo )
  if not result['OK']:
    return result
  srmBdiiDict = result['Value']

  result = getSEsFromCS()
  if not result['OK']:
    return result
  seDict = result['Value']

  result = getVOs()
  if result['OK']:
    csVOs = set( result['Value'] )
  else:
    csVOs = set( [vo] )

  for seHost, diracSE in seDict.items():
    seSection = '/Resources/StorageElements/%s' % diracSE[0]
    # Look up existing values first
    description = gConfig.getValue( cfgPath( seSection, 'Description'), 'Unknown' )
    backend = gConfig.getValue( cfgPath( seSection, 'BackendType'), 'Unknown' )
    vos = gConfig.getValue( cfgPath( seSection, 'VO'), 'Unknown' ).replace( ' ','' )
    size = gConfig.getValue( cfgPath( seSection, 'TotalSize'), 'Unknown' )
    # Look up current BDII values
    srmDict = {}
    seBdiiDict = {}
    for site in srmBdiiDict:
      if seHost in srmBdiiDict[site]:
        srmDict = srmBdiiDict[site][seHost]['SRM']
        seBdiiDict = srmBdiiDict[site][seHost]['SE']
        break

    if not srmDict or not seBdiiDict:
      continue

    newDescription = seBdiiDict.get( 'GlueSEName', 'Unknown' )
    newBackend = seBdiiDict.get( 'GlueSEImplementationName', 'Unknown' )
    newSize = seBdiiDict.get( 'GlueSESizeTotal', 'Unknown' )
    addToChangeSet( ( seSection, 'Description', description, newDescription ), changeSet )
    addToChangeSet( ( seSection, 'BackendType', backend, newBackend ), changeSet )
    addToChangeSet( ( seSection, 'TotalSize', size, newSize ), changeSet )

    # Evaluate VOs if no space token defined, otherwise this is VO specific
    spaceToken = ''
    for i in range( 1, 10 ):
      protocol = gConfig.getValue( cfgPath( seSection, 'AccessProtocol.%d' % i, 'Protocol' ), '' )
      if protocol.lower() == 'srm':
        spaceToken = gConfig.getValue( cfgPath( seSection, 'AccessProtocol.%d' % i, 'SpaceToken' ), '' )
        break
    if not spaceToken:
      bdiiVOs = srmDict.get( 'GlueServiceAccessControlBaseRule', [] )
      bdiiVOs = set( [ re.sub( '^VO:', '', rule ) for rule in bdiiVOs ] )
      seVOs = csVOs.intersection( bdiiVOs )
      newVOs = ','.join( seVOs )
      addToChangeSet( ( seSection, 'VO', vos, newVOs ), changeSet )

  return S_OK( changeSet )


#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
  doitlive
  ~~~~~~~~

  :copyright: (c) 2014 by Steven Loria.
  :license: MIT, see LICENSE for more details.
"""

from __future__ import unicode_literals
import os
import sys
import re
import getpass
import subprocess
from tempfile import NamedTemporaryFile

import click
from click import echo, style, getchar

__version__ = '0.2.0'
__author__ = 'Steven Loria'
__license__ = 'MIT'

env = os.environ
PY2 = int(sys.version[0]) == 2
if PY2:
    basestring = basestring
else:
    basestring = (str, bytes)

HERE = os.path.abspath(os.path.dirname(__file__))
ESC = u'\x1b'
RETURNS = {'\r', '\n'}
OPTION_RE = re.compile(r'^#\s?doitlive\s+'
            '(?P<option>prompt|shell|alias|env|speed):'
            '\s*(?P<arg>.+)$')
TESTING = False

class PromptState(object):
    user = ''
    cwd = ''
    display_dir = ''

    def update(self):
        self.user = style(getpass.getuser(), fg='cyan', bold=True)
        self.cwd = os.getcwd()
        display_cwd_raw = '~' if self.cwd == env['HOME'] else os.path.split(self.cwd)[-1]
        self.display_cwd = style(display_cwd_raw, fg='green')

_prompt_state = PromptState()

def echof(text, *args, **kwargs):
    echo(style(text, *args, **kwargs))

def get_default_prompt():
    if env.get('DOITLIVE_PROMPT'):
        return env['DOITLIVE_PROMPT']
    _prompt_state.update()
    return '{user}@{cwd}: $'.format(
        user=_prompt_state.user,
        cwd=_prompt_state.display_cwd
    )

def ensure_utf(string):
    return string.encode('utf-8') if PY2 else string

def run_command(cmd, shell=None, aliases=None, envvars=None, test_mode=True):
    shell = shell or env.get('DOITLIVE_INTERPRETER') or '/bin/bash'
    if cmd.startswith("cd "):
        directory = cmd.split()[1]
        os.chdir(os.path.expanduser(directory))
        _prompt_state.update()
    else:
        # Need to make a temporary command file so that $ENV are used correctly
        # and that shell built-ins, e.g. "source" work
        with NamedTemporaryFile('w') as fp:
            fp.write('#!{0}\n'.format(shell))
            fp.write('# -*- coding: utf-8 -*-\n')
            # Make aliases work in bash:
            if 'bash' in shell:
                fp.write("shopt -s expand_aliases\n")

            if envvars:
                # Write envvars
                for envvar in envvars:
                    envvar_line = 'export {0}\n'.format(envvar)
                    fp.write(ensure_utf(envvar_line))

            if aliases:
                # Write aliases
                for alias in aliases:
                    alias_line = 'alias {0}\n'.format(alias)
                    fp.write(ensure_utf(alias_line))
            cmd_line = cmd + '\n'
            fp.write(ensure_utf(cmd_line))
            fp.flush()
            if test_mode:
                return subprocess.check_output([shell, fp.name])
            else:
                return subprocess.call([shell, fp.name])

def wait_for(chars):
    while True:
        in_char = getchar()
        if in_char == ESC:
            echo()
            raise click.Abort()
        if in_char in chars:
            echo()
            return in_char

def magictype(text, shell, prompt_func=get_default_prompt, aliases=None,
        envvars=None, speed=1, test_mode=False):
    prompt = prompt_func()
    echo(prompt + ' ', nl=False)
    i = 0
    while i < len(text):
        char = text[i:i + speed]
        in_char = getchar()
        if in_char == ESC:
            echo()
            raise click.Abort()
        echo(char, nl=False)
        i += speed
    wait_for(RETURNS)
    output = run_command(text, shell,aliases=aliases, envvars=envvars,
        test_mode=test_mode)
    if isinstance(output, basestring):
        echo(output)

def format_prompt(prompt):
    _prompt_state.update()
    return prompt.format(
        user=_prompt_state.user,
        cwd=_prompt_state.display_cwd,
        full_cwd=_prompt_state.cwd
    )

def make_prompt_formatter(template):
    return lambda: format_prompt(template)

def run(commands, shell='/bin/bash', prompt_func=get_default_prompt, speed=1,
        test_mode=False):
    echof("We'll do it live!", fg='red', bold=True)
    echof('STARTING SESSION: Press ESC at any time to exit.', fg='yellow', bold=True)

    click.pause()
    click.clear()
    aliases, envvars = [], []
    for line in commands:
        command = line.strip()
        if not command:
            continue
        if command.startswith('#'):
            # Parse comment magic
            match = OPTION_RE.match(command)
            if match:
                option, arg = match.group('option'), match.group('arg')
                if option == 'prompt':
                    prompt_func = make_prompt_formatter(arg)
                elif option == 'shell':
                    shell = arg
                elif option == 'alias':
                    aliases.append(arg)
                elif option == 'env':
                    envvars.append(arg)
                elif option == 'speed':
                    speed = int(arg)
            continue
        magictype(command, shell, prompt_func=prompt_func, aliases=aliases,
            envvars=envvars, speed=speed, test_mode=test_mode)
    prompt = prompt_func()
    echo(prompt + ' ', nl=False)
    wait_for(RETURNS)
    echof("FINISHED SESSION", fg='yellow', bold=True)

@click.option('--speed', '-S', metavar='<int>', default=1, help='Typing speed.')
@click.option('--shell', '-s', metavar='<shell>',
    default='/bin/bash', help='The shell to use.')
@click.argument('session_file', type=click.File('r', encoding='utf-8'))
@click.version_option(__version__, '--version', '-v')
@click.command(context_settings={'help_option_names': ('-h', '--help')})
def cli(session_file, shell, speed):
    """The doitlive CLI.

    \b
    How to use:
        1. Create a file called session.sh. Fill it with bash commands.
        2. Run "doitlive session.sh"
        3. Type like a madman.

    Press ESC or ^C at any time to exit the session.
    To see a demo session, run "doitlive-demo".
    """
    run(session_file.readlines(),
        shell=shell,
        speed=speed,
        test_mode=TESTING)

DEMO = [
    'echo "Greetings"',
    'echo "This is just a demo session"',
    'echo "For more info, check out the home page..."',
    'echo "http://doitlive.rtfd.org"'
]

@click.option('--speed', '-S', default=1, help='Typing speed.')
@click.option('--shell', '-i', default='/bin/bash')
@click.command()
def demo(shell, speed):
    """Run a demo doitlive session."""
    run(DEMO, shell=shell, speed=speed, test_mode=TESTING)

if __name__ == '__main__':
    cli()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Aug  6 16:19:52 2019

@author: MeganT
"""

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Aug  5 14:47:06 2019

@author: MeganT
"""

from astropy.io import fits
import numpy.linalg as li
from extreme_deconvolution import extreme_deconvolution
import matplotlib.pyplot as plt
import shutil
import os
import numpy as np
import math
import sys

with fits.open(os.getcwd()+'/simulated_buzzard_data.fits') as hdul:
#    hdul.info()
    data = hdul[1].data
    header = hdul[1].header
    cols = hdul[1].columns

os.chdir(os.getcwd()+"/xdc_t4")
num_cols = 4
num_rows = data.field(0).shape[1]

ndata = np.zeros((num_rows, num_cols))
errors = np.zeros((num_rows, num_cols))
for i in range(num_cols):
    ndata[:, i] = data.field(i + 4)
    errors[:, i] = data.field(i + 8)

for i in range(num_rows):
    total_flux = sum(ndata[i, :])
    ndata[i, :] = ndata[i, :] / total_flux
    errors[i, :] = errors[i, :] / total_flux

# We fill ndata with the true values of the flux
true_data = np.zeros((num_rows, num_cols))

for i in range(num_cols):
    true_data[:, i] = data.field(i)

# Normalize the true_data
for i in range(num_rows):
    total_flux = sum(true_data[i, :])
    true_data[i, :] = true_data[i, :] / total_flux

neurons = []
with open('neurons.txt', 'r') as filehandle:
    lines = filehandle.readlines()
    for l in lines:
        strings = l.split(' ')
        a = np.asarray(strings[:len(strings)-1])
        neurons.append(a.astype(np.float))
neurons = np.array(neurons)
#print(neurons)

bin_values = []
with open('bin_values.txt', 'r') as filehandle:
    lines = filehandle.read().splitlines()
    for l in lines:
        bin_values.append(float(l))
#print(bin_values)

xmean = []
with open('new_xmeans.txt', 'r') as filehandle:
    lines = filehandle.readlines()
    for l in lines:
        strings = l.split(' ')
        a = np.asarray(strings[:len(strings)-1])
        xmean.append(a.astype(np.float))
xmean = np.array(xmean)
#print(xmean)

dx = 4
xcovar = []
with open('new_xcovars.txt', 'r') as filehandle:
    lines = filehandle.readlines()
    for l in lines:
        strings = l.split(' ')
        a = np.asarray(strings[:len(strings)-1])
        matrix = np.zeros([dx, dx])
        k = 0
        for i in range(dx):
            for j in range(dx):
                matrix[i][j] = a[k]
                k += 1
        xcovar.append(matrix.astype(np.float))
xcovar = np.array(xcovar)

xamp1 = []
with open('new_xamps.txt', 'r') as filehandle:
    lines = filehandle.read().splitlines()
    for l in lines:
        xamp1.append(float(l))
xamp1 = np.array(xamp1)
#print(xamp1)

# Bins true distribution into neurons
samples = 2
data = np.zeros([num_rows*samples,4],dtype=np.float)
#sigma is 0 for all dimensions
for i in range(num_rows):
    x = true_data[i,:]
    data[i*samples:(i+1)*samples, :] = np.asarray(
            [np.random.normal(x[0], 0,samples),
             np.random.normal(x[1], 0,samples),
             np.random.normal(x[2], 0, samples),
             np.random.normal(x[3], 0, samples)]).T

# Apply MCMC to sample the XDC probability
tot_samp = 100000 * 100
dim = xmean.shape[1]

#figure out the number of gaussians in the model
Ngauss = len(xamp1)

samples = np.zeros([tot_samp,dim],dtype=np.double)

#loop over the gaussians in the model
sample_count = 0  #counter for number of samples
count_samples = np.zeros(Ngauss)
for g in range(0,Ngauss):

    #set the number of samples proportional to the amplitude of this gaussian
    Gsamp = int(tot_samp*xamp1[g])
    count_samples[g] = Gsamp

    samples[sample_count:(sample_count+Gsamp),:] = np.random.multivariate_normal(xmean[g], xcovar[g], Gsamp)
    sample_count+=Gsamp

count_samples = np.asarray(count_samples, np.int32)

# Plot the contours
#V = xcovar
#xamp = xamp1
old_samples = samples.copy()
#g_factor = 50 / np.mean(samples[:, 0])
#r_factor = 50 / np.mean(samples[:, 1])
#i_factor = 50 / np.mean(samples[:, 2])
#z_factor = 50 / np.mean(samples[:, 3])
#samples[:, 0] *= np.repeat([g_factor], samples.shape[0], axis = 0)
#samples[:, 1] *= np.repeat([r_factor], samples.shape[0], axis = 0)
#samples[:, 2] *= np.repeat([i_factor], samples.shape[0], axis = 0)
#samples[:, 3] *= np.repeat([z_factor], samples.shape[0], axis = 0)
#print(samples[:,0])
#g_diff = np.amax(samples[:,0]) - np.amin(samples[:,0])
#r_diff = np.amax(samples[:,1]) - np.amin(samples[:,1])
#i_diff = np.amax(samples[:,2]) - np.amin(samples[:,2])
#z_diff = np.amax(samples[:,3]) - np.amin(samples[:,3])
g_min = np.amin(samples[:,0])
r_min = np.amin(samples[:,1])
i_min = np.amin(samples[:,2])
z_min = np.amin(samples[:,3])
g_max = np.amax(samples[:,0])
r_max = np.amax(samples[:,1])
i_max = np.amax(samples[:,2])
z_max = np.amax(samples[:,3])

g_min_u = np.amin(old_samples[:,0])
r_min_u = np.amin(old_samples[:,1])
i_min_u = np.amin(old_samples[:,2])
z_min_u = np.amin(old_samples[:,3])
g_max_u = np.amax(old_samples[:,0])
r_max_u = np.amax(old_samples[:,1])
i_max_u = np.amax(old_samples[:,2])
z_max_u = np.amax(old_samples[:,3])

#print(g_min,r_min,i_min,z_min,g_max,r_max,i_max,z_max)
#g_min = 0.0
#r_min = 0.0
#i_min = 0.15
#z_min = 0.15
#g_max = 0.4
#r_max = 0.3
#i_max = 0.4
#z_max = 0.75

g_diff = g_max-g_min
r_diff = r_max-r_min
i_diff = i_max-i_min
z_diff = z_max-z_min

pixel_num=301

samples[:, 0] =  (samples[:, 0] - np.repeat([g_min], samples.shape[0])) * \
 np.repeat([pixel_num/g_diff], samples.shape[0])
samples[:, 1] = (samples[:, 1] - np.repeat([r_min], samples.shape[0])) * \
 np.repeat([pixel_num/r_diff], samples.shape[0])
samples[:, 2] = (samples[:, 2] - np.repeat([i_min], samples.shape[0])) * \
 np.repeat([pixel_num/i_diff], samples.shape[0])
samples[:, 3] = (samples[:, 3] - np.repeat([z_min], samples.shape[0])) * \
 np.repeat([pixel_num/z_diff], samples.shape[0])

image_gr = np.zeros([pixel_num, pixel_num],dtype=np.double)
image_ri = np.zeros([pixel_num, pixel_num],dtype=np.double)
image_iz = np.zeros([pixel_num, pixel_num],dtype=np.double)
image_gz = np.zeros([pixel_num, pixel_num],dtype=np.double)

for sample in samples:
    g = int(sample[0])
    r = int(sample[1])
    i = int(sample[2])
    z = int(sample[3])
    if g > 0 and g < pixel_num and r > 0 and r < pixel_num:
        image_gr[g, r] += 1
    if r > 0 and r < pixel_num and i > 0 and i < pixel_num:
        image_ri[r, i] += 1
    if i > 0 and i < pixel_num and z > 0 and z < pixel_num:
        image_iz[i, z] += 1
    if g > 0 and g < pixel_num and z > 0 and z < pixel_num:
        image_gz[g, z] += 1

for i in range(image_gr.shape[0]):
    for j in range(image_gr.shape[1]):
        image_gr[i][j] /= samples.shape[0]

for i in range(image_ri.shape[0]):
    for j in range(image_ri.shape[1]):
        image_ri[i][j] /= samples.shape[0]

for i in range(image_iz.shape[0]):
    for j in range(image_iz.shape[1]):
        image_iz[i][j] /= samples.shape[0]

for i in range(image_gz.shape[0]):
    for j in range(image_gz.shape[1]):
        image_gz[i][j] /= samples.shape[0]

#image_gr[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_gr.shape))
#image_ri[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_ri.shape))
#image_iz[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_iz.shape))
#image_gz[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_gz.shape))
image_gr_q = image_gr.copy()
image_ri_q = image_ri.copy()
image_iz_q = image_iz.copy()
image_gz_q = image_gz.copy()

from scipy.ndimage.filters import gaussian_filter

image_gr = gaussian_filter(image_gr, sigma=3)
fits.writeto('gr_model.fits',image_gr,overwrite=True)
image_ri = gaussian_filter(image_ri, sigma=3)
fits.writeto('ri_model.fits',image_ri,overwrite=True)
image_iz = gaussian_filter(image_iz, sigma=3)
fits.writeto('iz_model.fits',image_iz,overwrite=True)
image_gz = gaussian_filter(image_gz, sigma=3)
fits.writeto('gz_model.fits',image_gz,overwrite=True)

g_grmin = pixel_num
g_grmax = -1
r_grmin = pixel_num
r_grmax = -1
for i in range(image_gr.shape[0]):
    for j in range(image_gr.shape[1]):
        if image_gr[i][j] != 0:
            if i < g_grmin:
                g_grmin = i
            if j < r_grmin:
                r_grmin = j
            if i > g_grmax:
                g_grmax = i
            if j > r_grmax:
                r_grmax = j
r_rimin = pixel_num
r_rimax = -1
i_rimin = pixel_num
i_rimax = -1
for i in range(image_ri.shape[0]):
    for j in range(image_ri.shape[1]):
        if image_ri[i][j] != 0:
            if i < r_rimin:
                r_rimin = i
            if j < i_rimin:
                i_rimin = j
            if i > r_rimax:
                r_rimax = i
            if j > i_rimax:
                i_rimax = j
i_izmin = pixel_num
i_izmax = -1
z_izmin = pixel_num
z_izmax = -1
for i in range(image_iz.shape[0]):
    for j in range(image_iz.shape[1]):
        if image_iz[i][j] != 0:
            if i < i_izmin:
                i_izmin = i
            if j < z_izmin:
                z_izmin = j
            if i > i_izmax:
                i_izmax = i
            if j > z_izmax:
                z_izmax = j
g_gzmin = pixel_num
g_gzmax = -1
z_gzmin = pixel_num
z_gzmax = -1
for i in range(image_gz.shape[0]):
    for j in range(image_gz.shape[1]):
        if image_gz[i][j] != 0:
            if i < g_gzmin:
                g_gzmin = i
            if j < z_gzmin:
                z_gzmin = j
            if i > g_gzmax:
                g_gzmax = i
            if j > z_gzmax:
                z_gzmax = j

plt.close()
fig, [(ax1, ax2), (ax3, ax4)] = plt.subplots(2, 2)
plt.subplots_adjust(left=0.125, bottom=0.1, right=0.9, top=0.9, wspace=0.5, hspace=0.5)
levels_gr=[1e-8, 1.16e-6,3.65e-6,9.0e-6,2.06e-5,4.54e-5,9.9e-5,2.14e-4,4.63e-4,1e-3]
levels_ri=[2.33043e-06,7.3512e-06,1.81681e-05,4.14725e-05,9.16801e-05, \
           0.000199849,0.000432893,0.00093497,0.00201666]
levels_iz=[2.06444e-06,6.51214e-06,1.60944e-05,3.67388e-05,8.12159e-05, \
           0.000177039,0.000383483,0.000828253,0.00178648]
levels_gz=[2.21448e-06,6.98544e-06,1.72642e-05,3.9409e-05,8.71186e-05, \
           0.000189906,0.000411354,0.00088845,0.00191632]
#fig.tight_layout()
ax1.contour(image_gr, levels_gr)
interval = 50

#i_ticks = np.around(np.linspace(i_min_u, i_max_u, len(ind)),2)
#z_ticks = np.around(np.linspace(z_min_u, z_max_u, len(ind)),2)

#ax1.set_xlim([0.018689261934454145, 0.30570522434917147])
#ax1.set_ylim([-0.02498731864164616, 0.37520237750109764])
ax1.set_xlabel("R")
ax1.set_ylabel("G")
x_ind = np.arange(start = r_grmin, stop = r_grmax, step=interval)
y_ind = np.arange(start = g_grmin, stop = g_grmax, step=interval)
r_ticks = np.around(np.linspace(r_min_u, r_max_u, len(x_ind)),2)
g_ticks = np.around(np.linspace(g_min_u, g_max_u, len(y_ind)),2)
ax1.set_xticks(x_ind)
ax1.set_yticks(y_ind)
ax1.set_xticklabels(r_ticks)
ax1.set_yticklabels(g_ticks)
#ax1.set_xlim(r_grmin, r_grmax)
#ax1.set_ylim(g_grmin, g_grmax)
ax1.set_xlim(18, 225)
ax1.set_ylim(0, 270)
ax1.set_title("Normalized G vs. Normalized R")

ax2.contour(image_ri, levels_ri)
#ax2.set_xlim([0.168327331025541, 0.3818603775513799])
#ax2.set_ylim([0.01591015407155072, 0.3084843322120745])
ax2.set_xlabel("I")
ax2.set_ylabel("R")
x_ind = np.arange(start = i_rimin, stop = i_rimax, step=interval)
y_ind = np.arange(start = r_rimin, stop = r_rimax, step=interval)
i_ticks = np.around(np.linspace(i_min_u, i_max_u, len(x_ind)),2)
r_ticks = np.around(np.linspace(r_min_u, r_max_u, len(y_ind)),2)
ax2.set_xticks(x_ind)
ax2.set_yticks(y_ind)
ax2.set_xticklabels(i_ticks)
ax2.set_yticklabels(r_ticks)
#ax2.set_xlim(i_rimin, i_rimax)
#ax2.set_ylim(r_rimin, r_rimax)
ax2.set_xlim(150, 270)
ax2.set_ylim(30, 218)
ax2.set_title("Normalized R vs. Normalized I")

ax3.contour(image_iz, levels_iz)
#ax3.set_xlim([0.10870964061586308, 0.7513928898988901])
#ax3.set_ylim([0.16554822316263784, 0.38463948541428344])
ax3.set_xlabel("Z")
ax3.set_ylabel("I")
x_ind = np.arange(start = z_izmin, stop = z_izmax, step=interval)
y_ind = np.arange(start = i_izmin, stop = i_izmax, step=interval)
z_ticks = np.around(np.linspace(z_min_u, z_max_u, len(x_ind)),2)
i_ticks = np.around(np.linspace(i_min_u, i_max_u, len(y_ind)),2)
ax3.set_xticks(x_ind)
ax3.set_yticks(y_ind)
ax3.set_xticklabels(z_ticks)
ax3.set_yticklabels(i_ticks)
#ax3.set_xlim(z_izmin, z_izmax)
#ax3.set_ylim(i_izmin, i_izmax)
ax3.set_xlim(90, 300)
ax3.set_ylim(150, 280)
ax3.set_title("Normalized I vs. Normalized Z")

ax4.contour(image_gz,levels_gz)
#ax4.set_xlim([0.10870964061586297, 0.75139288989889])
#ax4.set_ylim([-0.024987318641646213, 0.3752023775010975])
ax4.set_xlabel("Z")
ax4.set_ylabel("G")
x_ind = np.arange(start = z_gzmin, stop = z_gzmax, step=interval)
y_ind = np.arange(start = g_gzmin, stop = g_gzmax, step=interval)
z_ticks = np.around(np.linspace(z_min_u, z_max_u, len(x_ind)),2)
g_ticks = np.around(np.linspace(g_min_u, g_max_u, len(y_ind)),2)
ax4.set_xticks(x_ind)
ax4.set_yticks(y_ind)
ax4.set_xticklabels(z_ticks)
ax4.set_yticklabels(g_ticks)
#ax4.set_xlim(z_gzmin, z_gzmax)
#ax4.set_ylim(g_gzmin, g_gzmax)
ax4.set_xlim(100, 300)
ax4.set_ylim(0, 230)
ax4.set_title("Normalized G vs. Normalized Z")
fig.suptitle("Scaled and Pixelated")
plt.savefig("Scaled_And_Pixelated.png")

# Plot contours of true fluxes for comparison
true_copy = true_data.copy()
#g_min = np.amin(true_copy[:,0])
#r_min = np.amin(true_copy[:,1])
#i_min = np.amin(true_copy[:,2])
#z_min = np.amin(true_copy[:,3])
#g_max = np.amax(true_copy[:,0])
#r_max = np.amax(true_copy[:,1])
#i_max = np.amax(true_copy[:,2])
#z_max = np.amax(true_copy[:,3])

#g_min_u = np.amin(true_copy[:,0])
#r_min_u = np.amin(true_copy[:,1])
#i_min_u = np.amin(true_copy[:,2])
#z_min_u = np.amin(true_copy[:,3])
#g_max_u = np.amax(true_copy[:,0])
#r_max_u = np.amax(true_copy[:,1])
#i_max_u = np.amax(true_copy[:,2])
#z_max_u = np.amax(true_copy[:,3])

#print(g_min,r_min,i_min,z_min,g_max,r_max,i_max,z_max)
#g_min = 0.0
#r_min = 0.0
#i_min = 0.15
#z_min = 0.15
#g_max = 0.4
#r_max = 0.3
#i_max = 0.4
#z_max = 0.75

#g_diff = g_max-g_min
#r_diff = r_max-r_min
#i_diff = i_max-i_min
#z_diff = z_max-z_min

pixel_num=301

true_copy[:, 0] =  (true_copy[:, 0] - np.repeat([g_min], true_copy.shape[0])) * \
 np.repeat([pixel_num/g_diff], true_copy.shape[0])
true_copy[:, 1] = (true_copy[:, 1] - np.repeat([r_min], true_copy.shape[0])) * \
 np.repeat([pixel_num/r_diff], true_copy.shape[0])
true_copy[:, 2] = (true_copy[:, 2] - np.repeat([i_min], true_copy.shape[0])) * \
 np.repeat([pixel_num/i_diff], true_copy.shape[0])
true_copy[:, 3] = (true_copy[:, 3] - np.repeat([z_min], true_copy.shape[0])) * \
 np.repeat([pixel_num/z_diff], true_copy.shape[0])

image_gr = np.zeros([pixel_num, pixel_num],dtype=np.double)
image_ri = np.zeros([pixel_num, pixel_num],dtype=np.double)
image_iz = np.zeros([pixel_num, pixel_num],dtype=np.double)
image_gz = np.zeros([pixel_num, pixel_num],dtype=np.double)

for sample in true_copy:
    g = int(sample[0])
    r = int(sample[1])
    i = int(sample[2])
    z = int(sample[3])
    if g > 0 and g < pixel_num and r > 0 and r < pixel_num:
        image_gr[g, r] += 1
    if r > 0 and r < pixel_num and i > 0 and i < pixel_num:
        image_ri[r, i] += 1
    if i > 0 and i < pixel_num and z > 0 and z < pixel_num:
        image_iz[i, z] += 1
    if g > 0 and g < pixel_num and z > 0 and z < pixel_num:
        image_gz[g, z] += 1

for i in range(image_gr.shape[0]):
    for j in range(image_gr.shape[1]):
        image_gr[i][j] /= true_copy.shape[0]

for i in range(image_ri.shape[0]):
    for j in range(image_ri.shape[1]):
        image_ri[i][j] /= true_copy.shape[0]

for i in range(image_iz.shape[0]):
    for j in range(image_iz.shape[1]):
        image_iz[i][j] /= true_copy.shape[0]

for i in range(image_gz.shape[0]):
    for j in range(image_gz.shape[1]):
        image_gz[i][j] /= true_copy.shape[0]

#image_gr[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_gr.shape))
#image_ri[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_ri.shape))
#image_iz[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_iz.shape))
#image_gz[:,:] /= np.repeat(np.array([samples.shape[0]]), np.array(image_gz.shape))
image_gr_p = image_gr.copy()
image_ri_p = image_ri.copy()
image_iz_p = image_iz.copy()
image_gz_p = image_gz.copy()

image_gr = gaussian_filter(image_gr, sigma=3)
fits.writeto('gr_orig.fits',image_gr,overwrite=True)
image_ri = gaussian_filter(image_ri, sigma=3)
fits.writeto('ri_orig.fits',image_ri,overwrite=True)
image_iz = gaussian_filter(image_iz, sigma=3)
fits.writeto('iz_orig.fits',image_iz,overwrite=True)
image_gz = gaussian_filter(image_gz, sigma=3)
fits.writeto('gz_orig.fits',image_gz,overwrite=True)

plt.close()
fig, [(ax1, ax2), (ax3, ax4)] = plt.subplots(2, 2)
plt.subplots_adjust(left=0.125, bottom=0.1, right=0.9, top=0.9, wspace=0.5, hspace=0.5)
levels=[1e-8, 1.16e-6,3.65e-6,9.0e-6,2.06e-5,4.54e-5,9.9e-5,2.14e-4,4.63e-4,1e-3]
#fig.tight_layout()
ax1.contour(image_gr, levels_gr)
interval = 50
#ind = np.arange(pixel_num, step=interval)

#ax1.set_xlim([0.018689261934454145, 0.30570522434917147])
#ax1.set_ylim([-0.02498731864164616, 0.37520237750109764])
ax1.set_xlabel("R")
ax1.set_ylabel("G")
#ax1.set_xticks(ind)
#ax1.set_yticks(ind)
x_ind = np.arange(start = r_grmin, stop = r_grmax, step=interval)
y_ind = np.arange(start = g_grmin, stop = g_grmax, step=interval)
r_ticks = np.around(np.linspace(r_min_u, r_max_u, len(x_ind)),2)
g_ticks = np.around(np.linspace(g_min_u, g_max_u, len(y_ind)),2)
ax1.set_xticks(x_ind)
ax1.set_yticks(y_ind)
#ax1.set_xlim(r_grmin, r_grmax)
#ax1.set_ylim(g_grmin, g_grmax)
ax1.set_xlim(18, 225)
ax1.set_ylim(0, 270)
ax1.set_xticklabels(r_ticks)
ax1.set_yticklabels(g_ticks)
ax1.set_title("Normalized G vs. Normalized R")

ax2.contour(image_ri, levels_ri)
#ax2.set_xlim([0.168327331025541, 0.3818603775513799])
#ax2.set_ylim([0.01591015407155072, 0.3084843322120745])
ax2.set_xlabel("I")
ax2.set_ylabel("R")
#ax2.set_xticks(ind)
#ax2.set_yticks(ind)
x_ind = np.arange(start = i_rimin, stop = i_rimax, step=interval)
y_ind = np.arange(start = r_rimin, stop = r_rimax, step=interval)
i_ticks = np.around(np.linspace(i_min_u, i_max_u, len(x_ind)),2)
r_ticks = np.around(np.linspace(r_min_u, r_max_u, len(y_ind)),2)
ax2.set_xticks(x_ind)
ax2.set_yticks(y_ind)
ax2.set_xticklabels(i_ticks)
ax2.set_yticklabels(r_ticks)
#ax2.set_xlim(i_rimin, i_rimax)
#ax2.set_ylim(r_rimin, r_rimax)
ax2.set_xlim(150, 270)
ax2.set_ylim(30, 218)
ax2.set_title("Normalized R vs. Normalized I")

ax3.contour(image_iz, levels_iz)
#ax3.set_xlim([0.10870964061586308, 0.7513928898988901])
#ax3.set_ylim([0.16554822316263784, 0.38463948541428344])
ax3.set_xlabel("Z")
ax3.set_ylabel("I")
#ax3.set_xticks(ind)
#ax3.set_yticks(ind)
x_ind = np.arange(start = z_izmin, stop = z_izmax, step=interval)
y_ind = np.arange(start = i_izmin, stop = i_izmax, step=interval)
z_ticks = np.around(np.linspace(z_min_u, z_max_u, len(x_ind)),2)
i_ticks = np.around(np.linspace(i_min_u, i_max_u, len(y_ind)),2)
ax3.set_xticks(x_ind)
ax3.set_yticks(y_ind)
ax3.set_xticklabels(z_ticks)
ax3.set_yticklabels(i_ticks)
#ax3.set_xlim(z_izmin, z_izmax)
#ax3.set_ylim(i_izmin, i_izmax)
ax3.set_xlim(90, 300)
ax3.set_ylim(150, 280)
ax3.set_title("Normalized I vs. Normalized Z")

ax4.contour(image_gz,levels_gz)
#ax4.set_xlim([0.10870964061586297, 0.75139288989889])
#ax4.set_ylim([-0.024987318641646213, 0.3752023775010975])
ax4.set_xlabel("Z")
ax4.set_ylabel("G")
#ax4.set_xticks(ind)
#ax4.set_yticks(ind)
x_ind = np.arange(start = z_gzmin, stop = z_gzmax, step=interval)
y_ind = np.arange(start = g_gzmin, stop = g_gzmax, step=interval)
z_ticks = np.around(np.linspace(z_min_u, z_max_u, len(x_ind)),2)
g_ticks = np.around(np.linspace(g_min_u, g_max_u, len(y_ind)),2)
ax4.set_xticks(x_ind)
ax4.set_yticks(y_ind)
ax4.set_xticklabels(z_ticks)
ax4.set_yticklabels(g_ticks)
#ax4.set_xlim(z_gzmin, z_gzmax)
#ax4.set_ylim(g_gzmin, g_gzmax)
ax4.set_xlim(100, 300)
ax4.set_ylim(0, 230)
ax4.set_title("Normalized G vs. Normalized Z")
fig.suptitle("True Fluxes Scaled and Pixelated")
plt.savefig("Scaled_And_Pixelated_True.png")

# Compute KL-Divergence using two scaled images

#image_gr_q = np.where(image_gr_q < np.amin(image_gr_p[np.where(image_gr_p != 0)]), 0, image_gr_q)
image_gr_div = np.where(image_gr_q != 0, image_gr_p/image_gr_q, 1)
image_gr_diff = np.where(image_gr_p != 0, image_gr_p * np.log(image_gr_div), 0)
print(np.sum(image_gr_diff))

image_ri_div = np.where(image_ri_q != 0, image_ri_p/image_ri_q, 1)
image_ri_diff = np.where(image_ri_p != 0, image_ri_p * np.log(image_ri_div), 0)
print(np.sum(image_ri_diff))

image_iz_div = np.where(image_iz_q != 0, image_iz_p/image_iz_q, 1)
image_iz_diff = np.where(image_iz_p != 0, image_iz_p * np.log(image_iz_div), 0)
print(np.sum(image_iz_diff))

image_gz_div = np.where(image_gz_q != 0, image_gz_p/image_gz_q, 1)
image_gz_diff = np.where(image_gz_p != 0, image_gz_p * np.log(image_gz_div), 0)
print(np.sum(image_gz_diff))

with open('fits_kl_values.txt', 'w') as filehandle:
    filehandle.write('kl value for gr: ' + str(np.sum(image_gr_diff)) + '\n')
    filehandle.write('kl value for ri: ' + str(np.sum(image_ri_diff)) + '\n')
    filehandle.write('kl value for iz: ' + str(np.sum(image_iz_diff)) + '\n')
    filehandle.write('kl value for gz: ' + str(np.sum(image_gz_diff)) + '\n')

#image_gr = np.zeros([g_diff, r_diff],dtype=np.double)
#image_ri = np.zeros([r_diff, i_diff],dtype=np.double)
#image_iz = np.zeros([i_diff, z_diff],dtype=np.double)
#image_gz = np.zeros([g_diff, z_diff,],dtype=np.double)

#d=4
##factor_arr = np.repeat([20], d, axis = 0)
#count = 0
##print(count_samples)
#for i in range(len(count_samples)):
#    num_samples = count_samples[i]
#    for j in range(count, count + num_samples):
#        #diff = bin_xmean[i][j]-xmean[i]
#        #print(samples[j])
#        diff = old_samples[j] - xmean[i]
#        scalar = np.matmul(np.matmul(diff.T, li.inv(V[i])), diff)
#        #gaussian =np.power((2*np.pi),(-d/2)) * np.power(li.det(V[j]),-1/2)* np.exp((-1/2)*scalar)
#        gaussian = (2*np.pi)**(-d/2) * (li.det(V[i]))**(-1/2)* np.exp((-1/2)*scalar)
#        (g, r, i, z) = np.asarray(samples[j, :], np.int32)
##        print(g)
#        image_gr[g - g_min, r - r_min] += xamp[i] * gaussian
#        image_ri[r - r_min, i - i_min] += xamp[i] * gaussian
#        image_iz[i - i_min, z - z_min] += xamp[i] * gaussian
#        image_gz[g - g_min, z - z_min] += xamp[i] * gaussian
#    count += num_samples


import pandas as pd
import re

class DataSaver(object):
    def __init__(self):
        pass

    @classmethod
    def save(cls, file_path, data):
        file_type = re.split(re.compile(r'\.'), file_path)[-1]
        if file_type == 'csv':
            return cls.saveCsv(file_path, data)
        elif file_type == 'xls' or file_type == 'xlsx':
            return cls.saveXls(file_path, data)
        else:
            return None

    @classmethod
    def saveCsv(cls, file_path, data):
        df = pd.DataFrame(data)
        df.to_csv(file_path)
        return True

    @classmethod
    def saveXls(cls, file_path, data):
        df = pd.DataFrame(data)
        df.to_excel(file_path)
        return True


from typing import Dict, List, Union

import numpy as np
from maggma.builders import MapBuilder
from maggma.core import Store
from pymatgen import Structure

from emmet.core import SETTINGS
from emmet.core.vasp.calc_types import run_type, task_type
from emmet.core.vasp.task import TaskDocument
from emmet.core.vasp.validation import DeprecationMessage, ValidationDoc

__author__ = "Shyam Dwaraknath"
__email__ = "shyamd@lbl.gov"

class TaskValidator(MapBuilder):
    def __init__(
        self,
        tasks: Store,
        task_validation: Store,
        kpts_tolerance: float = SETTINGS.VASP_KPTS_TOLERANCE,
        **kwargs,
    ):
        """
        Creates task_types from tasks and type definitions

        Args:
            tasks: Store of task documents
            task_validation: Store of task_types for tasks
            input_sets: dictionary of task_type and pymatgen input set to validate against
            kpts_tolerance: the minimum kpt density as dictated by the InputSet to require
            LDAU_fields: LDAU fields to check for consistency
        """
        self.tasks = tasks
        self.task_validation = task_validation
        self.kpts_tolerance = kpts_tolerance

        self.kwargs = kwargs

        super().__init__(
            source=tasks,
            target=task_validation,
            projection=["orig_inputs", "output.structure", "input.parameters"],
            **kwargs,
        )

    def unary_function(self, item):
        """
        Find the task_type for the item

        Args:
            item (dict): a (projection of a) task doc
        """
        task_doc = TaskDocument(**item)
        return ValidationDoc.from_task_doc(task_doc=task_doc).dict()


# Copyright (C) 2020 Google Inc.
# Licensed under http://www.apache.org/licenses/LICENSE-2.0 <see LICENSE file>
"""Module for Mega mixin"""
from collections import defaultdict

import flask
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declared_attr

from ggrc import db
from ggrc.builder import simple_property
from ggrc.models import relationship
from ggrc.models import reflection
from ggrc.models.inflector import get_model

class Mega(object):
  """Mixin adds methods for Mega objects
  Mega objects can have mapped objects of the same type"""

  _api_attrs = reflection.ApiAttributes(
      reflection.Attribute('is_mega', create=False, update=False),
  )

  @simple_property
  def is_mega(self):
    """Returns True if object have children"""
    return bool(self._child_relationships)

  @declared_attr
  def _child_relationships(cls):  # pylint: disable=no-self-argument
    """Return relationships to children
    used to eagerly query is_mega property"""
    joinstr = (
        "and_(foreign(Relationship.source_id) == {cls_name}.id,"
        "foreign(Relationship.source_type) == '{cls_name}',"
        "foreign(Relationship.destination_type) == '{cls_name}')"
    )
    return db.relationship(
        "Relationship",
        primaryjoin=joinstr.format(cls_name=cls.__name__),
    )

  @classmethod
  def eager_query(cls, **kwargs):
    """Define fields to be loaded eagerly to lower the count of DB queries."""
    query = super(Mega, cls).eager_query(**kwargs)
    return query.options(
        sa.orm.subqueryload('_child_relationships').load_only("id")
    )

  @classmethod
  def get_all_relatives_ids(cls, _id, direction):
    """Returns ids of relatives for all generations

    Args:
        _id: ID of Mega object
        direction: could be 'parents' or 'children'
    Returns:
        set of ids
    """
    visited = set()
    not_visited = {_id, }
    while not_visited:
      visited.update(not_visited)
      not_visited = cls._get_relatives_for(direction, not_visited)
      not_visited -= visited
    return visited - {_id}

  @classmethod
  def get_relatives_ids(cls, _id, direction):
    """Returns ids of relatives for one generation

    Args:
        _id: ID of Mega object
        direction: could be 'parents' or 'children'
    Returns:
        set of ids
    """
    return cls._get_relatives_for(direction, {_id}) - {_id}

  @classmethod
  def _get_relatives_for(cls, direction, nodes):
    """Return set of ids of relatives of nodes in selected direction

    Args:
        direction: could be 'parents' or 'children'
        nodes: set of mega objects to find relatives for in selected direction
    Returns:
        set of ids"""
    rel = relationship.Relationship

    if direction == "children":
      direction_filter = rel.source_id.in_
      next_nodes_attr = "destination_id"
    elif direction == "parents":
      direction_filter = rel.destination_id.in_
      next_nodes_attr = "source_id"
    else:
      raise ValueError("Unknown value for direction attr")

    relationships = rel.query.filter(
        direction_filter(nodes),
        rel.source_type == cls.__name__,
        rel.destination_type == cls.__name__,
    )
    return set(getattr(r, next_nodes_attr) for r in relationships)

  @staticmethod
  def _is_parent_for(parent, obj):
    """Check that 'parent' is parent for 'obj'
    Cache parents ids for mega"""
    if hasattr(flask.g, "mega_parents_cache"):
      mega_parents_cache = flask.g.mega_parents_cache
    else:
      mega_parents_cache = flask.g.mega_parents_cache = defaultdict(dict)

    if obj.id in mega_parents_cache[obj.type]:
      parents_ids = mega_parents_cache[obj.type][obj.id]
    else:
      obj_model = get_model(obj.type)
      parents_ids = obj_model.get_all_relatives_ids(obj.id, "parents")
      mega_parents_cache[obj.type][obj.id] = parents_ids
    return parent.id in parents_ids

  @classmethod
  def skip_automapping(cls, src, dst, dst_related_obj):
    """Skip automappings from Mega to child"""
    # In case we mapped an object to Mega we should skip
    # mapping of the object to not parent Mega objects
    # In case of cycle mapping, one Mega object could be parent and child
    to_not_parent = (
        dst_related_obj.type == dst.type and
        not cls._is_parent_for(dst_related_obj, dst)
    )
    # In case we mapped Mega to Mega we should skip mappings of
    # dst related object to src, if src is not parent of dst
    from_not_parent = (
        src.type == dst.type and
        not cls._is_parent_for(src, dst)
    )
    return bool(to_not_parent or from_not_parent)


# Time:  O(a^2 + n), a is the number of ages,
#                    n is the number of people
# Space: O(a)

# 825
# Some people will make friend requests.
# The list of their ages is given and ages[i] is the age of the ith person.
#
# Person A will NOT friend request person B (B != A)
# if any of the following conditions are true:
#
# age[B] <= 0.5 * age[A] + 7
# age[B] > age[A]
# age[B] > 100 && age[A] < 100
# Otherwise, A will friend request B.
#
# Note that if A requests B, B does not necessarily request A.
# Also, people will not friend request themselves.
#
# How many total friend requests are made?
#
# Example 1:
#
# Input: [16,16]
# Output: 2
# Explanation: 2 people friend request each other.
# Example 2:
#
# Input: [16,17,18]
# Output: 2
# Explanation: Friend requests are made 17 -> 16, 18 -> 17.
# Example 3:
#
# Input: [20,30,100,110,120]
# Output:
# Explanation: Friend requests are made 110 -> 100, 120 -> 110, 120 -> 100.
#
# Notes:
# - 1 <= ages.length <= 20000.
# - 1 <= ages[i] <= 120.

try:
    xrange          # Python 2
except NameError:
    xrange = range  # Python 3

import collections

class Solution(object):
    # answer depends on ages not people, so we should COMPRESS data first by merge people w/ same age.
    # otherwise LTE with repeating calculation of people w/ same ages.
    def numFriendRequests(self, ages): # USE THIS
        """
        :type ages: List[int]
        :rtype: int
        """
        def request(a, b):
            return 0.5*a+7 < b <= a

        c = collections.Counter(ages)
        ans = 0
        for a in c:
            for b in c:
                if request(a, b):
                    ans += c[a]*c[b] if a != b else c[a]*(c[a]-1)
        return ans

    def numFriendRequests_ming(self, ages): # similar to the above, but separate a-a and a-b, more clearly
        cnt = collections.Counter(ages)
        ans = sum(cnt[k]*(cnt[k]-1) for k in cnt if k > 14)

        # sort so only consider one way
        unique = sorted(cnt)
        for i in range(len(unique)):
            for j in range(i):
                ans += int(unique[j] > (0.5*unique[i]+7)) * cnt[unique[i]] * cnt[unique[j]]
        return ans

    def numFriendRequests_bookshadow(self, ages): # 不用看了
        '''
        观察题设条件 1 <= ages[i] <= 120，年龄的范围很小, 统计每一个年龄的人数
        遍历每个人，统计符合其年龄条件约束的人数之和
        '''
        cnt = collections.Counter(ages)
        ans = 0
        for age in ages:
            cnt[age] -= 1
            left, right = age / 2 + 8, age
            ans += sum(cnt[age] for age in range(left, right + 1))
            cnt[age] += 1
        return ans

print(Solution().numFriendRequests([69, 24, 85, 8, 85])) # 4


from django.core.management.base import BaseCommand
from hearthstone import cardxml
from ...models import Card

class Command(BaseCommand):
	def add_arguments(self, parser):
		parser.add_argument("path", nargs="?", help="CardDefs.xml file")
		parser.add_argument("--locale", default="enUS")

	def handle(self, *args, **options):
		path = options["path"]
		db, _ = cardxml.load(path, locale=options["locale"])
		self.stdout.write("%i cards available" % (len(db)))

		qs = Card.objects.all().values_list("id")
		known_ids = [item[0] for item in qs]
		missing = [id for id in db if id not in known_ids]
		self.stdout.write("%i known cards" % (len(known_ids)))

		new_cards = [Card.from_cardxml(db[id]) for id in missing]
		Card.objects.bulk_create(new_cards)
		self.stdout.write("%i new cards" % (len(new_cards)))


## IMPORTS

import sys
sys.path.append('../api/sql wrapper')
import sql_wrapper as wrapper

from urllib.request import urlopen
import urllib
import requests
import webbrowser
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup

from geopy.geocoders import Nominatim

def population_density(city='aurangabad'):
    '''
    GIves the population density of a city
    :param city: cite name
    :return: population density
    '''
    return 366

def calculate_drift(todays_intentensity, yesterdays_intensity, ppd):
    '''
    Calculates drift for a region
    :param todays_intentensity: intensity value for today
    :param yesterdays_intensity: intensity value for yesterday
    :param ppd: population density of that region
    :return: drift
    '''
    return (todays_intentensity - yesterdays_intensity) / ppd

def calculate_intensity(count, ppd, last_drift, last_intensity):
    '''
    calculates intensity for given parameters
    :param count: count of patient
    :param ppd: population density
    :param last_drift: drift of yesterday
    :param last_intensity: drift of today
    :return: intensity
    '''
    current_factor = count / ppd
    inflation_factor = last_drift * last_intensity

    return current_factor + inflation_factor

def threshold(intensity):
    '''
    Gives threshold for epidemic
    :param intensity: today's intensity
    :return: Boolean whether intensity is above threshold or not
    '''
    return intensity >= 0.01

def intensity_and_drift_of_dataframe(df, last_intensity, last_drift):
    '''
    Calculates intensity, drift and epidemic threshold of complete dataframe
    :param df: pandas dataframe
    :param last_intensity: intensity of yesterday
    :param last_drift: drift for yesterday
    :return: (intensity, drift, boolean for epidemic)
    '''

    count = len(df)
    ppd = population_density()

    intensity = calculate_intensity(count, ppd, last_drift, last_intensity)
    drift = calculate_drift(intensity, last_intensity, ppd)
    is_epidemic = threshold(intensity)

    return intensity, drift, is_epidemic

def get_surrounding_pincodes(pincode, sqlWrapper=None):
    '''
    Returns a list of surrounding pincodes of a given pincode
    :param pincode: pincode of the region
    :param sqlWrapper: Optional, if already made an sqlWrapper
    :return: list of surrounding pincodes
    '''
    if sqlWrapper is None:
        sqlWrapper = wrapper.SqlWrapper(password='')
    query = "select pincode from district_pincode where pincode like '" + str(pincode)[:4] + "%'"
    l = sqlWrapper.custom_query(query, single=True)
    return l

def internet_on():
    try:
        response = urlopen('https://www.google.com/', timeout=10)
        return True
    except:
        return False

def geopy_latlong_from_pincode(pincode):
    '''
    Get latlong of a pincode using geopy
    :param pincode: pincode of the area
    :return: (latitude, longitude)
    '''
    geolocator = Nominatim(user_agent="default")
    location = geolocator.geocode(str(pincode), timeout=40)
    if location is None:
        return pincode_to_coordinates(pincode)
    return (location.latitude, location.longitude)

def pincode_to_coordinates(pincode):
    '''
        Function to get coordinates from a zipcode using seleniuim and scraping google searches
        Parameters:
            1. pincode: pincode of the area whose coordinates is to be searched
        Returns:
            tuple of coordinates if found else None
    '''

    if pincode == "" or pincode is None:
        raise Exception('Pincode cannot be empty')

    #     req = requests.get('http://clients3.google.com/generate_204')
    if not internet_on():
        raise Exception('Error: Internet is not connected')

    text = str(pincode) + ' coordinates'
    text = urllib.parse.quote_plus(text)
    url = 'https://google.com/search?q=' + text

    options = Options()
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    driver = webdriver.Chrome(r'C:\chromedriver\chromedriver.exe', chrome_options=options)

    driver.get(url)

    soup = BeautifulSoup(driver.page_source, "lxml")

    for g in soup.findAll('div', {'class': 'Z0LcW'}):
        if ' E' in str(g.text):
            driver.quit()
            lat, long = g.text.split(', ')
            lat = lat.replace('° N', '').strip()
            long = long.replace('° E', '').strip()
            return (lat, long)
    driver.quit()
    return None

def min_max_normalize(vals):
    '''
    Normalizes a pandas series according to min max normalization
    :param vals: pandas series
    :return: narmalized pandas series
    '''
    minimum = vals.min()
    maximum = vals.max()
    denominator = maximum - minimum
    if denominator <=0:
        denominator = 1
    return (vals - minimum) / denominator

# print(pincode_to_coordinates(431002))


##### SYSTEM AND APPIUM,SELENIUM SECTION #####
import time
from appium.webdriver.webelement import WebElement
from selenium.webdriver.common.keys import Keys

##### OUR FRAMEWORK LIB SECTION #####
from lib.core.mobile.assertions import AppiumAssertions
from settings.ios import iOSSettings
from settings.locatorsios import Locators

##### OUR MAIN PAGE TESTS SECTION #####
from tests.ios.mainpage.assertions import MainPageAssertions

class PlacementPage(AppiumAssertions):
    locators = Locators()
    settings = iOSSettings()

    def typeUserTag(self,tester,user_tag,want_to_save="no"):
        self.setTestProcedure("function", "typeUserTag=%s"%user_tag)
        time.sleep(2)
        element = self.getElementById(tester,self.locators.LOC_IOS_PLACEMENT_OPTION_USER_TAG_TEXTFIELD_ID)
        print("element=%s"%element)
        self.typeTextById(user_tag,self.locators.LOC_IOS_PLACEMENT_OPTION_USER_TAG_TEXTFIELD_ID)
        if want_to_save.lower() == "yes":
            self.clickElementById(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_SAVE_ID)

    def typeIncentivized(self,tester,title,body,close_text,continue_text,want_to_save="no"):
        self.setTestProcedure("function", "typeIncentivized")

        self.typeTextById(title,self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_TITLE_TEXTFIELD_ID)
        self.typeTextById(body,self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_BODY_TEXTFIELD_ID)
        self.typeTextById(close_text,self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_CLOSE_TEXTFIELD_ID)
        self.typeTextById(continue_text,self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_CONTINUE_TEXTFIELD_ID)
        time.sleep(3)
        if want_to_save.lower() == "yes":
            self.clickElementById(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_SAVE_ID)

    def clearUserTag(self,tester,want_to_save="no"):
        'clear all the fields belong to user_tag'
        self.setTestProcedure("function", "clearUserTag")
        self.clearTextByXpath(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_USER_TAG_TEXTFIELD_XPATH)
        if want_to_save.lower() == "yes":
            self.clickElementById(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_SAVE_ID)

    def clearIncentivized(self,tester,want_to_save="no"):
        'clear all the fields belong to Incentivized'
        self.setTestProcedure("function", "clearIncentivized")

        self.clearTextByXpath(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_TITLE_TEXTFIELD_XPATH)
        self.clearTextByXpath(tester,self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_BODY_TEXTFIELD_XPATH)
        self.clearTextByXpath(tester,self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_CLOSE_TEXTFIELD_XPATH)
        self.clearTextByXpath(tester,self.locators.LOC_IOS_PLACEMENT_OPTION_INCENTIVIZE_ALERT_CONTINUE_TEXTFIELD_XPATH)
        if want_to_save.lower() == "yes":
            self.clickElementById(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_SAVE_ID)

    def typeFlexFeedSize(self,tester,ad_width,ad_height,want_to_save="no"):
        self.setTestProcedure("function", "typeAlertSize")
        time.sleep(3)
        self.scroll(200, 500, 200, 200, 800)
        self.typeNumericById(ad_width, self.locators.LOC_IOS_PLACEMENT_OPTION_AD_WIDTH_TEXTFIELD_ID)
        time.sleep(2)
        self.typeNumericById(ad_height, self.locators.LOC_IOS_PLACEMENT_OPTION_AD_HEIGHT_TEXTFIELD_ID)
        time.sleep(2)
        if want_to_save.lower() == "yes":
            self.clickElementById(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_SAVE_ID)

    def typeAutoDismiss(self,tester,in_second,want_to_save="no",scroll_down="yes"):
        self.setTestProcedure("function", "typeAutoDismiss")
        time.sleep(3)
        if scroll_down.lower() =="yes":
            self.scroll(200, 500, 200, 200, 800)
        self.clickElementById(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_COLLECTION_VIEW_AD_EXPERIENCE_TEXTVIEW_ID)
        self.typeNumericById(in_second, self.locators.LOC_IOS_PLACEMENT_OPTION_AUTO_DISMISS_TEXTFIELD_ID)
        time.sleep(2)
        if want_to_save.lower() == "yes":
            self.clickElementById(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_SAVE_ID)

    def turnOnViewAdExperience(self,tester):
        self.setTestProcedure("function", "turnOnViewAdExperience")
        element_text = self.getElementTextByXPATH(self.locators.LOC_IOS_PLACEMENT_OPTION_COLLECTION_VIEW_AD_EXPERIENCE_SWITCH_XPATH)
        print("element_text=%s"%element_text)
        if element_text == "0":
            self.clickElementByXPATH(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_COLLECTION_VIEW_AD_EXPERIENCE_SWITCH_XPATH)
        else:
            print("Collection View Ad Experience is already ON . Do nothing!")

    def turnOffViewAdExperience(self,tester):
        self.setTestProcedure("function", "turnOffViewAdExperience")
        element_text = self.getElementTextByXPATH(self.locators.LOC_IOS_PLACEMENT_OPTION_COLLECTION_VIEW_AD_EXPERIENCE_SWITCH_XPATH)
        print("element_text=%s"%element_text)
        if element_text == "1":
            self.clickElementByXPATH(tester, self.locators.LOC_IOS_PLACEMENT_OPTION_COLLECTION_VIEW_AD_EXPERIENCE_SWITCH_XPATH)
        else:
            print("Collection View Ad Experience is already OFF. Do nothing!")

    def getTextFromAppIdField(self):
        self.setTestProcedure("function", "getTextFromAppIdField")
        element_text = self.getElementTextByXPATH(self.locators.LOC_IOS_APP_ID_TEXTBOX_XPATH)
        print("app_id_text=%s"%element_text)
        return element_text.strip()

    def getTextFromApiEndpointField(self):
        self.setTestProcedure("function", "getTextFromApiEndpointField")
        element_text = self.getElementTextByXPATH(self.locators.LOC_IOS_API_ENDPOINT_TEXTBOX_XPATH)
        print("api_endpoint_text=%s"%element_text)
        return element_text.strip()

    def tapDownloadButtonOnFlexFeedEndcard(self):
        self.setTestProcedure("function", "tapDownloadButtonOnFlexFeedEndcard")
        element_x_coord = self.getXCoordinateByXpath(self.locators.LOC_IOS_AD_FLEXFEED_XPATH)
        element_y_coord = self.getYCoordinateByXpath(self.locators.LOC_IOS_AD_FLEXFEED_XPATH)
        size = self.driver.find_element_by_xpath(self.locators.LOC_IOS_AD_FLEXFEED_XPATH).size
        print("size = %s" %size)
        element_width = int(size["width"])
        print("element_width = %s" %element_width)
        element_height = int(size["height"])
        print("element_height = %s" %element_height)
        download_button_x_coord = (element_x_coord + element_width)*(3/4)
        download_button_y_coord = (element_y_coord + element_height)*(7/8)
        print("Tapping on Download button at coordinator: x = %s, y= %s"%(download_button_x_coord, download_button_y_coord))
        self.tapElementByCoordinates(download_button_x_coord, download_button_y_coord)

    def tapDownloadButtonOnFlexViewEndcard(self):
        self.setTestProcedure("function", "tapDownloadButtonOnFlexViewEndcard")
        element_x_coord = self.getXCoordinateByXpath(self.locators.LOC_IOS_AD_FLEXVIEW_XPATH)
        element_y_coord = self.getYCoordinateByXpath(self.locators.LOC_IOS_AD_FLEXVIEW_XPATH)
        size = self.driver.find_element_by_xpath(self.locators.LOC_IOS_AD_FLEXVIEW_XPATH).size
        print("size = %s" %size)
        element_width = int(size["width"])
        print("element_width = %s" %element_width)
        element_height = int(size["height"])
        print("element_height = %s" %element_height)
        download_button_x_coord = (element_x_coord + element_width)*(3/4)
        download_button_y_coord = (element_y_coord + element_height)*(7/8)
        print("Tapping on Download button at coordinator: x = %s, y= %s"%(download_button_x_coord, download_button_y_coord))
        self.tapElementByCoordinates(download_button_x_coord, download_button_y_coord)

    def tapConsentButtons(self, consent_button="I consent"):
        self.setTestProcedure("function", "tapConsentButtons")
        if consent_button=="I consent":
            print("Clicking I consent button")
            self.clickElementById(self, self.locators.LOC_IOS_PLAY_AD_CONSENT_POPUP_I_CONSENT_BUTTON_ID)
        else:
            print("Clicking I do not consent button")
            self.clickElementById(self, self.locators.LOC_IOS_PLAY_AD_CONSENT_POPUP_I_DO_NOT_CONSENT_BUTTON_ID)

    def tapConsentButtonsMraidAd(self, consent_button="I consent"):
        self.setTestProcedure("function", "tapConsentButtonsMraidAd")
        height = self.getScreenHeight()
        width = self.getScreenWidth()
        if consent_button=="I consent":
            print("Clicking I consent button on position x=%s, y=%s"%(width/2, height*(3/4)))
            self.tap_position(width/2, height*(3/4))
        else:
            print("Clicking I do not consent button on position x=%s, y=%s"%(width/2, height*(7/8)))
            self.tap_position(width/2, height*(7/8))

    def tapGdprControlButtons(self, tester, gdpr_button):
        self.setTestProcedure("function", "tapOnGdprControlButton")
        if gdpr_button == "Accept":
            print("Click Accept button")
            self.clickElementById(tester, self.locators.LOC_IOS_GDPR_ACCEPT_BUTTON_ID)
        elif gdpr_button == "Deny":
            print("Click Deny button")
            self.clickElementById(tester, self.locators.LOC_IOS_GDPR_DENY_BUTTON_ID)
        elif gdpr_button == "Get":
            print("Click Get button")
            self.clickElementById(tester, self.locators.LOC_IOS_GDPR_GET_BUTTON_ID)


from Grafo import Grafo
#******************************************************************************
# Librerías para generar valores aleatorios
from random import seed
from random import randint
from random import random
#******************************************************************************
def grafoDorogovtsevMendes (n, dirigido=False):
    '''
    Genera grafo aleatorio con el modelo Dorogovtsev-Mendes
    :param n: número de nodos (≥ 3)
    :param dirigido: el grafo es dirigido?
    :return: grafo generado
    '''

    #Generar objeto grafo
    nombre='grafoDorogovtsevMendes_n_'+str(n)
    grafo = Grafo(nombre,dirigido)

    #si el número de nodos es menor que 3 regresar el grafo vacio
    if n<3:
        print('Error: Al menos debe haber 3 nodos')
        return grafo

    #Generar n nodos
    for i in range(n):
        grafo.agregar_nodo(i)

    #Generar 3 aristas para formar un triángulo con los primeros 3 nodos
    grafo.agregar_arista(0,1)
    grafo.agregar_arista(1,2)
    grafo.agregar_arista(2,0)

    #Si solo hay 3 nodos regresar grafo
    if n==3:
        return grafo

    nodoNuevo = 3 #Empezar por el nodo 4 (contando desde 0)
    while nodoNuevo<n: #Por cada nodo después del tercer nodo
        #Obtener lista de aristas
        aristasDisponibles = list(grafo.aristas.keys())
        #Obterner el total de aristas
        numeroAristas = grafo.totalAristas()

        #Seleccionar arista de manera aleatoria
        aleatorio = randint(0, numeroAristas-1)
        aristaSeleccionada = aristasDisponibles[aleatorio]

        #obtener los nodos extremos de la arista seleccionada
        extremo1=grafo.aristas[aristaSeleccionada].source.id
        extremo2=grafo.aristas[aristaSeleccionada].target.id

        #Crear una arista entre el nodo nuevo y los extremos de
        #la arista seleccionda
        grafo.agregar_arista(nodoNuevo,extremo1)
        grafo.agregar_arista(nodoNuevo,extremo2)

        nodoNuevo+=1

    return grafo


# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models, migrations

class Migration(migrations.Migration):

    dependencies = [
        ('setor', '0001_initial'),
        ('enderecos', '0001_initial'),
    ]

    operations = [
        migrations.CreateModel(
            name='InfoAbst',
            fields=[
                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
                ('nome', models.CharField(max_length=100)),
                ('telefone', models.PositiveIntegerField()),
                ('cpf', models.PositiveIntegerField()),
            ],
            options={
            },
            bases=(models.Model,),
        ),
        migrations.CreateModel(
            name='Funcionario',
            fields=[
                ('infoabst_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='funcionario.InfoAbst')),
                ('matricula', models.PositiveIntegerField()),
                ('salario', models.DecimalField(default=0, max_digits=7, decimal_places=2)),
                ('funcao', models.CharField(max_length=20)),
                ('endereco', models.ManyToManyField(to='enderecos.Endereco')),
                ('setor', models.ForeignKey(to='setor.Setor')),
            ],
            options={
            },
            bases=('funcionario.infoabst',),
        ),
    ]


from __future__ import annotations
from ..platform import platform
from .program import program
from . import common

@program.command(name="api", hidden=True)
def program_api(
    basepath: str = common.basepath,
    root: bool = common.root,
    port: int = common.port,
    debug: bool = common.debug,
):
    """
    Start API server
    """
    module = platform.frictionless_server
    config = module.Config.from_options(
        basepath=basepath,
        is_root=root,
        port=port,
        debug=debug,
    )
    server = module.Server.create(config)
    server.run()


import pandas as pd
import plotly.figure_factory as ff
import plotly.graph_objects as go
import statistics
import csv
import random

df = pd.read_csv("StudentsPerformance.csv")
data = df["reading score"].tolist()

mean = sum(data) / len(data)
std = statistics.stdev(data)
median = statistics.median(data)
mode = statistics.mode(data)

first_std_deviation_start , first_std_deviation_end = mean - std , mean+std
second_std_deviation_start , second_std_deviation_end = mean-(2*std) , mean+(2*std)
third_std_deviation_start , third_std_deviation_end = mean-(3*std) , mean+(3*std)

fig = ff.create_distplot([data], ["reading scores"], show_hist=False)
fig.add_trace(go.Scatter(x=[mean,mean] , y=[0,0.17] , mode ='lines' , name ="MEAN"))
fig.add_trace(go.Scatter(x=[first_std_deviation_start, first_std_deviation_start], y=[0,0.17] ,mode="lines" , name="SD 1"))
fig.add_trace(go.Scatter(x=[first_std_deviation_end, first_std_deviation_end], y=[0,0.17] ,mode="lines" , name="SD 1"))
fig.add_trace(go.Scatter(x=[second_std_deviation_start, second_std_deviation_start], y=[0,0.17] ,mode="lines" , name="SD 2"))
fig.add_trace(go.Scatter(x=[second_std_deviation_end, second_std_deviation_end], y=[0,0.17] ,mode="lines" , name="SD 2"))

list_of_data_within_1_std = [result for result in data if result > first_std_deviation_start and result < first_std_deviation_end]
list_of_data_within_2_std = [result for result in data if result > second_std_deviation_start and result < second_std_deviation_end]
list_of_data_within_3_std = [result for result in data if result > third_std_deviation_start and result < third_std_deviation_end]

print("Mean of this data is {}".format(mean))
print("Median of this data is {}".format(median))
print("Mode of this data is {}".format(mode))
print("SD of this data is {}".format(std))
print("\n")
print("{}% of data lies within 1 Std".format(len(list_of_data_within_1_std)*100.0/len(data)))
print("{}% of data lies within 2 Std".format(len(list_of_data_within_2_std)*100.0/len(data)))
print("{}% of data lies within 3 Std".format(len(list_of_data_within_3_std)*100.0/len(data)))


"""
Command handling for the bot.
"""
import asyncio
import sys
import traceback

import discord
from discord.ext import commands

from discordbot.main import DiscordBot
from discordbot.utils import exceptions

class CommandHandler:
    """
    Command handling for the bot.
    """

    def __init__(self, bot: DiscordBot):
        self.bot = bot

    async def __global_check(self, ctx):

        author = ctx.author
        if await self.bot.is_owner(ctx.author):
            return True

        # user is a bot
        if author.bot:
            return False

        # user is blacklisted
        if author.id in self.bot.ignored.get("users"):
            return False

        perms = ctx.channel.permissions_for(author)
        perm_list = [perms.administrator, perms.manage_messages, perms.manage_guild]
        un_ignore = any(x for x in perm_list)

        # now we can finally realise if we can actually bypass the ignore
        if not un_ignore and ctx.channel.id in self.bot.ignored.get("channels"):
            raise exceptions.Ignored

        return True

    async def on_message_edit(self, before, after):
        """
        Checks message edit to see if I screwed up a command...
        """
        await self.bot.process_commands(after)

    async def on_command_error(self, ctx, error):
        """
        Catch command errors.
        """
        if isinstance(error.__cause__, discord.errors.NotFound):
            return
        elif isinstance(error, exceptions.Ignored):
            await ctx.channel.send("\N{CROSS MARK} This channel is currently being ignored.", delete_after=5)
        elif isinstance(error, commands.errors.NotOwner):
            await ctx.channel.send(f"\N{CROSS MARK} {error}", delete_after=5)
        elif isinstance(error, discord.errors.Forbidden):
            await ctx.channel.send("\N{NO ENTRY} I don't have permission to perform the action", delete_after=5)
        elif isinstance(error, exceptions.ClearanceError):
            await ctx.channel.send(f"\N{NO ENTRY} {error}", delete_after=5)
        elif isinstance(error, commands.errors.CommandNotFound):
            return
        elif isinstance(error, exceptions.EmbedError):
            await ctx.channel.send("\N{NO ENTRY} This command requires the `Embed Links` "
                                   "permission to execute!", delete_after=5)
        elif isinstance(error, commands.errors.NoPrivateMessage):
            await ctx.channel.send("\N{NO ENTRY} That command can not be run in PMs!",
                                   delete_after=5)
            return
        elif isinstance(error, commands.errors.DisabledCommand):
            await ctx.channel.send("\N{NO ENTRY} Sorry, but that command is currently disabled!",
                                   delete_after=5)
        elif isinstance(error, commands.errors.CheckFailure):
            await ctx.channel.send("\N{CROSS MARK} Check failed. You probably don't have "
                                   "permission to do this.", delete_after=5)
        elif isinstance(error, commands.errors.CommandOnCooldown):
            await ctx.channel.send(f"\N{NO ENTRY} {error}", delete_after=5)
        elif isinstance(error, (commands.errors.BadArgument, commands.errors.MissingRequiredArgument)):
            await ctx.channel.send(f"\N{CROSS MARK} Bad argument: {' '.join(error.args)}", delete_after=5)
            formatted_help = await ctx.bot.formatter.format_help_for(ctx, ctx.command)
            for page in formatted_help:
                await ctx.channel.send(page, delete_after=20)
        else:
            await ctx.channel.send("\N{NO ENTRY} An error happened. This has been logged and reported.",
                                   delete_after=5)
            if isinstance(error, commands.errors.CommandInvokeError):
                traceback.print_exception(type(error), error.__cause__, error.__cause__.__traceback__, file=sys.stderr)
            else:
                traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)

    async def on_command(self, ctx):
        author = ctx.author
        if ctx.guild is not None:
            self.bot.command_logger.info(f"[Shard {ctx.guild.shard_id}] {ctx.guild.name} (ID: {ctx.guild.id}) > "
                                         f"{author} (ID: {author.id}): {ctx.message.clean_content}")
        else:
            self.bot.command_logger.info(f"[Shard 0] Private Messages > {author} (ID: {author.id}):"
                                         f" {ctx.message.clean_content}")

    async def on_command_completion(self, ctx):
        self.bot.commands_used[ctx.command.name] += 1
        if not ctx.guild:
            ctx.guild = "PMs"
        self.bot.commands_used_in[str(ctx.guild)] += 1
        await asyncio.sleep(5)
        try:
            await ctx.message.delete()
        except discord.DiscordException:
            pass

def setup(bot: DiscordBot):
    bot.add_cog(CommandHandler(bot))