from threading import Event
import errno
import json
try:
    import queue as Queue
except ImportError:
    import Queue

import cephfs
from mgr_module import MgrModule
import orchestrator

from .fs.subvolume import SubvolumePath, SubvolumeClient

class PurgeJob(object):
    def __init__(self, volume_fscid, subvolume_path):
        """
        Purge tasks work in terms of FSCIDs, so that if we process
        a task later when a volume was deleted and recreated with
        the same name, we can correctly drop the task that was
        operating on the original volume.
        """
        self.fscid = volume_fscid
        self.subvolume_path = subvolume_path

class Module(orchestrator.OrchestratorClientMixin, MgrModule):
    COMMANDS = [
        {
            'cmd': 'fs volume ls',
            'desc': "List volumes",
            'perm': 'r'
        },
        {
            'cmd': 'fs volume create '
                   'name=name,type=CephString '
                   'name=size,type=CephString,req=false ',
            'desc': "Create a CephFS volume",
            'perm': 'rw'
        },
        {
            'cmd': 'fs volume rm '
                   'name=vol_name,type=CephString',
            'desc': "Delete a CephFS volume",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolumegroup create '
                   'name=vol_name,type=CephString '
                   'name=group_name,type=CephString ',
            'desc': "Create a CephFS subvolume group in a volume",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolumegroup rm '
                   'name=vol_name,type=CephString '
                   'name=group_name,type=CephString '
                   'name=force,type=CephBool,req=false ',
            'desc': "Delete a CephFS subvolume group in a volume",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolume create '
                   'name=vol_name,type=CephString '
                   'name=sub_name,type=CephString '
                   'name=size,type=CephInt,req=false '
                   'name=group_name,type=CephString,req=false ',
            'desc': "Create a CephFS subvolume in a volume, and optionally, "
                    "with a specific size (in bytes) and in a specific "
                    "subvolume group",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolume rm '
                   'name=vol_name,type=CephString '
                   'name=sub_name,type=CephString '
                   'name=group_name,type=CephString,req=false '
                   'name=force,type=CephBool,req=false ',
            'desc': "Delete a CephFS subvolume in a volume, and optionally, "
                    "in a specific subvolume group",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolume getpath '
                   'name=vol_name,type=CephString '
                   'name=sub_name,type=CephString '
                   'name=group_name,type=CephString,req=false ',
            'desc': "Get the mountpath of a CephFS subvolume in a volume, "
                    "and optionally, in a specific subvolume group",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolumegroup snapshot create '
                   'name=vol_name,type=CephString '
                   'name=group_name,type=CephString '
                   'name=snap_name,type=CephString ',
            'desc': "Create a snapshot of a CephFS subvolume group in a volume",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolumegroup snapshot rm '
                   'name=vol_name,type=CephString '
                   'name=group_name,type=CephString '
                   'name=snap_name,type=CephString '
                   'name=force,type=CephBool,req=false ',
                   'desc': "Delete a snapshot of a CephFS subvolume group in a volume",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolume snapshot create '
                   'name=vol_name,type=CephString '
                   'name=sub_name,type=CephString '
                   'name=snap_name,type=CephString '
                   'name=group_name,type=CephString,req=false ',
            'desc': "Create a snapshot of a CephFS subvolume in a volume, "
                    "and optionally, in a specific subvolume group",
            'perm': 'rw'
        },
        {
            'cmd': 'fs subvolume snapshot rm '
                   'name=vol_name,type=CephString '
                   'name=sub_name,type=CephString '
                   'name=snap_name,type=CephString '
                   'name=group_name,type=CephString,req=false '
                   'name=force,type=CephBool,req=false ',
            'desc': "Delete a snapshot of a CephFS subvolume in a volume, "
                    "and optionally, in a specific subvolume group",
            'perm': 'rw'
        },

        # volume ls [recursive]
        # subvolume ls <volume>
        # volume authorize/deauthorize
        # subvolume authorize/deauthorize

        # volume describe (free space, etc)
        # volume auth list (vc.get_authorized_ids)

        # snapshots?

        # FIXME: we're doing CephFSVolumeClient.recover on every
        # path where we instantiate and connect a client.  Perhaps
        # keep clients alive longer, or just pass a "don't recover"
        # flag in if it's the >1st time we connected a particular
        # volume in the lifetime of this module instance.
    ]

    def __init__(self, *args, **kwargs):
        super(Module, self).__init__(*args, **kwargs)
        self._initialized = Event()

        self._background_jobs = Queue.Queue()

    def serve(self):
        # TODO: discover any subvolumes pending purge, and enqueue
        # them in background_jobs at startup

        # TODO: consume background_jobs
        #   skip purge jobs if their fscid no longer exists

        # TODO: on volume delete, cancel out any background jobs that
        # affect subvolumes within that volume.

        # ... any background init needed?  Can get rid of this
        # and _initialized if not
        self._initialized.set()

    def handle_command(self, inbuf, cmd):
        self._initialized.wait()

        handler_name = "_cmd_" + cmd['prefix'].replace(" ", "_")
        try:
            handler = getattr(self, handler_name)
        except AttributeError:
            return -errno.EINVAL, "", "Unknown command"

        return handler(inbuf, cmd)

    def _pool_base_name(self, volume_name):
        """
        Convention for naming pools for volumes

        :return: string
        """
        return "cephfs.{0}".format(volume_name)

    def _pool_names(self, pool_base_name):
        return pool_base_name + ".meta", pool_base_name + ".data"

    def _cmd_fs_volume_create(self, inbuf, cmd):
        vol_id = cmd['name']
        # TODO: validate name against any rules for pool/fs names
        # (...are there any?)

        size = cmd.get('size', None)

        base_name = self._pool_base_name(vol_id)
        mdp_name, dp_name = self._pool_names(base_name)

        r, outb, outs = self.mon_command({
            'prefix': 'osd pool create',
            'pool': mdp_name,
            'pg_num': 16,
            'pg_num_min': 16,
        })
        if r != 0:
            return r, outb, outs

        # count fs metadata omap at 4x usual rate
        r, outb, outs = self.mon_command({
            'prefix': 'osd pool set',
            'pool': mdp_name,
            'var': "pg_autoscale_bias",
            'val': "4.0",
        })
        if r != 0:
            return r, outb, outs

        r, outb, outs = self.mon_command({
            'prefix': 'osd pool create',
            'pool': dp_name,
            'pg_num': 8
        })
        if r != 0:
            return r, outb, outs

        # Create a filesystem
        # ====================
        r, outb, outs = self.mon_command({
            'prefix': 'fs new',
            'fs_name': vol_id,
            'metadata': mdp_name,
            'data': dp_name
        })

        if r != 0:
            self.log.error("Filesystem creation error: {0} {1} {2}".format(
                r, outb, outs
            ))
            return r, outb, outs

        # TODO: apply quotas to the filesystem root

        # Create an MDS cluster
        # =====================
        spec = orchestrator.StatelessServiceSpec()
        spec.name = vol_id
        try:
            completion = self.add_stateless_service("mds", spec)
            self._orchestrator_wait([completion])
            orchestrator.raise_if_exception(completion)
        except (ImportError, orchestrator.OrchestratorError):
            return 0, "", "Volume created successfully (no MDS daemons created)"
        except Exception as e:
            # Don't let detailed orchestrator exceptions (python backtraces)
            # bubble out to the user
            self.log.exception("Failed to create MDS daemons")
            return -errno.EINVAL, "", str(e)

        return 0, "", ""

    def _volume_get_fs(self, vol_name):
        fs_map = self.get('fs_map')
        for fs in fs_map['filesystems']:
            if fs['mdsmap']['fs_name'] == vol_name:
                return fs

        # Fall through
        return None

    def _volume_get_mds_daemon_names(self, vol_name):
        fs = self._volume_get_fs(vol_name)
        if fs is None:
            return []

        return [i['name'] for i in fs['mdsmap']['info'].values()]

    def _volume_exists(self, vol_name):
        return self._volume_get_fs(vol_name) is not None

    def _cmd_fs_subvolumegroup_create(self, inbuf, cmd):
        """
        :return: a 3-tuple of return code(int), empty string(str), error message (str)
        """
        vol_name = cmd['vol_name']
        group_name = cmd['group_name']

        if not self._volume_exists(vol_name):
            return -errno.ENOENT, "", \
                   "Volume '{0}' not found, create it with `ceph fs volume create` " \
                   "before trying to create subvolume groups".format(vol_name)

        # TODO: validate that subvol size fits in volume size

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            svc.create_group(group_name)

        return 0, "", ""

    def _cmd_fs_subvolumegroup_rm(self, inbuf, cmd):
        """
        :return: a 3-tuple of return code(int), empty string(str), error message (str)
        """
        vol_name = cmd['vol_name']
        group_name = cmd['group_name']

        force = cmd.get('force', False)

        if not self._volume_exists(vol_name):
            if force:
                return 0, "", ""
            else:
                return -errno.ENOENT, "", \
                       "Volume '{0}' not found, cannot remove subvolume group '{0}'".format(vol_name, group_name)

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            # TODO: check whether there are no subvolumes in the group
            try:
                svc.delete_group(group_name)
            except cephfs.ObjectNotFound:
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume group '{0}' not found, cannot remove it".format(group_name)

        return 0, "", ""

    def _cmd_fs_subvolume_create(self, inbuf, cmd):
        """
        :return: a 3-tuple of return code(int), empty string(str), error message (str)
        """
        vol_name = cmd['vol_name']
        sub_name = cmd['sub_name']

        size = cmd.get('size', None)
        group_name = cmd.get('group_name', None)

        if not self._volume_exists(vol_name):
            return -errno.ENOENT, "", \
                   "Volume '{0}' not found, create it with `ceph fs volume create` " \
                   "before trying to create subvolumes".format(vol_name)

        # TODO: validate that subvol size fits in volume size

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            if group_name and not svc.get_group_path(group_name):
                return -errno.ENOENT, "", \
                    "Subvolume group '{0}' not found, create it with `ceph fs subvolumegroup create` " \
                    "before trying to create subvolumes".format(group_name)
            svp = SubvolumePath(group_name, sub_name)
            svc.create_subvolume(svp, size)

        return 0, "", ""

    def _cmd_fs_subvolume_rm(self, inbuf, cmd):
        """
        :return: a 3-tuple of return code(int), empty string(str), error message (str)
        """
        vol_name = cmd['vol_name']
        sub_name = cmd['sub_name']

        force = cmd.get('force', False)
        group_name = cmd.get('group_name', None)

        fs = self._volume_get_fs(vol_name)
        if fs is None:
            if force:
                return 0, "", ""
            else:
                return -errno.ENOENT, "", \
                       "Volume '{0}' not found, cannot remove subvolume '{1}'".format(vol_name, sub_name)

        vol_fscid = fs['id']

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            if group_name and not svc.get_group_path(group_name):
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume group '{0}' not found, cannot remove subvolume '{1}'".format(group_name, sub_name)
            svp = SubvolumePath(group_name, sub_name)
            try:
                svc.delete_subvolume(svp)
            except cephfs.ObjectNotFound:
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume '{0}' not found, cannot remove it".format(sub_name)
            svc.purge_subvolume(svp)

        # TODO: purge subvolume asynchronously
        # self._background_jobs.put(PurgeJob(vol_fscid, svp))

        return 0, "", ""

    def _cmd_fs_volume_rm(self, inbuf, cmd):
        vol_name = cmd['vol_name']

        # Tear down MDS daemons
        # =====================
        try:
            completion = self.remove_stateless_service("mds", vol_name)
            self._orchestrator_wait([completion])
            orchestrator.raise_if_exception(completion)
        except (ImportError, orchestrator.OrchestratorError):
            self.log.warning("OrchestratorError, not tearing down MDS daemons")
        except Exception as e:
            # Don't let detailed orchestrator exceptions (python backtraces)
            # bubble out to the user
            self.log.exception("Failed to tear down MDS daemons")
            return -errno.EINVAL, "", str(e)

        if self._volume_exists(vol_name):
            # In case orchestrator didn't tear down MDS daemons cleanly, or
            # there was no orchestrator, we force the daemons down.
            r, out, err = self.mon_command({
                'prefix': 'fs set',
                'fs_name': vol_name,
                'var': 'cluster_down',
                'val': 'true'
            })
            if r != 0:
                return r, out, err

            for mds_name in self._volume_get_mds_daemon_names(vol_name):
                r, out, err = self.mon_command({
                    'prefix': 'mds fail',
                    'role_or_gid': mds_name})
                if r != 0:
                    return r, out, err

            # Delete CephFS filesystem
            # =========================
            r, out, err = self.mon_command({
                'prefix': 'fs rm',
                'fs_name': vol_name,
                'yes_i_really_mean_it': True,
            })
            if r != 0:
                return r, out, err
        else:
            self.log.warning("Filesystem already gone for volume '{0}'".format(
                vol_name
            ))

        # Delete pools
        # ============
        base_name = self._pool_base_name(vol_name)
        mdp_name, dp_name = self._pool_names(base_name)

        r, out, err = self.mon_command({
            'prefix': 'osd pool rm',
            'pool': mdp_name,
            'pool2': mdp_name,
            'yes_i_really_really_mean_it': True,
        })
        if r != 0:
            return r, out, err

        r, out, err = self.mon_command({
            'prefix': 'osd pool rm',
            'pool': dp_name,
            'pool2': dp_name,
            'yes_i_really_really_mean_it': True,
        })
        if r != 0:
            return r, out, err

        return 0, "", ""

    def _cmd_fs_volume_ls(self, inbuf, cmd):
        fs_map = self.get("fs_map")

        result = []

        for f in fs_map['filesystems']:
            result.append({
                'name': f['mdsmap']['fs_name']
            })

        return 0, json.dumps(result, indent=2), ""

    def _cmd_fs_subvolume_getpath(self, inbuf, cmd):
        vol_name = cmd['vol_name']
        sub_name = cmd['sub_name']

        group_name = cmd.get('group_name', None)

        if not self._volume_exists(vol_name):
            return -errno.ENOENT, "", "Volume '{0}' not found".format(vol_name)

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            if group_name and not svc.get_group_path(group_name):
                return -errno.ENOENT, "", \
                    "Subvolume group '{0}' not found".format(group_name)
            svp = SubvolumePath(group_name, sub_name)
            path = svc.get_subvolume_path(svp)
            if not path:
                return -errno.ENOENT, "", \
                       "Subvolume '{0}' not found".format(sub_name)
        return 0, path, ""

    def _cmd_fs_subvolumegroup_snapshot_create(self, inbuf, cmd):
        vol_name = cmd['vol_name']
        group_name = cmd['group_name']
        snap_name = cmd['snap_name']

        if not self._volume_exists(vol_name):
            return -errno.ENOENT, "", \
                   "Volume '{0}' not found, cannot create snapshot '{1}'".format(vol_name, snap_name)

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            if group_name and not svc.get_group_path(group_name):
                return -errno.ENOENT, "", \
                    "Subvolume group '{0}' not found, cannot create snapshot '{1}'".format(group_name, snap_name)
            svc.create_group_snapshot(group_name, snap_name)

        return 0, "", ""

    def _cmd_fs_subvolumegroup_snapshot_rm(self, inbuf, cmd):
        vol_name = cmd['vol_name']
        group_name = cmd['group_name']
        snap_name = cmd['snap_name']

        force = cmd.get('force', False)

        if not self._volume_exists(vol_name):
            if force:
                return 0, "", ""
            else:
                return -errno.ENOENT, "", \
                       "Volume '{0}' not found, cannot remove subvolumegroup snapshot '{1}'".format(vol_name, snap_name)

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            if group_name and not svc.get_group_path(group_name):
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume group '{0}' not found, cannot remove subvolumegroup snapshot '{1}'".format(group_name, snap_name)
            try:
                svc.delete_group_snapshot(group_name, snap_name)
            except cephfs.ObjectNotFound:
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume group snapshot '{0}' not found, cannot remove it".format(sub_name)

        return 0, "", ""

    def _cmd_fs_subvolume_snapshot_create(self, inbuf, cmd):
        vol_name = cmd['vol_name']
        sub_name = cmd['sub_name']
        snap_name = cmd['snap_name']

        group_name = cmd.get('group_name', None)

        if not self._volume_exists(vol_name):
            return -errno.ENOENT, "", \
                   "Volume '{0}' not found, cannot create snapshot '{1}'".format(vol_name, snap_name)

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            if group_name and not svc.get_group_path(group_name):
                return -errno.ENOENT, "", \
                    "Subvolume group '{0}' not found, cannot create snapshot '{1}'".format(group_name, snap_name)
            svp = SubvolumePath(group_name, sub_name)
            if not svc.get_subvolume_path(svp):
                return -errno.ENOENT, "", \
                       "Subvolume '{0}' not found, cannot create snapshot '{1}'".format(sub_name, snap_name)
            svc.create_subvolume_snapshot(svp, snap_name)

        return 0, "", ""

    def _cmd_fs_subvolume_snapshot_rm(self, inbuf, cmd):
        vol_name = cmd['vol_name']
        sub_name = cmd['sub_name']
        snap_name = cmd['snap_name']

        force = cmd.get('force', False)
        group_name = cmd.get('group_name', None)

        if not self._volume_exists(vol_name):
            if force:
                return 0, "", ""
            else:
                return -errno.ENOENT, "", \
                       "Volume '{0}' not found, cannot remove subvolume snapshot '{1}'".format(vol_name, snap_name)

        with SubvolumeClient(self, fs_name=vol_name) as svc:
            if group_name and not svc.get_group_path(group_name):
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume group '{0}' not found, cannot remove subvolume snapshot '{1}'".format(group_name, snap_name)
            svp = SubvolumePath(group_name, sub_name)
            if not svc.get_subvolume_path(svp):
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume '{0}' not found, cannot remove subvolume snapshot '{1}'".format(sub_name, snap_name)
            try:
                svc.delete_subvolume_snapshot(svp, snap_name)
            except cephfs.ObjectNotFound:
                if force:
                    return 0, "", ""
                else:
                    return -errno.ENOENT, "", \
                           "Subvolume snapshot '{0}' not found, cannot remove it".format(snap_name)

        return 0, "", ""


