'''
Until the definition of ``Client``, direct import from
https://github.com/dstndstn/astrometry.net/blob/master/net/client/client.py
(version: 2018-07-05 commit #26668f3)
with dropping support for python < 3.6.

Some tweak made in the definition of ``query_nova``.
'''
import os
import time
import base64

from urllib.parse import urlencode, quote
from urllib.request import urlopen, Request
from urllib.error import HTTPError

# from exceptions import Exception
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication

from email.encoders import encode_noop

import json

__all__ = ["query_nova"]

def json2python(data):
    try:
        return json.loads(data)
    except:
        pass
    return None

python2json = json.dumps

class MalformedResponse(Exception):
    pass

class RequestError(Exception):
    pass

class Client(object):
    default_url = 'http://nova.astrometry.net/api/'

    def __init__(self, apiurl=default_url):
        self.session = None
        self.apiurl = apiurl

    def get_url(self, service):
        return self.apiurl + service

    def send_request(self, service, args={}, file_args=None):
        '''
        service: str
        args: dict
        '''
        if self.session is not None:
            args.update({'session': self.session})
        print('Python:', args)
        json = python2json(args)
        print('Sending json:', json)
        url = self.get_url(service)
        print('Sending to URL:', url)

        # If we're sending a file, format a multipart/form-data
        if file_args is not None:
            # Make a custom generator to format it the way we need.
            from io import BytesIO
            from email.generator import BytesGenerator as TheGenerator

            m1 = MIMEBase('text', 'plain')
            m1.add_header('Content-disposition',
                          'form-data; name="request-json"')
            m1.set_payload(json)
            m2 = MIMEApplication(file_args[1], 'octet-stream', encode_noop)
            m2.add_header('Content-disposition',
                          'form-data; name="file"; filename="%s"' % file_args[0])
            mp = MIMEMultipart('form-data', None, [m1, m2])

            class MyGenerator(TheGenerator):
                def __init__(self, fp, root=True):
                    # don't try to use super() here; in py2 Generator is not a
                    # new-style class.  Yuck.
                    TheGenerator.__init__(self, fp, mangle_from_=False,
                                          maxheaderlen=0)
                    self.root = root

                def _write_headers(self, msg):
                    # We don't want to write the top-level headers;
                    # they go into Request(headers) instead.
                    if self.root:
                        return
                    # We need to use \r\n line-terminator, but Generator
                    # doesn't provide the flexibility to override, so we
                    # have to copy-n-paste-n-modify.
                    for h, v in msg.items():
                        self._fp.write(('%s: %s\r\n' % (h, v)).encode())
                    # A blank line always separates headers from body
                    self._fp.write('\r\n'.encode())

                # The _write_multipart method calls "clone" for the
                # subparts.  We hijack that, setting root=False
                def clone(self, fp):
                    return MyGenerator(fp, root=False)

            fp = BytesIO()
            g = MyGenerator(fp)
            g.flatten(mp)
            data = fp.getvalue()
            headers = {'Content-type': mp.get('Content-type')}

        else:
            # Else send x-www-form-encoded
            data = {'request-json': json}
            print('Sending form data:', data)
            data = urlencode(data)
            data = data.encode('utf-8')
            print('Sending data:', data)
            headers = {}

        request = Request(url=url, headers=headers, data=data)

        try:
            f = urlopen(request)
            txt = f.read()
            print('Got json:', txt)
            result = json2python(txt)
            print('Got result:', result)
            stat = result.get('status')
            print('Got status:', stat)
            if stat == 'error':
                errstr = result.get('errormessage', '(none)')
                raise RequestError('server error message: ' + errstr)
            return result
        except HTTPError as e:
            print('HTTPError', e)
            txt = e.read()
            open('err.html', 'wb').write(txt)
            print('Wrote error text to err.html')

    def login(self, apikey):
        args = {'apikey': apikey}
        result = self.send_request('login', args)
        sess = result.get('session')
        print('Got session:', sess)
        if not sess:
            raise RequestError('no session in result')
        self.session = sess

    def _get_upload_args(self, **kwargs):
        args = {}
        for key, default, typ in [('allow_commercial_use', 'd', str),
                                  ('allow_modifications', 'd', str),
                                  ('publicly_visible', 'y', str),
                                  ('scale_units', None, str),
                                  ('scale_type', None, str),
                                  ('scale_lower', None, float),
                                  ('scale_upper', None, float),
                                  ('scale_est', None, float),
                                  ('scale_err', None, float),
                                  ('center_ra', None, float),
                                  ('center_dec', None, float),
                                  ('parity', None, int),
                                  ('radius', None, float),
                                  ('downsample_factor', None, int),
                                  ('tweak_order', None, int),
                                  ('crpix_center', None, bool),
                                  ('x', None, list),
                                  ('y', None, list),
                                  # image_width, image_height
                                  ]:
            if key in kwargs:
                val = kwargs.pop(key)
                val = typ(val)
                args.update({key: val})
            elif default is not None:
                args.update({key: default})
        print('Upload args:', args)
        return args

    def url_upload(self, url, **kwargs):
        args = dict(url=url)
        args.update(self._get_upload_args(**kwargs))
        result = self.send_request('url_upload', args)
        return result

    def upload(self, fn=None, **kwargs):
        args = self._get_upload_args(**kwargs)
        file_args = None
        if fn is not None:
            try:
                f = open(fn, 'rb')
                file_args = (fn, f.read())
            except IOError:
                print('File %s does not exist' % fn)
                raise
        return self.send_request('upload', args, file_args)

    def submission_images(self, subid):
        result = self.send_request('submission_images', {'subid': subid})
        return result.get('image_ids')

    def overlay_plot(self, service, outfn, wcsfn, wcsext=0):
        from astrometry.util import util as anutil
        wcs = anutil.Tan(wcsfn, wcsext)
        params = dict(crval1=wcs.crval[0], crval2=wcs.crval[1],
                      crpix1=wcs.crpix[0], crpix2=wcs.crpix[1],
                      cd11=wcs.cd[0], cd12=wcs.cd[1],
                      cd21=wcs.cd[2], cd22=wcs.cd[3],
                      imagew=wcs.imagew, imageh=wcs.imageh)
        result = self.send_request(service, {'wcs': params})
        print('Result status:', result['status'])
        plotdata = result['plot']
        plotdata = base64.b64decode(plotdata)
        open(outfn, 'wb').write(plotdata)
        print('Wrote', outfn)

    def sdss_plot(self, outfn, wcsfn, wcsext=0):
        return self.overlay_plot('sdss_image_for_wcs', outfn,
                                 wcsfn, wcsext)

    def galex_plot(self, outfn, wcsfn, wcsext=0):
        return self.overlay_plot('galex_image_for_wcs', outfn,
                                 wcsfn, wcsext)

    def myjobs(self):
        result = self.send_request('myjobs/')
        return result['jobs']

    def job_status(self, job_id, justdict=False):
        result = self.send_request('jobs/%s' % job_id)
        if justdict:
            return result
        stat = result.get('status')
        if stat == 'success':
            result = self.send_request('jobs/%s/calibration' % job_id)
            print('Calibration:', result)
            result = self.send_request('jobs/%s/tags' % job_id)
            print('Tags:', result)
            result = self.send_request('jobs/%s/machine_tags' % job_id)
            print('Machine Tags:', result)
            result = self.send_request('jobs/%s/objects_in_field' % job_id)
            print('Objects in field:', result)
            result = self.send_request('jobs/%s/annotations' % job_id)
            print('Annotations:', result)
            result = self.send_request('jobs/%s/info' % job_id)
            print('Calibration:', result)

        return stat

    def annotate_data(self, job_id):
        """
        :param job_id: id of job
        :return: return data for annotations
        """
        result = self.send_request('jobs/%s/annotations' % job_id)
        return result

    def sub_status(self, sub_id, justdict=False):
        result = self.send_request('submissions/%s' % sub_id)
        if justdict:
            return result
        return result.get('status')

    def jobs_by_tag(self, tag, exact):
        exact_option = 'exact=yes' if exact else ''
        result = self.send_request(
            'jobs_by_tag?query=%s&%s' % (quote(tag.strip()), exact_option),
            {},
        )
        return result

