"""
  Use graph structures to identify chemical functional groups
"""

import itertools
from automol.graph._graph_base import atom_symbol_idxs
from automol.graph._ring import rings
from automol.graph._graph_dep import atom_symbols
from automol.graph._graph_dep import remove_atoms
from automol.graph._graph_dep import atoms_neighbor_atom_keys
from automol.graph._graph_dep import bond_orders
from automol.graph._graph_dep import dominant_resonance
from automol.graph._graph import full_isomorphism
from automol.graph._res import resonance_dominant_radical_atom_keys
from automol.graph._util import ring_idxs
from automol.graph._util import filter_idxs
from automol.graph._util import atom_idx_to_symb

class FunctionalGroup():
    """ Functional groups
    """
    ALCOHOL = 'alcohol'
    PEROXY = 'peroxy'
    HYDROPEROXY = 'hydroperoxy'
    ETHER = 'ether'
    EPOXIDE = 'epoxide'
    ALDEHYDE = 'aldehyde'
    KETONE = 'ketone'
    ESTER = 'ester'
    CARBOX_ACID = 'carboxylic_acid'
    HALIDE = 'halide'
    THIOL = 'thiol'
    # TO ADD
    AMINE = 'amine'
    AMIDE = 'amide'
    NITRO = 'nitro'

def functional_group_dct(gra):
    """ Determine the functional groups for a given molecule.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: dict[str: tuple(int)]
    """

    # Build a dictionary by calling all the functional group functions
    # Certain smaller groups are removed when they are a part of larger groups
    peroxy_grps = peroxy_groups(gra)
    hydroperoxy_grps = hydroperoxy_groups(gra)
    ether_grps = ether_groups(gra)
    epoxide_grps = epoxy_groups(gra)
    carbox_acid_grps = carboxylic_acid_groups(gra)
    ester_grps = ester_groups(gra)
    ether_grps = ether_groups(gra, filterlst=ester_grps)
    alcohol_grps = alcohol_groups(gra, filterlst=carbox_acid_grps)
    aldehyde_grps = aldehyde_groups(gra, filterlst=carbox_acid_grps)
    ketone_grps = ketone_groups(gra, filterlst=carbox_acid_grps+ester_grps)
    # amine_grps = amine_groups(gra)
    amide_grps = amide_groups(gra)
    nitro_grps = nitro_groups(gra)
    halide_grps = halide_groups(gra)
    thiol_grps = thiol_groups(gra)

    # might have to filter it to remove ketone/oh if carbox acids are ther
    func_grp_dct = {
        FunctionalGroup.PEROXY: peroxy_grps,
        FunctionalGroup.HYDROPEROXY: hydroperoxy_grps,
        FunctionalGroup.ETHER: ether_grps,
        FunctionalGroup.EPOXIDE: epoxide_grps,
        FunctionalGroup.CARBOX_ACID: carbox_acid_grps,
        FunctionalGroup.ESTER: ester_grps,
        FunctionalGroup.ALCOHOL: alcohol_grps,
        FunctionalGroup.ALDEHYDE: aldehyde_grps,
        FunctionalGroup.KETONE: ketone_grps,
        # FunctionalGroup.AMINE: amine_grps,
        FunctionalGroup.AMIDE: amide_grps,
        FunctionalGroup.NITRO: nitro_grps,
        FunctionalGroup.HALIDE: halide_grps,
        FunctionalGroup.THIOL: thiol_grps
    }

    return func_grp_dct

# SEARCH FOR CERTAIN OVERARCHING MOLECULE TYPES
def hydrocarbon_species(gra):
    """ Determine if molecule is a hydrocarbon.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: bool
    """
    return bool(set(_unique_atoms(gra)) <= {'C', 'H'})

def radical_species(gra):
    """ Determine if molecule is a radical species.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: bool
    """
    return bool(resonance_dominant_radical_atom_keys(gra))

# SEARCH FOR REACTIVE SITES AND GROUPS
def alkene_sites(gra):
    """ Determine the location alkene groups

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: bool
    """
    return bonds_of_type(gra, symb1='C', symb2='C', mbond=2)

def alkyne_sites(gra):
    """ Determine the location alkyne groups

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: bool
    """
    return bonds_of_type(gra, symb1='C', symb2='C', mbond=3)