def next_palindrome(n):
    indigits = []
    for i in str(n):
        indigits.append(i)
    #isEven = 0
    digits = len(indigits)
    #if digits%2 == 0:
    #    isEven = 1
    #if isEven:
    #else:
    middle = indigits[digits//2]
    i = digits//2

    for j in range(1, (digits-1)//2 + 1):
        indigits[i+j] = indigits[i-j]
    possible = int(''.join(indigits))
    if possible > num:
        return possible
    else:
        if middle!='9':
            indigits[i] = f"{int(middle) + 1}"
            pos1 = int(''.join(indigits))
            return next_palindrome(pos1)

num = 128
print(next_palindrome(num))


class Solution(object):
    def findTargetSumWays(self, nums, S):
        """
        :type nums: List[int]
        :type S: int
        :rtype: int
        """
        if not nums:
            return 0

        if nums[0] != 0:
            buff_dict = {nums[0]:1, -nums[0]: 1}
        else:
            buff_dict = {0: 2}

        for i in range(1,len(nums)):
            temp = {}
            for d in buff_dict:
                temp[d+nums[i]] = temp.get(d+nums[i], 0) + buff_dict.get(d, 0)
                temp[d-nums[i]] = temp.get(d-nums[i], 0) + buff_dict.get(d, 0)
            buff_dict = temp
        return buff_dict.get(S, 0)#default is 0


""" Name- Kishan Sharma
    Roll No - B20294
    Mob no - 8000543233 """
# Python code for Part-A (Lab-5)

# import module from python library
import pandas as pd
from sklearn.mixture import GaussianMixture
from sklearn.metrics import confusion_matrix , accuracy_score

# read the csv file of spilting data of train and test set using pandas library
train_data=pd.read_csv('SteelPlateFaults-train.csv')
test_data=pd.read_csv('SteelPlateFaults-test.csv')

# remove the some data column using drop function
train_data=train_data.drop(columns=[train_data.columns[0],'X_Minimum','Y_Minimum','TypeOfSteel_A300','TypeOfSteel_A400'])
test_data=test_data.drop(columns=[test_data.columns[0],'X_Minimum','Y_Minimum','TypeOfSteel_A300','TypeOfSteel_A400'])

# Classifing the train data basis on classes (class 1 or 0)
train_0=train_data[train_data['Class']==0].drop(columns=['Class'])
train_1=train_data[train_data['Class']==1].drop(columns=['Class'])

# Classifing the TEST data basis on classes (class 1 or 0)
test_0=test_data[test_data['Class']==0].drop(columns=['Class'])
test_1=test_data[test_data['Class']==1].drop(columns=['Class'])

# assume the value of maximum accurancy and corrosponding Q-value
Max_acc=0
Max_acc_Q=2
# Put the all Q-value in a list for GaussianMixture model predection
Q_list=[2,4,8,16]
for Q in Q_list:
    # make the GaussianMixture model for class 0 and class 1 using sklearn library function
    gmm_0 = GaussianMixture(n_components=Q,covariance_type='full',reg_covar=1e-4)
    gmm_1 = GaussianMixture(n_components=Q,covariance_type='full',reg_covar=1e-4)
    gmm_0.fit(train_0)
    gmm_1.fit(train_1)
    # find the probability of sample class of all the test data using score_samples function
    y_0=gmm_0.score_samples(test_data.iloc[:,:23])
    y_1=gmm_1.score_samples(test_data.iloc[:,:23])
    # Predect the class of test data using for loop
    pred=[]
    for i in range(len(y_1)):
        if y_0[i]>y_1[i]:
            pred.append(0)
        else:
            pred.append(1)
    # find the confusion matrix oand accuracy_score of test data for different Q-value
    conf_matrix = confusion_matrix(test_data['Class'],pred)
    predicted_acc=  accuracy_score(test_data['Class'],pred)

    print('Accuracy for the data predicted for ',Q,' components is :', round(predicted_acc,3))
    print("Confusion matrix for Q =",Q," is ---> ")
    print(conf_matrix)
    if(predicted_acc>Max_acc):
        Max_acc=predicted_acc
        Max_acc_Q=Q
    print("------")
# print the highest accuracy and corrosponding Q-value
print("Highest accuracy of the GMM model is: ",Max_acc," for Q: ",Max_acc_Q)
print("-----------------------------------------------------------------------------------")

Data Preprocessing and Modelling/Lab-5/Part-A-Que1.py


from typing import TypedDict, List, Dict

SltxUrl = str
SltxDriver = str
SltxStrPattern = str
SltxStrKey = str

# we use a value constructor to allow for '-' in TypedDict
SltxDependency = TypedDict('SltxDependency', {
   'url': SltxUrl,
   'driver': SltxDriver,
   'grab-files': List[SltxStrPattern]
}, total=False)  # keys are optional

SltxDependencies = Dict[SltxStrKey, SltxDependency]


import os
from time import sleep
from selenium.webdriver.support.select import Select
from webdriver_setup import get_webdriver_for

driver = get_webdriver_for("firefox")

html_page = "file://" + os.getcwd() + "/deselect_option.html"
driver.get(html_page)

select_element = driver.find_element_by_id("langs")

select_object = Select(select_element)

print(f"Multiple selections enabled: {select_object.is_multiple}")

# print all options
print("All options")
for option in select_object.options:
    print(option.text)

sleep(1)

# select three options
select_object.select_by_index(0)
select_object.select_by_value("js")
select_object.select_by_visible_text("Python")

# print all selected options
print("\nSelected options")
for option in select_object.all_selected_options:
    print(option.text)

sleep(1)

# deselect first option
select_object.deselect_by_index(0)

# print all selected options
print("\nSelected options after first deselect")
for option in select_object.all_selected_options:
    print(option.text)

sleep(1)

# deselect all selected options
print("\nDeselect all selected options")
select_object.deselect_all()

print(f"Number of selected options: {len(select_object.all_selected_options)}")

sleep(2)

driver.quit()


from typing import List, Set, Dict, Tuple, Any, Optional, Iterator, Union, Callable
from pathlib import Path
from tqdm import tqdm

import numpy as np
import tensorflow as tf
from tensorflow.keras.models import load_model

from realestate_core.common.run_config import home, bOnColab

import pandas as pd

class ExteriorClassifier:
  def __init__(self):
    self.model_files = [
                           'resnet50_distill_exteriors.acc.0.9106.h5',
                           'resnet50_distill_exteriors.acc.0.9114.h5',
                           'resnet50_distill_exteriors.acc.0.9131.h5',
                           'resnet50_distill_exteriors.acc.0.9116.h5',
                           'resnet50_distill_exteriors.acc.0.9072.h5'
                           ]

    self.labels = ['facade', 'backyard', 'view', 'exterior']

    self.img_height, self.img_width = 224, 224    # exterior classification model take in 224x224 images

  def predict(self,
              batch_img_ds: tf.data.Dataset = None,
              img_array: np.ndarray = None,
              img_names: List[str] = None,
              data_src: str=None,
              return_pd_dataframe=False) -> Union[pd.DataFrame, np.ndarray]:

    # either img_array or batch_img_ds must be provided
    assert (img_array is not None) or (batch_img_ds is not None), 'Either img_array or batch_img_ds must be provided.'

    if img_array is not None:
      assert img_array.shape[1:] == (self.img_height, self.img_width, 3), f'img_array shape must be (N, {self.img_height}, {self.img_width}, 3)'

    inputs = img_array if img_array is not None else batch_img_ds

    y_preds = []
    for m in self.model_files:
      print(m)
      model = load_model(home/'ListingImageClassification'/'training'/'exteriors'/m)
      input_img_height, input_img_width = model.input.shape[1:3]

      assert input_img_height == self.img_height and input_img_width == self.img_width, 'model input shape is not 224x224'

      y_pred = model.predict(inputs)
      y_pred = tf.nn.sigmoid(y_pred).numpy()     # distill model return logits
      y_preds.append(y_pred)

    y_preds = np.stack(y_preds)
    y_pred = np.mean(y_preds, axis=0)

    if not return_pd_dataframe: return y_pred
    else:
      df = self._convert_pred_to_df(y_pred, img_names, data_src)
      return df

  def predict_from_img_paths(self, img_paths: List[Path], return_pd_dataframe=False) -> Union[pd.DataFrame, np.ndarray]:
    if isinstance(img_paths, str) or isinstance(img_paths, Path): img_paths = [img_paths]

    def read_decode_resize(fname):
      img = tf.image.decode_jpeg(tf.io.read_file(fname), channels=3)
      img = tf.image.resize(img, (224, 224), method=tf.image.ResizeMethod.BILINEAR)
      return img

    img_names = [p.name for p in img_paths]
    img_paths = [str(p) for p in img_paths]

    file_ds = tf.data.Dataset.from_tensor_slices(img_paths)
    img_ds = file_ds.map(read_decode_resize, num_parallel_calls=tf.data.AUTOTUNE)

    batch_img_ds = img_ds.batch(32).prefetch(tf.data.AUTOTUNE)

    return self.predict(batch_img_ds, img_names, return_pd_dataframe=return_pd_dataframe)

  def _convert_pred_to_df(self, y_pred: np.ndarray, img_names: List[str], data_src=None) -> pd.DataFrame:
    df = pd.DataFrame(data={
        'img': img_names,
        'p_facade': np.round(y_pred[:, 1].astype('float'), 4),    # first element was an indicator for hard vs. soft labels during training, should ignore during inference.
        'p_backyard': np.round(y_pred[:, 2].astype('float'), 4),
        'p_view': np.round(y_pred[:, 3].astype('float'), 4),
        'p_exterior': np.round(y_pred[:, 4].astype('float'), 4),
        'data_src': data_src
      })

    return df

class GeneralClassifier:
  INOUT_DOOR_CLASS_NAMES = ['indoor', 'other', 'outdoor']
  ROOM_CLASS_NAMES = ['basement', 'bathroom', 'bedroom', 'dining_room', 'garage', 'gym_room', 'kitchen', 'laundry_room', 'living_room', 'office', 'other', 'storage']
  BOOLEAN_FEATURE_CLASS_NAMES = ['fireplace', 'agpool', 'body_of_water', 'igpool', 'balcony', 'deck_patio_veranda', 'ss_kitchen', 'double_sink', 'upg_kitchen']

  def __init__(self):
    self.model_file = home/'ListingImageClassification'/'training'/'hydra_all'/'resnet50_hydra_all.acc.0.9322.h5'

    self.img_height, self.img_width = 416, 416    # general classification model take in 416x416 images

  def predict(self,
              batch_img_ds: tf.data.Dataset = None,
              img_array: np.ndarray = None,
              img_names: List[str] = None,
              data_src: str=None,
              return_pd_dataframe=False) -> Union[pd.DataFrame, np.ndarray]:

    # either img_array or batch_img_ds must be provided
    assert (img_array is not None) or (batch_img_ds is not None), 'Either img_array or batch_img_ds must be provided.'

    if img_array is not None:
      assert img_array.shape[1:] == (self.img_height, self.img_width, 3), f'img_array shape must be (N, {self.img_height}, {self.img_width}, 3)'

    inputs = img_array if img_array is not None else batch_img_ds

    model = load_model(self.model_file, compile=False)
    input_img_height, input_img_width = model.input.shape[1:3]

    assert input_img_height == self.img_height and input_img_width == self.img_width, 'model input shape is not 416x416'

    yhats = model.predict(inputs)
    if not return_pd_dataframe: return yhats

    df = self._convert_pred_to_df(yhats, img_names, data_src)
    return df

  def predict_from_img_paths(self, img_paths: List[Path], return_pd_dataframe=False) -> Union[pd.DataFrame, np.ndarray]:
    if isinstance(img_paths, str) or isinstance(img_paths, Path): img_paths = [img_paths]

    def read_decode_resize(fname):
      img = tf.image.decode_jpeg(tf.io.read_file(fname), channels=3)
      img = tf.image.resize(img, (416, 416), method=tf.image.ResizeMethod.BILINEAR)
      return img

    img_names = [p.name for p in img_paths]
    img_paths = [str(p) for p in img_paths]

    file_ds = tf.data.Dataset.from_tensor_slices(img_paths)
    img_ds = file_ds.map(read_decode_resize, num_parallel_calls=tf.data.AUTOTUNE)

    batch_img_ds = img_ds.batch(32).prefetch(tf.data.AUTOTUNE)

    return self.predict(batch_img_ds, img_names, return_pd_dataframe=return_pd_dataframe)

  def _convert_pred_to_df(self, yhats: np.ndarray, img_names: List[str], data_src=None) -> pd.DataFrame:
    iodoor_yhats = yhats[0]
    room_yhats = yhats[1]

    fireplace_yhats = yhats[2]
    agpool_yhats = yhats[3]
    body_of_water_yhats = yhats[4]
    igpool_yhats = yhats[5]
    balcony_yhats = yhats[6]
    deck_patio_veranda_yhats = yhats[7]
    ss_kitchen_yhats = yhats[8]
    double_sink_yhats = yhats[9]
    upg_kitchen_yhats = yhats[10]

    room_top_3 = tf.math.top_k(room_yhats, k=3)
    inoutdoor = [GeneralClassifier.INOUT_DOOR_CLASS_NAMES[int(y)] for y in np.squeeze(np.argmax(iodoor_yhats, axis=-1))]

    predictions_df = pd.DataFrame(data={
      # 'img': [Path(img).name for img in imgs],
      'img': img_names,
      'inoutdoor': inoutdoor,
      'p_iodoor': np.round(np.max(iodoor_yhats, axis=-1).astype('float'), 4),

      'room': [GeneralClassifier.ROOM_CLASS_NAMES[int(y)] for y in np.squeeze(np.argmax(room_yhats, axis=-1))],
      'p_room': np.round(np.max(room_yhats, axis=-1).astype('float'), 4),

      'room_1': np.array(GeneralClassifier.ROOM_CLASS_NAMES)[room_top_3.indices.numpy()[:, 1]],
      'p_room_1': np.round(room_top_3.values.numpy()[:, 1].astype('float'), 4),
      'room_2': np.array(GeneralClassifier.ROOM_CLASS_NAMES)[room_top_3.indices.numpy()[:, 2]],
      'p_room_2': np.round(room_top_3.values.numpy()[:, 2].astype('float'), 4),

      'p_fireplace': np.round(np.squeeze(fireplace_yhats).astype('float'), 4),
      'p_agpool': np.round(np.squeeze(agpool_yhats).astype('float'), 4),
      'p_body_of_water': np.round(np.squeeze(body_of_water_yhats).astype('float'), 4),
      'p_igpool': np.round(np.squeeze(igpool_yhats).astype('float'), 4),
      'p_balcony': np.round(np.squeeze(balcony_yhats).astype('float'), 4),
      'p_deck_patio_veranda': np.round(np.squeeze(deck_patio_veranda_yhats).astype('float'), 4),
      'p_ss_kitchen': np.round(np.squeeze(ss_kitchen_yhats).astype('float'), 4),
      'p_double_sink': np.round(np.squeeze(double_sink_yhats).astype('float'), 4),
      'p_upg_kitchen': np.round(np.squeeze(upg_kitchen_yhats).astype('float'), 4),

      'data_src': data_src
    })

    return predictions_df


from datetime import datetime
from sys import exit

from ..concurrency import WorkerPool
from ..utils.cmdline import count_items, get_target_nodes
from ..utils.table import ROW_SEPARATOR, render_table
from ..utils.text import (
    blue,
    bold,
    cyan,
    cyan_unless_zero,
    error_summary,
    format_duration,
    green,
    green_unless_zero,
    mark_for_translation as _,
    red,
    red_unless_zero,
)
from ..utils.ui import io

def stats_summary(node_stats, total_duration):
    for node in node_stats.keys():
        node_stats[node]['total'] = sum([
            node_stats[node]['good'],
            node_stats[node]['bad'],
            node_stats[node]['unknown'],
        ])
        try:
            node_stats[node]['health'] = \
                (node_stats[node]['good'] / float(node_stats[node]['total'])) * 100.0
        except ZeroDivisionError:
            node_stats[node]['health'] = 0

    totals = {
        'items': 0,
        'good': 0,
        'bad': 0,
        'unknown': 0,
    }
    node_ranking = []

    for node_name, stats in node_stats.items():
        totals['items'] += stats['total']
        totals['good'] += stats['good']
        totals['bad'] += stats['bad']
        totals['unknown'] += stats['unknown']
        node_ranking.append((
            stats['health'],
            node_name,
            stats['total'],
            stats['good'],
            stats['bad'],
            stats['unknown'],
            stats['duration'],
        ))

    node_ranking = sorted(node_ranking, reverse=True)

    try:
        totals['health'] = (totals['good'] / float(totals['items'])) * 100.0
    except ZeroDivisionError:
        totals['health'] = 0

    rows = [[
        bold(_("node")),
        _("items"),
        green(_("good")),
        red(_("bad")),
        cyan(_("unknown")),
        _("health"),
        _("duration"),
    ], ROW_SEPARATOR]

    for health, node_name, items, good, bad, unknown, duration in node_ranking:
        rows.append([
            node_name,
            str(items),
            green_unless_zero(good),
            red_unless_zero(bad),
            cyan_unless_zero(unknown),
            "{0:.1f}%".format(health),
            format_duration(duration),
        ])

    if len(node_ranking) > 1:
        rows.append(ROW_SEPARATOR)
        rows.append([
            bold(_("total ({} nodes)").format(len(node_stats.keys()))),
            str(totals['items']),
            green_unless_zero(totals['good']),
            red_unless_zero(totals['bad']),
            cyan_unless_zero(totals['unknown']),
            "{0:.1f}%".format(totals['health']),
            format_duration(total_duration),
        ])

    alignments = {
        1: 'right',
        2: 'right',
        3: 'right',
        4: 'right',
        5: 'right',
        6: 'right',
        7: 'right',
    }

    for line in render_table(rows, alignments=alignments):
        io.stdout("{x} {line}".format(x=blue("i"), line=line))

def bw_verify(repo, args):
    errors = []
    node_stats = {}
    pending_nodes = get_target_nodes(repo, args['targets'])
    start_time = datetime.now()
    io.progress_set_total(count_items(pending_nodes))

    def tasks_available():
        return bool(pending_nodes)

    def next_task():
        node = pending_nodes.pop()
        return {
            'target': node.verify,
            'task_id': node.name,
            'kwargs': {
                'autoonly_selector': args['autoonly'],
                'autoskip_selector': args['autoskip'],
                'show_all': args['show_all'],
                'show_diff': args['show_diff'],
                'workers': args['item_workers'],
            },
        }

    def handle_result(task_id, return_value, duration):
        node_stats[task_id] = return_value

    def handle_exception(task_id, exception, traceback):
        msg = "{}: {}".format(
            task_id,
            exception,
        )
        io.stderr(traceback)
        io.stderr(repr(exception))
        io.stderr(msg)
        errors.append(msg)

    worker_pool = WorkerPool(
        tasks_available,
        next_task,
        handle_result=handle_result,
        handle_exception=handle_exception,
        pool_id="verify",
        workers=args['node_workers'],
    )
    worker_pool.run()

    if args['summary'] and node_stats:
        stats_summary(node_stats, datetime.now() - start_time)

    error_summary(errors)

    exit(1 if errors else 0)


"""
Train model on qbf formulae over already trained models for lower quantification levels.
"""
import argparse
from tqdm import tqdm
import tensorflow as tf

from model import QBF_Model
from qcsp_utils import QCSP_Instance
from data_utils import load_qbf_formulas

tf.compat.v1.enable_eager_execution() # works only in eager mode currently...

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-s', '--state_size', type=int, default=128, help='Size of the variable states in QBF_Model')
    parser.add_argument('-e', '--epochs', type=int, default=25, help='Number of training epochs')
    parser.add_argument('-t', '--t_max', type=int, default=30, help='Number of iterations t_max for which QBF_Model runs on each instance')
    parser.add_argument('-b', '--batch_size', type=int, default=10, help='Batch size for training')
    parser.add_argument('-c', '--train_size', type=int, nargs='+', default=None, help='Scope of training instances in the data directory')
    parser.add_argument('-m', '--model_dirs', type=str, nargs='+', help='Directories in which the models are stored')
    parser.add_argument('-d', '--data_path', help='A path to a training set of formulas in the (Q)DIMACS cnf format.')
    args = parser.parse_args()

    print('Loading qbf formulas...')
    _, formulas = load_qbf_formulas(args.data_path, scope=args.train_size)
    print('Converting formulas to QCSP instances...')
    instances = [QCSP_Instance.qbf_to_instance(f) for f in tqdm(formulas)]

    # Combine instances into batches
    train_batches = QCSP_Instance.batch_instances(instances, args.batch_size)

    # Fetch weights from model directories
    models = QBF_Model.get_models(args.model_dirs, train_batches[0], state_size=args.state_size)

    # Construct and train new network
    trainable_model, inference_models = models[0], models[1:]
    trainable_model.train(train_batches, inference_models, iterations=args.t_max, epochs=args.epochs)

if __name__ == '__main__':
    main()


from .models import Customer, Product, Order, OrderItem

def query_data(self):
    if self.request.user.is_authenticated:
        customer = self.request.user.customer
    else:
        device = self.request.COOKIES["device"]
        customer, created = Customer.objects.get_or_create(device=device)

    order, created = Order.objects.get_or_create(
        customer=customer, complete=False)
    items = order.orderitem_set.all()
    cartItems = order.get_cart_items
    return {"order": order, "items": items, "cartItems": cartItems}


import time
import sys

if sys.argv[1]:
  val = sys.argv[1]
else:
  val = 'No inputs'
print('--Run analysis and create NW policy: inputs {}--'.format(val))
retry_max = 5
retry_cnt = 0
while retry_cnt < retry_max:
  time.sleep(1)
  retry_cnt += 1
  print('processing ...')
print('The following policies where generated')
print('1) nwpolicy1.yaml')
print('2) nwpolicy2.yaml')
print('3) nwpolicy3.yaml')
print('Completed')


from django.db import models
from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator, MaxValueValidator
from reviews.validators import year_validator

User = get_user_model()
CROP_LEN_TEXT = 30

class Genre(models.Model):
    """Модель для работы с жанрами"""

    name = models.CharField(
        max_length=256,
        verbose_name='Название жанра'
    )
    slug = models.SlugField(
        max_length=50,
        unique=True,
        verbose_name='Конвертер пути',
        help_text='Введите данные типа slug',
    )

    class Meta:
        verbose_name = 'Жанр'
        verbose_name_plural = 'Жанры'
        ordering = ['name']

    def __str__(self):
        return self.name

class Category(models.Model):
    """Модель для работы с категориями."""

    name = models.CharField(
        max_length=256,
        verbose_name='Название категории'
    )
    slug = models.SlugField(
        max_length=50,
        unique=True,
        verbose_name='Конвертер пути',
        help_text='Введите данные типа slug'
    )

    class Meta:
        verbose_name = 'Категория'
        verbose_name_plural = 'Категории'
        ordering = ['name']

    def __str__(self):
        return self.name

class Title(models.Model):
    """Модель для работы с произведениями."""

    name = models.CharField(
        max_length=256,
        verbose_name='Название произведения'
    )
    description = models.TextField(
        null=True,
        blank=True,
        verbose_name='Описание произведения'
    )
    year = models.PositiveSmallIntegerField(
        validators=[year_validator],
        verbose_name='Дата написания'

    )
    category = models.ForeignKey(
        Category,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
        related_name='titles',
        verbose_name='Категория'
    )
    genre = models.ManyToManyField(
        Genre,
        through='GenreToTitle',
        verbose_name='Жанр'
    )

    class Meta:
        verbose_name = 'Произведение'
        verbose_name_plural = 'Произведения'
        indexes = [models.Index(fields=['-year'])]

    def __str__(self):
        return self.name

class GenreToTitle(models.Model):
    """Модель, связывающая произведение с жанром."""

    title = models.ForeignKey(Title, on_delete=models.CASCADE)
    genre = models.ForeignKey(Genre, on_delete=models.CASCADE)

    def __str__(self):
        return f'{self.title} {self.genre}'

class Review(models.Model):
    """Модель отзывов к произведениям."""

    text = models.TextField('Текст')
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='reviews',
        verbose_name='Автор'
    )
    score = models.IntegerField(
        'Оценка',
        validators=[
            MinValueValidator(1),
            MaxValueValidator(10),
        ]
    )

    pub_date = models.DateTimeField(
        'Дата публикации',
        auto_now_add=True,
    )
    title = models.ForeignKey(
        Title,
        on_delete=models.CASCADE,
        related_name='reviews',
        verbose_name='Произведение'
    )

    class Meta:
        verbose_name = 'Отзыв'
        verbose_name_plural = 'Отзывы'
        indexes = [models.Index(fields=['-pub_date'])]
        ordering = ('-pub_date',)
        constraints = [
            models.UniqueConstraint(
                fields=['title', 'author'],
                name='unique_title_author'
            ),
        ]

    def __str__(self):
        return self.text[:CROP_LEN_TEXT]

class Comment(models.Model):
    """Модель комментариев к отзывам."""

    text = models.TextField('Текст')
    author = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='comments',
        verbose_name='Автор'
    )
    review = models.ForeignKey(
        Review,
        on_delete=models.CASCADE,
        related_name='comments',
        verbose_name='Отзыв'
    )
    pub_date = models.DateTimeField(
        'Дата публикации',
        auto_now_add=True,
    )

    class Meta:
        verbose_name = 'Комментарий к отзывам'
        verbose_name_plural = 'Комментарии к отзывам'
        indexes = [models.Index(fields=['-pub_date'])]
        ordering = ('-pub_date',)

    def __str__(self):
        return self.text[:CROP_LEN_TEXT]