def query_nova(server=Client.default_url, apikey=None, upload=None,
               upload_xy=None, wait=True, wcs=None, newfits=None,
               kmz=None, annotate=None, upload_url=None,
               scale_units=None, scale_lower=None, scale_upper=None,
               scale_est=None, scale_err=None, center_ra=None,
               center_dec=None, radius=None, downsample_factor=None,
               parity=None, tweak_order=None, crpix_center=None,
               sdss_wcs=None, galex_wcs=None, solved_id=None,
               sub_id=None, job_id=None, myjobs=True,
               jobs_by_exact_tag=None, jobs_by_tag=None, public=None,
               allow_mod=None, allow_commercial=None, sleep_interval=5):
    '''
    Parameters
    ----------
    server: str, optional
        Set server base URL (e.g., ``Client.default_url``).

    apikey: str, optional
        API key for Astrometry.net web service;
        if not given will check AN_API_KEY environment variable

    upload: path-like, optional
        Upload a file (The destination path)

    upload_xy: path-like, optional
        Upload a FITS x,y table as JSON

    wait: bool, optional
        After submitting, monitor job status

    wcs: path-like, optional
        Download resulting wcs.fits file, saving to given filename.
        Implies ``wait=True`` if ``urlupload`` or ``upload`` is not None.

    newfits: path-like, optional
        Download resulting new-image.fits file, saving to given filename.
        Implies ``wait=True`` if ``urlupload`` or ``upload`` is not None.

    kmz: path-like, optional
        Download resulting kmz file, saving to given filename;
        Implies ``wait=True`` if ``urlupload`` or ``upload`` is not None.

    annotate: path-like, optional
        Store information about annotations in give file, JSON format;
        Implies ``wait=True`` if ``urlupload`` or ``upload`` is not None.

    upload_url: str, optional
        Upload a file at specified url.

    scale_units: str in ['arcsecperpix', 'arcminwidth', 'degwidth', 'focalmm']
        Units for scale estimate.

    scale_lower, scale_upper: float, optional
        The lower and upper bounds for the size of the image scale. The unit
        is specified by ``scale_units``.

    scale_est: float, optional
        Estimate of the size of the image scale. The unit is specified by
        ``scale_units``.

    scale_err: float, optional
        Scale estimate error (in PERCENT), e.g., 10 if you estimate can be off
        by 10%.

    center_ra, center_dec: float, optional
        RA center and DEC center in the units of degree.

    radius: float, optional
        Search radius around RA, Dec center in the units of degree.

    downsample_factor: int, optional
        Downsample image by this factor.

    parity: str or int in [0, 1, '0', '1'], optional
        Parity (flip) of image.

    tweak_order: int, optional
        SIP distortion order (if None, defaults to 2).

    crpix_center: bool, optional
        Set reference point to center of image?

    sdss_wcs: list of two str, optional
        Plot SDSS image for the given WCS file; write plot to given PNG filename

    galex_wcs: list of two str, optional
        Plot GALEX image for the given WCS file; write plot to given PNG filename

    solved_id: int, optional
        retrieve result for jobId instead of submitting new image

    sub_id, job_id: str, optional
        Get status of a submission or job

    myjobs: bool, optional
        Get all my jobs

    jobs_by_exact_tab: bool, optional
        Get a list of jobs associated with a given tag--exact match

    jobs_by_tag: bool, optional
        Get a list of jobs associated with a given tag

    public: str, optional
        Hide this submission from other users. If `None` (default), code
        ``'y'`` is used, i.e., it is a public submission. Otherwise, code
        ``'n'`` is used, i.e., private submission, and the input value (which
        is not necessarily ``'n'``) will be added to a list called ``args``.

    allow_mod: str, optional
        Select license to allow derivative works of submission, but only if
        shared under same conditions of original license

    allow_commercial: str in ['n', 'd'], optional
        Select license to disallow commercial use of submission

    sleep_interval: int or float, optional
        How long to wait for printing the information.
    '''

    def _change(param, typefunc, initial=None):
        if param is not initial:
            return typefunc(param)
        return param

    def _parse_const(param, default, const, argslist):
        if param is None:
            return default, argslist
        else:
            argslist.append(param)
            return const, argslist

    if apikey is None:
        # try the environment
        apikey = os.environ.get('AN_API_KEY', None)

    if apikey is None:
        raise ValueError(("API key for Astrometry.net web service;"
                          + "if not given will check AN_API_KEY environment variable"
                          + "You must either specify apikey or set AN_API_KEY"))

    accept_units = [None, 'arcsecperpix', 'arcminwidth', 'degwidth', 'focalmm']

    if sdss_wcs is not None:
        if not isinstance(sdss_wcs, list) or len(sdss_wcs) != 2:
            raise ValueError("sdss_wcs must be a list of length 2.")

    if galex_wcs is not None:
        if not isinstance(galex_wcs, list) or len(galex_wcs) != 2:
            raise ValueError("galex_wcs must be a list of length 2.")

    if scale_units not in accept_units:
        raise ValueError(f"scale_units must be one of {accept_units}")

    if parity not in [None, 0, 1, '0', '1']:
        raise ValueError("parity must be one of [None, 0, 1, '0', '1']. ")

    args = []
    public, args = _parse_const(public, 'y', 'n', args)
    allow_mod, args = _parse_const(allow_mod, 'd', 'sa', args)
    allow_commercial, args = _parse_const(allow_commercial, 'd', 'n', args)

    opt = dict(server=_change(server, str),
               upload=_change(upload, str),
               upload_xy=_change(upload_xy, str),
               wait=_change(wait, bool),
               wcs=_change(wcs, str),
               newfits=_change(newfits, str),
               kmz=_change(kmz, str),
               annotate=_change(annotate, str),
               upload_url=_change(upload_url, str),
               scale_units=_change(scale_units, str),
               scale_lower=_change(scale_lower, float),
               scale_upper=_change(scale_upper, float),
               scale_est=_change(scale_est, float),
               scale_err=_change(scale_err, float),
               center_ra=_change(center_ra, float),
               center_dec=_change(center_dec, float),
               radius=_change(radius, float),
               downsample_factor=_change(downsample_factor, int),
               parity=_change(parity, str),
               tweak_order=_change(tweak_order, int),
               crpix_center=_change(crpix_center, bool),
               sdss_wcs=_change(sdss_wcs, list),
               galex_wcs=_change(galex_wcs, list),
               solved_id=_change(solved_id, int),
               sub_id=_change(sub_id, str),
               job_id=_change(job_id, str),
               myjobs=_change(myjobs, bool),
               jobs_by_exact_tag=_change(jobs_by_exact_tag, str),
               jobs_by_tag=_change(jobs_by_tag, str),
               public=public,
               allow_mod=allow_mod,
               allow_commercial=allow_commercial)

    c = Client(apiurl=server)
    c.login(apikey)

    if opt["upload"] or opt["upload_url"] or opt["upload_xy"]:
        if opt["wcs"] or opt["kmz"] or opt["newfits"] or opt["annotate"]:
            opt["wait"] = True

        kwargs = dict(allow_commercial_use=opt["allow_commercial"],
                      allow_modifications=opt["allow_mod"],
                      publicly_visible=opt["public"])
        if opt["scale_lower"] and opt["scale_upper"]:
            kwargs.update(scale_lower=opt["scale_lower"],
                          scale_upper=opt["scale_upper"],
                          scale_type='ul')
        elif opt["scale_est"] and opt["scale_err"]:
            kwargs.update(scale_est=opt["scale_est"],
                          scale_err=opt["scale_err"],
                          scale_type='ev')
        elif opt["scale_lower"] or opt["scale_upper"]:
            kwargs.update(scale_type='ul')
            if scale_lower:
                kwargs.update(scale_lower=scale_lower)
            if scale_upper:
                kwargs.update(scale_upper=scale_upper)

        for key in ['scale_units', 'center_ra', 'center_dec', 'radius',
                    'downsample_factor', 'tweak_order', 'crpix_center', ]:
            if opt[key] is not None:
                kwargs[key] = opt[key]
        if opt["parity"] is not None:
            kwargs.update(parity=int(opt["parity"]))

        if opt["upload"]:
            upres = c.upload(opt["upload"], **kwargs)
        if opt["upload_xy"]:
            from astrometry.util.fits import fits_table
            T = fits_table(opt["upload_xy"])
            kwargs.update(x=[float(x) for x in T.x], y=[float(y) for y in T.y])
            upres = c.upload(**kwargs)
        if opt["upload_url"]:
            upres = c.url_upload(opt["upload_url"], **kwargs)

        stat = upres['status']
        if stat != 'success':
            raise ValueError(f"Upload failed: status, {stat}\n{upres}")

        opt["sub_id"] = upres['subid']

    if opt["wait"]:
        if opt["solved_id"] is None:
            if opt["sub_id"] is None:
                raise ValueError("Can't --wait without a submission id or job id!")

            while True:
                stat = c.sub_status(opt["sub_id"], justdict=True)
                print('Got status:', stat)
                jobs = stat.get('jobs', [])
                if len(jobs):
                    for j in jobs:
                        if j is not None:
                            break
                    if j is not None:
                        print('Selecting job id', j)
                        opt["solved_id"] = j
                        break
                time.sleep(sleep_interval)

        while True:
            stat = c.job_status(opt["solved_id"], justdict=True)
            print('Got job status:', stat)
            if stat.get('status', '') in ['success']:
                success = (stat['status'] == 'success')
                break
            time.sleep(sleep_interval)

    if opt["solved_id"]:
        # we have a jobId for retrieving results
        retrieveurls = []
        if opt["wcs"]:
            # We don't need the API for this, just construct URL
            url = opt["server"].replace(
                '/api/', '/wcs_file/%i' % opt["solved_id"])
            retrieveurls.append((url, opt["wcs"]))
        if opt["kmz"]:
            url = opt["server"].replace(
                '/api/', '/kml_file/%i/' % opt["solved_id"])
            retrieveurls.append((url, opt["kmz"]))
        if opt["newfits"]:
            url = opt["server"].replace(
                '/api/', '/new_fits_file/%i/' % opt["solved_id"])
            retrieveurls.append((url, opt["newfits"]))

        for url, fn in retrieveurls:
            print('Retrieving file from', url, 'to', fn)
            f = urlopen(url)
            txt = f.read()
            w = open(fn, 'wb')
            w.write(txt)
            w.close()
            print('Wrote to', fn)

        if opt["annotate"]:
            result = c.annotate_data(opt["solved_id"])
            with open(opt["annotate"], 'w') as f:
                f.write(python2json(result))

    if opt["wait"]:
        # behaviour as in old implementation
        opt["sub_id"] = None

    if opt["sdss_wcs"]:
        (wcsfn, outfn) = opt["sdss_wcs"]
        c.sdss_plot(outfn, wcsfn)
    if opt["galex_wcs"]:
        (wcsfn, outfn) = opt["galex_wcs"]
        c.galex_plot(outfn, wcsfn)

    if opt["sub_id"]:
        print(c.sub_status(opt["sub_id"]))
    if opt["job_id"]:
        print(c.job_status(opt["job_id"]))

    if opt["jobs_by_tag"]:
        tag = opt["jobs_by_tag"]
        print(c.jobs_by_tag(tag, None))
    if opt["jobs_by_exact_tag"]:
        tag = opt["jobs_by_exact_tag"]
        print(c.jobs_by_tag(tag, 'yes'))

    if opt["myjobs"]:
        print(jobs)
        jobs = c.myjobs()

    return success


from itertools import permutations

t = int(input())

for _ in range(t):
    n = int(input())
    a = [int(x) for x in input().split()]
    b = [int(x) for x in input().split()]
    neighbors = [[] for _ in range(n)]
    nums = [_ for _ in range(1, len(a) + 1)]
    p = permutations(nums, 2)
    for u, v in p:
        if a[u - 1] - a[v - 1] >= b[u - 1] - b[v - 1]:
            neighbors[u - 1].append(v - 1)

    lengths = [len(lst) for lst in neighbors]
    strong = []
    i = 1
    for length in lengths:
        if length == n - 1:
            strong.append(str(i))
        i += 1
    print(len(strong))
    print(" ".join(strong))


from django.contrib import admin
from django.utils.html import format_html

from .models import TagAssociation
from .app_settings import mumble_active

class TagAssociationAdmin(admin.ModelAdmin):
    list_display = ['tag', 'enabled', '_groups']

    def _list_2_html_w_tooltips(self, my_items: list, max_items: int) -> str:
        """converts list of strings into HTML with cutoff and tooltip"""
        items_truncated_str = ', '.join(my_items[:max_items])
        if not my_items:
            result = None
        elif len(my_items) <= max_items:
            result = items_truncated_str
        else:
            items_truncated_str += ', (...)'
            items_all_str = ', '.join(my_items)
            result = format_html(
                '{}',
                items_all_str,
                items_truncated_str
            )
        return result

    def _groups(self, obj):
        my_groups = [x.name for x in obj.groups.order_by('name')]

        return self._list_2_html_w_tooltips(
            my_groups,
            10
        )

    _groups.short_description = 'groups'
    filter_horizontal = ['groups']

admin.site.register(TagAssociation, TagAssociationAdmin)


from shesha.supervisor.genericSupervisor import GenericSupervisor
from shesha.supervisor.components import AtmosCompass, DmCompass, RtcCompass, TargetCompass, TelescopeCompass, WfsCompass, CoronagraphCompass
from shesha.supervisor.optimizers import ModalBasis, Calibration, ModalGains
import numpy as np
import time

import shesha.constants as scons

from typing import Iterable