def alcohol_groups(gra, filterlst=()):
    """ Determine the location of alcohol groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-O-H atoms
        of the group: (C-idx, O-idx, H-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    alc_grps = two_bond_idxs(gra, symb1='C', cent='O', symb2='H')
    alc_grps = filter_idxs(alc_grps, filterlst=filterlst)

    return alc_grps

def peroxy_groups(gra):
    """ Determine the location of peroxy groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-O-O atoms
        of the group: (C-idx, O-idx, O-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    coo_r_grps = tuple()

    rad_idxs = resonance_dominant_radical_atom_keys(gra)

    coo_grps = two_bond_idxs(gra, symb1='C', cent='O', symb2='O')
    for coo_grp in coo_grps:
        c_idx, o1_idx, o2_idx = coo_grp
        if o2_idx in rad_idxs:
            coo_r_grps += ((c_idx, o1_idx, o2_idx),)

    return coo_r_grps

def hydroperoxy_groups(gra):
    """ Determine the location of hydroperoxy groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-O-O-H atoms
        of the group: (C-idx, O-idx, O-idx, H-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    cooh_grps = tuple()

    coo_grps = two_bond_idxs(gra, symb1='C', cent='O', symb2='O')
    for coo_grp in coo_grps:
        c_idx, o1_idx, o2_idx = coo_grp
        o2_neighs = neighbors_of_type(gra, o2_idx, symb='H')
        if o2_neighs:
            cooh_grps += ((c_idx, o1_idx, o2_idx, o2_neighs[0]),)

    return cooh_grps

def ether_groups(gra, filterlst=()):
    """ Determine the location of ether groups. The locations are
        specified as tuple of idxs indicating the C-O-C atoms
        of the group: (C-idx, O-idx, C-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    ether_grps = tuple()

    # Determing the indices of all rings in the molecule

    _ring_idxs = ring_idxs(rings(gra))

    coc_grps = two_bond_idxs(gra, symb1='C', cent='O', symb2='C')
    for coc_grp in coc_grps:
        c1_idx, o_idx, c2_idx = coc_grp
        if not _ring_idxs:
            ether_grps += ((c1_idx, o_idx, c2_idx),)
        else:
            for idxs in _ring_idxs:
                if not set(coc_grp) <= set(idxs):
                    ether_grps += ((c1_idx, o_idx, c2_idx),)

    ether_grps = filter_idxs(ether_grps, filterlst=filterlst)

    return ether_grps

def epoxy_groups(gra):
    """ Determine the location of 1,2-epoxy groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-O-C atoms
        of the group: (C-idx, O-idx, C-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    epox_grps = tuple()

    # Determing the indices of all rings in the molecule
    _ring_idxs = ring_idxs(rings(gra))

    coc_grps = two_bond_idxs(gra, symb1='C', cent='O', symb2='C')
    for coc_grp in coc_grps:
        c1_idx, o_idx, c2_idx = coc_grp
        if _ring_idxs:
            for idxs in _ring_idxs:
                if set(coc_grp) <= set(idxs):
                    epox_grps += ((c1_idx, o_idx, c2_idx),)

    return epox_grps

def aldehyde_groups(gra, filterlst=()):
    """ Determine the location of aldehyde groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-O atoms
        of the group: (C-idx, O-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    ald_grps = tuple()

    co_bonds = bonds_of_type(gra, symb1='C', symb2='O', mbond=2)
    for co_bond in co_bonds:
        c_idx, o_idx = co_bond
        c_neighs = neighbors_of_type(gra, c_idx, symb='H')
        if c_neighs:
            ald_grps += ((c_idx, o_idx),)

    ald_grps = filter_idxs(ald_grps, filterlst=filterlst)

    return ald_grps

def ketone_groups(gra, filterlst=()):
    """ Determine the location of ketone groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-O atoms
        of the group: (C-idx, O-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    ket_grps = tuple()

    co_bonds = bonds_of_type(gra, symb1='C', symb2='O', mbond=2)
    for co_bond in co_bonds:
        c_idx, o_idx = co_bond
        c_neighs = neighbors_of_type(gra, c_idx, symb='H')
        if not c_neighs:
            ket_grps += ((c_idx, o_idx),)

    ket_grps = filter_idxs(ket_grps, filterlst=filterlst)

    return ket_grps

def ester_groups(gra):
    """ Determine the location of ester groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C(O)-O-C atoms
        of the group: (C-idx, O-idx, O-idx, C-idx).

        Likely identifies anhydrides as an ester.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    ester_grps = tuple()

    ether_grps = ether_groups(gra)
    ket_grps = ketone_groups(gra)

    for egrp, kgrp in itertools.product(ether_grps, ket_grps):
        c1_idx, o_idx, c2_idx = egrp

        ket_o_idx, ket_c_idx = None, None
        if c1_idx in kgrp:
            ket_o_idx = kgrp[1]
            ket_c_idx, term_c_idx = c1_idx, c2_idx
        elif c2_idx in kgrp:
            ket_o_idx = kgrp[1]
            ket_c_idx, term_c_idx = c2_idx, c1_idx

        if ket_o_idx is not None and ket_c_idx is not None:
            ester_grps += ((ket_o_idx, ket_c_idx, o_idx, term_c_idx),)

    return ester_grps

def carboxylic_acid_groups(gra):
    """ Determine the location of ester groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C(O)-O-H atoms
        of the group: (C-idx, O-idx, O-idx, H-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    carbox_grps = tuple()

    alc_grps = alcohol_groups(gra)
    ket_grps = ketone_groups(gra)

    for agrp, kgrp in itertools.product(alc_grps, ket_grps):
        c_idx_set = list(set(agrp) & set(kgrp))
        if c_idx_set:
            ca_idx, oa_idx, ha_idx = agrp
            _, ok_idx = kgrp
            carbox_grps += ((ok_idx, ca_idx, oa_idx, ha_idx),)

    return carbox_grps

def amide_groups(gra):
    """ Determine the location of amide groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C(O)-O-H atoms
        of the group: (C-idx, O-idx, O-idx, H-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    amide_grps = tuple()

    ket_grps = ketone_groups(gra)
    noc_grps = two_bond_idxs(gra, symb1='N', cent='O', symb2='C')

    for noc_grp in noc_grps:
        n_idx, o_idx, c_idx = noc_grp
        if (c_idx, o_idx) in ket_grps:
            amide_grps += ((n_idx, o_idx, c_idx),)

    return amide_grps

def nitro_groups(gra):
    """ Determine the location of nitro groups. The locations are
        specified as tuple-of-tuple of idxs indicating the O-N-O atoms
        of the group: (N-idx, O-idx, O-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    return two_bond_idxs(gra, symb1='O', cent='N', symb2='O')

def halide_groups(gra):
    """ Determine the location of halide groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-X atoms
        of the group: (C-idx, X-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """

    hal_grps = tuple()

    symb_idx_dct = atom_symbol_idxs(gra)

    for symb in ('F', 'Cl', 'Br', 'I'):
        hal_idxs = symb_idx_dct.get(symb, ())
        for hal_idx in hal_idxs:
            hal_neighs = neighbors_of_type(gra, hal_idx, symb='C')
            hal_grps += ((hal_neighs[0], hal_idx),)

    return hal_grps

def thiol_groups(gra):
    """ Determine the location of thiol groups. The locations are
        specified as tuple-of-tuple of idxs indicating the C-S-H atoms
        of the group: (C-idx, S-idx, H-idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(int)
    """
    return two_bond_idxs(gra, symb1='C', cent='S', symb2='H')

# FIND GENERIC ATOM AND BOND GROUPS
def _unique_atoms(gra):
    """ Determine the symbols of unique atom types.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :rtype: tuple(str)
    """

    symb_idx_dct = atom_symbol_idxs(gra)

    return tuple(symb_idx_dct.keys())

def chem_unique_atoms_of_type(gra, symb):
    """ For the given atom type, determine the idxs of all the
         chemically unique atoms.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :param symb: atomic symbol to determine symbols for
        :type symb: str
        :rtype: tuple(int)
    """

    # Get the indices for the atom type
    symb_idx_dct = atom_symbol_idxs(gra)
    atom_idxs = symb_idx_dct[symb]

    # Loop over each idx
    uni_idxs = tuple()
    uni_del_gras = []
    for idx in atom_idxs:

        # Remove the atom from the graph
        del_gra = remove_atoms(gra, [idx])

        # Test if the del_gra is isomorphic to any of the uni_del_gras
        new_uni = True
        for uni_del_gra in uni_del_gras:
            iso_dct = full_isomorphism(del_gra, uni_del_gra)
            if iso_dct:
                new_uni = False
                break

        # Add graph and idx to lst if del gra is unique
        if new_uni:
            uni_del_gras.append(del_gra)
            uni_idxs += (idx,)

    return uni_idxs

def bonds_of_type(gra, symb1, symb2, mbond=1):
    """ Determine the indices of all a specific bond
        specified by atom type and bond order.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :param symb1: symbol of atom 1 in the bond
        :type symb1: str
        :param symb2: symbol of atom 2 in the bond
        :type symb2: str
        :param mbond: bond order of desired bond type
        :type mbond: int
        :rtype: tuple(int)
    """

    # Get the dict that relates atom indices to symbols
    idx_symb_dct = atom_symbols(gra)

    # Loop over all the bonds and build a list of ones that match
    _bonds_of_type = tuple()

    _bonds = bonds_of_order(gra, mbond=mbond)
    for bond in _bonds:
        idx1, idx2 = bond
        symb1, symb2 = idx_symb_dct[idx1], idx_symb_dct[idx2]
        if (symb1, symb2) in ((symb1, symb2), (symb2, symb1)):
            _bonds_of_type += ((idx1, idx2),)

    return _bonds_of_type

def bonds_of_order(gra, mbond=1):
    """ Determine the indices of all bonds in a molecule with
        the specified bond order.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :param mbond: bond order of desired bond type
        :type mbond: int
    """

    # Build resonance graph to get the bond orders
    gra = dominant_resonance(gra)
    bond_order_dct = bond_orders(gra)

    mbond_idxs = tuple()
    for bond, order in bond_order_dct.items():
        if order == mbond:
            bnd1, bnd2 = bond
            mbond_idxs += ((bnd1, bnd2),)

    return mbond_idxs

def two_bond_idxs(gra, symb1, cent, symb2):
    """ Determine the triplet of indices of atoms of specified
        types that are connected in a chain by two bonds:
        (symb1_idx, cent_idx, symb2_idx).

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :param symb1: symbol of atom at one end of chain
        :type symb1: str
        :param cent: symbol of atom in the middle of a chain
        :type cent: str
        :param symb2: symbol of atom at other end of chain
        :type symb2: str
    """

    grps = tuple()

    neigh_dct = atoms_neighbor_atom_keys(gra)
    idx_symb_dct = atom_symbols(gra)
    symb_idx_dct = atom_symbol_idxs(gra)

    cent_idxs = symb_idx_dct.get(cent, tuple())
    for cent_idx in cent_idxs:
        neighs = tuple(neigh_dct[cent_idx])
        neigh_symbs = atom_idx_to_symb(neighs, idx_symb_dct)
        if neigh_symbs == (symb1, symb2):
            grp_idxs = (neighs[0], cent_idx, neighs[1])
        elif neigh_symbs == (symb2, symb1):
            grp_idxs = (neighs[1], cent_idx, neighs[0])
        else:
            grp_idxs = ()

        if grp_idxs:
            grps += ((grp_idxs),)

    return grps

def neighbors_of_type(gra, aidx, symb):
    """ For a given atom, determine the indices of all the atoms
        which neighbor it that are of the type specified.

        :param gra: molecular graph
        :type gra: molecular graph data structure
        :param aidx: index of atom for which to find neighbors
        :type aidx: int
        :param symb: symbols of desired atom types for neighbors
        :type symb: str
    """

    idx_symb_dct = atom_symbols(gra)
    neighs = atoms_neighbor_atom_keys(gra)[aidx]
    neigh_symbs = atom_idx_to_symb(neighs, idx_symb_dct)

    idxs_of_type = tuple()
    for nidx, nsymb in zip(neighs, neigh_symbs):
        if nsymb == symb:
            idxs_of_type += (nidx,)

    return idxs_of_type


#!/bin/env python

import sys, os
#from typing_extensions import final

# --- Classes

class Menu:
    """XDG Menu class"""

    def __init__(self, dryrun = False):
        """Constructor"""
        self.name = "Lunarc Applications On-Demand"
        self.dir_file = "Lunarc-On-Demand.directory"
        self.items = []
        self.sub_menus = {}
        self.dest_filename = ""
        self.directory_dir = ""
        self._indent_level = 0
        self._tab = "    "
        self.dryrun = dryrun

    def _write_header(self, f):
        """Writes menu header"""
        f.write('<!DOCTYPE Menu PUBLIC "-//freedesktop//DTD Menu 1.0//EN"\n')
        f.write('  "http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd">\n')

    def _indent(self):
        """Increase indentation level"""
        self._indent_level += 1

    def _dedent(self):
        """Decrease indentation level"""
        if self._indent_level > 0:
            self._indent_level -= 1

    def _tag_value(self, f, name, value):
        """Write a single line tag value"""
        f.write(self._tab * self._indent_level + "<%s>%s</%s>\n" % (name, value, name))

    def _tag(self, f, name):
        """Begin a tag"""
        f.write(self._tab * self._indent_level + "<%s>\n" % (name))

    def _close_tag(self, f, name):
        """End a tag"""
        f.write(self._tab * self._indent_level + "</%s>\n" % (name))

    def _begin_tag(self, f, name):
        """Begin a tag and increas indent"""
        self._tag(f, name)
        self._indent()

    def _end_tag(self, f, name):
        """End a tag and decreas indentation"""
        self._dedent()
        self._close_tag(f, name)

    def _write_dir_entry(self, filename, name):
        """Write directory entry"""

        try:

            f = None

            if self.dryrun:
                f = sys.stdout
                f.write("direntry = "+filename+"\n")
            else:
                f = open(filename, "w")

            f.write("[Desktop Entry]\n")
            f.write("Type = Directory\n")
            f.write("Name = %s\n" % name)
            f.write("Icon = /usr/share/icons/mate/48x48/actions/lunarc.png\n")

        except PermissionError:
            print("Menu: Couldn't write, %s, check permissions." % filename)
        finally:
            if not self.dryrun:
                if f!=None:
                    f.close()

            # [Desktop Entry]
            # Type = Directory
            # Name = Python
            # Icon = / usr / share / icons / mate / 48
            # x48 / actions / lunarc.png

    def write(self):
        """Write menu XML"""
        if self.dest_filename == "":
            return

        try:

            f = None
            dir_entries = None

            if self.dryrun:
                f = sys.stdout
            else:
                f = open(self.dest_filename, "w")

            self._write_header(f)

            self._begin_tag(f, "Menu")
            self._tag_value(f, "Name", "Applications")
            self._begin_tag(f, "Menu")
            self._tag_value(f, "Name", self.name)
            self._tag_value(f, "Directory", self.dir_file)
            self._begin_tag(f, "Include")

            for item in self.items:
                self._tag_value(f, "Filename", item)

            self._end_tag(f, "Include")

            dir_entries = []

            for key in list(self.sub_menus.keys()):
                self._begin_tag(f, "Menu")
                self._tag_value(f, "Name", key)
                self._tag_value(f, "Directory", key.replace(" ", "_")+".directory")
                dir_entries.append([key, key.replace(" ", "_")+".directory"])
                self._begin_tag(f, "Include")
                for item in self.sub_menus[key]:
                    self._tag_value(f, "Filename", item)
                self._end_tag(f, "Include")
                self._end_tag(f, "Menu")

            self._end_tag(f, "Menu")
            self._end_tag(f, "Menu")

            #< Menu >
            #< Name > Python < / Name >
            #< Directory > Python.directory < / Directory >
            #< Include >
            #< Filename > Paraview.desktop < / Filename >
            #< / Include >
            #< / Menu >

        except PermissionError:
            print("Menu: Couldn't write, %s, check permissions" % self.dest_filename)
            return
        finally:
            if not self.dryrun:
                if f!=None:
                    f.close()

        for dir_entry in dir_entries:
            filename = os.path.join(self.directory_dir, dir_entry[1])
            self._write_dir_entry(filename, dir_entry[0])

class DesktopEntry:
    """Implements a XDG menu entry"""

    def __init__(self, dryrun):
        self._version = "1.0"
        self._type = "Application"
        self.terminal = False
        self.icon = ""
        self.name = "Entry"
        self.exec_file = ""
        self.filename = ""
        self.dryrun = dryrun

    def write(self):
        """Write desktop entry"""
        if self.filename == "":
            return

        try:

            f = None

            if self.dryrun:
                f = sys.stdout
                f.write("desktop entry = "+self.filename+"\n")
            else:
                f = open(self.filename, "w")

            f.write("[Desktop Entry]\n")
            f.write("Name=%s\n" % self.name)
            f.write("Type=%s\n" % self._type)
            if self.terminal:
                f.write("Terminal=true\n")
            else:
                f.write("Terminal=false\n")

            if self.icon != "":
                f.write("Icon=%s\n" % self.icon)

            if self.exec_file != "":
                f.write("Exec=%s\n" % self.exec_file)

            if not self.dryrun:
                f.close()

        except PermissionError:
            print("DesktopEntry: Couldn't write, %s, check permissions. " % self.filename)
        finally:
            if not self.dryrun:
                if f!=None:
                    f.close()


import pandas as pd
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
import datetime
import community
import community.community_louvain
from community.community_louvain import modularity
import easygraph as eg
import random
import copy
from sklearn.cluster import AffinityPropagation

pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

# load the dataset
print("loading the dataset...")
path = '../yelp_dataset/'
users = pd.read_json(path + 'yelp_academic_dataset_user.json', orient='columns', lines=True)
users = users[["user_id", "friends"]]
total_users = users.shape[0]
print(users.shape)
# print(users.head())

print("getting the whole user graph...")

# add nodes
G = eg.Graph()
G.add_nodes_from(users['user_id'])
print("adding nodes...")

# add edges
edge_list = []

def relationship(row):
    if row['friends'] != 'None':
        edge_list.extend([(row['user_id'], x.strip()) for x in str(row['friends']).split(',')])

users.apply(relationship, axis=1)
print("size of edge_list:" + str(len(edge_list)))
print("adding edges into the graph...")
G.add_edges_from(edge_list)

# CDF of degree

# degree
print("getting the degree...")
degree = list(dict(G.degree()).values())

# only take the degree<100
degree = [x for x in degree if x <= 100]
min_degree = min(degree)
print(min_degree)
print(degree.count(min_degree))
res_freq = stats.relfreq(degree, numbins=100)
cdf_value = np.cumsum(res_freq.frequency)
cdf_value = cdf_value*100
x = res_freq.lowerlimit + np.linspace(0, res_freq.binsize * res_freq.frequency.size, res_freq.frequency.size)
plt.xlabel("Degree")
plt.ylabel("CDF(%)")
plt.ylim(0, 100)
plt.xlim(0, 100)
plt.plot(x, cdf_value)
plt.savefig('CDF_of_degree.png')
plt.show()

# Connected Components

print('getting major connected components ...')
connected_components = list(nx.connected_components(G))
num = []
for i in range(len(connected_components)):
    num.append(len(connected_components[i]))
num.sort(reverse=True)

print('The number of connected components in the raw network:'+str(len(num)))
users_num = G.number_of_nodes()
print("total users: {}".format(users_num))
for i in range(10):
    print("Component {}: {} users".format(i, num[i]))

plt.xlabel("Top 10 connected component")
plt.ylabel("Component size")
plt.yscale("log")
x = ['1st','2nd','3rd','4th','5th','6th','7th','8th','9th','10th']
plt.bar(x, num[0:10])
plt.savefig('size_of_top10_connected_components.png')
plt.show()

# CDF of clustering coefficient

print("getting the subgraph...")
# sample
sub_users = users.sample(frac=0.3, replace=False, axis=0, random_state=None)
sub_G = G.subgraph(sub_users['user_id'])
print(sub_G.number_of_nodes())
print(sub_G.number_of_edges())

print("getting clustering coefficient...")
# pre_time = datetime.datetime.now()
# get CC of the whole network
CC = nx.clustering(sub_G)
CC = list(dict(CC).values())

min_CC = min(CC)
print("min CC:" + str(min(CC)))
print("node at min CC:" + str(CC.count(min_CC)))

res_freq = stats.relfreq(CC, numbins=100)
cdf_value = np.cumsum(res_freq.frequency)
cdf_value = cdf_value*100
x = res_freq.lowerlimit + np.linspace(0, res_freq.binsize * res_freq.frequency.size, res_freq.frequency.size)
plt.xlabel("Clustering Coefficient")
plt.ylabel("CDF(%)")
plt.xlim(xmin=0)
plt.ylim(0, 100)
plt.plot(x, cdf_value)
plt.savefig('CDF_of_CC.png')
plt.show()

print("average clustering coefficient: {}".format(np.mean(CC)))

# Modularity

# Louvain Algorithm
print("Applying Louvain Algorithm...")
partition = community.community_louvain.best_partition(G)
modularity = modularity(partition, G)
print("modularity:" + str(modularity))

# CDF of size of community

print()
print("getting CDF of size of community...")
num_communities = max(partition.values()) + 1
print("the number of community:" + str(num_communities))
community_sizes = [0] * num_communities  # 用于存储每个社区的节点数量
for node, community_id in partition.items():
    community_sizes[community_id] += 1
print(max(community_sizes))
print(min(community_sizes))
print(np.mean(community_sizes))
community_list = pd.DataFrame(columns=['size'],data=community_sizes)

# print(size_of_community)
res_freq = stats.relfreq(community_sizes , numbins=100)
cdf_value = np.cumsum(res_freq.frequency)
cdf_value = cdf_value*100
x = res_freq.lowerlimit + np.linspace(0, res_freq.binsize * res_freq.frequency.size, res_freq.frequency.size)
plt.xlabel("size of community")
plt.ylabel("CDF(%)")
# plt.xlim(xmin=0)
plt.ylim(0, 100)
plt.plot(x, cdf_value)
# plt.savefig('CDF_of_size_of_community.png')
plt.show()

# 下面只考虑nonsingleton
nonsingleton = [x for x in community_sizes if x>1]
nonsingleton.sort()
print()
print("getting nonsingleton users...")
nonsingleton_count = len(nonsingleton)
print("nonsingleton_count" + str(nonsingleton_count))
nonsingleton_avg_size = np.average(nonsingleton)
print("avg size:" + str(nonsingleton_avg_size))
nonsingleton_user_count = sum(nonsingleton)
print("nonsingleton user count:" + str(nonsingleton_user_count))


import requests
import json
headers={
    "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36",
    "Accept": "*/*"
}
def get_data_file(headers):
    url="https://www.landingfolio.com/"
    r=requests.get(url=url, headers=headers)
    with open("index.html", 'w', encoding="utf-8") as file:
        file.write(r.text)

    page=0
    result_list=[]
    img_count=0
    while True:
        url=f'https://www.landingfolio.com/api/inspiration?page={page}&sortBy=most-popular'
        responce=requests.get(url=url,headers=headers)
        data=responce.json()

        for item in data:
            if 'screenshots' in item:
                images=item.get('images')

                for img in images:
                    img.update({"url": f"https://landingfoliocom.imgix.net/{img.get('url')}"})
                result_list.append(
                {
                    'title': item.get('title'),
                    'url': item.get('url'),
                    'images': images

                }
                )
            else:
                with open('result_list.json', 'a',encoding='utf-8') as file:
                    json.dump(result_list,file, ensure_ascii=False,indent=4)
                return f"'[INFO]' Work finished."

        print(f"[+] Proceesed {page}")
        page += 1

def download_imgs(file_path):
    pass

def main():
   get_data_file(headers=headers)

if __name__ == '__main__':
    main()


class Solution:
    def solve(self, A, n):
        if not n:
            return 'First'

        cnt = 0
        for i in range(n):
            if A[i] < i+1:
                cnt += ((i + 1) - A[i])

        if cnt % 2 != 0:
            return 'First'
        else:
            return 'Second'

if __name__ == '__main__':
    S = Solution()
    T = int(input())
    for _ in range(T):
        N = int(input())
        A = list(map(int, input().split()))
        print(S.solve(A, N))

March Long Challenge 2021/4. Space Arrays.py


import glob
import os
import re

import dpgen.auto_test.lib.abacus as abacus

def make_refine(init_from_suffix, output_suffix, path_to_work):
    cwd = os.getcwd()
    init_from = re.sub(
        output_suffix[::-1], init_from_suffix[::-1], path_to_work[::-1], count=1
    )[::-1]
    if not os.path.exists(init_from):
        raise FileNotFoundError("the initial directory does not exist for refine")

    output = path_to_work
    init_from_task_tot = glob.glob(os.path.join(init_from, "task.[0-9]*[0-9]"))

    task_num = len(init_from_task_tot)

    task_list = []
    for ii in range(task_num):
        output_task = os.path.join(output, "task.%06d" % ii)
        os.makedirs(output_task, exist_ok=True)
        os.chdir(output_task)
        for jj in [
            "INCAR",
            "POTCAR",
            "POSCAR.orig",
            "POSCAR",
            "conf.lmp",
            "in.lammps",
            "STRU",
        ]:
            if os.path.exists(jj):
                os.remove(jj)
        task_list.append(output_task)
        init_from_task = os.path.join(init_from, "task.%06d" % ii)
        if not os.path.exists(init_from_task):
            raise FileNotFoundError(
                "the initial task directory does not exist for refine"
            )

        if os.path.isfile(os.path.join(init_from_task, "INPUT")) and os.path.isfile(
            os.path.join(init_from_task, "STRU")
        ):
            # if there has INPUT and STRU files in this path, we believe this is a ABACUS job
            CONTCAR = abacus.final_stru(init_from_task)
            POSCAR = "STRU"
        else:
            CONTCAR = "CONTCAR"
            POSCAR = "POSCAR"
        contcar = os.path.join(init_from_task, CONTCAR)
        init_poscar = os.path.join(init_from_task, POSCAR)
        if os.path.exists(contcar):
            os.symlink(os.path.relpath(contcar), POSCAR)
        elif os.path.exists(init_poscar):
            os.symlink(os.path.relpath(init_poscar), POSCAR)
        else:
            raise FileNotFoundError(
                f"no {CONTCAR} or {POSCAR} in the init_from directory"
            )
    os.chdir(cwd)

    return task_list


class Solution(object):
    def searchRange(self, nums, target):
        """
        :type nums: List[int]
        :type target: int
        :rtype: List[int]
        """
        ans=[-1,-1]
        if not nums or len(nums) ==0:
            return  ans
        ans[0] = self.leftSide(nums,target)
        ans[1] = self.rightSide(nums,target)
        return  ans
    def leftSide(self,nums,target):

        left =0
        right = len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] == target:
                if mid >0 :
                    if nums[mid-1] != target:
                        return mid
                    else:
                        right = mid-1
                else:
                    return  mid
            elif nums[mid] > target:
                right = mid-1
            else:
                left = mid+1
        return  -1
    def rightSide(self,nums,target):
        left =0
        right = len(nums)-1
        while left <= right:
            mid = (left+right)//2
            if nums[mid] == target:
                if mid < len(nums)-1 :
                    if nums[mid+1] != target:
                        return mid
                    else:
                        left = mid+1
                else:
                    return  mid
            elif nums[mid] > target:
                right = mid-1
            else:
                left = mid+1
        return  -1

if __name__ == '__main__':

    so = Solution()
    print(so.searchRange([5, 7, 7, 8, 8, 10],18))


__author__ = 'Azatris'

import logging
import sys
import numpy as np

from trainer import Mac
import network
import mnist_loader

""" Sandbox. """

# The logging initialization should be more general and taken out of run.py.
log = logging.root
log.setLevel(logging.DEBUG)
formatter = logging.Formatter("[%(levelname)s %(asctime)s] %(message)s", "%H:%M:%S")
handler_stream = logging.StreamHandler(sys.stdout)
handler_stream.setFormatter(formatter)
log.addHandler(handler_stream)

tr_d, va_d, te_d = mnist_loader.load_data_revamped()

# Subset the data
data_size = 5000
tr_d = (np.asarray(tr_d[0][:data_size]), np.asarray(tr_d[1][:data_size]))

architecture = [784, 400, 400, 10]
net = network.Network(architecture, 0.1)
trainer = Mac(
    net,
    tr_d,
    va_d)
trainer.train()


# use instead !!!
# pip install enasearch
# it useless!!!!!

"""
For wgs_set
"""
import requests
import json
import enasearch

base_url = "https://www.ebi.ac.uk/ena/portal/api/links"
# url_template = f"{base_url}/sample?accession=ERS3641673&format=JSON&result=wgs_set"

def ena_sample(sample_id,result='wgs_set'):

    url = f"{base_url}/sample?accession={sample_id}&format=JSON&result={result}"
    response = requests.get(url, )
    return response

def sample2wgs(sample_id):
    response = ena_sample(sample_id,result='wgs_set')
    if response.status_code != 200:
        return ''
    else:
        out = response.text
        data = json.loads(out)
        return data[0]

def sample2assembly(sample_id):
    response = ena_sample(sample_id,result='assembly')
    if response.status_code != 200:
        return ''
    else:
        out = response.text
        data = json.loads(out)
        return data[0]

data = enasearch.search_data(
    free_text_search=True,
    query="CABMLH010000000",
    result='wgs_set',
    display='xml'
)
data = enasearch.retrieve_data(
    ids="CABMLH010000000",
    display="html")

def get_returnable_fields(result):
    url = f"https://www.ebi.ac.uk/ena/portal/api/returnFields?dataPortal=ena&format=json&result={result}"
    response = requests.get(url, )
    out = response.text
    data = json.loads(out)
    return data
returnable_fields = get_returnable_fields('wgs_set')
returnable_fields = [_['columnId'] for _ in returnable_fields]

def file_report(sample_id):
    fields = ','.join(returnable_fields)
    url = f"https://www.ebi.ac.uk/ena/portal/api/filereport?accession={sample_id}&fields={fields}&format=json&result=wgs_set"
    response = requests.get(url, )
    out = response.text
    data = json.loads(out)
    return data

returnable_fields_assembly = get_returnable_fields('assembly')
returnable_fields_assembly = [_['columnId'] for _ in returnable_fields_assembly]

def file_report_assembly(sample_id):
    fields = ','.join(returnable_fields_assembly)
    url = f"https://www.ebi.ac.uk/ena/portal/api/filereport?accession={sample_id}&fields={fields}&format=json&result=assembly"
    response = requests.get(url, )
    out = response.text
    data = json.loads(out)
    return data

from tqdm import tqdm
s2info = {}
record_failed = []
for _ in tqdm(t):
    try:
        s2info[_] = file_report(_)
    except:
        record_failed.append(_)
cmds = []
for acc,_dict in s2info.items():
    url = _dict[0]['fasta_file']
    name = url.split('/')[-1]
    cmd = f"wget {url} -O ./rawdata/extra_data/fna/{name}"
    cmds.append(cmd)
from subprocess import check_call
for cmd in cmds:
    check_call(cmd,shell=1)

s2assembly_info = {}
for _f in record_failed:
    s2assembly_info[_f] = file_report_assembly(_f)


class Inventory:
    def __init__(self, max_capacity):
        self.max_capacity = max_capacity
        self.items = {}
        self.items_Qty = 0

    def add_item(self, name, price, quantity):
        if name in self.items:
            return (False)

        elif self.items_Qty + quantity > self.max_capacity:
            return (False)

        else:
            self.items[name] = {"name": name, "price": price, "quantity": quantity}
            self.items_Qty += quantity
            return (True)

    def delete_item(self, name):
        if name in self.items:
            self.items_Qty -= self.items[name]["quantity"]
            del self.items[name]
            return (True)

        else:
            return (False)

    def get_items_in_price_range(self, min_price, max_price):
        items_in_range = []

        for item in self.items.values():
            item_price = item["price"]
            item_name = item["name"]

            if item_price > min_price and item_price < max_price:
                items_in_range.append(item_name)
        print (items_in_range)

    def get_most_stocked_item(self):
        biggest_qty = 0
        biggest_qty_name = None

        for item in self.items.values():
            bqty = item["quantity"]
            bname = item["name"]

            if bqty > biggest_qty:
                biggest_qty = bqty
                biggest_qty_name = bname
        return biggest_qty_name

i = Inventory(4)
i.add_item('Chocolate', 4.99, 1)
i.add_item('Cereal', 6.99, 1)
i.add_item('Milk', 3.99, 2)
i.add_item('Butter', 2.99, 1)
i.delete_item('Bread')
i.delete_item('Cereal')
i.get_items_in_price_range(4.50, 6.50)
i.get_most_stocked_item()


import os
import sys

import torchvision.transforms as T
from PIL import Image
import matplotlib.pyplot as plt
from torchvision.datasets import ImageFolder

if __name__ == '__main__':

    img_shape = (224, 224)
    folder_name = r'C:\Users\c22056054\OneDrive - Cardiff University\Desktop\SM\Semester-II\Applications of Machine Learning\datasets_coursework2\Flickr\Flickr'
    save_folder_name = r'C:\Users\c22056054\OneDrive - Cardiff University\Desktop\SM\Semester-II\Applications of Machine Learning\datasets_coursework2\Resized_FI'

    if not os.path.isdir(save_folder_name):
        print('Creating Reshaped images dataset...')
        os.mkdir(save_folder_name)
    classes = os.listdir(folder_name)

    for clas in classes:

        if not os.path.isdir(os.path.join(save_folder_name, clas)):
            print('Creating folder of class', clas)
            os.mkdir(os.path.join(save_folder_name, clas))

        class_name = os.path.join(folder_name, clas)
        files = os.listdir(class_name)

        for file in files:
            file_name = os.path.join(class_name, file)
            save_file_name = os.path.join(save_folder_name, clas, file)
            # print(save_file_name)
            # define the transforms
            img = Image.open(file_name)

            transform = T.Resize((224, 224))
            resized_img = transform(img)

            resized_img.save(save_file_name)


import sys      #paramètre et fonction propres au system [sys.argv}
import json     #api encode/decode json
import argparse #facilite l'écriture d'interfaces de ligne de commande conviviale
import inspect  #méthode pour founir des informations sur class fonctin objet
import os       #permet d'interagir avec le système os et acces aux infos system
import subprocess#gestion génère de nouveau processus remplace des modules ou fonctions plus anciennes
import site     #configuration hook crochet
import importlib#permet de charger des modules au fur et à mesure ou utilise des obj perso
from importlib import reload#recharge un module précédemment importé par le programme

# Import stuff common to all tools
if '..' not in sys.path:
    sys.path.insert(0, '..') #ajoute .. retour dans le path en position 0 début

import tools_common

# Now import the codecs
tools_common.update_path_to_get_module('payloadcodecs')

import payloadcodecs.cnssrf.frame as cnssrf_frame

# Check if we are running on Windows
running_on_Windows = (sys.platform == 'Windows' or sys.platform == 'win32')
to_ascii           = running_on_Windows

serial_port  = None
key_listener = None

EXIT_CODE_OK             = 0
EXIT_CODE_STOP           = 1
EXIT_CODE_NO_SERIAL_PORT = 2
EXIT_CODE_IMPORT_ERROR   = 3

def exit_program(exit_code):
    global serial_port
    global key_listener

    if serial_port:  serial_port .close()
    if key_listener: key_listener.stop()

    if exit_code == EXIT_CODE_STOP:
        print("Bye! See you soon...")

    os._exit(exit_code)

#detecte et propose d'installer les packages manquant
def install_and_import_module(package_name, confirm, required, import_name = None):
    if not import_name:
        import_name = package_name

    # Print some user messages
    required_msg = "optionnal"
    if required:
        required_msg = "required"
    print("Python module '{0}' is not installed on your computer; this module is {1}.".format(
        package_name, required_msg),
        file = sys.stderr)
    print("Your computer must be connected to Internet to install Python modules.")
    input("Press 'Enter' key.")

    # Ask for confirmation
    if confirm:
        c = ''
        while len(c) != 1:
            c = input("Do you wish to install '{0}' module [Y/n]?:".format(package_name))
        if c == 'n' or c == 'N':
            return False

    # Install mosule using pip
    print("Installing '{0}' Python module...".format(package_name))
    subprocess.call([sys.executable, '-m', 'pip', 'install', package_name])

    # update sys.path; just in case.
    reload(site)

    # Import module
    try:
        importlib.invalidate_caches()
        importlib.import_module(import_name)
    except ImportError:
        print("ERROR: failed to import '{0}' Python module. Try to restart the application.".format(package_name),
              file = sys.stderr)
        exit_program(EXIT_CODE_IMPORT_ERROR)

    return True

# Import pyserial
try:
    import serial
except ImportError:
    install_and_import_module('pyserial', False, True, 'serial')
import serial.tools.list_ports

# Import pynput
has_pynput  = False
if running_on_Windows:
    try:
        import pynput
        has_pynput = True
    except ImportError:
        has_pynput = install_and_import_module('pynput', True, False)
        has_pynput

        if not has_pynput:
            print(
        """WARNING: Failed to import 'pynput' module.
This module is not needed but without it you cannot exit program using a key press.""",
                file = sys.stderr)

 #decode les données du port série
def bytes_to_string(b):

    if to_ascii:
        return b.decode('ascii', 'replace')

    s = None
    try:
        s = b.decode('utf-8')
    except UnicodeDecodeError:
        pass
    if not s:
        try:
            s = b.decode('cp1252')
        except UnicodeDecodeError:
            pass
    if not s:
        try:
            s = b.decode('latin-1')
        except UnicodeDecodeError:
            pass
    if not s:
        try:
            s = b.decode('iso8859-15')
        except UnicodeDecodeError:
            pass
    if not s:
        print("Error: can't decode log line.")
        return ''

    return s

 #appelle la fonction frame et depuis frame:
#frame appelle les datatypes pour décodé le payload
def process_log_line(line):
    line = bytes_to_string(line).rstrip('\r\n') #transforme les bytes en string et on enlève le \r\n
    print(line)
    if "|CNSSRF payload:" in line:
        payload_index = line.rfind(':')
        if payload_index == -1:
            # This should not happen
            pass
        payload_index = payload_index + 1;#on positionne le curseur de lecture au niveau du payload+1 pour l'espace
        while line[payload_index] in [' ', '/t']:
            payload_index = payload_index + 1
        payload = line[payload_index : ]  # +1 to remove space character after colon
        print(payload)
        #transforme notre string payload pour créer un objets bytes à partir
        #d'une chaîne de chiffres hexadécimaux
        payload = bytes.fromhex(payload)  # Convert hexas string to bytes array
        res     = cnssrf_frame.decode_payload(payload)
        print(json.dumps(res, sort_keys = True, indent = 2, ensure_ascii = to_ascii))

def get_port(port):
    if port is not None:
        return port

    # Go through the ports to see if there is only one candidate
    ports          = serial.tools.list_ports.comports();
    nb_candidates  = 0
    last_candidate = None
    for port in ports:
        if 'ttyUSB' in port.device or 'COM' in port.device:
            nb_candidates  = nb_candidates + 1
            last_candidate = port.device
    if nb_candidates == 0:
        print("""No serial port has been detected.
Make sure that your adaptator is plugged in or use the -p (--port) command line switch to specify the port to use.""",
            file = sys.stderr)
        exit_program(EXIT_CODE_NO_SERIAL_PORT)
    elif nb_candidates == 1:
        return last_candidate

    # More than one candidate; display a list for the user to choose from
    print("Choose port from this list:")
    i = 0
    for port in ports:
        print("{0}: {1}".format(i, port.device))
        i = i + 1
    i = int(input("Number of port to use: "))
    return ports[i].device

def key_press(key):
    if key.char == 'q':
        exit_program(EXIT_CODE_STOP)

def main():
    global serial_port
    global key_listener

    # Parse command line arguments
    parser = argparse.ArgumentParser("ConnecSenS logs serial console")
    parser.add_argument('-p', '--port',  default = None)
    parser.add_argument('-s', '--speed', default = 115200, type = int)
    args = parser.parse_args()

    port = get_port(args.port)

    # Build exit message
    msg = "'Ctrl+C'"
    if running_on_Windows:
        msg = "'Ctrl+Break' ('Ctrl+Pause' on French keyboard)"
    if has_pynput:
        msg = "'q' key or " + msg
    print("Press " + msg + " key(s) to quit application.")

    # Start key listener if ther is one
    if has_pynput:
        key_listener = pynput.keyboard.Listener(on_press = key_press)
        key_listener.start()

    print("Serial port '{0}' opened at {1} bauds".format(port, args.speed))
    serial_port = serial.Serial(port, args.speed)
    try:
        while True:
            process_log_line(serial_port.readline())
    except KeyboardInterrupt:
        exit_program(EXIT_CODE_STOP)
    exit_program(EXIT_CODE_OK)

if __name__ == "__main__":
	main()
os.system("pause")


import sys
input = sys.stdin.readline
sys.setrecursionlimit(100000) # 최대 크기가 250x250 이라 재귀 많이 함

def dfs(row, col):
    global sheep, wolf
    if grid[row][col] == 'o':
        sheep += 1
    elif grid[row][col] == 'v':
        wolf += 1
    """DFS 순회 하면서 해당 영역(같은 울타리 내)에 늑대와 양이 몇 마리 있는지 카운트
       그 후 둘 중에 큰 값을 최종 정답에 추가
    """

    visited[row][col] = 1
    for dx, dy in zip([0, 0, 1, -1], [1, -1, 0, 0]):
        nx = row + dx
        ny = col + dy

        if nx < 0 or nx >= r or ny < 0 or ny >= c:
            continue
        if visited[nx][ny] or grid[nx][ny] == '#':
            continue

        dfs(nx, ny)

r, c = map(int, input().split())
ans = [0, 0]  # 전체 양과 늑대의 값 저장
grid = [list(input()) for _ in range(r)]
visited = [[0] * c for _ in range(r)]

for i in range(r):
    for j in range(c):
        if not visited[i][j] and grid[i][j] != '#':
            sheep, wolf = 0, 0  # 양과 늑대 초기값 (영역 별로 초기화)
            dfs(i, j)

            if sheep > wolf:
                ans[0] += sheep
            else:
                ans[1] += wolf

print(ans[0], ans[1])


__author__ = "Jianfeng Sun"
__version__ = "v1.0"
__copyright__ = "Copyright 2023"
__license__ = "GPL v3.0"
__email__ = "jianfeng.sunmt@gmail.com"
__maintainer__ = "Jianfeng Sun"

def Color(color, sel_name):
    """PyMOL color a chain"""

    from pymol import cmd

    cmd.color(color=color, selection=sel_name)
    # cmd.spectrum(
    #     palette=sm_c,
    #     selection="sm"
    # )


from fastapi import APIRouter, Depends, HTTPException, status
from yaml.tokens import ValueToken
from sql.apis.schemas.requests.aws.sagemaker_request import (
    CreateTrainingJob,
    TrainingJob,
)
from sql.apis.schemas.responses.aws.sagemaker_response import (
    TrainingJobResponse,
    TrainingStatus,
)
from sql.controllers.aws.sagemaker_controller import SagemakerController
from fastapi.security import OAuth2PasswordBearer
from commons.auth import decodeJWT

oauth2_scheme = OAuth2PasswordBearer(tokenUrl="user/login")
sagemaker_router = APIRouter()

@sagemaker_router.post(
    "/aws/sagemaker/start_training_job", response_model=TrainingJobResponse
)
def start_training_job(
    create_training_job_request: CreateTrainingJob, token: str = Depends(oauth2_scheme)
):
    if decodeJWT(token=token):
        response = SagemakerController().start_training_job_controller(
            create_training_job_request
        )
        return TrainingJobResponse(**response)
    else:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid access token",
            headers={"WWW-Authenticate": "Bearer"},
        )

@sagemaker_router.post(
    "/aws/sagemaker/stop_training_job", response_model=TrainingStatus
)
def stop_training_job(
    stop_training_job_request: TrainingJob, token: str = Depends(oauth2_scheme)
):
    if decodeJWT(token=token):
        response = SagemakerController().stop_training_job_controller(
            stop_training_job_request
        )
        return TrainingStatus(**response)
    else:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid access token",
            headers={"WWW-Authenticate": "Bearer"},
        )

@sagemaker_router.post("/aws/sagemaker/describe_training_job")
def describe_training_job(
    describe_training_job_request: TrainingJob, token: str = Depends(oauth2_scheme)
):
    if decodeJWT(token=token):
        response = SagemakerController().describe_training_job_controller(
            describe_training_job_request
        )
        return TrainingStatus(**response)
    else:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid access token",
            headers={"WWW-Authenticate": "Bearer"},
        )

@sagemaker_router.get("/aws/sagemaker/list_training_job")
def list_training_job(token: str = Depends(oauth2_scheme)):
    if decodeJWT(token=token):
        response = SagemakerController().list_training_job_controller()
        return response
    else:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid access token",
            headers={"WWW-Authenticate": "Bearer"},
        )


def improve_k_flip(graph, k=3):
    vertex_to_flip = [None] * k
    for i in range(k):
        max_cost = 0
        for vertex in graph.vertices():
            if not vertex.is_locked():
                cost = 0
                for incident_edge in graph.incident_edges(vertex):
                    opposite_vertex = incident_edge.opposite(vertex)

                    if opposite_vertex.partition() != vertex.partition() ^ opposite_vertex.is_locked():
                        cost -= incident_edge.element()
                    else:
                        cost += incident_edge.element()
                if cost > max_cost:
                    max_cost = cost
                    if vertex_to_flip[i] is not None:
                        vertex_to_flip[i].lock(False)
                    vertex.lock(True)
                    vertex_to_flip[i] = vertex

    return vertex_to_flip


text_in = "Infix : "
text_pre = "Prefix : "

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

    def __str__(self):
        return str(self.data)
class Stack:
    def __init__(self):
        self.items = []

    def is_empty(self):
        return len(self.items) == 0

    def size(self):
        return len(self.items)

    def push(self, data):
        self.items.append(data)

    def pop(self):
        if not self.is_empty():
            return self.items.pop()

class BST:
    def __init__(self):
        self.root = None

    def insert(self, data):
        if self.root is None:
            self.root = Node(data)
        else:
            root = self.root
            while True:
                if data < root.data:
                    if root.left is None:
                        root.left = Node(data)
                        break
                    root = root.left
                else:
                    if root.right is None:
                        root.right = Node(data)
                        break
                    root = root.right
        return self.root
    def printTree(self, node, level=0):
        if node is not None:
            self.printTree(node.right, level + 1)
            print('     ' * level, node)
            self.printTree(node.left, level + 1)
def infix(T):
    global text_in
    if T is not None:
        if T.left is not None or T.right is not None:
            text_in += "("
        infix(T.left)
        text_in += str(T.data)
        infix(T.right)
        if T.left is not None or T.right is not None:
            text_in += ")"

def prefix(T):
    global text_pre
    if T is not None:
        text_pre += str(T.data)
        prefix(T.left)
        prefix(T.right)

inp = input("Enter Postfix : ")
T = BST()
s = Stack()
for ch in inp:
    if ch in '+-*/':
        op1 = s.pop()
        op2 = s.pop()
        s.push(Node(ch, op2, op1))
    else:
        s.push(Node(ch))
print("Tree :")
T.root = s.pop()
T.printTree(T.root)
print("--------------------------------------------------")
infix(T.root)
print(text_in)
prefix(T.root)
print(text_pre)


def checkSpecialKill(imgbox,imgname):
	specialHightLight=[]
	killway={
		'killbox':'',
		'grenadebox':'',
		'smokebox':'',
		'headshotbox':'',
		'penetrationbox':'',
		'cardiacbox':''
	}
	for i , box in enumerate(imgbox):
		pts = np.array(box).reshape((-1,1,2))
		cv2.polylines(crop_im,[pts],True,(0,255,255),2)
		newim = affine(im,box,imfn,i,120,32)
		text = recogh_model.infer([newim])
		if text != '':
			cv2.putText(padding_image, text, (pts[1,0,0],20*(i+1)), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,255), 1, cv2.LINE_AA)
			res_im = np.concatenate((padding_image, crop_im), axis=0)
			cv2.imwrite("output/{}_text.png".format(imname),res_im)
			if text == 'kill':
				killway['killbox']= pts
			elif text == 'smoke':
				killway['smokebox'] = pts
			elif text == 'grenade':
				killway['grenadebox'] = pts
			elif text == 'cardiac':
				killway['cardiacbox'] = pts
			elif text == 'head':
				killway['headshotbox']=pts
			elif text == 'penetration':
				killway['penetrationbox']=pts

	if  killway['killbox']  is not '':
		killpointy = int(killway['killbox'][0][0][1])
		if  killway['grenadebox'] is not '':
			if int( killway['grenadebox'][3][0][1])+20 > killpointy:
				specialHightLight.append('grenade')
		if  killway['smokebox'] is not'':
			if int( killway['smokebox'][3][0][1])+20 > killpointy:
				specialHightLight.append('smoke')
		if  killway['headshotbox'] is not'':
			if int( killway['headshotbox'][3][0][1])+20 > killpointy:
				specialHightLight.append('head')
		if  killway['penetrationbox'] is not '':
			if int( killway['penetrationbox'][3][0][1])+20 > killpointy:
				specialHightLight.append('penetration')
		if  killway['cardiacbox']  is not'':
			specialHightLight.append('cardiac')
	if len(specialHightLight) is not 0:
		print('specialHightLight   ' + imgname + ':'+str(specialHightLight))


import sys

#from PySide6.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QFileDialog, QMainWindow, QLabel, QMenuBar, QMenu, QTabWidget, QFormLayout, QLineEdit, QHBoxLayout, QRadioButton, QCheckBox, QGridLayout, QSpinBox, QToolButton, QLCDNumber, QFrame, QVBoxLayout, QScrollBar
#from PySide6.QtGui import QCloseEvent, QAction, QKeySequence

#from PySide6.QtCore import Qt

#from PySide6.QtGui import QAction, QIcon, QKeySequence, QScreen, QPalette

#from PySide6.QtCore import QPointF
#from PySide6.QtGui import QPainter
#from PySide6.QtWidgets import QMainWindow, QApplication
#from PySide6.QtCharts import QChart, QChartView, QLineSeries,QScatterSeries,QValueAxis

#from PySide6.QtCore import Slot

from PySide6.QtWidgets import *
from PySide6.QtGui import *
from PySide6.QtCore import *
from PySide6.QtCharts import *

from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qtagg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt

#from qtrangeslider import QRangeSlider

#import gui.toto as toto
#import gui.tab as tab

from ..core import *

from pathlib import Path

import numpy as np

class PowerBar(QWidget):
    def __init__(self,parent=None):
        super(PowerBar, self).__init__(parent)

        layout = QHBoxLayout()

        #self.enable = QCheckBox("Enable")
        #layout.addWidget(self.enable)

        self.firstButton = QToolButton()
        #icon = QIcon.fromTheme("go-first-symbolic.svg")
        icon = QIcon.fromTheme("go-first", QIcon("xlight/icon/go-first.png"))
        self.firstButton.setIcon(icon)
        layout.addWidget(self.firstButton)

        self.previousButton = QToolButton()
        #icon = QIcon.fromTheme("go-previous-symbolic.svg")
        icon = QIcon.fromTheme("go-previous", QIcon("xlight/icon/go-previous.png"))
        self.previousButton.setIcon(icon)
        layout.addWidget(self.previousButton)

        self.lcd = QLCDNumber()
        #self.lcd.resize(40, 40)
        layout.addWidget(self.lcd)

        self.nextButton = QToolButton()
        #icon = QIcon.fromTheme("go-next-symbolic.svg")
        icon = QIcon.fromTheme("go-next", QIcon("xlight/icon/go-next.png"))
        self.nextButton.setIcon(icon)
        layout.addWidget(self.nextButton)

        self.lastButton = QToolButton()
        #icon = QIcon.fromTheme("go-last-symbolic.svg")
        icon = QIcon.fromTheme("go-last", QIcon("xlight/icon/go-last.png"))
        self.lastButton.setIcon(icon)
        layout.addWidget(self.lastButton)

        self.setLayout(layout)

class InfoWidget(QWidget):
    def __init__(self,parent=None):
        super(InfoWidget, self).__init__(parent)

        self.profil=None

        layout = QVBoxLayout()
        self.KhiLabel=QLabel()
        self.PhiLabel=QLabel()
        self.GammaLabel=QLabel()
        self.TimeLabel=QLabel()
        self.AnodeLabel=QLabel()
        self.R2Label=QLabel()
        layout.addWidget(self.KhiLabel)
        layout.addWidget(self.PhiLabel)
        layout.addWidget(self.GammaLabel)
        layout.addWidget(self.TimeLabel)
        layout.addWidget(self.AnodeLabel)
        layout.addWidget(self.R2Label)

        #self.enable = QCheckBox("Enable")
        self.enable = QPushButton()
        self.enable.setCheckable(True)
        layout.addWidget(self.enable)

        #redb = QPushButton('Red', self)
        #redb.setCheckable(True)
        #layout.addWidget(redb)
        #self.enable.stateChanged.connect(lambda:self.stateProfil())
        self.Set()

        self.setLayout(layout)

    def Set(self,profil=None):
        if profil:
            khi="%1.2f" % (profil.Khi)
            self.KhiLabel.setText("\u03c7="+khi+"\u00B0")
            phi="%1.2f" % (profil.Phi)
            self.PhiLabel.setText("\u03c6="+phi+"\u00B0")
            gamma="%1.2f" % (profil.Gamma)
            self.GammaLabel.setText("\u03b3="+gamma+"\u00B0")
            time="%1.2f" % (profil.Time)
            self.TimeLabel.setText("Time="+time+"s")
            self.AnodeLabel.setText("Anode="+str(profil.Anode.name))

            self.KhiLabel.setVisible(True)
            self.PhiLabel.setVisible(True)
            self.GammaLabel.setVisible(True)
            self.TimeLabel.setVisible(True)
            self.AnodeLabel.setVisible(True)
            #self.R2Label.setVisible(True)
            self.enable.setVisible(True)

            if profil.Fun.IsInit:
                R2="%1.3f" % (profil.Fun.r_squared)
                self.R2Label.setText("R\u00b2="+R2)
                self.R2Label.setVisible(True)
            else:
                self.R2Label.setText("R\u00b2=")
                self.R2Label.setVisible(False)
            self.profil=profil
            if profil.IsEnable:
                self.enable.setChecked(True)
            else:
                self.enable.setChecked(False)

            #self.enable.stateChanged.connect(self.stateProfil())
        else:
            self.KhiLabel.setText("\u03c7=")
            self.PhiLabel.setText("\u03c6=")
            self.GammaLabel.setText("\u03b3=")
            self.TimeLabel.setText("Time=")
            self.AnodeLabel.setText("Anode=")
            self.R2Label.setText("R\u00b2=")
            self.KhiLabel.setVisible(False)
            self.PhiLabel.setVisible(False)
            self.GammaLabel.setVisible(False)
            self.TimeLabel.setVisible(False)
            self.AnodeLabel.setVisible(False)
            self.R2Label.setVisible(False)
            self.enable.setChecked(False)
            self.enable.setVisible(False)

        if self.enable.isChecked():
            self.enable.setText("Enable")
            self.enable.setStyleSheet('QPushButton {background-color: green}')
        else:
            self.enable.setText("Disable")
            self.enable.setStyleSheet('QPushButton {background-color: red}')
            #self.profil=None
    #def stateProfil(self):
    #    print("HHH")
    #    if self.profil:
    #        self.profil.SetEnable(self.enable.isChecked())
    #        if self.enable.isChecked():
    #            #self.profil.Enable=True
    #            print("toto")
    #        else:
    #            #self.profil.IsEnable=False
    #            print("tutu")

#from QCharts import *

def format_coord(x, y):
    xlabel=u"2\u03b8="
    ylabel="Intensity="
    xvalue="%1.2f" % (x)
    yvalue="%1.2f" % (y)
    xunity=u"\u00B0"
    yunity=" cps"
    return xlabel+xvalue+xunity+", "+ylabel+yvalue+yunity
    #return '2u\03b8=%1.4f, Intensity=%1.4f' % (x, y)

class InspectWidget(QWidget):
    def __init__(self,parent=None, model=None):
        super(InspectWidget, self).__init__(parent)
        self.model=model

        self.figure = plt.figure()
        self.ax=self.figure.add_subplot(111)

        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)
        #self.toolbar.removeAction('forward')
        unwanted_buttons=['Back','Forward','Subplots','Customize']
        for x in self.toolbar.actions():
            #print(x.text())
            if x.text() in unwanted_buttons:
                self.toolbar.removeAction(x)

        #self.toolbar.toolitems=[('Home', 'Reset original view', 'home', 'home')]
        #self.toolbar = NavigationToolbar(self.canvas)
        self.layout = QGridLayout(self)

        self.Displacement=PowerBar(self)
        self.layout.addWidget(self.Displacement,0,0,1,1)
        self.iprofil=0

        #self.layout.addWidget(self.ChartView,1,0,1,1)
        self.layout.addWidget(self.toolbar,0,1,1,1)
        self.layout.addWidget(self.canvas,1,0,1,2)

        self.info=InfoWidget()
        self.layout.addWidget(self.info,1,2)
        self.info.enable.clicked.connect(lambda:self.ChangeState())
        self.ChangeState()

        self.Displacement.nextButton.clicked.connect(self.Next)
        self.Displacement.lastButton.clicked.connect(self.Last)

        self.Displacement.previousButton.clicked.connect(self.Previous)
        self.Displacement.firstButton.clicked.connect(self.First)

        self.setLayout(self.layout)
        self.SetDisplay()

        return

    def ChangeState(self):
        #print("zzz")
        if self.iprofil>=0 and self.iprofil<len(self.model.profils):
            self.model.profils[self.iprofil].SetEnable(self.info.enable.isChecked())
            self.ReLoad()

    def Next(self):
        self.iprofil+=1
        self.iprofil=min(self.iprofil,len(self.model.profils)-1)
        self.iprofil=max(0,self.iprofil)
        #self.Displacement.lcd.display(self.iprofil+1)
        #self.ReLoad()
        self.SetDisplay()
    def Last(self):
        self.iprofil=len(self.model.profils)-1
        self.iprofil=max(0,self.iprofil)
        #self.Displacement.lcd.display(self.iprofil+1)
        #self.ReLoad()
        self.SetDisplay()

    def Previous(self):
        self.iprofil-=1
        self.iprofil=max(0,self.iprofil)
        #self.Displacement.lcd.display(self.iprofil+1)
        #self.ReLoad()
        self.SetDisplay()
    def First(self):
        self.iprofil=0
        #self.Displacement.lcd.display(self.iprofil+1)
        self.SetDisplay()
        #self.ReLoad()
    def SetDisplay(self):
        self.Displacement.lcd.display(self.iprofil+1)
        self.ReLoad()

    def ReLoad(self):
        self.ax.clear()
        self.ax.set_xlabel(u"2\u03b8 (deg)", fontsize=20)
        self.ax.set_ylabel('Intensity (cps)', fontsize=20)
        self.ax.format_coord = format_coord
        self.figure.tight_layout()

        if self.iprofil>=0 and self.iprofil<len(self.model.profils):
            ppp=self.model.profils[self.iprofil]
            self.info.Set(self.model.profils[self.iprofil])
            self.ax.plot(ppp.TwoTheta,ppp.Intensity,'*-',label="experiment", color='black')
            if ppp.Fun.IsInit and ppp.IsEnable:
                ii=ppp.GetFunctionData(False)
                self.ax.plot(ppp.TwoTheta,ii, '-',label="model", color="red")
        else:
            self.info.Set()

        self.canvas.draw()


class Anna:

    def ana_ener(self, mass: float, height: float) -> None:
        pe = self.ana_pot_ene(mass, height)
        print('i am anna, anna ener')
        return 1000 - pe

    def ana_pot_ene(self, mass:float, height:float):
        pe = mass * 9.81 * height
        print('i am anna, anna pot ene')
        return pe

class Kar:

    def ana_ener(self, mass:float, velocity: float) -> None:
        print('kar')
        ke = 0.5 * mass * velocity ** 2

        return ke

class Yoyota(Kar,Anna):
    def __init__(self, a: float, b: float=100) -> None:

        self.a = a
        self.b = b

        if b is None:
            print("provide val for b")
        else:
            print(self.a)
            print(self.b)
            print(self.ana_ener(5,5))
            print(self.ana_pot_ene(6,6))

            print("created")

    def get_kin(self) -> float:
        print('yoyota get kin')
        return self.ana_ener(self.a, self.b)

def main():
    print('im main')
    ca = Yoyota(1)

if __name__ == "__main__":
    main()


from . import cm_utils, cm_active, cm

def _notsame(a, b, **kwargs):
    params = {'ignore_case': True, 'ignore_no_data': 1}
    for key, val in kwargs.items():
        params[key] = val
    if params['ignore_case']:
        a = a.lower()
        b = b.lower()
    if params['ignore_no_data'] and (a == '-' and b == '-'):  # no data for either
        return False
    if params['ignore_no_data'] > 1 and (a == '-' or b == '-'):  # no data for one
        return False
    if a == 'x' or b == 'x':  # one doesn't have access
        return False
    if a == b:
        return False
    return True

class Checks:
    """Check class."""

    def __init__(self, start_time=2458500, stop_time='now', day_step=1.0):
        """Initialize."""
        self.session = cm.CMSessionWrapper()
        self.active = cm_active.ActiveData(self.session, 'now')
        self.start = cm_utils.get_astropytime(start_time, float_format='jd')
        self.stop = cm_utils.get_astropytime(stop_time, float_format='jd')
        self.step = day_step
        self.chk_same = None

    def info_log(self, look_back=7.0, outfile='info_log.csv'):
        """
        Get all info comments within look_back time (days).
        """
        from cmds import cm_hookup
        import datetime
        print(f"Writing log of last {look_back} days to {outfile}")
        import csv
        look_back = datetime.datetime.now() - datetime.timedelta(days=look_back)
        self.active.load_info(look_back, window=True)
        fnd = {}
        hookup = cm_hookup.Hookup()
        for hpn, data in self.active.info.items():
            if len(data):
                xx = hookup.get_hookup(hpn)
                try:
                    node = xx[hpn].hookup.popitem()[-1][-1].downstream_part
                except:  # noqa
                    node = 'N/A'
            for entry in data:
                key = f"{entry.posting_gpstime}:{hpn}"
                datet = cm_utils.get_astropytime(entry.posting_gpstime, float_format='gps')
                fnd[key] = [hpn, node, entry.comment, datet.isot]

        with open(outfile, 'w') as fp:
            writer = csv.writer(fp)
            for key in sorted(fnd.keys(), reverse=True):
                writer.writerow(fnd[key])

    def for_same(self, sep=',', **kwargs):
        """
        use sep='\t' for pretty and ',' for csv
        """
        if self.chk_same is None:
            print("Run 'check_hosts_ethers' first.")
            return
        for key, data in self.chk_same.items():
            for dev in ['arduino', 'wr', 'snap0', 'snap1', 'snap2', 'snap3']:
                for id in ['serial', 'mac', 'ip']:
                    for _i in range(len(data['source']) - 1):
                        for _j in range(_i + 1, len(data['source'])):
                            if _notsame(data[dev][id][_i], data[dev][id][_j], **kwargs):
                                print(f"{key}-{dev}-{id}", end=sep)
                                print("{}|{}{}{}{}!={}{}".format(data['source'][_i],
                                                                 data['source'][_j], sep,
                                                                 data[dev][id][_i], sep, sep,
                                                                 data[dev][id][_j]))

    def duplicate_comments(self, verbose=False):
        """Check the database for duplicate comments."""
        cmdpre = 'delete from part_info where hpn='
        filename = 'dupcomm.sql'
        self.active.load_info('now')
        duplicates_found = 0
        with open(filename, 'w') as fp:
            for part, comments in self.active.info.items():
                ncomm = len(comments)
                for i in range(ncomm - 1):
                    for j in range(i + 1, ncomm):
                        if comments[i].comment == comments[j].comment:
                            duplicates_found += 1
                            hpn, rev = cm_utils.split_part_key(part)
                            if comments[i].posting_gpstime > comments[j].posting_gpstime:
                                posting_gpstime = comments[i].posting_gpstime
                            else:
                                posting_gpstime = comments[j].posting_gpstime
                            print("{}'{}' and hpn='{}' and posting_gpstime='{}';"
                                  .format(cmdpre, hpn, rev, posting_gpstime), file=fp)
                            if verbose:
                                print(f"{hpn} ({posting_gpstime}): {comments[i]}")
        if duplicates_found:
            print("{} duplicates found".format(duplicates_found))
            print("run 'psql XXX -f {}'".format(filename))
        else:
            print("No duplicates found.")

    def apriori(self):
        """Check for multiple apriori active states between start and stop times."""
        next = self.start
        while next < self.stop:
            print(next.isot)
            print("This doesn't do anything yet")
            self.active.load_apriori(next)
            next += self.step

    def part_conn_assoc(self):
        """
        Check to make sure that all connections have an associated active part.

        The database will allow non-active parts to have a connection, which is not
        desired.  This will check and list connections without an associated active
        part.  It does not Error or Warn, but just lists.

        Returns
        -------
        list
            List of missing parts.
        """
        missing_parts = {}
        next = self.start
        print("Starting check at {}".format(next.isot))
        while next < self.stop:
            self.active.load_parts(next)
            self.active.load_connections(next)
            full_part_set = list(self.active.parts.keys())
            full_conn_set = set(list(self.active.connections['up'].keys())
                                + list(self.active.connections['down'].keys()))
            for key in full_conn_set:
                if key not in full_part_set:
                    if key not in missing_parts:
                        print(self.active.at_date.isot)
                        print("\t{} is not listed as an active part "
                              "even though listed in an active connection.".format(key))
                        try:
                            print('\t', self.active.connections['up'][key])
                        except KeyError:
                            pass
                        try:
                            print('\t', self.active.connections['down'][key])
                        except KeyError:
                            pass
                    missing_parts.setdefault(key, [])
                    missing_parts[key].append(next.gps)
            next += self.step
        print("Stopping check at {}".format(next.isot))
        if len(missing_parts.keys()):
            print('Found the following parts:')
            for key in missing_parts.keys():
                print(f"\t{key}:  {missing_parts[key][0]}")


import pygame
from pygame.locals import *
from sys import exit

def playground():
    pygame.init()
    screen = pygame.display.set_mode((800, 600), 0, 32)
    pygame.display.set_caption('myGame')
    screen.fill((0, 0, 0))
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                exit()
        pygame.display.update()
if __name__ == '__main__':
    playground()


# 11663 : 선분 위의 점
import sys

def binary_search(dots, a, b):  # 이진 탐색
    # 선분에 포함되는 dots의 제일 왼쪽 인덱스 찾기
    start = 0
    end = len(dots)-1
    while start <= end:
        left = (start+end)//2
        if a <= dots[left] <= b:
            end = left-1
        else:
            if dots[left] < a:
                start = left+1
            elif dots[left] > b:
                end = left-1

    # 선분에 포함되는 dots의 제일 오른쪽 인덱스 찾기
    start = 0
    end = len(dots)-1
    while start <= end:
        right = (start+end)//2
        if a <= dots[right] <= b:
            start = right + 1
        else:
            if dots[right] < a:
                start = right + 1
            elif dots[right] > b:
                end = right - 1

    if dots[left] >= a and dots[right] <= b:
        return right-left+1
    if dots[left] < a and dots[right] > b:
        return right-left-1

    return right-left

input = sys.stdin.readline
n, m = map(int, input().split())  # n : 점 수, m : 선분 수
dots = sorted(map(int, input().split()))    # 점 정보
lines = [tuple(map(int, input().split())) for _ in range(m)]    # 선분 정보

for a, b in lines:  # 선분별로 이진탐색
    print(binary_search(dots, a, b))