import boto3, argparse, os, sys, logging
from application import Application
from loghelper import LogHelper
def main():
    LogHelper.start_logging("logdownloader.log")
    parser = argparse.ArgumentParser(
        description="AWS bootstrapper log downloader" +
                    "Downloads instances logs from AWS S3")
    parser.add_argument("--manifestPath", help = "path to a manifest file describing the jobs and data requirements for the application", required=True)
    parser.add_argument("--outputPath", help = "directory to where instance logs will be copied", required=True)

    try:
        args = vars(parser.parse_args())
        manifestPath = os.path.abspath(args["manifestPath"])
        outputdir = os.path.abspath(args["outputPath"])
        s3 = boto3.resource('s3')
        app = Application(s3, manifestPath, outputdir)
        app.downloadLogs(outputdir)

    except Exception as ex:
        logging.exception("error in log downloader")
        sys.exit(1)

if __name__ == "__main__":
    main()


"""
The module implementations in this file are taken from (https://nlp.seas.harvard.edu/2018/04/03/attention.html)
"""
import math
import torch
import torch.nn as nn
import torch.nn.functional as F
from models.transformer.utils import clones, attention

class MultiHeadedAttention(nn.Module):
    def __init__(self, h, d_model, dropout=0.1):
        """
        Implements Figure 2 (right) of the paper (https://arxiv.org/pdf/1706.03762.pdf)
        """
        super(MultiHeadedAttention, self).__init__()
        assert d_model % h == 0
        # We assume d_v always equals d_k
        self.d_k = d_model // h
        self.h = h
        self.linears = clones(nn.Linear(d_model, d_model), 4)
        self.attn = None
        self.dropout = nn.Dropout(p=dropout)

    def forward(self, query, key, value, mask=None):
        """Implements Figure 2"""
        if mask is not None:
            # Same mask applied to all h heads.
            mask = mask.unsqueeze(1)
        nbatches = query.size(0)

        # 1) Do all the linear projections in batch from d_model => h x d_k
        query, key, value = [l(x).view(nbatches, -1, self.h, self.d_k).transpose(1, 2)
                             for l, x in zip(self.linears, (query, key, value))]

        # 2) Apply attention on all the projected vectors in batch.
        x, self.attn = attention(query, key, value, mask=mask, dropout=self.dropout)

        # 3) "Concat" using a view and apply a final linear.
        x = x.transpose(1, 2).contiguous().view(nbatches, -1, self.h * self.d_k)
        return self.linears[-1](x)