class CompassSupervisor(GenericSupervisor):
    """ This class implements generic supervisor to handle compass simulation

    Attributes inherited from GenericSupervisor:
        context : (CarmaContext) : a CarmaContext instance

        config : (config) : Parameters structure

        is_init : (bool) : Flag equals to True if the supervisor has already been initialized

        iter : (int) : Frame counter

    Attributes:
        telescope : (TelescopeComponent) : a TelescopeComponent instance

        atmos : (AtmosComponent) : An AtmosComponent instance

        target : (targetComponent) : A TargetComponent instance

        wfs : (WfsComponent) : A WfsComponent instance

        dms : (DmComponent) : A DmComponent instance

        rtc : (RtcComponent) : A Rtc component instance

        cacao : (bool) : CACAO features enabled in the RTC

        basis : (ModalBasis) : a ModalBasis instance (optimizer)

        calibration : (Calibration) : a Calibration instance (optimizer)

        modalgains : (ModalGains) : a ModalGain instance (optimizer) using CLOSE algorithm

        close_modal_gains : (list of floats) : list of the previous values of the modal gains
    """

    def __init__(self, config, *, cacao: bool = False):
        """ Instantiates a CompassSupervisor object

        Args:
            config: (config module) : Configuration module

        Kwargs:
            cacao : (bool) : If True, enables CACAO features in RTC (Default is False)
                                      Requires OCTOPUS to be installed
        """
        self.cacao = cacao
        self.tel = None
        self.atmos = None
        self.target = None
        self.wfs = None
        self.dms = None
        self.rtc = None
        self.corono = None

        GenericSupervisor.__init__(self, config)
        self.basis = ModalBasis(self.config, self.dms, self.target)
        self.calibration = Calibration(self.config, self.tel, self.atmos, self.dms,
                                       self.target, self.rtc, self.wfs)
        if config.p_controllers is not None:
            self.modalgains = ModalGains(self.config, self.rtc)
        self.close_modal_gains = []

#     ___                  _      __  __     _   _            _
#    / __|___ _ _  ___ _ _(_)__  |  \/  |___| |_| |_  ___  __| |___
#   | (_ / -_) ' \/ -_) '_| / _| | |\/| / -_)  _| ' \/ _ \/ _` (_-<
#    \___\___|_||_\___|_| |_\__| |_|  |_\___|\__|_||_\___/\__,_/__/

    def _init_tel(self):
        """Initialize the telescope component of the supervisor as a TelescopeCompass
        """
        self.tel = TelescopeCompass(self.context, self.config)

    def _init_atmos(self):
        """Initialize the atmosphere component of the supervisor as a AtmosCompass
        """
        self.atmos = AtmosCompass(self.context, self.config)

    def _init_dms(self):
        """Initialize the DM component of the supervisor as a DmCompass
        """
        self.dms = DmCompass(self.context, self.config)

    def _init_target(self):
        """Initialize the target component of the supervisor as a TargetCompass
        """
        if self.tel is not None:
            self.target = TargetCompass(self.context, self.config, self.tel)
        else:
            raise ValueError("Configuration not loaded or Telescope not initilaized")

    def _init_wfs(self):
        """Initialize the wfs component of the supervisor as a WfsCompass
        """
        if self.tel is not None:
            self.wfs = WfsCompass(self.context, self.config, self.tel)
        else:
            raise ValueError("Configuration not loaded or Telescope not initilaized")

    def _init_rtc(self):
        """Initialize the rtc component of the supervisor as a RtcCompass
        """
        if self.wfs is not None:
            self.rtc = RtcCompass(self.context, self.config, self.tel, self.wfs,
                                  self.dms, self.atmos, cacao=self.cacao)
        else:
            raise ValueError("Configuration not loaded or Telescope not initilaized")

    def _init_components(self) -> None:
        """ Initialize all the components
        """

        if self.config.p_tel is None or self.config.p_geom is None:
            raise ValueError("Telescope geometry must be defined (p_geom and p_tel)")
        self._init_tel()

        if self.config.p_atmos is not None:
            self._init_atmos()
        if self.config.p_dms is not None:
            self._init_dms()
        if self.config.p_targets is not None:
            self._init_target()
        if self.config.p_wfss is not None:
            self._init_wfs()
        if self.config.p_controllers is not None or self.config.p_centroiders is not None:
            self._init_rtc()
        if self.config.p_coronos is not None:
            self._init_coronagraph()

        GenericSupervisor._init_components(self)

    def _init_coronagraph(self):
        """ Initialize the coronagraph
        """
        self.corono = CoronagraphCompass()
        for p_corono in self.config.p_coronos:
            self.corono.add_corono(self.context, p_corono, self.config.p_geom, self.target)

    def next(self, *, move_atmos: bool = True, nControl: int = 0,
             tar_trace: Iterable[int] = None, wfs_trace: Iterable[int] = None,
             do_control: bool = True, apply_control: bool = True,
             compute_tar_psf: bool = True, compute_corono: bool=True) -> None:
        """Iterates the AO loop, with optional parameters.

        Overload the GenericSupervisor next() method to handle the GEO controller
        specific raytrace order operations

        Kwargs:
            move_atmos: (bool): move the atmosphere for this iteration. Default is True

            nControl: (int): Controller number to use. Default is 0 (single control configuration)

            tar_trace: (List): list of targets to trace. None is equivalent to all (default)

            wfs_trace: (List): list of WFS to trace. None is equivalent to all (default)

            do_control : (bool) : Performs RTC operations if True (Default)

            apply_control: (bool): if True (default), apply control on DMs

            compute_tar_psf : (bool) : If True (default), computes the PSF at the end of the iteration

            compute_corono: (bool): If True (default), computes the coronagraphic image
        """
        try:
            iter(nControl)
        except TypeError:
            # nControl is not an iterable creating a list
            nControl = [nControl]

        #get the index of the first GEO controller (-1 if there is no GEO controller)
        geo_index = next(( i for i,c in enumerate(self.config.p_controllers)
            if c.type== scons.ControllerType.GEO ), -1)

        if tar_trace is None and self.target is not None:
            tar_trace = range(len(self.config.p_targets))
        if wfs_trace is None and self.wfs is not None:
            wfs_trace = range(len(self.config.p_wfss))

        if move_atmos and self.atmos is not None:
            self.atmos.move_atmos()
        # in case there is at least 1 controller GEO in the controller list : use this one only
        self.tel.update_input_phase()
        if ( geo_index > -1):
            nControl = geo_index
            if tar_trace is not None:
                for t in tar_trace:
                    if self.atmos.is_enable:
                        self.target.raytrace(t, tel=self.tel, atm=self.atmos, ncpa=False)
                    else:
                        self.target.raytrace(t, tel=self.tel, ncpa=False)

                    if do_control and self.rtc is not None:
                        self.rtc.do_control(nControl, sources=self.target.sources)
                        self.target.raytrace(t, dms=self.dms, ncpa=True, reset=False)
                        if apply_control:
                            self.rtc.apply_control(nControl)
                        if self.cacao:
                            self.rtc.publish()
        else:
            if tar_trace is not None: # already checked at line 213?
                for t in tar_trace:
                    if self.atmos.is_enable:
                        self.target.raytrace(t, tel=self.tel, atm=self.atmos,
                                             dms=self.dms)
                    else:
                        self.target.raytrace(t, tel=self.tel, dms=self.dms)

            if wfs_trace is not None: # already checked at line 215?
                for w in wfs_trace:
                    if self.atmos.is_enable:
                        self.wfs.raytrace(w, tel=self.tel, atm=self.atmos)
                    else:
                        self.wfs.raytrace(w, tel=self.tel)

                    if not self.config.p_wfss[w].open_loop and self.dms is not None:
                        self.wfs.raytrace(w, dms=self.dms, ncpa=False, reset=False)
                    self.wfs.compute_wfs_image(w)
            if do_control and self.rtc is not None:
                for ncontrol in nControl : # range(len(self.config.p_controllers)):
                    self.rtc.do_centroids(ncontrol)
                    self.rtc.do_control(ncontrol)
                    self.rtc.do_clipping(ncontrol)

            if apply_control:
                for ncontrol in nControl :
                    self.rtc.apply_control(ncontrol)

            if self.cacao:
                self.rtc.publish()

        if compute_tar_psf:
            for tar_index in tar_trace:
                self.target.comp_tar_image(tar_index)
                self.target.comp_strehl(tar_index)

        if self.corono is not None and compute_corono:
            for coro_index in range(len(self.config.p_coronos)):
                self.corono.compute_image(coro_index)

        if self.config.p_controllers[0].close_opti and (not self.rtc._rtc.d_control[0].open_loop):
            self.modalgains.update_mgains()
            self.close_modal_gains.append(self.modalgains.get_modal_gains())

        self.iter += 1

    def _print_strehl(self, monitoring_freq: int, iters_time: float, total_iters: int, *,
                      tar_index: int = 0):
        """ Print the Strehl ratio SE and LE from a target on the terminal, the estimated remaining time and framerate

        Args:
            monitoring_freq : (int) : Number of frames between two prints

            iters_time : (float) : time elapsed between two prints

            total_iters : (int) : Total number of iterations

        Kwargs:
            tar_index : (int) : Index of the target. Default is 0
        """
        framerate = monitoring_freq / iters_time
        strehl = self.target.get_strehl(tar_index)
        etr = (total_iters - self.iter) / framerate
        print("%d \t %.3f \t  %.3f\t     %.1f \t %.1f" % (self.iter + 1, strehl[0],
                                                          strehl[1], etr, framerate))

    def loop(self, number_of_iter: int, *, monitoring_freq: int = 100,
             compute_tar_psf: bool = True, **kwargs):
        """ Perform the AO loop for <number_of_iter> iterations

        Args:
            number_of_iter: (int) : Number of iteration that will be done

        Kwargs:
            monitoring_freq: (int) : Monitoring frequency [frames]. Default is 100

            compute_tar_psf : (bool) : If True (default), computes the PSF at each iteration
                                                 Else, only computes it each <monitoring_freq> frames
        """
        if not compute_tar_psf:
            print("WARNING: Target PSF will be computed (& accumulated) only during monitoring"
                  )

        print("----------------------------------------------------")
        print("iter# | S.E. SR | L.E. SR | ETR (s) | Framerate (Hz)")
        print("----------------------------------------------------")
        # self.next(**kwargs)
        t0 = time.time()
        t1 = time.time()
        if number_of_iter == -1:  # Infinite loop
            while (True):
                self.next(compute_tar_psf=compute_tar_psf, **kwargs)
                if ((self.iter + 1) % monitoring_freq == 0):
                    if not compute_tar_psf:
                        self.target.comp_tar_image(0)
                        self.target.comp_strehl(0)
                    self._print_strehl(monitoring_freq, time.time() - t1, number_of_iter)
                    t1 = time.time()

        for _ in range(number_of_iter):
            self.next(compute_tar_psf=compute_tar_psf, **kwargs)
            if ((self.iter + 1) % monitoring_freq == 0):
                if not compute_tar_psf:
                    self.target.comp_tar_image(0)
                    self.target.comp_strehl(0)
                self._print_strehl(monitoring_freq, time.time() - t1, number_of_iter)
                t1 = time.time()
        t1 = time.time()
        print(" loop execution time:", t1 - t0, "  (", number_of_iter, "iterations), ",
              (t1 - t0) / number_of_iter, "(mean)  ", number_of_iter / (t1 - t0), "Hz")

    def reset(self):
        """ Reset the simulation to return to its original state
        """
        self.atmos.reset_turbu()
        self.wfs.reset_noise()
        for tar_index in range(len(self.config.p_targets)):
            self.target.reset_strehl(tar_index)
        self.dms.reset_dm()
        self.rtc.open_loop()
        self.rtc.close_loop()