class PositionwiseFeedForward(nn.Module):
    """
    Implements FFN equation (Eq2/Page 5) in the paper (https://arxiv.org/pdf/1706.03762.pdf)
    """
    def __init__(self, d_model, d_ff, dropout=0.1):
        super(PositionwiseFeedForward, self).__init__()
        self.w_1 = nn.Linear(d_model, d_ff)
        self.w_2 = nn.Linear(d_ff, d_model)
        self.dropout = nn.Dropout(dropout)

    def forward(self, x):
        return self.w_2(self.dropout(F.relu(self.w_1(x))))

class PositionalEncoding(nn.Module):
    """
    Implement the PE function (Page 6) in the paper (https://arxiv.org/pdf/1706.03762.pdf)
    """
    def __init__(self, d_model, dropout, max_len=5000):
        super(PositionalEncoding, self).__init__()
        self.dropout = nn.Dropout(p=dropout)

        # Compute the positional encodings once in log space.
        pe = torch.zeros(max_len, d_model)
        position = torch.arange(0., max_len).unsqueeze(1)
        div_term = torch.exp(torch.arange(0., d_model, 2) * -(math.log(10000.0) / d_model))
        pe[:, 0::2] = torch.sin(position * div_term)
        pe[:, 1::2] = torch.cos(position * div_term)
        pe = pe.unsqueeze(0)
        self.register_buffer('pe', pe)

    def forward(self, x):
        x = x + self.pe[:, :x.size(1)].clone().detach().requires_grad_(False)
        return self.dropout(x)