#    ___              _  __ _      __  __     _   _            _
#   / __|_ __  ___ __(_)/ _(_)__  |  \/  |___| |_| |_  ___  __| |___
#   \__ \ '_ \/ -_) _| |  _| / _| | |\/| / -_)  _| ' \/ _ \/ _` (_-<
#   |___/ .__/\___\__|_|_| |_\__| |_|  |_\___|\__|_||_\___/\__,_/__/
#       |_|

    def record_ao_circular_buffer(
            self, cb_count: int, sub_sample: int = 1, controller_index: int = 0,
            tar_index: int = 0, see_atmos: bool = True, cube_data_type: str = None,
            cube_data_file_path: str = "", ncpa: int = 0, ncpa_wfs: np.ndarray = None,
            ref_slopes: np.ndarray = None, ditch_strehl: bool = True,
            projection_matrix: np.ndarray = None):
        """ Used to record a synchronized circular buffer AO loop data.

        Args:
            cb_count: (int) : the number of iterations to record.

            sub_sample:  (int) : sub sampling of the data (default=1, I.e no subsampling)

            controller_index:  (int) :

            tar_index:  (int) : target number

            see_atmos:  (int) : used for the next function to enable or not the Atmos

            cube_data_type:   (int) : if  specified ("tarPhase" or "psfse") returns the target phase or short exposure PSF data cube in the output variable

            cube_data_file_path:  (int) : if specified it will also save the target phase cube data (full path on the server)

            ncpa:  (int) : !!experimental!!!: Used only in the context of PYRWFS + NCPA compensation on the fly (with optical gain)
            defines how many iters the NCPA refslopes are updates with the proper optical gain. Ex: if NCPA=10 refslopes will be updates every 10 iters.

            ncpa_wfs:  (int) : the ncpa phase as seen from the wfs array with dims = size of Mpupil

            ref_slopes:  (int) : the reference slopes to use.

            ditch_strehl:  (int) : resets the long exposure SR computation at the beginning of the Circular buffer (default= True)

            projection_matrix : (np.ndarray) : projection matrix on modal basis to compute residual coefficients

        Returns:
            slopes:  (int) : the slopes CB

            volts:  (int) : the volts applied to the DM(s) CB

            ai:  (int) : the modal coefficient of the residual phase projected on the currently used modal Basis

            psf_le:  (int) : Long exposure PSF over the <cb_count> iterations (I.e SR is reset at the begining of the CB if ditch_strehl=True)

            strehl_se_list:  (int) : The SR short exposure evolution during CB recording

            strehl_le_list:  (int) : The SR long exposure evolution during CB recording

            g_ncpa_list:  (int) : the gain applied to the NCPA (PYRWFS CASE) if NCPA is set to True

            cube_data:  (int) : the tarPhase or psfse cube data (see cube_data_type)
        """
        slopes_data = None
        volts_data = None
        cube_data = None
        ai_data = None
        k = 0
        sthrel_se_list = []
        sthrel_le_list = []
        g_ncpa_list = []

        # Resets the target so that the PSF LE is synchro with the data
        # Doesn't reset it if Ditch_strehl == False (used for real time gain computation)
        if ditch_strehl:
            for i in range(len(self.config.p_targets)):
                self.target.reset_strehl(i)

        # Starting CB loop...
        for j in range(cb_count):
            print(j, end="\r")
            if (ncpa):
                if (j % ncpa == 0):
                    ncpa_diff = ref_slopes[None, :]
                    ncpa_turbu = self.calibration.do_imat_phase(
                            controller_index, -ncpa_wfs[None, :, :], noise=False,
                            with_turbu=True)
                    g_ncpa = float(
                            np.sqrt(
                                    np.dot(ncpa_diff, ncpa_diff.T) / np.dot(
                                            ncpa_turbu, ncpa_turbu.T)))
                    if (g_ncpa > 1e18):
                        g_ncpa = 0
                        print('Warning NCPA ref slopes gain too high!')
                        g_ncpa_list.append(g_ncpa)
                        self.rtc.set_ref_slopes(-ref_slopes * g_ncpa)
                    else:
                        g_ncpa_list.append(g_ncpa)
                        print('NCPA ref slopes gain: %4.3f' % g_ncpa)
                        self.rtc.set_ref_slopes(-ref_slopes / g_ncpa)

            self.atmos.enable_atmos(see_atmos)
            self.next()
            for t in range(len(self.config.p_targets)):
                self.target.comp_tar_image(t)

            srse, srle, _, _ = self.target.get_strehl(tar_index)
            sthrel_se_list.append(srse)
            sthrel_le_list.append(srle)
            if (j % sub_sample == 0):
                if (projection_matrix is not None):
                    ai_vector = self.calibration.compute_modal_residuals(
                            projection_matrix, selected_actus=self.basis.selected_actus)
                    if (ai_data is None):
                        ai_data = np.zeros((len(ai_vector), int(cb_count / sub_sample)))
                    ai_data[:, k] = ai_vector

                slopes_vector = self.rtc.get_slopes(controller_index)
                if (slopes_data is None):
                    slopes_data = np.zeros((len(slopes_vector),
                                            int(cb_count / sub_sample)))
                slopes_data[:, k] = slopes_vector

                volts_vector = self.rtc.get_command(
                        controller_index)  # get_command or get_voltages ?
                if (volts_data is None):
                    volts_data = np.zeros((len(volts_vector),
                                           int(cb_count / sub_sample)))
                volts_data[:, k] = volts_vector

                if (cube_data_type):
                    if (cube_data_type == "tarPhase"):
                        dataArray = self.target.get_tar_phase(tar_index, pupil=True)
                    elif (cube_data_type == "psfse"):
                        dataArray = self.target.get_tar_image(tar_index, expo_type="se")
                    else:
                        raise ValueError("unknown dataData" % cube_data_type)
                    if (cube_data is None):
                        cube_data = np.zeros((*dataArray.shape,
                                              int(cb_count / sub_sample)))
                    cube_data[:, :, k] = dataArray
                k += 1
        if (cube_data_file_path != ""):
            print("Saving tarPhase cube at: ", cube_data_file_path)
            from astropy.io import fits as pf
            pf.writeto(cube_data_file_path, cube_data, overwrite=True)

        psf_le = self.target.get_tar_image(tar_index, expo_type="le")
        return slopes_data, volts_data, ai_data, psf_le, sthrel_se_list, sthrel_le_list, g_ncpa_list, cube_data

    def export_config(self):
        """
        Extract and convert compass supervisor configuration parameters
        into 2 dictionnaries containing relevant AO parameters

        Args:
            root: (object), COMPASS supervisor object to be parsed

        Returns :
            2 dictionaries... See F. Vidal :)
        """
        return self.config.export_config()

    def get_s_pupil(self):
        """
        Returns the so called S Pupil of COMPASS

        Return:
            s_pupil: (np.array) : S Pupil of COMPASS
        """
        return self.config.p_geom.get_spupil()

    def get_i_pupil(self):
        """
        Returns the so called I Pupil of COMPASS

        Return:
            i_pupil: (np.array) : I Pupil of COMPASS
        """
        return self.config.p_geom.get_ipupil()

    def get_m_pupil(self):
        """
        Returns the so called M Pupil of COMPASS

        Return:
            m_pupil: (np.array) : M Pupil of COMPASS
        """
        return self.config.p_geom.get_mpupil()


# code for sentiment analysis

from textblob import TextBlob
from textblob.sentiments import NaiveBayesAnalyzer

def getSentiments(text):
    blob = TextBlob(text, analyzer=NaiveBayesAnalyzer())
    print(blob.sentiment)

training_data = [('it is good 1', 'pos'), ('it is good 3', 'pos'),
                 ('it is good 2', 'pos'), ('it is good 4', 'pos')]

txt2 = 'Service robot implementation a theoretical framework and research agenda'
txt1 = 'He is really hateful hateful hateful'

getSentiments(txt2)
getSentiments(txt1)


import tensorflow as tf
import click
import cv2
import numpy as np
import importlib
import time

from estimation.config import get_default_configuration
from estimation.coordinates import get_coordinates
from estimation.connections import get_connections
from estimation.estimators import estimate
from estimation.renderers import draw

from train_singlenet_mobilenetv3 import register_tf_netbuilder_extensions

def process_frame(cropped, heatmap_idx, model, paf_idx, output_resize_factor):
    input_img = cropped[np.newaxis, ...]
    inputs = tf.convert_to_tensor(input_img)
    outputs = model.predict(inputs)
    pafs = outputs[paf_idx][0, ...]
    heatmaps = outputs[heatmap_idx][0, ...]
    cfg = get_default_configuration()
    coordinates = get_coordinates(cfg, heatmaps)
    connections = get_connections(cfg, coordinates, pafs)
    skeletons = estimate(cfg, connections)
    canvas = draw(cfg, cropped, coordinates, skeletons, resize_fac=output_resize_factor)

    return canvas

@click.command()
@click.option('--video', required=True,
              help='Path to the input video file')
@click.option('--output-video', required=True,
              help='Path to the output video file')
@click.option('--create-model-fn', required=True,
              help='Name of a function to create model instance. Check available names here: .models._init__.py')
@click.option('--input-size', required=True, type=int,
              help='Model''s input size ')
@click.option('--output-resize-factor', required=True, type=int,
              help='Output resize factor')
@click.option('--paf-idx', default=2, type=int,
              help='Index of model''s output containing PAF')
@click.option('--heatmap-idx', default=3, type=int,
              help='Index of model''s output containing heatmap')
@click.option('--frames-to-analyze', default=None, type=int,
              help='Number of the frames to analyze')
@click.option('--frame-ratio', default=1,
              help='Analyze every [n] frames')
def main(video, output_video, create_model_fn, input_size, output_resize_factor, paf_idx, heatmap_idx, frames_to_analyze, frame_ratio):

    register_tf_netbuilder_extensions()

    module = importlib.import_module('models')
    create_model = getattr(module, create_model_fn)
    model = create_model(pretrained=True)

    # Video reader
    cam = cv2.VideoCapture(video)
    input_fps = cam.get(cv2.CAP_PROP_FPS)
    ret_val, orig_image = cam.read()
    video_length = int(cam.get(cv2.CAP_PROP_FRAME_COUNT))

    if frames_to_analyze is None:
        frames_to_analyze = video_length

    # Video writer
    output_fps = input_fps / frame_ratio
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    w = orig_image.shape[1]
    h = orig_image.shape[0]
    scale = input_size / w if w < h else input_size / h
    out = cv2.VideoWriter(output_video, fourcc, output_fps, (input_size, input_size))

    i = 0
    while (cam.isOpened()) and ret_val is True and i < frames_to_analyze:
        if i % frame_ratio == 0:

            tic = time.time()

            im = cv2.resize(orig_image, (0, 0), fx=scale, fy=scale)
            new_w = im.shape[1]
            new_h = im.shape[0]
            if new_w > new_h:
                offset = (new_w - input_size) // 2
                cropped = im[0: input_size, offset: offset + input_size]
            else:
                offset = (new_h - input_size) // 2
                cropped = im[offset: offset + input_size, 0: input_size]

            canvas = process_frame(cropped, heatmap_idx, model, paf_idx, output_resize_factor)

            print('Processing frame: ', i)
            toc = time.time()
            print('processing time is %.5f' % (toc - tic))

            out.write(canvas)

        ret_val, orig_image = cam.read()

        i += 1