class LayerNorm(nn.Module):
    """
    Construct a LayerNorm module (See https://arxiv.org/abs/1607.06450 for details)
    """
    def __init__(self, features, eps=1e-6):
        super(LayerNorm, self).__init__()
        self.a_2 = nn.Parameter(torch.ones(features))
        self.b_2 = nn.Parameter(torch.zeros(features))
        self.eps = eps

    def forward(self, x):
        mean = x.mean(-1, keepdim=True)
        std = x.std(-1, keepdim=True)
        return self.a_2 * (x - mean) / (std + self.eps) + self.b_2

class SublayerConnection(nn.Module):
    """
    A residual connection followed by a layer norm.
    Note for code simplicity the norm is first as opposed to last.
    """
    def __init__(self, size, dropout):
        super(SublayerConnection, self).__init__()
        self.norm = LayerNorm(size)
        self.dropout = nn.Dropout(dropout)

    def forward(self, x, sublayer):
        """
        Apply residual connection to any sublayer with the same size.
        """
        return x + self.dropout(sublayer(self.norm(x)))

class EncoderLayer(nn.Module):
    """
    Encoder is made up of self-attn and feed forward
    """
    def __init__(self, size, self_attn, feed_forward, dropout):
        super(EncoderLayer, self).__init__()
        self.self_attn = self_attn
        self.feed_forward = feed_forward
        self.sublayer = clones(SublayerConnection(size, dropout), 2)
        self.size = size

    def forward(self, x, mask):
        """
        Follow Figure 1 (left) for connections [https://arxiv.org/pdf/1706.03762.pdf]
        """
        x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
        return self.sublayer[1](x, self.feed_forward)

class DecoderLayer(nn.Module):
    """
    Decoder is made of self-attn, src-attn, and feed forward
    """
    def __init__(self, size, self_attn, src_attn, feed_forward, dropout):
        super(DecoderLayer, self).__init__()
        self.size = size
        self.self_attn = self_attn
        self.src_attn = src_attn
        self.feed_forward = feed_forward
        self.sublayer = clones(SublayerConnection(size, dropout), 3)

    def forward(self, x, memory, src_mask, tgt_mask):
        """
        Follow Figure 1 (right) for connections [https://arxiv.org/pdf/1706.03762.pdf]
        """
        m = memory
        x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, tgt_mask))
        x = self.sublayer[1](x, lambda x: self.src_attn(x, m, m, src_mask))
        return self.sublayer[2](x, self.feed_forward)

class Embeddings(nn.Module):
    def __init__(self, d_model, vocab):
        super(Embeddings, self).__init__()
        self.lut = nn.Embedding(vocab, d_model)
        self.d_model = d_model

    def forward(self, x):
        return self.lut(x) * math.sqrt(self.d_model)

class Generator(nn.Module):
    """
    Define standard linear + softmax generation step.
    """
    def __init__(self, d_model, vocab):
        super(Generator, self).__init__()
        self.proj = nn.Linear(d_model, vocab)

    def forward(self, x):
        return F.log_softmax(self.proj(x), dim=-1)


import sys

input = sys.stdin.readline

n = int(input())

nums = list(map(int, input().split()))

def gcd(a, b):
    if a % b == 0:
        return b
    else:
        return gcd(b, a%b)

def multiple(num):
    result = []
    for i in range(1, num // 2 + 1):
        if num % i == 0:
            result.append(i)
    result.append(num)
    return result

if n == 2:
    gcd = gcd(nums[0], nums[1])
else:
    temp = gcd(nums[0], nums[1])
    gcd = gcd(temp, nums[2])

result = multiple(gcd)
for i in result:
    print(i)


import collections
import time
from typing import Tuple, Any, Dict, List
import gym  # type: ignore
import numpy as np

from pyreach.gyms import core
from pyreach.gyms import reach_env

class BenchmarkIntegrationEnv(reach_env.ReachEnv):  # type: ignore
  """Benchmark integration testing environment."""

  def __init__(self, **kwargs: Any) -> None:
    """Initialize the Singulation environment."""
    center_joint_angles: List[float] = [3.06, -1.66, -1.57, -1.10, 1.7, 0.0]
    low_joint_angles: Tuple[float, ...] = tuple(
        [cja - 5.0 for cja in center_joint_angles])
    high_joint_angles: Tuple[float, ...] = tuple(
        [cja + 5.0 for cja in center_joint_angles])

    task_params: Dict[str, str] = {
        "task-code": "9999999999",
    }

    pyreach_config: Dict[str, reach_env.ReachElement] = {
        "arm":
            reach_env.ReachArm(
                "", low_joint_angles, high_joint_angles, is_synchronous=True),
        # pylint: disable=g-bad-todo
        # TODO: These should be re-enabled and checked that there
        # is an observation in there.
        # "camera":
        #     reach_env.ReachColorCamera("", (576, 1024), is_synchronous=True),
        # "depth_camera":
        #     reach_env.ReachDepthCamera(
        #         "", (720, 1280), True, is_synchronous=True),
        "server":
            reach_env.ReachServer("Server"),
        "text_instructions":
            reach_env.ReachTextInstructions("instruction-generator"),
    }

    super().__init__(
        pyreach_config=pyreach_config, task_params=task_params, **kwargs)

  def step(self,
           action: core.Action) -> Tuple[core.Observation, float, bool, Any]:
    """Perform one step."""
    observation: core.Observation
    reward: float
    done: bool
    info: Any

    observation, reward, done, info = super().step(action)

    if done:
      observation, _, _, info = self._ask_for_new_instruction(observation)
      return (observation, reward, done, info)

    return (observation, reward, done, info)

  def _ask_for_new_instruction(
      self, current_observation: core.Observation
  ) -> Tuple[core.Observation, float, bool, Any]:
    """Asks for a new instruction.

    If we time out waiting for a new instruction, that means that
    we have completed all instructions, and we return None,
    otherwise we return the latest observation.

    Args:
      current_observation: the current observation.

    Returns:
      The observation when the instruction is received.
    """
    print(f"{time.time()}: Asking for a new text instruction")

    # End current task
    action = collections.OrderedDict(
        {"text_instructions": collections.OrderedDict({"task_enable": 0})})

    _, _, _, _ = super().step(action)

    # Start new task
    action = collections.OrderedDict(
        {"text_instructions": collections.OrderedDict({"task_enable": 1})})
    return super().step(action)

  def reset(self) -> core.Observation:
    """Resets the benchmark.

    On SIM, this resets the scene and returns an observation. On real, it only
    returns an observation.

    Returns:
      Initial observation.
    """

    # End any current task
    action = collections.OrderedDict(
        {"text_instructions": collections.OrderedDict({"task_enable": 0})})
    _, _, _, _ = super().step(action)
    obs = super().reset()

    # Start a new task
    action = collections.OrderedDict(
        {"text_instructions": collections.OrderedDict({"task_enable": 1})})
    obs, _, _, _ = super().step(action)

    return obs

class BenchmarkIntegrationWrapper(gym.Wrapper):
  """A wrapper for the Benchmark integration testing environment.

  This environment is a stripped-down environment which provides actions for
  moves of joints only.

  == Actions ==

  action["arm"]:
    "joint_angles":
        # The joints to move to, in radians.
        gym.spaces.Box(
            low=np.array((-6.283, -2.059, -3.926, -3.141, 1.692, -6.283)),
            high=np.array((6.283, 2.094, 0.191, 3.141, 3.141, 6.283)),
            dtype=np.dtype(float)),

  == Observations ==

    No filters! See BenchmarkIntegrationEnv!
  """

  def __init__(self, env: BenchmarkIntegrationEnv) -> None:
    super().__init__(env)

    self.env = env

    self.action_space: core.Space = gym.spaces.Dict({
        "arm":
            gym.spaces.Dict({
                "joint_angles": self.env.action_space["arm"]["joint_angles"],
            })
    })
    self.observation_space: core.Space = self.env.observation_space

  def step(self,
           action: core.Action) -> Tuple[core.Observation, float, bool, Any]:
    assert isinstance(action, (dict, collections.OrderedDict))
    arm: Any = action["arm"]
    assert isinstance(arm, (dict, collections.OrderedDict))
    pose: Any = arm["joint_angles"]
    assert isinstance(pose, np.ndarray)
    new_action = {
        "arm": {
            "command": 1,
            "joint_angles": action["arm"]["joint_angles"],
        },
    }

    return self.env.step(new_action)


class cached_property(object):

    def __init__(self, fget):
        self.fget = fget
        self.name = fget.__name__

    def __get__(self, obj, cls):
        if obj is None:
            return
        value = self.fget(obj)
        setattr(obj, self.name, value)
        return value

def format_bytes(x):

    suffix = ('', 'k', 'M', 'G', 'T', 'P')
    order = 0

    while order < 5 and x > 1000:
        x /= 1024
        order += 1

    return f'{x:.2f}{suffix[order]}B'


# coding:utf8
'''
单元测试：
测试file_util中的方法
'''
from unittest import TestCase
from util import file_util as fu
import os

class TestFileUtil(TestCase):
    def setUp(self) -> None:
        self.test_path = os.getcwd().replace("\\", "/")  # 获取当前路径，并替换斜杠

    def test_get_dir_files_list(self):
        '''
        请在工程根目录的test文件夹内建立:
        test_dir/
            inner1/
                3
                4
                inner2/
                    5
        1
        2
        的目录结构用于进行此方法的单元测试
        不递归结果应该是1和2
        递归结果应该是1,2,3,4,5
        '''
        test_dir_path = self.test_path + '/test_dir/'  # 获取测试文件夹所在路径
        # 不递归
        result = []  # 用于存放测试结果文件列表
        for i in fu.get_dir_files_list(test_dir_path):  # 不递归获取测试中所有文件名
            result.append(os.path.basename(i))  # 只添加文件名
        result.sort()  # 对结果排序，防止乱序时通不过测试
        self.assertEqual(['1', '2'], result)

        # 递归
        result = []  # 用于存放测试结果文件列表
        for i in fu.get_dir_files_list(test_dir_path, recursion=True):  # 递归获取测试中所有文件名
            result.append(os.path.basename(i))  # 只添加文件名
        result.sort()  # 对结果排序，防止乱序通不过测试
        self.assertEqual(['1', '2', '3', '4', '5'], result)

        '''
        推导式写法
        # 不递归
        result1 = [os.path.basename(i) for i in fu.get_dir_files_list(test_dir_path)]
        self.assertEqual(['1', '2'], result1)

        # 递归
        result2 = [os.path.basename(i) for i in fu.get_dir_files_list(test_dir_path, recursion=True)]
        self.assertEqual(['1', '2', '3', '4', '5'], result2)
        '''

    def test_get_new_files_by_comparing_lists(self):
        '''建立两个列表进行独立测试'''
        big_list = ['D:/a.json', 'D:/b.json', 'D:/c.json', 'D:/d.json']
        small_list = ['D:/a.json', 'D:/b.json']
        result = fu.get_new_files_by_comparing_lists(big_list, small_list)
        self.assertEqual(['D:/c.json', 'D:/d.json'], result)


# Copyright 2022 The OFA-Sys Team.
# All rights reserved.
# This source code is licensed under the Apache 2.0 license
# found in the LICENSE file in the root directory.

import os
from io import BytesIO

import logging
import warnings
import string

import numpy as np
import torch
import base64
import random
from torchvision import transforms

from PIL import Image, ImageFile

from data import data_utils
from data.ofa_dataset import OFADataset
from utils.vision_helper import RandomAugment
import utils.transforms as T

ImageFile.LOAD_TRUNCATED_IMAGES = True
ImageFile.MAX_IMAGE_PIXELS = None
Image.MAX_IMAGE_PIXELS = None

logger = logging.getLogger(__name__)
warnings.filterwarnings("ignore", "(Possibly )?corrupt EXIF data", UserWarning)

IMAGENET_DEFAULT_MEAN = (0.485, 0.456, 0.406)
IMAGENET_DEFAULT_STD = (0.229, 0.224, 0.225)

def collate(samples, pad_idx, eos_idx):
    if len(samples) == 0:
        return {}

    def merge(key):
        return data_utils.collate_tokens(
            [s[key] for s in samples],
            pad_idx,
            eos_idx=eos_idx,
        )

    id = np.array([s["id"] for s in samples])
    src_tokens = merge("source")
    src_lengths = torch.LongTensor([s["source"].ne(pad_idx).long().sum() for s in samples])

    patch_images = torch.stack([sample['patch_image'] for sample in samples], dim=0)
    patch_masks = torch.cat([sample['patch_mask'] for sample in samples])

    prev_output_tokens = None
    target = None
    if samples[0].get("target", None) is not None:
        target = merge("target")
        tgt_lengths = torch.LongTensor([s["target"].ne(pad_idx).long().sum() for s in samples])
        ntokens = tgt_lengths.sum().item()

        if samples[0].get("prev_output_tokens", None) is not None:
            prev_output_tokens = merge("prev_output_tokens")
    else:
        ntokens = src_lengths.sum().item()

    batch = {
        "id": id,
        "nsentences": len(samples),
        "ntokens": ntokens,
        "net_input": {
            "src_tokens": src_tokens,
            "src_lengths": src_lengths,
            "patch_images": patch_images,
            "patch_masks": patch_masks,
            "prev_output_tokens": prev_output_tokens
        },
        "target": target,
    }

    return batch

class CaptionDataset(OFADataset):
    def __init__(
        self,
        split,
        dataset,
        bpe,
        src_dict,
        tgt_dict=None,
        mimic_t2i=None,
        mimic_i2t=None,
        max_src_length=128,
        max_tgt_length=30,
        patch_image_size=224,
        imagenet_default_mean_and_std=False,
        scst=False,
        negative_dataset=None
    ):
        super().__init__(split, dataset, bpe, src_dict, tgt_dict, mimic_t2i=mimic_t2i, mimic_i2t=mimic_i2t)
        self.max_src_length = max_src_length
        self.max_tgt_length = max_tgt_length
        self.patch_image_size = patch_image_size
        self.scst = scst

        self.transtab = str.maketrans({key: None for key in string.punctuation})

        if imagenet_default_mean_and_std:
            mean = IMAGENET_DEFAULT_MEAN
            std = IMAGENET_DEFAULT_STD
        else:
            mean = [0.5, 0.5, 0.5]
            std = [0.5, 0.5, 0.5]

        scales = np.arange(patch_image_size, patch_image_size+10).tolist()
        """
        # data augmentation
        self.patch_resize_transform = transforms.Compose([
            lambda image: image.convert("RGB"),
            T.RandomResize(scales, max_size=512),
            transforms.CenterCrop(patch_image_size),
            RandomAugment(2, 2, isPIL=True, augs=['Identity', 'AutoContrast', 'Equalize', 'Brightness',
                                                  'ShearX', 'ShearY', 'TranslateX', 'TranslateY', 'Rotate']),
            transforms.ToTensor(),
            transforms.Normalize(mean=mean, std=std),
        ])
        """
        # self.patch_resize_transform = transforms.Compose([
        #     lambda image: image.convert("RGB"),
        #     transforms.Resize((patch_image_size, patch_image_size), interpolation=Image.BICUBIC),
        #     transforms.ToTensor(),
        #     transforms.Normalize(mean=mean, std=std),
        # ])
        # """

        self.patch_resize_transform = transforms.Compose([
            lambda image: image.convert("RGB"),
            transforms.RandomCrop(int(patch_image_size//8*7)),
            transforms.ToTensor(),
            transforms.Normalize(mean=mean, std=std),
        ])

        if type(bpe).__name__ == 'GPT2BPE':
            # self.prompt = " what does the image describe?"
            # self.prompt = " what report can a doctor give for this 2D medical image? "
            # self.prompt = " what can we get from this chest medical image? "
            self.prompt = " what disease does this chest image have? "
        elif type(bpe).__name__ == 'BertBPE':
            self.prompt = "图片描述了什么内容?"
        # print(f"TTTTTTTTTTTTTTTTTTTTTTTTTTTT: ")
        # print(self.pad, self.eos)
        # exit()
        self.negative_dataset = negative_dataset
        self.diseases_mimic = ['Atelectasis', 'Lung Lesion', 'Pneumonia', 'Fracture', 'Cardiomegaly', 'Support Devices', 'Enlarged Cardiomediastinum', 'Pleural Effusion', 'Pleural Other', 'Pneumothorax', 'Consolidation', 'Lung Opacity', 'Edema']

    def __getitem__(self, index):
        # """
        ## random choose from positive or negative dataset (9:1)
        high = 5
        # random_choose = np.random.randint(low=0, high=high)
        random_choose = random.randint(0, high)
        # print(f"self.negative_dataset: {self.negative_dataset}")
        split_ind = 2 if self.negative_dataset is not None else high
        split_ind = high
        # print(f"Random choose: {random_choose, split_ind}")
        if self.split != 'train':
            split_ind = high
        if random_choose <= split_ind:
            uniq_id, image, caption, labels, adjs = self.dataset[index]
            # uniq_id, image, caption, labels, info1, info2 = self.dataset[index]
            # print(f"Use positive data: {uniq_id, image, caption}")
        else:
            uniq_id, image, caption, labels, adjs = self.negative_dataset[index]
            # uniq_id, image, caption, labels, info1, info2 = self.negative_dataset[index]
            # print("Use negative data: {uniq_id, image, captioin}")

        """
        unique_id, image, caption = self.dataset[index]
        # print(unique_id, image, caption)
        """

        caption = caption.lower()
        caption = caption.split('&&')
        caption = [c.strip() for c in caption if len(c.strip())]
        # random.shuffle(caption)
        caption = sorted(caption)
        caption = ", ".join(caption)
        # print(caption)

        images = image.split(',')
        random_image_ind = np.random.randint(low=0, high=len(images))
        # print(f"Random Image: {random_image_ind}")
        image = images[random_image_ind]

        ## add label info in prompt
        # """
        label_list = labels.split('&&')
        label_list = [l.lower() for l in label_list]

        """
        ### add extra info based on classifications
        if 'No Finding'.lower() in label_list:
            extra_info = ' it seems that there are no diseases in this image.'
        else:
            # extra_info = ' there can be {} diseases in this image.'.format(', '.join(label_list))
            extra_info = ' what disease does this image have? there are {} in this image. '.format(', '.join(label_list))
            for d in self.diseases_mimic:
                if d.lower() in label_list:
                    vqa_info = ' does this image have {}? yes, there is {}. '.format(d.lower(), d.lower())
                else:
                    vqa_info = ' does this image have {}? no, no {} find in this image. '.format(d.lower(), d.lower())
                extra_info += vqa_info
        # extra_info = ' test '
        self.prompt = " based on the following info: ' {} ', what can we get from this chest medical image? ".format(extra_info)
        # exit()
        """

        ## Cardiomegaly prompt
        # self.prompt = " based on the following cardiomegaly info: ' {} ', what can we get from this chest medical image? ".format(card_prompt)
        # self.prompt = " what can we get from this chest medical image? "
        # self.prompt = " based on the following pneumothorax info: ' {} ', what can we get from this chest medical image? ".format(card_prompt)

        # self.prompt = ' given the following info: {}, please generate an report for this DR image. '.format(', '.join([info1, info2]))

        # ### 1. just 'what disease does this image have'
        # if 'No Finding'.lower() in label_list:
        #     extra_info = ' it seems that there are no diseases in this image.'
        # else:
        #     extra_info = ' what disease does this image have? there are {} in this image. '.format(', '.join(label_list))
        # self.prompt = " based on the following info: ' {} ', what can we get from this chest medical image? ".format(extra_info)

        # ### 2. 'what disease does this image have?' + 'does this image have xxx ?'
        # if 'No Finding'.lower() in label_list:
        #     extra_info = ' it seems that there are no diseases in this image.'
        # else:
        #     # extra_info = ' there can be {} diseases in this image.'.format(', '.join(label_list))
        #     extra_info = ' what disease does this image have? there are {} in this image. '.format(', '.join(label_list))
        #     for d in self.diseases_mimic:
        #         if d.lower() in label_list:
        #             vqa_info = ' does this image have {}? yes, there is {}. '.format(d.lower(), d.lower())
        #         else:
        #             vqa_info = ' does this image have {}? no, no {} find in this image. '.format(d.lower(), d.lower())
        #         extra_info += vqa_info
        # self.prompt = " based on the following info: ' {} ', what can we get from this chest medical image? ".format(extra_info)

        # ### 3. based on 2, add all prompt
        # prompt_list = prompt.split(',')
        # prompt_dict = {}
        # for i in range(0, len(prompt_list), 2):
        #     if i + 1 >= len(prompt_list):
        #         break
        #     k = prompt_list[i].lower()
        #     v = prompt_list[i+1]
        #     v = ' '.join(v.split('&')).lower()
        #     prompt_dict[k] = v
        # if 'No Finding'.lower() in label_list:
        #     extra_info = ' it seems that there are no diseases in this image.'
        # else:
        #     # extra_info = ' there can be {} diseases in this image.'.format(', '.join(label_list))
        #     extra_info = ' what disease does this image have? there are {} in this image. '.format(', '.join(label_list))
        #     for d in self.diseases_mimic:
        #         cur_disease = d.lower()
        #         if cur_disease in label_list:
        #             adjs = prompt_dict.get(cur_disease, '')
        #             vqa_info = ' does this image have {}? yes, there is {} {}. '.format(cur_disease, adjs, cur_disease)
        #         else:
        #             if cur_disease == 'cardiomegaly':
        #                 vqa_info = ' does this image have {}? no, find normal cardiomegaly in this image. '.format(cur_disease)
        #             else:
        #                 vqa_info = ' does this image have {}? no, no {} find in this image. '.format(cur_disease, cur_disease)
        #         extra_info += vqa_info
        # self.prompt = " based on the following info: ' {} ', what can we get from this chest medical image? ".format(extra_info)

        # ### 4. just 'what disease does this image have' + descriptions
        # if 'No Finding'.lower() in label_list:
        #     extra_info = ' it seems that there are no diseases in this image.'
        # else:
        #     label_with_description = []
        #     for l in label_list:
        #         adjs = prompt_dict.get(l, '')
        #         label_with_description.append(adjs + ' ' + l)
        #     extra_info = ' what disease does this image have? there are {} in this image. '.format(', '.join(label_with_description))
        # self.prompt = " based on the following info: ' {} ', what can we get from this chest medical image? ".format(extra_info)

        # ### For disease level test
        # prompt_list = prompt.split(',')
        # prompt_dict = {}
        # for i in range(0, len(prompt_list), 2):
        #     if i + 1 >= len(prompt_list):
        #         break
        #     k = prompt_list[i].lower()
        #     v = prompt_list[i+1]
        #     v = ' '.join(v.split('&&')).lower()
        #     prompt_dict[k] = v
        # nums = len(prompt_dict)
        # rand_ind = random.randint(0, nums-1)
        # test_k = list(prompt_dict.keys())[rand_ind]
        # test_v = prompt_dict[test_k]
        # self.prompt = " what is the level of {} ?".format(test_k)
        # caption = test_v

        # print(f'************** {self.prompt}')
        # print(f"++++++++++++++++++++ {caption}")

        # self.prompt = " what can we get from this chest medical image? "

        # ### [Classsification]-[location]
        # adj_process = self._process_adjs(adjs)
        # if adj_process is None:
        #     return self.__getitem__(index+1)
        # k, v = adj_process
        # caption = v
        # self.prompt = " where is {} in this DR image ?".format(k)

        # image = Image.open(BytesIO(base64.urlsafe_b64decode(image)))
        if image == '/mnt/lustre/niziyu/data/MIMIC/dr_preprocessed_jpgs/17486231_53979270.jpg':
            return self.__getitem__(index)

        image = Image.open(image)
        patch_image = self.patch_resize_transform(image)
        patch_mask = torch.tensor([True])

        if self.split == 'train' and not self.scst:
            # caption = caption.translate(self.transtab).strip()
            caption_token_list = caption.strip().split()
            tgt_caption = ' '.join(caption_token_list[:self.max_tgt_length])
        else:
            caption = ' '.join(caption.strip().split())
            caption_list = [cap.translate(self.transtab).strip() for cap in caption.strip().split('&&')]
            tgt_caption = '&&'.join(caption_list)
        src_item = self.encode_text(self.prompt)
        tgt_item = self.encode_text(" {}".format(tgt_caption), use_mimic=True)
        src_item = torch.cat([self.bos_item, src_item, self.eos_item])
        target_item = torch.cat([tgt_item, self.eos_item])
        prev_output_item = torch.cat([self.bos_item, tgt_item])

        example = {
            "id": uniq_id,
            "source": src_item,
            "patch_image": patch_image,
            "patch_mask": patch_mask,
            "target": target_item,
            "prev_output_tokens": prev_output_item
        }
        return example

    def collater(self, samples, pad_to_length=None):
        """Merge a list of samples to form a mini-batch.
        Args:
            samples (List[dict]): samples to collate
        Returns:
            dict: a mini-batch containing the data of the task
        """
        return collate(samples, pad_idx=self.pad, eos_idx=self.eos)

    def _process_adjs(self, adjs):
        locations = ['right', 'left', 'mid', 'base', 'lower lobe', 'bibasilar', 'basilar']
        locations = {l:1 for l in locations}
        adj_list = adjs.split(',')
        adj_tuple = []
        for i in range(0, len(adj_list), 2):
            if i + 1 >= len(adj_list):
                continue
            k = adj_list[i].strip().lower()
            vs = adj_list[i+1].split('&')
            vs = sorted([v.strip() for v in vs if v.strip() in locations], reverse=True)
            if not len(vs):
                continue
            adj_tuple.append((k, vs[0]))
        if len(adj_tuple) == 0:
            return None
        return adj_tuple[random.randint(0, len(adj_tuple)-1)]


# This file has an example of writing data to a file

def writeFile():
    num_days = int(input('How many days do you have sales for: '))

    sales_file = open('../data/sales.txt', 'w')  # w = write
    for count in range(1, num_days + 1):
        sales = float(input('Enter the sales for day #' + str(count) + ': '))

        # write to file
        sales_file.write(str(sales) + '\n')

    # close file
    sales_file.close()
    print('Data written to sales.txt')

writeFile()  # call function


from aiogram import types, Router
from aiogram.filters import Filter

from .. import assets
from ..app import dp

router = Router(name=__name__)

class MyFilter(Filter):
    def __init__(self, my_text: str) -> None:
        self.my_text = my_text

    async def __call__(self, message: types.Message) -> bool:
        return message.text == self.my_text

@dp.message(MyFilter(assets.reply_keyboards.hello_button.text))
async def hello_message(message: types.Message):
    from ..assets.reply_keyboards import menu_buttons
    from ..assets.message_text import send_question

    keyboard = types.ReplyKeyboardMarkup(keyboard=menu_buttons,resize_keyboard=True)
    await message.answer(text=send_question, reply_markup=keyboard)

    return

@dp.message(MyFilter(assets.reply_keyboards.back_button.text))
async def back_button(message: types.Message):
    await hello_message(message)

    return

@dp.message(MyFilter(assets.reply_keyboards.rsreu_site.text))
async def get_doc(message: types.Message):
    from ..assets.inline_keyboards import menu_button, rsreu_site_button
    from ..assets.message_text import link_to_rsreu

    keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
            [rsreu_site_button],
            [menu_button]])
    await message.answer(text=link_to_rsreu, reply_markup=keyboard)

    return

@dp.message(MyFilter(assets.reply_keyboards.cdo_site.text))
async def get_doc(message: types.Message):
    from ..assets.inline_keyboards import menu_button, cdo_site_button
    from ..assets.message_text import link_to_cdo

    keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
            [cdo_site_button],
            [menu_button]])
    await message.answer(text=link_to_cdo, reply_markup=keyboard)

    return