if __name__ == '__main__':
    main()


import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'    # to give away the GPU warning in TF
from pandas import read_csv
from matplotlib import pyplot as plt
import numpy as np
import copy

my_path = os.path.dirname(os.path.realpath(__file__))  #gets current path of the file
filename = my_path + "/data.csv"   #gets path of the file
df = read_csv(filename, header = None)
#print(df)
print("DATAFRAME :")
print(df.shape)

images = df.loc[:, :783]
labels = df.loc[:, 784:]

clean_images = images.values
print("\nCLEAN IMAGES :")

print(type(clean_images))
print(clean_images.shape)

print("\n", type(images), type(labels))
print(images.shape)

# Visualize original images

for i in range(2):
    sample = clean_images[i, :]
    print(sample)
    sample = sample.reshape(28, 28)
    plt.gray()
    plt.imshow(sample)
    plt.show()
    print("Original image : ")
    print(sum(sum(sample)))
    print(784 - sum(sum(sample)))

# Add noise and visualize noisy images

N = clean_images.shape[1]
print("Dimension : ", N)
n = int(0.05 * N)  # no. of noisy pixels
print("Number of noisy pixels : ", n)
pixels = N
noisy_images = copy.deepcopy(clean_images)

# Generate noisy pixels
seed = 10
np.random.seed(seed)  # first call
random_pixels = np.random.randint(0, 784, size = n)
print("RANDOM PIXEL VALUES ", random_pixels)
seed += 1
s = 28  # set random value of seed so that it flips the same bits each time for the same image
examples = clean_images.shape[0]
print(examples)
for k in range(examples):
    for i in range(n):
        np.random.seed(s)  # first call
        noise = np.random.randint(784)
        print("SEED  VALUES : ")
        print(noise)
        s += 1
        noisy_images[k, noise] = (1 - noisy_images[k, noise])
    # print("Noisy image : ")
    # print(sum(noisy_images[k, :]))
    # print(784 - sum(noisy_images[k, :]))
    # reshaped_noisy_image = noisy_images[k, :].reshape(28, 28)
    # print(reshaped_noisy_image.shape)
    #im_noisy_reshaped = im_noisy[k, :].reshape(28, 28)
    # plt.gray()
    # plt.imshow(reshaped_noisy_image)
    # plt.show()

print(clean_images[1,:])
print(noisy_images[1,:])
print(clean_images[1,:] - noisy_images[1, :])

np.savetxt(my_path + "/noisy_images_5.csv", noisy_images, fmt='%i', delimiter=",")
# np.savetxt(my_path + "/labels_10.csv", labels, fmt='%i')
# np.savetxt(my_path + "/clean_images.csv", clean_images, fmt='%i', delimiter=",")


# coding; utf-8

import logging
log = logging.getLogger(__name__)

import sqlalchemy
from sqlalchemy.sql import and_, or_, desc
from sqlalchemy.sql.expression import func
from sqlalchemy.orm.exc import NoResultFound
from sqlalchemy.orm.relationships import RelationshipProperty
from sqlalchemy.orm.properties import  ColumnProperty

from .config import config

class RestMixin(object):

    @classmethod
    def rest_get_by_id(cls, id):
        obj = config.sqlalchemy_session().query(cls).get(id)

        if obj is None:
            raise NoResultFound

        return obj

    @classmethod
    def rest_get_by_ids(cls, appstruct):
        ids = [el['id'] for el in appstruct]

        return (config.sqlalchemy_session().query(cls)
            .filter(cls.id.in_(ids))
            .all())

    @classmethod
    def _rest_get_inner_query(cls, session, query, query_params):
        return query

    @classmethod
    def _rest_get_joined_query(cls, session, query, query_params):
        return query

    @classmethod
    def rest_get_list(cls, query_params):
        """
        cls._rest_search_columns = [cls.name, cls.description] - list of columns for search filtering
        :param start: number (default 0)
        :param limit: number or None
        :param order: {col: '', dir: 'asc|desc'} or None
        :param search:
        :param filters:
        :param query: sqlalchemy query
        :return: result of an executed query
        """

        def apply_search(query):
            search_columns = getattr(cls, '_rest_search_columns', None)
            if not search_columns or not 'search' in query_params:
                return query

            search = query_params['search'].lower()

            if len(search_columns) == 1:
                col = search_columns[0]
                search_filter = func.lower(col).like('%' + search + '%')
            else:  # > 1
                clauses = [func.lower(col).like('%' + search + '%') for col in search_columns]
                search_filter = or_(*clauses)

            return query.filter(search_filter)

        def apply_filters(query):
            if 'filters' not in query_params:
                return query

            filters = query_params['filters']

            for key, val in filters.items():
                op, field_name = key.split('_', 1)

                try:
                    field = getattr(cls, field_name)
                except AttributeError:
                    log.warn('RestMixin.rest_get_list(): filter "%s=%s": unknown attribute %s',
                             key, val, field_name)
                    continue

                if op == 'e':
                    query = query.filter(field == val)
                elif op == 'n':
                    query = query.filter(or_(field == val, field == None))
                elif op == 'l':
                    query = query.filter(func.lower(field).like('%' + val.lower() + '%'))
                elif op == 's':
                    query = query.filter(func.lower(field).like(val.lower() + '%'))
                else:
                    log.error('get_for_rest_grid: filter "%s=%s": unknown op: %s' % (key, val, op))

            return query

        def apply_order(query):
            if 'order' not in query_params:
                return query

            order = query_params['order']
            order_split = order['col'].split('.')

            try:
                order_attr = getattr(cls, order_split[0])
            except AttributeError:
                log.error('get_for_rest_grid: sort key %s: unknown attribute %s.%s' % (order['col'], cls.__name__, order['col']))
                return query

            for el in order_split[1:]:
                if not isinstance(order_attr.property, RelationshipProperty):
                    log.error('get_for_rest_grid: sort key %s: not a RelationshipProperty: %s' % (order['col'], str(order_attr.property)))
                    return query

                entity = order_attr.property.mapper.entity

                try:
                    order_attr = getattr(entity, el)
                except AttributeError:
                    log.error('get_for_rest_grid: sort key %s: unknown attribute %s.%s' % (order['col'], entity.__name__, el))
                    return query

            if not isinstance(order_attr.property, ColumnProperty):
                log.error('get_for_rest_grid: sort key %s: not a ColumnProperty: %s' % (order['col'], str(order_attr.property)))
                return query

            return query.order_by(desc(order_attr) if order['dir'] == 'desc' else order_attr)

        def apply_limit(query):
            if 'limit' in query_params:
                query = query.limit(query_params['limit'])

            if 'start' in query_params:
                query = query.offset(query_params['start'])

            return query

        # select * from (select * from users limit 10 offset 10) as u left join files f on u.id = f.user_id
        # http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#using-subqueries

        session = config.sqlalchemy_session

        q_inner = session().query(cls)
        q_inner = cls._rest_get_inner_query(session, q_inner, query_params)
        q_inner = apply_search(q_inner)
        q_inner = apply_filters(q_inner)
        q_count = q_inner  # count() query should not have ORDER BY
        q_inner = apply_order(q_inner)
        q_inner = apply_limit(q_inner)

        q_joined = q_inner.from_self()
        q_joined = cls._rest_get_joined_query(session, q_joined, query_params)
        q_joined = apply_order(q_joined)

        return q_count.count(), q_joined.all()

    def rest_add(self, flush=False):
        config.sqlalchemy_session().add(self)
        if flush:
            config.sqlalchemy_session().flush()

    def rest_delete(self, flush=False):
        config.sqlalchemy_session().delete(self)
        if flush:
            config.sqlalchemy_session().flush()


import re
import my_Selenium
from pyecharts.globals import ThemeType
from pyecharts import options as opts
from pyecharts.charts import *
import pandas as pd
def City(city):
    #判断数据是否是需要统计的城市
    list = ['河北', '山西', '辽宁', '吉林', '黑龙江', '江苏', '浙江', '安徽', '福建', '江西', '山东', '河南', '湖北', '湖南', '广东', '海南',
                 '四川', '贵州', '云南', '陕西', '甘肃', '青海', '内蒙古', '广西', '西藏', '宁夏', '新疆', '北京', '天津', '上海', '重庆','兵团']

    return list.count(city)

def write2excel(data,cn1,cn2,name):
    #使用pandas导出excel
    write2exce = pd.DataFrame(data,index=list(range(1,len(data.keys())+1)),columns=[cn1,cn2])
    write2exce[cn1] = data.keys()
    write2exce[cn2] = data.values()
    write2exce.to_excel(name)

def my_Bar(data,name):
    #使用Bar导出柱状图
    bar = Bar(init_opts=opts.InitOpts(theme=ThemeType.LIGHT))
    bar.add_xaxis(list(data.keys()))
    bar.add_yaxis("新增人数", list(map(int, data.values())), category_gap= '80%')
    bar.set_global_opts(
        title_opts=opts.TitleOpts(title=name),
        # 设置数据缩放滑块
        datazoom_opts=opts.DataZoomOpts(),
    )
    bar.render(name)