@dp.message(MyFilter(assets.reply_keyboards.edu_site.text))
async def get_doc(message: types.Message):
    from ..assets.inline_keyboards import menu_button, edu_site_button
    from ..assets.message_text import link_to_edu

    keyboard = types.InlineKeyboardMarkup(inline_keyboard=[
            [edu_site_button],
            [menu_button]])
    await message.answer(text=link_to_edu, reply_markup=keyboard)

    return


import pandas as pd
import en_core_web_sm
import spacy
from spacy import displacy
import nltk
from nltk.tokenize import word_tokenize
from nltk.tag import pos_tag
import random
import time
import numpy as np

''' Compare the efficiency of spaCy against NLTK '''

# nltk.download('punkt')
# nltk.download('averaged_perceptron_tagger')
# nltk.download('maxent_ne_chunker')
# nltk.download('words')
def relevant_entity(e):
    unwanted = ['ORDINAL', 'CARDINAL', 'QUANTITY', 'MONEY', 'PERCENT', 'TIME', 'DATE']
    return e not in unwanted

def ner_using_spacy(article):
    doc = nlp(article)
    return doc
    # return [(X.text, X.label_) for X in doc.ents]

def ner_using_nltk(article):
    tokens = word_tokenize(article)
    pos = pos_tag(tokens)
    ner = nltk.ne_chunk(pos)
    return ner