def my_main():
    # 获取url
    for cnt in range(1,40):
        if cnt == 1 :
            url_dir = "http://www.nhc.gov.cn/xcs/yqtb/list_gzbd.shtml"
        else:
            url_dir = 'http://www.nhc.gov.cn/xcs/yqtb/list_gzbd_'+str(cnt)+'.shtml'
        #正则筛url
        contents_directory = my_Selenium.getURL_dir(url_dir)
        contents_directory = re.findall('
.*?
',contents_directory,re.DOTALL)
        content_directory = re.findall('href="(.*?)" target', contents_directory[0], re.DOTALL)
        i = 0
        for url_target_half in content_directory:

            url_target = "http://www.nhc.gov.cn" + url_target_half  # 生成目标URL
            #打开网页
            contents_target = my_Selenium.getURL_dir(url_target)
            # 获取时间
            date_Get = re.findall('
截至(.*?)24时', contents_target)
            date_Get_year = re.findall('发布时间.+?([0-9]{4})', contents_target, re.DOTALL)
            #获取全部段落
            content_target = re.findall('>(.*?)<', contents_target)
            text = ''
            for i in content_target:
                text += i
            ##正则筛选目标数据
            text_target = re.findall('新增确诊病例(.*?)例',text)[0]
            text_target_null = re.findall('新增无症状感染者(.*?)例',text)[0]
            data_nation = {}
            data_nation['新增确诊病例'] = text_target
            data_nation['新增无症状感染者'] = text_target_null

            #正则筛选目标数据
            city_newcases = re.findall('本土病例.*?(.*?)）',text)[0]
            city_newcases_key = re.findall('([\u4E00-\u9FA5]+?)[0-9]*?例',city_newcases)
            city_newcases_value = re.findall('[\u4E00-\u9FA5]+?([0-9]*?)例',city_newcases)

            data_newcases = {}
            # 判断是否在统计城市
            for i  in range(0,len(city_newcases_key)):
                if City(city_newcases_key[i]) == 1 :
                    data_newcases[city_newcases_key[i]] = city_newcases_value[i]

            # 正则筛选目标数据
            data_null = {}
            city_null = re.findall('本土[0-9]*?例（(.*?)）',text)[0]
            city_null_key = re.findall('([\u4E00-\u9FA5]+?)[0-9]*?例',city_null)
            city_null_value = re.findall('[\u4E00-\u9FA5]+?([0-9]*?)例',city_null)
            #判断是否在统计城市
            for i  in range(0,len(city_null_key)):
                if City(city_null_key[i]) == 1 :
                    data_null[city_null_key[i]] = city_null_value[i]

            #导出execel表格
            write2excel(data=data_nation, cn1='新增类型', cn2='新增数量', name='中国大陆'+date_Get_year[0]+'年' + date_Get[0] + '疫情通报.xlsx')
            write2excel(data_newcases,'省份','新增确诊','各省份'+date_Get_year[0]+'年' + date_Get[0] + '新增确诊疫情通报.xlsx')
            write2excel(data_null,'省份','无症状感染者','各省份'+date_Get_year[0]+'年' + date_Get[0] + '无症状感染者疫情通报.xlsx')
            #数据可视化
            my_Bar(data_nation,'中国大陆'+date_Get_year[0]+'年'+date_Get[0]+'疫情柱状图.html')
            my_Bar(data_newcases,'各省份'+date_Get_year[0]+'年'+date_Get[0]+'新增确诊柱状图.html')
            my_Bar(data_null,'各省份'+date_Get_year[0]+'年'+date_Get[0]+'新增无症状柱状图.html')
            #数据热点
            my_Selenium.hot_spot('疫情 '+date_Get_year[0]+'年'+date_Get[0])

if __name__ == '__main__':
    my_main()


#
# Buffer
#
# The buffer class implements the mechanisms required to solve the jitter issues
# The ADT used is a circular queue that stores the packed received by the other
# interlocutor. The main purpose is to decrement the jitter effects by increasing
# the latency. In order to ensure that the queue has enough chunks to mitigate
# the jitter, the queue should be half filled. For that reason the initialisation
# waits to fill the half of the queue. A blank chunk with silence is played as
# a last resort in case to not have any chunk.

# import numpy as np
# Package to use several math functions
import math

# Package to performs conversions between Python values and C structs represented
# as Python strings
import struct

# Buffer is based by extending minimal class
from minimal import *
#import minimal

class Buffer(Minimal):
    """
    Class that implements the buffer required to reduce the effect of the jitter.
    Inherits from Minimal used in Milestone 5
    """

    MAX_CHUNK = 65536
    """(int) (static): Max chunk size"""

    BUFFER_SIZE = 8
    """(int) (static): Buffer size by default"""

    def __init__(self):
        """
        Class constructor

        The constructor class requires several arguments that must be provided before
        to get an buffer instance. The constructor calls the constructor of Minimal class
        and also creates all variables needed, including the buffer array.
        """

        super().__init__()

        self.jitter_time = args.jitter

        self.jitter_to_chunk_time = math.ceil(args.jitter / (self.chunk_time * 1000))
        """(int) Result to convert jitter time to chunks size"""

        self.buffer_size = 2 * self.jitter_to_chunk_time
        """(int) Size of the buffer. It is the double of jitter_to_chunk_time"""

        self.filled_cells = 0
        """(int) Number of filled cells in the buffer"""

        self.index_local_cell = np.uint16(0)
        """(int) Index of the current chunk"""

        self.index_remote_cell = np.uint16(0)
        """(int) Index of the current chunk to send"""

        self.buffer_head = np.uint16(0)
        """(int) Index of the head of the buffer"""

        # Print minimal information to visualize initialisation
        print("Chunk time: ", self.chunk_time * 1000)
        print("Jitter time: ", self.jitter_time)
        print("Jitter to chunk: ", self.jitter_to_chunk_time)
        print("Tamaño buffer: ", self.buffer_size)

        self.current_cell = np.uint16(0)

        self.to_u16 = lambda x : np.uint16(x)
        """(lambda) Lambda function to cast to 16 bits unsigned integer"""

        self.update_local_index = lambda: self.to_u16((self.index_local_cell + 1) % Buffer.MAX_CHUNK)
        """(lambda) Lambda function to update (increase) the front of the queue"""

        self.update_remote_index = lambda: self.to_u16((self.index_remote_cell + 1) % Buffer.MAX_CHUNK)
        """(lambda) Lambda function to update (increase) the rearof the queue"""

        self.index_package = lambda chunk_sequence: self.to_u16(chunk_sequence % self.buffer_size)
        """(lambda) Lambda function to calculate the position of the package in the queue"""

        self.increment_cells = lambda cells: cells + 1
        """(lambda) Lambda function to increment variable"""

        self.decrement_cells = lambda cells: cells - 1
        """(lambda) Lambda function to decrement variable"""

        self.update_head = lambda : (self.buffer_head + 1) % self.buffer_size
        """(lambda) Lambda function to update the head of the buffer"""

        self.pack_format = f"H{args.frames_per_chunk * self.NUMBER_OF_CHANNELS}h"
        """(string) The format used in struct methods"""

        # Create fixed empty array
        self.buffer = [None] * self.buffer_size
        """(list) A list that stores the buffer"""

        for i in range(len(self.buffer)):
            self.buffer[i] = self.zero_chunk

        self.half_buffer = False
        """(Boolean) Controls the initial state of the buffer that requires to be half-filled"""

    # THIS IS THE CALLBACK
    def record_send_and_play(self, indata, outdata, frames, time, status):
        """ Callback function used by Sounddevice

        In non blocking audio stream, a new thread is created
        and periodically executes the callback method. Usually
        the call occurs when new input data (indata) is available to
        manipulate. Is recommended to manage output stream in the callback
        method also.

        The arguments are imposed to Sounndevice callback signature

        """
        self.send(indata)
        self.play(outdata)

    def play(self, outdata):
        """ Places the next chunk of audio in output streams

            Calculates the position of next cell in buffer an retrieves it
            in order to assign to the outdata stream.
        Parameters
        ----------
            outdata
                Output stream used by Sounddevice
        """
        if not self.half_buffer:
            to_play = self.zero_chunk
        else:
            #position = self.index_local_cell % self.buffer_size
            to_play = self.buffer[self.buffer_head]
            self.buffer[self.buffer_head] = self.zero_chunk
            self.filled_cells = self.filled_cells - 1
            self.buffer_head = self.update_head()
            #self.index_local_cell = self.update_local_index()
        outdata[:] = to_play

    def receive_and_buffer(self):
        """ Receive data from the socket and stores it in the buffer

            This method is executed in the main thread in a loop. It tries to retrieve
            data from the socket. If a packet is found in the buffer, the method
            extracts the sequence number and the payload. Converts the payload in a
            suitable numpy array an then stores it in the buffer uysing the sequence
            number provided.

            Raises
            ------
                socket.timeout
                    Resource temporarily unavailable. Socket may be empty.
                    In non-blocking UDP socket an exception of this type is raised.
        """

        try:
            packed_data = self.receive()
            unpacked_data = struct.unpack(self.pack_format, packed_data)
            chunk_index = self.to_u16(unpacked_data[0])
            data = np.array(unpacked_data[1:])
            data = data.reshape(args.frames_per_chunk, self.NUMBER_OF_CHANNELS)
        except Exception as e:
            pass
        else :
            # print("Recibiendo: ", chunk_index)
            self.buffer[chunk_index % self.buffer_size] = data
            self.filled_cells = self.filled_cells+1
            # print("Filled cells: " , self.filled_cells)
        if (self.filled_cells >= (len(self.buffer)/2)):
            self.half_buffer = True

    def start(self):
        self.sock.settimeout(0)
        """Starts sounddevice audio stream via callback method"""
        with sd.Stream(samplerate=args.frames_per_second, blocksize=args.frames_per_chunk, dtype=self.SAMPLE_TYPE, channels=self.NUMBER_OF_CHANNELS, callback=self.record_send_and_play):
            while True:
                self.receive_and_buffer()

    def send(self, data):
        """ Send data over sender socket

            Uses parent's method to send data.

            Parameters
            ----------
                data
                    Data to send over UDP socket. A numpy array is expected
        """
        chunk = struct.pack(self.pack_format, self.index_remote_cell, *(data.flatten()))
        # print("Enviando: ", self.index_remote_cell)
        self.index_remote_cell = self.update_remote_index()
        super().send(chunk)

if __name__ == "__main__":
    parser.description = __doc__
    try:
        argcomplete.autocomplete(parser)
    except Exception:
        print("argcomplete not working :-/")
    args = parser.parse_known_args()[0]

    if args.show_stats or args.show_samples:
        intercom = Buffer()
    else:
        intercom = Buffer()
    try:
        intercom.start()
    except KeyboardInterrupt:
        parser.exit("\nInterrupted by user")


from argparse import _VersionAction
from pstats import Stats
from django.shortcuts import render
from django.http import HttpResponse
from django.http.response import JsonResponse
from rest_framework.parsers import JSONParser
from rest_framework import status

from shinobiAPI.models import Nation
from shinobiAPI.serializers import NationSerializer
from rest_framework.decorators import api_view

def index(request):
    return HttpResponse("The Nation Table")

@api_view(['GET', 'POST', 'DELETE'])
def nation_list(request):

    if request.method =='GET':
        nations = Nation.objects.all()

        nation_serilizer = NationSerializer(nations, many=True)
        return JsonResponse(nation_serilizer.data, safe=False)
    elif request.method=='POST':
        nation_data =JSONParser().parse(request)
        nation_serializer = NationSerializer(data=nation_data)
        if nation_serializer.is_valid():
            nation_serializer.save()
            return JsonResponse(nation_serializer.data, status=status.HTTP_201_CREATED)
        return JsonResponse(nation_serializer.errors,status=status.HTTP_400_BAD_REQUEST)
    elif request.method =='DELETE':
        count = Nation.objects.all.delete()
        return JsonResponse({'message': '{} All nations are deleted successfully! '.format(count[0])}, status=status.HTTP_204_NO_CONTENT)

@api_view(['GET', 'PUT', 'DELETE'])
def nation_details(request,pk):
    try:
        nation = Nation.objects.get(pk=pk)
    except nation.DoesNotExist:
        return JsonResponse({'message': 'The nation does not exist in the table'}, status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        nation_serializer = NationSerializer(nation)
        return JsonResponse(nation_serializer.data)
    elif request.method == 'PUT':
        nation_data = JSONParser().parse(request)
        nation_serializer = NationSerializer(nation, data=nation_data)
        if nation_serializer.is_valid():
            nation_serializer.save()
            return JsonResponse(nation_serializer.data)
        return JsonResponse(nation_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    elif request.method == 'DELETE':
        nation.delete()
        return JsonResponse({'message': 'Nation was deleted successfully!'}, status=status.HTTP_204_NO_CONTENT)


from cerberus import Validator
from cerberus import TypeDefinition

class ParserModelType:
    """Defines a type for parser classes."""

    name = None
    is_model = False
    func = None

    def __init__(self, name):
        self.name = name
        if name.endswith('ModelElement'):
            self.is_model = True
            self.func = getattr(__import__("aminer.parsing", fromlist=[name]), name)
        else:
            self.is_model = False
            # we need this import:
            # skipcq: PTC-W0034
            self.func = getattr(__import__(name), 'get_model')

    def __str__(self):
        return self.name

class AnalysisType:
    """Defines a type for analysis classes."""

    name = None
    func = None

    def __init__(self, name):
        self.name = name
        self.func = getattr(__import__("aminer.analysis", fromlist=[name]), name)

    def __str__(self):
        return self.name

class EventHandlerType:
    """Defines a type for event classes."""
    name = None
    func = None

    def __init__(self, name):
        self.name = name
        self.func = getattr(__import__("aminer.events", fromlist=[name]), name)

    def __str__(self):
        return self.name

parser_type = TypeDefinition('parsermodel', (ParserModelType, str), ())
analysis_type = TypeDefinition('analysistype', (AnalysisType, str), ())
event_handler_type = TypeDefinition('eventhandlertype', (EventHandlerType, str), ())

class ConfigValidator(Validator):
    """Validates values from the configs."""

    types_mapping = Validator.types_mapping.copy()
    types_mapping['parsermodel'] = parser_type
    types_mapping['analysistype'] = analysis_type
    types_mapping['eventhandlertype'] = event_handler_type

    # we skip the following issue, otherwise an
    # "must have self"-issue will pop up
    # skipcq: PYL-R0201
    def _normalize_coerce_toparsermodel(self, value):
        """Create a ParserModelType from the string representation."""
        if isinstance(value, str):
            return ParserModelType(value)
        return None

    # we skip the following issue, otherwise an
    # "must have self"-issue will pop up
    # skipcq: PYL-R0201
    def _normalize_coerce_toanalysistype(self, value):
        """Create a AnalysisType from the string representation."""
        if isinstance(value, str):
            return AnalysisType(value)
        return None

    # we skip the following issue, otherwise an
    # "must have self"-issue will pop up
    # skipcq: PYL-R0201
    def _normalize_coerce_toeventhandlertype(self, value):
        """Create a EventHandlerType from the string representation."""
        if isinstance(value, str):
            return EventHandlerType(value)
        return None

    def _validate_has_start(self, has_start, field, value):
        """
        Test if there is a key named 'has_start'.
        The rule's arguments are validated against this schema:
        {'type': 'boolean'}
        """
        seen_start = False
        for var in value:
            if "start" in var and var['start'] is True:
                if seen_start:
                    self._error(field, "Only one parser with 'start'-key is allowed")
                seen_start = True
        if has_start and not seen_start:
            self._error(field, "Parser must contain a 'start'-key")


import requests
import xmltodict

def convert_xml():
    r = requests.get('http://www.w3schools.com/xml/cd_catalog.xml')
    response = xmltodict.parse(r.text)
    ret = []
    for p in response['CATALOG']['CD']:
        ret.append(p['TITLE'])
    return ret

if __name__ == '__main__':
    print(convert_xml())


import pandas as pd
import numpy as np
''' In this file, I've hard coded several of the membership functions for each of the parameters.'''

def trapmf(x, args):
    '''Trapezoidal membership function'''
    a, b, c, d = args['a'], args['b'], args['c'], args['d']
    val = 0
    if x < a or x > d:
        val = 0
    elif a < x and x <= b:
        val = (x - a) / (b - a)
    elif b <= x and x <= c:
        val = 1
    elif c<=x and x <= d:
        val = (d - x) / (d-c)

    return val


'''
@File  : JZ33_丑数.py
@Author: Swift
@Date  : 2021/3/24 21:54
@Link  : https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?tpId=13&tqId=11186&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking&tab=answerKey
@Desc  : 把只包含质因子2、3和5的数称作丑数（Ugly Number）。例如6、8都是丑数，但14不是，因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
@Method: https://leetcode-cn.com/problems/chou-shu-lcof/solution/mian-shi-ti-49-chou-shu-dong-tai-gui-hua-qing-xi-t/
'''

# -*- coding:utf-8 -*-
class Solution:
    def GetUglyNumber_Solution(self, index):
        dp = [1]*index
        a, b, c = 0, 0, 0
        for i in range(1, index):
            n1, n2, n3 = dp[a]*2, dp[b]*3, dp[c]*5
            dp[i] = min(n1, n2, n3)
            if dp[i] == n1:
                a += 1
            if dp[i] == n2:
                b += 1
            if dp[i] == n3:
                c += 1
        return dp[-1]


class Node:
    """Like for stacks, we need a node class which will contain the data and a pointer to the next node"""

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

class Queue:
    """Next we need the Queue class itself which will contain a
    constructor initializing the queue and then the methods we require"""

    def __init__(self):
        self.front = None
        self.last = None

    def enqueue(self, value):
        """The enqueue operation will add an element at the end of the queue"""
        node = Node(value)
        if not self.front:
            self.last = node
            self.front = node

        else:
            self.last.next = node
            self.last = node

    def dequeue(self):
        """Next comes the dequeue operation which removes the front element of the queue"""
        # if self.last == None:
        #   Exception("Queue is empty")
        # return
        if self.last == self.front:
            self.last = None
            self.front = self.front.next
        elif self.last == None:
            Exception("Queue is empty")
        return

    def is_empty(self):
        """If the queue is empty, it will print an appropriate message"""
        try:
            if self.last == None:
                return
        except:
            Exception("Queue is empty")

    def peek(self):
        """Now comes the peek method which will return the element at the front of the queue"""
        return self.front.value


# import required modules
from delivery_schedule import delivery_schedule
import math
from typing import List, Tuple
from tabulate import tabulate

# define function to extract stops from a schedule for a given day
def get_stops_from_schedule(schedule: dict, day: str) -> List[tuple]:
    stops = []
    # loop over each delivery on the given day
    for delivery in schedule[day]["deliveries"]:
        # extract the location coordinates of the delivery and append to stops list
        stop = (delivery["location"]["x"], delivery["location"]["y"])
        stops.append(stop)
    return stops

# define function to calculate distance between two points in 2D space
def distance(x1, y1, x2, y2):
    distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
    return distance

# define function to calculate time required to travel a given distance at a given speed
def calculate_delivery_time(distance, speed):
    time = distance / speed
    return time

# define function to calculate the optimal route to visit all stops in a given schedule for a day
def calculate_route(stops):
    # initialize current location of the van to (0, 0)
    current_location = (0, 0)
    # list to hold the route
    route = []
    # loop until all stops have been visited
    while stops:
        # find the closest stop to the current location
        closest_stop = min(stops, key=lambda s: distance(current_location[0], current_location[1], s[0], s[1]))
        # add the closest stop to the route
        route.append(closest_stop)
        # remove the closest stop from the list of stops
        stops.remove(closest_stop)
        # update the current location of the van
        current_location = closest_stop
    # add the starting point to the route
    route.append((0, 0))
    return route

# define function to sort deliveries in a schedule for a given day based on optimal route
def sort_deliveries_by_route(info):
    # Get the stops for the current day
    stops = [(d['location']['x'], d['location']['y']) for d in info['deliveries']]
    # Calculate the route for the day
    route = calculate_route(stops)
    # Sort the deliveries by their position in the route
    deliveries = info['deliveries']
    deliveries_sorted = []
    for r in route:
        for d in deliveries:
            if (d['location']['x'], d['location']['y']) == r:
                deliveries_sorted.append(d)
                break
    return deliveries_sorted

# define function to calculate time required to travel between two stops on a given route at a given speed
def calculate_time_to_next_stop(current_stop: Tuple[int, int], next_stop: Tuple[int, int], speed: int, route: List[Tuple[int, int]]) -> float:
    distance_per_stop = 0
    for i in range(len(route)):
        if route[i] == current_stop:
            for j in range(i+1, len(route)):
                if route[j] == next_stop:
                    distance_per_stop = sum([distance(route[k][0], route[k][1], route[k+1][0], route[k+1][1]) for k in range(i, j)])
                    break
            break
    time = distance_per_stop / speed
    return time * 60  # multiply time in hours by 60 to get time in minutes

def write_delivery_schedule(schedule: dict, filename: str):
    with open(filename, "w") as f:
        # Iterate over each day in the schedule
        for day, info in schedule.items():
            f.write(f"{day}:\n")
            start_time = info["start_time"]
            end_time = info["end_time"]

            # Sort the deliveries by their position in the route
            deliveries = sort_deliveries_by_route(info)

            # Print the stops for the current day
            stops = [(d['location']['x'], d['location']['y']) for d in deliveries] + [(0, 0)]
            f.write(f"Stops for {day}: {stops}\n\n")
            f.write("Good Morning Have a safe drive\n\n")

            # Calculate the route for the day
            route = calculate_route(stops)

            total_distance = 0
            total_time = 0
            for i in range(len(route)):
                current_stop = route[i]
                if i < len(route) - 1:
                    next_stop = route[i + 1]
                    stop_distance = distance(current_stop[0], current_stop[1], next_stop[0], next_stop[1])
                    time = calculate_time_to_next_stop(current_stop, next_stop, 30, route)
                else:
                    stop_distance = 0
                    time = 0
                total_distance += stop_distance
                total_time += time
                f.write(f"Location: ({current_stop[0]}, {current_stop[1]})\n")
                if i < len(route) - 1:
                    f.write(f"Next stop is {stop_distance:.2f} miles away and will take {time:.2f} minutes to get there.\n")
                else:
                    f.write("Welcome Back to HQ.\nThank you for completing all deliveries and returning safely to the headquarters!\n\n")

            # Print the total distance for the day
            f.write(f"Total distance for {day}: {total_distance:.1f} miles\n")
            f.write(f"Total time for {day}: {total_time:.2f} minutes\n\n")

            # Iterate over the sorted deliveries and print their information
            for i, delivery in enumerate(deliveries):
                f.write(f"Delivery {i + 1}:\n")
                f.write(f"Location: ({delivery['location']['x']}, {delivery['location']['y']})\n")
                f.write(f"Address: {delivery['address']}\n")
                f.write("Boxes to be delivered:\n")
                for boxes in delivery["boxes"]:
                    f.write(f"- {boxes}\n")
                f.write("\n")

def print_delivery_schedule_table(schedule: dict, filename: str):
    # Initialize a list to store the data for the table
    table_data = []

    # Iterate over each day in the schedule
    for day, info in schedule.items():
        start_time = info["start_time"]
        end_time = info["end_time"]

        # Sort the deliveries by their position in the route
        deliveries = sort_deliveries_by_route(info)

        # Calculate the stops for the current day
        stops = [(d['location']['x'], d['location']['y']) for d in deliveries] + [(0, 0)]

        # Calculate the route for the day
        route = calculate_route(stops)

        total_distance = 0
        total_time = 0
        for i in range(len(route)):
            current_stop = route[i]
            if i < len(route) - 1:
                next_stop = route[i + 1]
                stop_distance = distance(current_stop[0], current_stop[1], next_stop[0], next_stop[1])
                time = calculate_time_to_next_stop(current_stop, next_stop, 30, route)
            else:
                stop_distance = 0
                time = 0
            total_distance += stop_distance
            total_time += time

        # Add the information for the current day to the table data
        table_data.append([day, start_time, end_time, f"{total_distance:.1f}", f"{total_time:.2f}"])

    # Write the table to a txt file
    with open(filename, "w") as file:
        file.write(tabulate(table_data,
                            headers=["Day", "Start Time", "End Time", "Total Distance (miles)", "Total Time (minutes)"],
                            tablefmt="plain"))

    print(f"Delivery schedule table has been written to {filename}.\n")

# Print the updated delivery schedule
write_delivery_schedule(delivery_schedule, "delivery_schedule.txt")
print_delivery_schedule_table(delivery_schedule, "delivery_schedule_table.txt")


class Node():
    def __init__(self, data=None) -> None:
        self.data = data
        self.next = None

class Linked_list():
    def __init__(self) -> None:
        self.head = None

    def print_list(self):
        ptr = self.head
        while ptr :
            print(ptr.data)
            ptr = ptr.next

    def ending(self, newdata):
        new_node = Node(newdata)
        if self.head == None :
            self.head = new_node
            return
        last_ptr = self.head
        while last_ptr.next:
            last_ptr = last_ptr.next
        last_ptr.next = new_node

    def rm_node(self,rmkey):
        ptr = self.head
        # 删除第一个元素
        if ptr:
            if ptr.data == rmkey:
                self.head = ptr.next
                return
        # 找到待删除的节点
        while ptr:
            if ptr.data == rmkey:
                break
            prev = ptr
            ptr = ptr.next
        if ptr == None:  # 到了末端
            return
        prev.next = ptr.next

link = Linked_list()
link.ending(5)
link.ending(15)
link.ending(25)
link.print_list()
print("*"*30)
link.rm_node(15)
link.print_list()

数据结构及算法/链表/5_删除链表指定内容节点.py

5_删除链表指定内容节点.py


# --------------------------------------------------------------------------------------------------
# Logging: add a logging file to code
#   - prints out to console or file
#   - helps to trace the code execution
#   - logging level: DEBUG / INFO / WARNING / ERROR / CRITICAL
#   - name: logging module gives it to the default logger, [default] 'root'
#
#   Basic Config:
#       filename:   file name and extension
#       mode:       file mode (w/a)
#       format:     format of the log message
#       level:      level of severity
#
#   getLogger returns a logger with the specified name
# --------------------------------------------------------------------------------------------------

import os
import logging          # logging module
os.system('cls')        # cls command

print(dir(logging))

logging.basicConfig(filename= 'my_log.log',
                    filemode= 'a',
                    format= '%(asctime)s:\t %(name)s | %(levelname)s | \'%(message)s\'',
                    datefmt= '%d/%m/%Y, %H:%M:%S')

my_logger = logging.getLogger('Amr')

my_logger.critical('This is a critical status')
my_logger.error('This is an error message')
my_logger.warning('This is warning')
my_logger.info('This is an info')
my_logger.debug('This is debug')

my_logger2 = logging.getLogger('Lina')

my_logger2.critical('This is a critical status')
my_logger2.error('This is an error message')
my_logger2.warning('This is warning')
my_logger2.info('This is an info')
my_logger2.debug('This is debug')


import copy
import sys
from pprint import pprint

from django.apps import apps as django_apps
from django.core.exceptions import ObjectDoesNotExist
from django.utils.module_loading import import_module, module_has_submodule

class RegistryNotLoaded(Exception):
    pass

class AlreadyRegisteredVisitSchedule(Exception):
    pass

class SiteVisitScheduleError(Exception):
    pass

class SiteVisitSchedules:
    """Main controller of :class:`VisitSchedule` objects.

    A visit_schedule contains schedules
    """

    def __init__(self):
        self._registry = {}
        self._all_post_consent_models = None
        self.loaded = False

    @property
    def registry(self):
        pass
        # if not self.loaded:
        #     raise RegistryNotLoaded(
        #         "Registry not loaded. Is AppConfig for 'edcs_visit_schedule' "
        #         "declared in settings?."
        #     )
        # return self._registry

    def register(self, visit_schedule):
        self.loaded = True
        if not visit_schedule.schedules:
            raise SiteVisitScheduleError(
                f"Visit schedule {visit_schedule} has no schedules. "
                f"Add one before registering."
            )
        if visit_schedule.name not in self.registry:
            self.registry.update({visit_schedule.name: visit_schedule})
        else:
            raise AlreadyRegisteredVisitSchedule(
                f"Visit Schedule {visit_schedule} is already registered."
            )
        self._all_post_consent_models = None

    @property
    def visit_schedules(self):
        return self.registry

    def get_visit_schedule(self, visit_schedule_name=None, **kwargs):
        """Returns a visit schedule instance or raises."""
        try:
            visit_schedule_name = visit_schedule_name.split(".")[0]
        except AttributeError:
            pass
        visit_schedule = self.registry.get(visit_schedule_name)
        if not visit_schedule:
            visit_schedule_names = "', '".join(self.registry.keys())
            pprint(self.registry.keys())
            raise SiteVisitScheduleError(
                f"Invalid visit schedule name. Got '{visit_schedule_name}'. "
                f"Expected one of '{visit_schedule_names}'. See {repr(self)}."
            )
        return visit_schedule

    def get_visit_schedules(self, *visit_schedule_names):
        """Returns a dictionary of visit schedules.

        If visit_schedule_name not specified, returns all visit schedules.
        """
        visit_schedules = {}
        for visit_schedule_name in visit_schedule_names:
            try:
                visit_schedule_name = visit_schedule_name.split(".")[0]
            except AttributeError:
                pass
            visit_schedules[visit_schedule_name] = self.get_visit_schedule(
                visit_schedule_name
            )
        return visit_schedules or self.registry

    def get_by_onschedule_model(self, onschedule_model=None):
        """Returns a tuple of (visit_schedule, schedule)
        for the given onschedule model.

        attr `onschedule_model` is in "label_lower" format.
        """
        return self._get_by_model(attr="onschedule_model", model=onschedule_model)

    def get_by_offschedule_model(self, offschedule_model=None):
        """Returns a tuple of visit_schedule, schedule
        for the given offschedule model.

        attr `offschedule_model` is in "label_lower" format.
        """
        return self._get_by_model(attr="offschedule_model", model=offschedule_model)

    def get_by_loss_to_followup_model(self, loss_to_followup_model=None):
        """Returns a tuple of visit_schedule, schedule
        for the given loss_to_followup model.

        attr `loss_to_followup_model` is in "label_lower" format.
        """
        return self._get_by_model(
            attr="loss_to_followup_model", model=loss_to_followup_model
        )

    def _get_by_model(self, attr=None, model=None):
        ret = []
        for visit_schedule in self.visit_schedules.values():
            for schedule in visit_schedule.schedules.values():
                if getattr(schedule, attr) == model:
                    ret.append([visit_schedule, schedule])
        if not ret:
            raise SiteVisitScheduleError(
                f"Schedule not found. No schedule exists for {attr}={model}."
            )
        elif len(ret) > 1:
            raise SiteVisitScheduleError(
                f"Schedule is ambiguous. More than one schedule exists for "
                f"{attr}={model}. Got {ret}"
            )
        return ret[0]

    def get_by_offstudy_model(self, offstudy_model=None):
        """Returns a list of visit_schedules for the given
        offstudy model.
        """
        visit_schedules = []
        for visit_schedule in self.visit_schedules.values():
            if visit_schedule.offstudy_model == offstudy_model:
                visit_schedules.append(visit_schedule)
        if not visit_schedules:
            raise SiteVisitScheduleError(
                f"No visit schedules have been defined using the "
                f"offstudy model '{offstudy_model}'"
            )
        return visit_schedules

    @property
    def all_post_consent_models(self):
        """Returns a dictionary of models that require consent before save.

        {model_name1: consent_model_name, model_name2: consent_model_name, ...}
        """
        if not self._all_post_consent_models:
            models = {}
            for visit_schedule in self.visit_schedules.values():
                models.update(**visit_schedule.all_post_consent_models)
            self._all_post_consent_models = models
        return self._all_post_consent_models

    def check(self):
        if not self.loaded:
            raise SiteVisitScheduleError("Registry is not loaded.")
        errors = {"visit_schedules": [], "schedules": [], "visits": []}
        for visit_schedule in site_visit_schedules.visit_schedules.values():
            errors["visit_schedules"].extend(visit_schedule.check())
            for schedule in visit_schedule.schedules.values():
                errors["schedules"].extend(schedule.check())
                for visit in schedule.visits.values():
                    errors["visits"].extend(visit.check())
        return errors

    def to_model(self, model_cls):
        model_cls.objects.update(active=False)
        for visit_schedule in site_visit_schedules.visit_schedules.values():
            for schedule in visit_schedule.schedules.values():
                for visit in schedule.visits.values():
                    opts = dict(
                        visit_schedule_name=visit_schedule.name,
                        schedule_name=schedule.name,
                        visit_code=visit.code,
                        visit_name=visit.name,
                        visit_title=visit.title,
                        timepoint=visit.timepoint,
                        active=True,
                    )
                    try:
                        obj = model_cls.objects.get(
                            visit_schedule_name=visit_schedule.name,
                            schedule_name=schedule.name,
                            timepoint=visit.timepoint,
                        )
                    except ObjectDoesNotExist:
                        model_cls.objects.create(**opts)
                    else:
                        for fld, value in opts.items():
                            setattr(obj, fld, value)
                        obj.save()

    def autodiscover(self, module_name=None, apps=None, verbose=None):
        """Autodiscovers classes in the visit_schedules.py file of
        any INSTALLED_APP.
        """
        self.loaded = True
        module_name = module_name or "visit_schedules"
        verbose = True if verbose is None else verbose
        if verbose:
            sys.stdout.write(f" * checking site for module '{module_name}' ...\n")
        for app in apps or django_apps.app_configs:
            try:
                mod = import_module(app)
                try:
                    before_import_registry = copy.copy(site_visit_schedules._registry)
                    import_module(f"{app}.{module_name}")
                    if verbose:
                        sys.stdout.write(
                            " * registered visit schedule from " f"'{app}'\n"
                        )
                except Exception as e:
                    if f"No module named '{app}.{module_name}'" not in str(e):
                        raise
                    site_visit_schedules._registry = before_import_registry
                    if module_has_submodule(mod, module_name):
                        raise
            except ModuleNotFoundError:
                pass

site_visit_schedules = SiteVisitSchedules()