nlp = en_core_web_sm.load()
df = pd.read_csv('data/news-2018.csv')
spacy_time = []
nltk_time = []

for i in range(50):
    x = random.randint(1, df.shape[0]-1)
    article = df.loc[x]['article']
    start = time.time()
    ner_using_spacy(article)
    spacy_elapsed = time.time() - start
    spacy_time.append(spacy_elapsed)
    start = time.time()
    ner_using_nltk(article)
    nltk_elpased = time.time() - start
    nltk_time.append(nltk_elpased)
    print("spacy:", spacy_elapsed, "nltk:", nltk_elpased)

print("Spacy average time to recognize entities: ", np.average(np.array(spacy_time)))
print("Nltk average time to recognize entities: ", np.average(np.array(nltk_time)))


#
# @lc app=leetcode id=64 lang=python3
#
# [64] Minimum Path Sum
#
from typing import List
# @lc code=start
class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        h = len(grid)
        w = len(grid[0])
        for i in range(1, w):
            grid[0][i] = grid[0][i-1]+grid[0][i]
        for i in range(1, h):
            grid[i][0] = grid[i-1][0]+grid[i][0]

        for y in range(1, h):
            for x in range(1, w):
                grid[y][x] = min(
                    grid[y][x-1],
                    grid[y-1][x]
                )+grid[y][x]
        return grid[-1][-1]
# @lc code=end

grid = [
  [1,3,1],
  [1,5,1],
  [4,2,1]
]

res = Solution().minPathSum(grid)

print(res)


#!/usr/bin/python3

from gi.repository import Gtk
from gi.repository import GObject
import webbrowser
import urllib.request
import re

def getNyan():
	USER_AGENT = "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.154 Safari/537.36"
	r = urllib.request.Request("http://nyanyan.it/", headers={'User-Agent': USER_AGENT, 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'})
	data = urllib.request.urlopen(r)
	data = data.read()
	found = re.findall( '
.*
', str(data) )
	return found[0]
class nyanIcon:
	def __init__( self ):
		self.site = getNyan()
		self.trayicon = Gtk.StatusIcon()
		self.trayicon.set_from_file( "normal.png" )
		self.trayicon.set_visible( True )
		self.trayicon.connect( "activate", self.openNyan )
		self.trayicon.connect( "popup-menu", self.options )
		GObject.timeout_add( 5000, self.checkNyan )
		Gtk.main()
	def options( self, icon, button, time ):
		self.menu = Gtk.Menu()

		exit = Gtk.MenuItem()
		exit.set_label( "Exit" )
		exit.connect( "activate", Gtk.main_quit )

		self.menu.append( exit )
		self.menu.show_all()

		def pos( menu, icon):
			return (Gtk.StatusIcon.position_menu(menu, icon))
		self.menu.popup(None, None, pos, self.trayicon, button, time)
	def checkNyan( self, *args ):
		tempsite = getNyan()
		if tempsite != self.site:
			self.site = tempsite
			self.trayicon.set_from_file( "new.png" )
		GObject.timeout_add( 60000*5, self.checkNyan )
	def openNyan( self, *args ):
		self.trayicon.set_from_file( "normal.png" )
		webbrowser.open( "http://nyanyan.it/" )

app = nyanIcon()


def internet_check():
        try:
            host = socket.gethostbyname("www.google.com")
            s = socket.create_connection((host, 80), 2)
            return True
        except:
            pass
        return False

def getdata():
    start=time.time()
    resolution=4.096/32767
    gain = 2.815

    x=adc.read_adc(0,1,data_rate=860)
    y=adc.read_adc(1,1,data_rate=860)
    #z=adc.read_adc_difference(3,1,data_rate=860)

    signal1 = round(x*resolution*gain,2)

    signal2 = round(y*resolution*gain,2)

    #signal3 = round(z*resolution,2)

    while 1:
        if time.time()-start>=updateInterval:
            return signal1, signal2

def updatepayload():
    while True:
        global lastUpdateTime
        global initialtime
        global payload
        global messageBuffer
        global timesave
        global lastConnectionTime

        plot= round(time.time() - lastConnectionTime + timesave,2)
        signal,signal2 = getdata()

        messageBuffer['time']= plot
        messageBuffer['signal1']=signal
        messageBuffer['signal2']=signal2
        messageBuffer['signal3']=signal3

        payload.append(messageBuffer)
        messageBuffer={}

        if time.time()-lastConnectionTime>= postingInterval:
            store_data()
            lastConnectionTime=time.time()

        if time.time()-lastConnectionTime+timesave >= timespanInterval+1:
            timesave=0
            return

def store_data():
    global ident
    global lastConnectionTime
    global timesave
    global payload

    timesave= timesave + (time.time() - lastConnectionTime)
    identstr=str(ident)
    filename="data"+identstr+".txt"
    with open(filename, 'w') as outfile:
        json.dump(payload, outfile)
    ident=ident+1
    payload=[]

def senddata():
    global ident

    count=0
    for count in range(0,ident):
        text="data"+str(count)+".txt"
        with open(text) as infile:
            payload = json.load(infile)
        data=(json.dumps(payload,separators=(',', ':')))
        data=data.encode('utf-8')
        data=base64.b64encode(zlib.compress(data,9))
        data=data.decode("utf-8")
        myMQTTClient.publish("data", data, 0)
        time.sleep(1)
    count=0

def get_date():
    utc_now=pytz.utc.localize(datetime.datetime.utcnow())
    Cet_now=utc_now.astimezone(pytz.timezone('Canada/Central'))
    date=Cet_now.strftime("%Y/%m/%d %H:%M:%S")
    return date

def intro():
    global lastConncetionTime
    global lastUpdateTime
    global intialtime
    global messageBuffer

    date=get_date()
    print (date)
    messageBuffer={}
    messageBuffer['Machine']='Tractor: ' + date