'''
Each filter returns the new_mask from the
parameter list as updated according to its filtering criteria.
Each filter function must have the following parameters:

Parameters
----------
swim_assay : SwimAssay
    swim object (only necessary for some functions)
'''

import functools
import numba
import numpy
from scipy import stats as spstats

from swimfunction.data_access.data_utils import AnnotationTypes
from swimfunction.global_config.config import config
from swimfunction.data_models.SwimAssay import SwimAssay

ANGLE_CHANGE_Z_LIM = config.getint('POSE FILTERING', 'angle_change_z_lim')
FRAME_SIDE_BUFFER_WIDTH = config.getint('POSE FILTERING', 'frame_side_buffer_width')
FRAME_REAR_BUFFER_WIDTH = config.getint('POSE FILTERING', 'frame_rear_buffer_width')
MIN_LIKELIHOOD_THRESHOLD = config.getfloat('POSE FILTERING', 'min_likelihood_threshold')

NO_FLOW = config.getint('FLOW', 'none')
SLOW_FLOW = config.getint('FLOW', 'slow')
FAST_FLOW = config.getint('FLOW', 'fast')

NO_FLOW_START = config.getint('FLOW', 'none_start')
SLOW_FLOW_START = config.getint('FLOW', 'slow_start')
FAST_FLOW_START = config.getint('FLOW', 'fast_start')

ORIENTED_WITH = config.getint('RHEOTAXIS', 'with_flow')
ORIENTED_AGAINST = config.getint('RHEOTAXIS', 'against_flow')
NOT_QUITE_AGAINST = config.getint('RHEOTAXIS', 'not_quite_against_flow')
NOT_QUITE_WITH = config.getint('RHEOTAXIS', 'not_quite_with_flow')

BEHAVIORS = config.getnamedtuple('BEHAVIORS', 'names', 'BEHAVIORS', 'symbols')

ANGLE_LOWER_BOUNDS = config.getfloatlist('POSE FILTERING', 'angle_lower_bounds')
ANGLE_UPPER_BOUNDS = config.getfloatlist('POSE FILTERING', 'angle_upper_bounds')

def _ones_mask(swim_assay: SwimAssay):
    ''' Get a blank mask of "True" for the swim assay.
    '''
    return numpy.ones(swim_assay.raw_coordinates.shape[0], dtype=bool)

def _zeros_mask(swim_assay: SwimAssay):
    ''' Get a blank mask of "False" for the swim assay.
    '''
    return numpy.zeros(swim_assay.raw_coordinates.shape[0], dtype=bool)

@numba.njit(parallel=True, fastmath=True)
def _get_fish_lengths(poses):
    ''' For each pose: uses the Pythagorean Theorem
    to get segment lengths given by adjacent points,
    then sums the segment lengths.

    Parameters
    ----------
    poses: numpy.ndarray
        Array with shape=(num_poses, points_per_pose, 2)
    '''
    return numpy.sqrt(
        numpy.square(
            poses[:, :-1, 0] - poses[:, 1:, 0]
        ) + numpy.square(
            poses[:, :-1, 1] - poses[:, 1:, 1]
        )
    ).sum(axis=1)

def filter_by_cleaned(swim_assay: SwimAssay, *args, **kwargs):
    return numpy.logical_not(swim_assay.was_cleaned_mask.astype(bool))

def filter_by_likelihood(swim_assay: SwimAssay, *args, **kwargs):
    ''' Filters by DeepLabCut (DLC) likelihood score
    '''
    new_mask = _ones_mask(swim_assay)
    if swim_assay.likelihoods is None:
        return new_mask
    mins = swim_assay.likelihoods.min(axis=1)
    new_mask[numpy.where(mins < MIN_LIKELIHOOD_THRESHOLD)] = 0
    return new_mask

def filter_by_distance_from_neighbors(swim_assay: SwimAssay, *args, **kwargs):
    ''' Filters by comparing the distance between adjacent poses,
    and masking out any pose with distance z-score greater than ANGLE_CHANGE_Z_LIM.
    '''
    poses = swim_assay.smoothed_complete_angles
    # Ensure poses are between -pi and pi
    poses[numpy.logical_and(
        numpy.logical_not(numpy.isnan(poses)),
        poses > numpy.pi)] -= numpy.pi
    poses[numpy.logical_and(
        numpy.logical_not(numpy.isnan(poses)),
        poses < (-1 * numpy.pi))] += numpy.pi
    # The smallest difference between 2 angles
    # (https://stackoverflow.com/questions/1878907/the-smallest-difference-between-2-angles)
    differences = numpy.abs(numpy.arctan2(
        numpy.sin(numpy.abs(poses[:-1, :]) - numpy.abs(poses[1:, :])),
        numpy.cos(numpy.abs(poses[:-1, :]) - numpy.abs(poses[1:, :]))
    ))
    diff_mean = numpy.nanmean(differences)
    diff_std = numpy.nanstd(differences)
    max_differences = numpy.nanmax(differences, axis=1)
    # Absolute value zs
    # print(f'Differences min: {numpy.nanmin(differences)}')
    # print(f'Differences mean: {diff_mean}')
    # print(f'Differences max: {numpy.nanmax(differences)}')
    diff_zs = numpy.abs(max_differences - diff_mean) / diff_std
    max_zs = numpy.empty(poses.shape[0])
    max_zs[0] = diff_zs[0]
    max_zs[-1] = diff_zs[-1]
    max_zs[1:-1] = numpy.min(numpy.array((diff_zs[:-1], diff_zs[1:])), axis=0)
    new_mask = _ones_mask(swim_assay)
    new_mask[max_zs > ANGLE_CHANGE_Z_LIM] = 0
    new_mask[numpy.isnan(max_zs)] = 0
    return new_mask

def filter_by_distance_from_edges(swim_assay: SwimAssay, *args, **kwargs):
    ''' If the fish is too close to the back or left/right sides, mask that frame!
    '''
    from swimfunction.data_access.fish_manager import DataManager as FDM
    new_mask = _ones_mask(swim_assay)
    coordinate_poses = swim_assay.smoothed_coordinates
    # NOTE: maxy is not important. Flow comes from maxy, so if the fish swims really well,
    # then it may be close to maxy and that's ok.
    minx, miny, maxx, maxy = FDM.get_corners_of_swim_area(swim_assay.fish_name, swim_assay.assay_label)
    new_mask[numpy.any(coordinate_poses[..., 0] < (minx + FRAME_SIDE_BUFFER_WIDTH), axis=1)] = 0
    new_mask[numpy.any(coordinate_poses[..., 0] > (maxx - FRAME_SIDE_BUFFER_WIDTH), axis=1)] = 0
    # new_mask[numpy.any(coordinate_poses[..., 1] > (maxy - FRAME_REAR_BUFFER_WIDTH), axis=1)] = 0
    new_mask[numpy.any(coordinate_poses[..., 1] < (miny + FRAME_REAR_BUFFER_WIDTH), axis=1)] = 0
    return new_mask

def filter_away_inactive(swim_assay: SwimAssay, *args, **kwargs):
    return numpy.logical_not(TEMPLATE_filter_by_behavior(
        BEHAVIORS.rest,
        annotation_type=AnnotationTypes.predicted)(swim_assay))

def filter_raw_coordinates_nan(swim_assay: SwimAssay, *args, **kwargs):
    axis = tuple(range(1, len(swim_assay.raw_coordinates.shape)))
    return ~numpy.any(numpy.isnan(swim_assay.raw_coordinates), axis=axis)

def filter_caudal_fin_nan(swim_assay: SwimAssay, *args, **kwargs):
    axis = tuple(range(1, len(swim_assay.smoothed_coordinates_with_caudal.shape)))
    return ~numpy.any(numpy.isnan(swim_assay.smoothed_coordinates_with_caudal), axis=axis)

def filter_extreme_angles(swim_assay: SwimAssay, *args, **kwargs):
    from swimfunction.data_access.PoseAccess import get_feature_from_assay
    poses = get_feature_from_assay(swim_assay, 'smoothed_angles', [], keep_shape=True)
    mask = _ones_mask(swim_assay)
    mask[numpy.any(poses < ANGLE_LOWER_BOUNDS, axis=1) | numpy.any(poses > ANGLE_UPPER_BOUNDS, axis=1)] = 0
    return mask

def filter_by_fish_length(swim_assay: SwimAssay, *args, **kwargs):
    ''' Filters by comparing the fish's length to all other lengths in this swim,
    and masking out any pose with length outside the range (median ± 8 * MAD)
    '''
    # Calculate stats on a good subset
    check_mask = filter_raw_coordinates_nan(swim_assay) & filter_extreme_angles(swim_assay)
    coordinate_poses = swim_assay.smoothed_coordinates
    lengths = _get_fish_lengths(coordinate_poses)
    med = numpy.nanmedian(lengths[check_mask])
    mad = spstats.median_abs_deviation(lengths[check_mask], nan_policy='omit')
    # Apply to all lengths, even if they have extreme angles.
    new_mask = _ones_mask(swim_assay)
    upper_limit = med + (8 * mad)
    lower_limit = max((med - (8 * mad)), 0)
    new_mask[lengths >= upper_limit] = 0
    new_mask[lengths <= lower_limit] = 0
    new_mask[numpy.isnan(lengths)] = 0
    return new_mask

def TEMPLATE_filter_by_highest_recovery_score(min_recovery_score: int):
    ''' Checks get_highest_recovered_quality
    for the target recovery score. Masks out the entire SwimAssay if the target is not achieved.
    '''
    from swimfunction.data_access.fish_manager import DataManager as FDM
    def inner(swim_assay: SwimAssay, *args, **kwargs):
        new_mask = _ones_mask(swim_assay)
        quality = FDM.get_highest_recovered_quality(swim_assay.fish_name)
        if quality is None or quality < min_recovery_score:
            new_mask[:] = False
        return new_mask
    return inner

def TEMPLATE_filter_by_behavior(behavior: str, annotation_type: str = AnnotationTypes.all):
    if behavior not in BEHAVIORS:
        raise RuntimeError(f'Behavior must be in {list(BEHAVIORS.keys())}')
    from swimfunction.data_access.PoseAccess import get_behaviors
    def inner(swim_assay: SwimAssay, *args, **kwargs):
        new_mask = _zeros_mask(swim_assay)
        behaviors = get_behaviors(swim_assay, annotation_type)
        if behaviors is not None and len(behaviors) > 0:
            new_mask[numpy.where(numpy.asarray(behaviors) == behavior)] = 1
        return new_mask
    return inner

def TEMPLATE_filter_by_flow_rate(flow_speed):
    '''
    Parameters
    ----------
    flow_speed : int
        see config.ini for available values

    Raises
    ------
    ValueError
        If flow_speed is not recognized in config.ini
    '''
    def inner(swim_assay: SwimAssay, *args, **kwargs):
        mask = _zeros_mask(swim_assay)
        if flow_speed == FAST_FLOW:
            mask[FAST_FLOW_START:] = 1
        elif flow_speed == SLOW_FLOW:
            mask[SLOW_FLOW_START:FAST_FLOW_START] = 1
        elif flow_speed == NO_FLOW:
            mask[NO_FLOW_START:SLOW_FLOW_START] = 1
        else:
            raise ValueError(f'Flow speed ({flow_speed}) not recognized.')
        return mask
    return inner

def TEMPLATE_rheotaxis(allowed_orientations: list):
    ''' Keep in mind that rheotaxis only applies during flow.
    Do not use this filter for pre-flow (first five minutes of video) analysis.
    Parameters
    ----------
    orientation : int
        See config.ini
        Options are
            1 (with flow >= 45 degrees),
            -1 (against flow >= 45 degrees), or
            0 (not oriented to flow).
    '''
    allowed_orientations = set(allowed_orientations)
    presence_fn = numpy.vectorize(lambda x: x in allowed_orientations)
    def inner(swim_assay: SwimAssay, *args, **kwargs):
        from swimfunction.data_access.PoseAccess import get_feature_from_assay
        from swimfunction.recovery_metrics.metric_analyzers\
            .swim_capacity_calculations import pose_orientations
        coords = get_feature_from_assay(
            swim_assay,
            'smoothed_coordinates',
            filters=[],
            keep_shape=True)
        return presence_fn(pose_orientations(coords))
    return inner

def get_filter_mask(swim_assay: SwimAssay, filters=None):
    ''' Given a swim assay and filters, get a boolean mask for keep-able poses.
    '''
    if filters is None:
        filters = []
    masks = [f(swim_assay) for f in filters] + [_ones_mask(swim_assay)]
    return functools.reduce(lambda a, b: a & b, masks)

def apply_filter_mask(mask, poses, keep_shape=False, fill_value=numpy.nan):
    ''' Keeps poses where mask is 1.
    If keep_shape fills with fill_value where mask is 0,
    otherwise it removes that pose from the array.
    '''
    if not numpy.issubdtype(mask.dtype, bool):
        mask = mask.astype(bool)
    new_poses = poses.copy()
    if keep_shape:
        new_poses[numpy.logical_not(mask), ...] = fill_value
    else:
        new_poses = new_poses[mask, ...]
    return new_poses

# Basic filters are those that are required
# for reasonable posture estimation, regardless of behavior.
BASIC_FILTERS = [
    filter_raw_coordinates_nan,
    filter_by_likelihood,
    filter_by_fish_length,
    filter_by_cleaned,
    filter_extreme_angles
]


import os
import sys
import logging
from types import FrameType
from typing import cast

from loguru import logger

import config

loguru_setting = None

class InterceptHandler(logging.Handler):
    def emit(self, record: logging.LogRecord) -> None:  # pragma: no cover
        # Get corresponding Loguru level if it exists
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = str(record.levelno)

        # Find caller from where originated the logged message
        frame, depth = logging.currentframe(), 2
        while frame.f_code.co_filename == logging.__file__:  # noqa: WPS609
            frame = cast(FrameType, frame.f_back)
            depth += 1

        logger.opt(depth=depth, exception=record.exc_info).log(
            level,
            record.getMessage(),
        )

class LoguruSetting:
    def __init__(self):
        self.PROJECT_LOG_DIR = config.PROJECT_LOGS_DIR
        self.PROJECT_APP = config.PROJECT_APP
        self.log_configs = [
            {
                "level": "INFO",
                "filename": "info_{time:YYYY-MM-DD}.log",
                "rotation": "daily",  # new file is created each day at midnight
                "retention": "1 months",
                "formatter": "<level>{level: <8}</level>|<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green>|<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan>|<level>{message}</level>",
            },
            {
                "level": "DEBUG",
                "filename": "debug_{time:YYYY-MM-DD}.log",
                "rotation": "daily",  # new file is created each day at midnight
                "retention": "1 months",
                "formatter": "<level>{level: <8}</level>|<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green>|<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan>|<level>{message}</level>",
            },
            {
                "level": "ERROR",
                "filename": "error_{time:YYYY-MM-DD}.log",
                "rotation": "daily",  # new file is created each day at midnight
                "retention": "1 months",
                "formatter": "<level>{level: <8}</level>|<green>{time:YYYY-MM-DD HH:mm:ss.SSS}</green>|<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan>|<level>{message}</level>",
            },
        ]

    def customize_logging(self, level, filename, rotation, retention, formatter):
        # pylint: disable=unnecessary-lambda-assignment,too-many-arguments
        log_config_filter = lambda record: record["level"].name == f"{level}"
        ## Add log output to stdout
        logger.add(
            sys.stdout,
            enqueue=True,
            backtrace=True,
            level=level.upper(),
            format=formatter,
            filter=log_config_filter,
            colorize=True,
        )
        app_paths = self.PROJECT_APP.split(".")
        full_project_app_paths = os.path.join(
            self.PROJECT_LOG_DIR, *app_paths, filename
        )

        ## Add log output to file
        logger.add(
            str(full_project_app_paths),
            enqueue=True,
            backtrace=True,
            level=level.upper(),
            format=formatter,
            rotation=rotation,
            retention=retention,
            filter=log_config_filter,
            colorize=False,
        )

    def setup_app_logging(self):
        """Prepare custom logging for our application."""
        logger.remove()
        for lc in self.log_configs:
            self.customize_logging(**lc)

        logging.basicConfig(handlers=[InterceptHandler()], level=logging.NOTSET)

        for _log in ["uvicorn", "uvicorn.error", "uvicorn.access", "fastapi"]:
            _logger = logging.getLogger(_log)
            _logger.handlers = [InterceptHandler(level=logging.WARNING)]

if loguru_setting is None:
    loguru_setting = LoguruSetting()


import numpy as np
import pandas as pd
import pickle
from sklearn.pipeline import make_pipeline
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, f1_score, recall_score, precision_score

def main():
    X_train_inputfile = "../dataset/2.1_X_train.csv.gz"
    X_valid_inputfile = "../dataset/2.1_X_valid.csv.gz"
    y_train_inputfile = "../dataset/2.1_y_train.csv.gz"
    y_valid_inputfile = "../dataset/2.1_y_valid.csv.gz"

    X_train = pd.read_csv(X_train_inputfile)
    X_valid = pd.read_csv(X_valid_inputfile)
    y_train = pd.read_csv(y_train_inputfile).transpose().values[0]
    y_valid = pd.read_csv(y_valid_inputfile).transpose().values[0]

    # classify with KNN model
    knn_model = make_pipeline(
        KNeighborsClassifier()
    )

    knn_model.fit(X_train, y_train)

    knn_pkl = '../models/knn_classifier.pkl'
    pickle.dump(knn_model, open(knn_pkl, 'wb'))

if __name__ == '__main__':
    main()


import socket
import sys
import tqdm
import os
import os.path
from os import path

SEPARATOR = "<SEPARATOR>"
BUFFER_SIZE = 4096

def server_program():
    # get the hostname and print it
    host = socket.gethostname()
    print("Host Name: " + str(host))

    if(len(sys.argv) != 2):
        print("Usage is python server.py <port number>")
        sys.exit()

    port = int(sys.argv[1])

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP

    server_socket.bind((host, port)) # note - takes a tuple

    print(f"Opened server on port {port}. I am {host}")

    server_socket.listen(10)

    data = "just_opened"
    while data != "CLOSE_ME":
        connection, client_address = server_socket.accept()
        print("Connection from" + str(client_address))

        try:
            # receive data. we will call break when the connection closes
            # while True:
            data = connection.recv(1024).decode() # max 1024 bytes to receive at once
            print("==GOT==")
            print(data)
            print("=======")
            if not data: # something went wrong, or no more data. exit the loop for this connection.
                break
            data_stripped = data.strip()
            if data_stripped == "cease":
                data = "CLOSE_ME"
                connection.send("Shutting down".encode())
                break
            elif data_stripped.find("iWant ", 0) == 0: # command words must be at the very start
                handleIWant(data_stripped, connection) # file does not exist
            elif data_stripped.find("uTake ", 0) == 0:
                handleUTake(data_stripped, connection)
            else:
                print("unrecognized data format")

        except ConnectionResetError:
            print("Client connection was reset - disconnecting them")
            connection.close()
        except ConnectionAbortedError:
            print("Client connection was aborted - disconnecting them")
            connection.close()

        connection.close()
        print("Goodbye " + str(client_address))

def handleUTake(data_stripped, connection):
    filePath = data_stripped[6::]
    print("calling uTake. Path is: " + filePath)

    connection.send("DATAI".encode())
    print("Sent DATAI")

    # receive the file infos
    # receive using client socket, not server socket
    received = connection.recv(BUFFER_SIZE).decode()
    print("Got fileinfo:")
    print(received)
    filename, filesize = received.split(SEPARATOR)
    # remove absolute path if there is
    filename = os.path.basename(filename)
    # convert to integer
    filesize = int(filesize)

    connection.send("YRECV".encode())
    print("Sent YRECV. awaiting file data")

    receiveFile(filename, filesize, connection)
    connection.close()

def handleIWant(data_stripped, connection):
    filePath = data_stripped[6::]
    filePath = f"store/{filePath}"
    print("calling iWant. Path is: " + filePath)

    if(path.exists(filePath)):
        print("File exists, sending FILEE")
        connection.send("FILEE".encode()) # file exists

        response = connection.recv(1024).decode()
        if(str(response) == "DATAI"):
            print("Got DATAI - sending file info")

            filename = filePath
            filesize = os.path.getsize(filename)
            connection.send(f"{filename}{SEPARATOR}{filesize}".encode())

            response = connection.recv(1024).decode()
            if(str(response) == "YRECV"):
                print("Got YRECV - sending file contents")

                sendFile(filename, connection)
                connection.close()
            else:
                print("Client did not send YRECV")

        else:
            print("Client did not send DATAI")
    else:
        print("Requested file " + filePath + " does not exist, sending FILEN")
        connection.send("FILEN".encode()) # file does not exist

def sendFile(filename, client_socket):
    with open(filename, "rb") as f:
        while True:
            # read the bytes from the file

            bytes_read = f.read(BUFFER_SIZE)

            if not bytes_read:
                # file transmission is finished
                print("File sent!")
                break

            client_socket.sendall(bytes_read)

    print("Done sending file")

def receiveFile(filename, filesize, client_socket):
    with open(filename, "wb") as f:
        while True:

            bytes_read = client_socket.recv(BUFFER_SIZE)

            if not bytes_read:
                # nothing received
                print("Finished recv")
                break

            f.write(bytes_read)

        print("Finished recv")

if __name__ == '__main__':
    server_program()


# coding: utf-8

"""
Process RDI adcp data using dolfyn (lkilcher.github.io/dolfyn/)
"""

#from dolfyn.adp import api
from dolfyn.io import rdi
#from dolfyn.adp import rotate

# AZ commenting these out because my cython is not working.
# from transform import Transform, rdi_xyz_enu

import xarray as xr
import os
from datetime import datetime, timedelta
from collections import OrderedDict
import numpy as np
from scipy.interpolate import interp1d

from matplotlib.dates import num2date, date2num

import rdi_adcp_utils
import pdb

deg2rad = np.pi / 180.
rad2deg = 180./np.pi

class rdi_adcp(object):
    """
    Wrapper object for parsing an RDI file with the "dolfyn" package from github

    Attributes:
    --------
        ds   - xr dataset with the pertinent data
        _data - adcp data object from dolfyn

    Methods:
    --------
        to_netcdf : save xr.Dataset to netcdf

    """

    def __init__(self, adcpfile, group=None, rotate=False, \
        mapbins=False, config_update = {}):
        """
        Inputs:
        -----
                adcpfile - RDI binary or a netcdf file
                rotate - [False] option to rotate
                config_update - dictionary with keys to replace in the ADCP config file

        """

        self.adcpfile = adcpfile

        self.rotate = rotate
        self.mapbins = mapbins

        try:
            # Load data directly from a netcdf file
            self.ds = xr.open_dataset(self.adcpfile, group=group, decode_coords=False)

        except:
            # Load the raw binary data
            self._data = rdi.read_rdi(self.adcpfile) # This would be Levi Kilcher's dat object

            # Override settings in the configuration dictionary
            for kk in list(config_update.keys()):
                self._data.config[kk] = config_update[kk]

            self.positive = self._data.config['orientation']

            # Rotate raw data
            if rotate:
                print('Rotating...')
                #self._rotate_velocity()
                #self._rotate_velocity_uhdas(self._data._u, \
                self.u, self.v, self.w, self.errvel,\
                self.u_inst, self.v_inst, self.w_inst = \
                    self._rotate_velocity(self._data.vel.astype('float64'), \
                        self._data.range,\
                        self._data.orient.raw.heading.astype('float64'),\
                        self._data.orient.raw.pitch.astype('float64'),\
                        self._data.orient.raw.roll.astype('float64'),\
                        float(self._data.config['beam_angle']),\
                        self._data.config['beam_pattern'],\
                        self._data.config['orientation'],\
                        self._data.config['coord_sys'])

            self.time = num2date(self._data.mpltime)

            self.ds, self.encoding = self._to_xray(self._data)

    def to_netcdf(self, ncfile, mode='w', group=None):
        """
        Save to a netcdf file
        """
        print('Saving data to file %s...'%ncfile)

        if 'encoding' in list(self.__dict__.keys()):
            encoding=self.encoding
        else:
            encoding = None

        self.ds.to_netcdf(ncfile,mode=mode, group=group, encoding=encoding)
        print('Done.')

    #######
    # Private methods
    #######
    def _calc_depth(self, orientation=None, P=None):
        """
        Calculate the bin depths as a 2D array using the instrument pressure
        """
        ds = self.ds

        tilt = self._calc_tilt(ds['pitch'].values,\
               ds['roll'].values)

        if orientation is None:
            orientation = ds.orientation

        # Calculate the depth using the TILT and pressure
        z = ds.distance.values
        dz = np.abs(z[1] - z[0])
        zhat = z[:,np.newaxis] * np.cos(tilt*deg2rad)

        # Depth of the instrument
        if P is None:
            P = ds['pressure'].values

        if ds.orientation == 'down':
            zhat = P + zhat
            #flag_depth = zhat > max_depth - 0.15*max_depth # too conservative
            #flag_depth = zhat > max_depth - 1.5*dz
        else:
            zhat = P - zhat
            #flag_depth = zhat < 0. + 0.15*max_depth
            #flag_depth = zhat < 0. + 1.5*dz

        # Update the internal object
        zda = xr.DataArray(zhat,
            dims = ('distance','time',),\
            coords = {'time':ds.time.values,\
                    'distance':ds.distance.values},
            attrs = {\
                    'long_name':'Depth below free-surface',\
                    'units':'m',\
                    'positive':'down',\
                    },
        )

        ds.update({'zhat':zda})

    def _calc_tilt(self, pitch, roll):
        """
        Calculate instrument tilt
        """

        for i in np.arange(0, 10):
            print('MAKE THIS A PROPERTY')

        # See the IMOS wiki for recomendations on this:
        # https://github.com/aodn/imos-toolbox/wiki/QCProcedures#adcp-tilt-test---imostiltvelocitysetqc---compulsory
        #TILT = acos(sqrt(1 - sin(ROLL)^2 - sin(PITCH)^2))

        TILT = np.arccos(np.sqrt(1 - np.sin(roll*deg2rad)**2\
                - np.sin(pitch*deg2rad)**2)) * rad2deg

        return TILT

    def _rotate_velocity(self, beamvel, distance,\
        heading_deg, pitch_deg, roll_deg,\
        beam_angle, beam_pattern, orientation, coord_sys):
        """
        Rotate from beam to compass coordinates

        Using the rotation routines from the dolyfn libary

        """

        beamvel = beamvel.transpose([1, 0, 2]) #

        if not coord_sys == 'beam':
            print('Data collected in %s coordinates - not rotating.'%(coord_sys))
            # error velocity is stored first
            return beamvel[:,0,:], beamvel[:,1,:], beamvel[:,2,:]
            #return beamvel[:,1,:], -beamvel[:,0,:], beamvel[:,2,:]

        # local copy of data for convenience
        #data = self._data

        # Map onto the correct depth-bins
        if self.mapbins:
            beamvelnew = binmap(beamvel, distance, pitch_deg, roll_deg)
        else:
            beamvelnew = beamvel

        # Calculate the rotation matrix
        #isconvex = data.config['beam_pattern'] == 'convex'
        isconvex = beam_pattern == 'convex'
        rotmat = rdi_adcp_utils.calc_beam_rotmatrix(theta = beam_angle,convex=isconvex)
        print(rotmat)

        #data.config.update({'rotmat':rotmat})

        ## Update the beam
        #data.add_data('beam1vel',data._u[:,0,:])
        #data.add_data('beam2vel',data._u[:,1,:])
        #data.add_data('beam3vel',data._u[:,2,:])
        #data.add_data('beam4vel',data._u[:,3,:])

        # Rotate the beam to instrument coordinates
        #  this populates the variables: u_inst, v_inst
        u_inst, v_inst, w_inst, errvel = rdi_adcp_utils.beam2inst(beamvelnew, rotmat)

        # Rotate the instrument to earth coordinates
        #self.u, self.v, self.w = rotate.inst2earth(data)

        u, v, w = rdi_adcp_utils.inst2earth(u_inst, v_inst, w_inst,\
            heading_deg, pitch_deg, roll_deg,\
            orientation=orientation,\
            heading_offset=None, declination=None,\
            fixed_orientation=False)

        #return u_inst, v_inst, w_inst
        return u, v, w, errvel, u_inst, v_inst, w_inst

    def _to_xray(self, data):
        """
        Create a dictionary of the output variables
        and convert to an xr Dataset
        """
        #data = self._data
        print('Converting to xarray')

        # dimensions
        adcp_dims = {
            'distance':data.range.squeeze(),
            'time':self.time,
            'beam':list(range(1,5)),
        }

        if not data.config.coord_sys == 'beam':
            raise(Exception)

        # Variables
        #      - Shift the beam to the end. I find it nicer this way so that when you pull out a single variable you have a 2D matrix - easier to plot.

        adcp_vars = {
            'beamvel':
                {'data':data.vel.transpose([1, 2, 0]),
                 'attrs':{'long_name':'Beam velocity',
                     'units':'m/s'},
                 'dims':('distance','time','beam')
                },
            'percent_good':
                {'data':data.signal.prcnt_gd.transpose([1, 2, 0]),
                 'attrs':{'long_name':'Percentage good',
                     'units':''},
                 'dims':('distance','time','beam')
                },
            'echo':
                {'data':data.signal.echo.transpose([1, 2, 0]),
                 'attrs':{'long_name':'Echo intensity',
                     'units':''},
                 'dims':('distance','time','beam')
                },
            'corr':
                {'data':data.signal.corr.transpose([1, 2, 0]),
                 'attrs':{'long_name':'Correlation',
                     'units':''},
                 'dims':('distance','time','beam')
                },
            'pressure':
                {'data':data.depth_m,
                 'attrs':{'long_name':'Pressure',
                     'units':'decibars'},
                 'dims':('time',)
                },
            'temperature':
                {'data':data.env.temperature_C,
                 'attrs':{'long_name':'Water temperature',
                     'units':'degrees C'},
                 'dims':('time',)
                },
            'heading':
                {'data':data.orient.raw.heading,
                 'attrs':{'long_name':'Instrument heading',
                     'units':'degrees'},
                 'dims':('time',)
                },
            'pitch':
                {'data':data.orient.raw.pitch,
                 'attrs':{'long_name':'Instrument pitch',
                     'units':'degrees'},
                 'dims':('time',)
                },
            'roll':
                {'data':data.orient.raw.roll,
                 'attrs':{'long_name':'Instrument roll',
                     'units':'degrees'},
                 'dims':('time',)
                },
        }

        if self.rotate:
            adcp_vars_rotation = {
                'u':
                    {'data':self.u,
                    'attrs':{'long_name':'Eastward water velocity',
                'coordinates':'time distance',
                        'units':'m/s'},
                    'dims':('distance','time')
                    },
                'v':
                    {'data':self.v,
                    'attrs':{'long_name':'Northward water velocity',
                'coordinates':'time distance',
                        'units':'m/s'},
                    'dims':('distance','time')
                    },
                'w':
                    {'data':self.w,
                    'attrs':{'long_name':'Vertical water velocity',
                'coordinates':'time distance',
                        'units':'m/s'},
                    'dims':('distance','time')
                    },
                'uinst':
                    {'data':self.u_inst,
                    'attrs':{'long_name':'Instrument x velocity',
                'coordinates':'time distance',
                        'units':'m/s'},
                    'dims':('distance','time')
                    },
                'vinst':
                    {'data':self.v_inst,
                    'attrs':{'long_name':'Instrument y velocity',
                'coordinates':'time distance',
                        'units':'m/s'},
                    'dims':('distance','time')
                    },
                'winst':
                    {'data':self.w_inst,
                    'attrs':{'long_name':'Instrument upward velocity',
                'coordinates':'time distance',
                        'units':'m/s'},
                    'dims':('distance','time')
                    },
                'errvel':
                    {'data':self.errvel,
                    'attrs':{'long_name':'Error velocity',
                'coordinates':'time distance',
                        'units':'m/s'},
                    'dims':('distance','time')
                    },
                    }

            print(' Adding rotation variables')
            adcp_vars.update(adcp_vars_rotation)

        var_names = list(adcp_vars.keys())

        # Create an output dataset
        # Global attrs
        attrs = data.config

        ds = xr.Dataset(attrs=attrs)

        encoding = {}
        for var in var_names:
        #for var in ['beamvel']:
            print('Converting variable: %s...'%var)

            coords = OrderedDict()
            for dd in adcp_vars[var]['dims']:
                coords.update({dd:adcp_dims[dd]})

            V = xr.DataArray( adcp_vars[var]['data'],\
                dims=adcp_vars[var]['dims'],\
                name=var,\
                attrs = adcp_vars[var]['attrs'],\
                coords = coords
            )

            ds.update({var:V})

            encoding.update({var:{'zlib':True,'_FillValue':-999999.}})

        return ds, encoding


import json
import re

#import netifaces
import requests
from flask import request
from speedtest import Speedtest
from app import *
from Red.ConvertDbm import *
from BD.SaveDataNetworkClient import *

listaretorn = []
dict1 = {}
protoc = ["802.11a","802.11b","802.11g","802.11n","802.11ac","802.11ax"]
bandWidth = ["5GHz","2.4GHz","2.4GHz","2.4GHz-5GHz","5GHz", "5GHz"]
channels = [1,2,3,4,5,6,7,8,9,10,11]
"""
def dictionay(userId):
    val,iduser, nameFile = validarArchivoUser()
    filename = 'C:/Users/cmb585103/Desktop/SenecaWebex/Archivos/'+nameFile+'.txt'
    #print(iduser)
    if iduser == userId:
        print("son iguales")
        with open(filename) as fh:
            lis = []
            for line in fh:
                wh = line.strip().split('\r\n')

                d = {}
                for line in wh:
                    if ': ' in line:
                        vals = line.split(': ')
                        #print(vals)
                        if vals[0].strip() != '' and vals[1].strip() != '':
                            d[vals[0].strip()] = vals[1].strip()

                for key in d.keys():

                    if key == "SSID":
                        ssid = d[key]
                        print(ssid)
                        listaretorn.append(ssid)
                    if key == "Tipo de radio":
                        bandFreq = d[key]
                        print(bandFreq)
                        listaretorn.append(bandFreq)
                    if key == "Canal":
                        canal = d[key]
                        print(canal)
                        # bandFreqG = returnBandWidth(listaretorn[2],canal)
                        listaretorn.append(canal)
                        # listaretorn.append(bandFreqG)
                    if key == "Direcci¢n f¡sica":
                        mac = d[key].replace(": ", "")
                        print(mac)
                        listaretorn.append(mac)
                    if key == "Se¤al":
                        signal = d[key]
                        print(d[key])
                        listaretorn.append(signal)
                        # dbm = convert(signal)
                        # listaretorn.append(dbm)
                        # listaretorn.append("null") # ip

                    if key == "Direcci¢n IP":
                        ip = d[key]
                        print(ip)
                        listaretorn.append(ip)
                        #listaretorn.append("Wi-Fi")
                    #print(listaretorn)
    confirmacion = selects(userId)
    #if confirmacion == True:
    #    print("validado en bd, no guarda")
    #else:
    #    print("Ya esta guardado")

    #receiveData(userId,listaretorn[0], listaretorn[1], listaretorn[2], listaretorn[3], listaretorn[4], listaretorn[5])

    #return listaretorn
"""
def validarArchivoUser(user):
    print("entra")
    try:
        validat = selects(user)
        if validat[1] == user:
            return True
        else:
            return False

        """
        path = "C:/Users/cmb585103/Desktop/SenecaWebex/Archivos"
        lstDir = os.walk(path)
        # conversion()
        for root, dirs, files in lstDir:
            for fichero in files:
                (nombreFichero, extension) = os.path.splitext(fichero)
                #print(nombreFichero)
                userId = nombreFichero.split("_")
                #print(userId[1])

                if (extension == ".txt" and nombreFichero == "datos_"+userId):
                    status = True
                    print("Estado txt",status)
                    return status, userId[1], nombreFichero
                else:
                    status = False
                    #SendFile()
                    print("Estado txt",status)
                    return status
            """
    except:
        print("error")
        #SendFile()
        #print("No esta datos.txt", status)

def validar(ids):
    try:
        validat = selects(ids)
        print(validat)
        if validat[1] == ids:
            return True
        #elif validat == None:
        #    return False
        else:
            return False
        """
        path = "C:/Users/cmb585103/Desktop/SenecaWebex/Archivos"
        lstDir = os.walk(path)
        # conversion()
        for root, dirs, files in lstDir:
            for fichero in files:
                (nombreFichero, extension) = os.path.splitext(fichero)
                # print(nombreFichero)
                userId = nombreFichero.split("_")
                #print(userId[1])
                if userId[1] == ids:
                    print("NO SE REQUIERE DESCARGAR ARCHIVO")
                    return True
                else:
                    print("SE REQUIERE DESCARGAR")
                    return False
                    #SendFile()
                """

    except:
        print("error")
        return False

#validar("Y2lzY29zcGFyazovL3VzL1BFT1BMRS9mYWM0MTY2OC1jYTUwLTRhMDUtYjMzOS1hNTliMzZiYjQ0OGM")
#validarArchivoUser()
#dictionay("Y2lzY29zcGFyazovL3VzL1BFT1BMRS9mYWM0MTY2OC1jYTUwLTRhMDUtYjMzOS1hNTliMzZiYjQ0OGM")


def reverse_vowels(s):
    """Reverse vowels in a string.

    Characters which re not vowels do not change position in string, but all
    vowels (y is not a vowel), should reverse their order.

    >>> reverse_vowels("Hello!")
    'Holle!'

    >>> reverse_vowels("Tomatoes")
    'Temotaos'

    >>> reverse_vowels("Reverse Vowels In A String")
    'RivArsI Vewols en e Streng'

    reverse_vowels("aeiou")
    'uoiea'

    reverse_vowels("why try, shy fly?")
    'why try, shy fly?''
    """

    """I've seen a problem like this before (maybe on Interview Cake...? But I wasn't sure how I'd solve it. Either using a nested loop, or possibly by making a dictionary of vals/indices and reversing them...?) I couldn't come up with a good implementation in a reasonable amount of time.
    """

    # SB Approach
    vowels = set("aeiou")

    string = list(s)
    i = 0
    j = len(s) - 1

    while i < j:
        if string[i].lower() not in vowels:
            i += 1
        elif string[j].lower() not in vowels:
            j -= 1
        else:
            string[i], string[j] = string[j], string[i]
            i += 1
            j -= 1

    return "".join(string)


def out_csvdata(**kwargs):
    out_list = []
    for token in ['B', 'L', 'D']:
        if token in kwargs.keys():
            out_list.append(kwargs[token])
        else:
            out_list.append('-')

    print(",".join(out_list))
eat = {}
while True:
    menu = input("朝食(B) 昼食(L) 夕食(D)と食べたものを入力してください：")
    if menu == '':
        break
    token, menu = menu.split(',')
    if token in ['B', 'L', 'D']:
        eat[token] = menu
    else:
        print('記号が間違っています。登録しません')
        continue
out_csvdata(**eat)


import hashlib
from os import path

from django.conf import settings
from django.template.loader import render_to_string

from cms.functions import visualiseDateTime

from attendance.models import Event_Attendance
from members.functions import get_active_members

from .models import Invitation, Participant

###############################
# EVENTS SUPPORTING FUNCTIONS #
###############################

def gen_events_calendar(overview,events,board):
  content = { 'overview' : overview }

  content['events'] = events
  content['board'] = board

  return render_to_string(overview['template'],content)

def get_event_attendance(event):
  out=''
  for p in Participant.objects.filter(event=event):
    out += str(p) + '<br/>'

  return out

def gen_event_overview(overview,event,p=False):
  content = { 'overview' : overview }

  content['title'] = event.title
  content['when'] = visualiseDateTime(event.when)
  content['time'] = visualiseDateTime(event.time)
  content['location'] = event.location
  content['agenda'] = event.agenda
  content['price'] = event.price
  try:
    I = Invitation.objects.get(event=event)
    content['invitation'] = I.message
    if I.attachement: content['attachement'] = I.attachement
  except Invitation.DoesNotExist:
    pass
  content['attendance'] = get_event_attendance(event)
  content['registration'] = settings.EVENTS_REG_BASE_URL + event.registration
  if p: content['regcode'] = p.regcode

  return render_to_string(overview['template'],content)

def gen_event_initial(e):
  initial_data = {}
  initial_data['title'] = e.title
  initial_data['when'] = e.when
  initial_data['time'] = e.time
  initial_data['location'] = e.location
  initial_data['deadline'] = e.deadline

  return initial_data

def gen_current_attendance(e):

  initial_data = {}
  initial_data['subscribe'] = Event_Attendance.objects.filter(event=e,present=True).only('member')
  initial_data['excuse'] = Event_Attendance.objects.filter(event=e,present=False).only('member')

  return initial_data

def gen_reg_hash(event):
  #hash
  h = hashlib.md5()
  h.update(str(event.agenda).encode('utf-8')) #salt
  h.update(str(event.title).encode('utf-8') + str(event.when).encode('utf-8')) #message
  return str(h.hexdigest()[:10])

def gen_reg_code(e,p):
  #hash
  h = hashlib.md5()
  h.update(str(p.email).encode('utf-8')) #salt
  h.update(str(e.title).encode('utf-8') + str(e.when).encode('utf-8')) #message
  return str(h.hexdigest()[:15])

def gen_registration_message(template,event,participant):
  content = {}

  from html2text import html2text

  content['title'] = event.title
  content['when'] = event.when
  content['time'] = visualiseDateTime(event.time)
  content['location'] = html2text(event.location)
  content['agenda'] = html2text(event.agenda)
  try:
    I = Invitation.objects.get(event=event)
    content['info'] = html2text(str(I.message))
  except Invitation.DoesNotExist:
    pass
  content['price'] = event.price
  content['code'] = participant.regcode

  return render_to_string(template,content)


from odoo import api, fields, models, _
from odoo.exceptions import UserError

class AssignProdctionWzd(models.TransientModel):
    _name = 'assign.production.wzd'
    _description = "Assign Production Wizard"

    sale_id = fields.Many2one('sale.order', 'Asignar a')

    def confirm(self):
        productions = self.env['mrp.production'].browse(
            self._context.get('active_ids'))
        if productions:

            assigned = productions.filtered(
                lambda p: p.sale_line_id)
            if assigned:
                raise UserError('La producción ya está asociadada a una venta')

            productions.write({
                'sale_id': self.sale_id.id,
                'imprevist': True,
            })
        return


import imageio
import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds

_DESCRIPTION = """
Convert srn_cars dataset into a tensorflow dataset (tfds).

It should also contain any processing which has been applied (if any),
(e.g. corrupted example skipped, images cropped,...):
"""

_CITATION = """
@article{dupont2020equivariant,
  title={Equivariant Neural Rendering},
  author={Dupont, Emilien and Miguel Angel, Bautista and Colburn, Alex and Sankar, Aditya and Guestrin, Carlos and Susskind, Josh and Shan, Qi},
  journal={arXiv preprint arXiv:2006.07630},
  year={2020}
}
"""

class SrnCars(tfds.core.GeneratorBasedBuilder):
  """DatasetBuilder for srn_cars dataset."""

  VERSION = tfds.core.Version('1.0.0')
  RELEASE_NOTES = {
      '1.0.0': 'Initial release.',
  }

  def _info(self) -> tfds.core.DatasetInfo:
    """Returns the dataset metadata."""
    return tfds.core.DatasetInfo(
        builder=self,
        description=_DESCRIPTION,
        features=tfds.features.FeaturesDict({
            'images':
                tfds.features.Tensor(shape=(None, 128, 128, 3), dtype=tf.uint8),
            'poses':
                tfds.features.Tensor(shape=(None, 4, 4), dtype=tf.float32),
            'focal':
                tfds.features.Scalar(dtype=tf.float32)
        }),
        supervised_keys=None,  # Set to `None` to disable
        disable_shuffling=True,  # Fix ordering as scenes are already shuffled
        homepage='https://github.com/apple/ml-equivariant-neural-rendering',
        citation=_CITATION,
    )

  def _split_generators(self, dl_manager: tfds.download.DownloadManager):
    """Returns SplitGenerators."""
    path = dl_manager.download_and_extract(
        'https://drive.google.com/uc?export=download&confirm=9iBg'
        '&id=19yDsEJjx9zNpOKz9o6AaK-E8ED6taJWU')

    return {
        'train': self._generate_examples(path / 'cars_train'),
        'test': self._generate_examples(path / 'cars_test'),
    }

  def _generate_examples(self, path):
    """Yields examples."""
    # Coordinate transform matrix required to make SRN poses consistent
    # with other NeRF models
    coord_trans = np.diag(np.array([1., -1., -1., 1.], dtype=np.float32))

    for key, scene_path in enumerate(sorted(path.iterdir())):
      # Load intrinsics
      intrinsics_path = scene_path / 'intrinsics.txt'
      with intrinsics_path.open() as f:
        lines = f.readlines()
        # Extract focal length (required to obtain rays)
        focal = float(lines[0].split()[0])

      # Load images and their associated pose
      pose_dir = scene_path / 'pose'
      rgb_dir = scene_path / 'rgb'
      pose_paths = sorted(list(pose_dir.iterdir()))
      rgb_paths = sorted(list(rgb_dir.iterdir()))

      all_imgs = []
      all_poses = []
      for rgb_path, pose_path in zip(rgb_paths, pose_paths):
        img = imageio.imread(str(rgb_path))[..., :3]
        pose = np.loadtxt(str(pose_path), dtype=np.float32).reshape(4, 4)
        pose = pose @ coord_trans  # Fix coordinate system
        all_imgs.append(img)
        all_poses.append(pose)

      all_imgs = np.stack(all_imgs)
      all_poses = np.stack(all_poses)

      yield key, {
          'images': all_imgs,
          'poses': all_poses,
          'focal': focal,
      }


#!/usr/bin/python3
""" Contains the CLI that guides the user
    on the use of the WebScrapping Tool
"""
import json
import math
import scrap_engine
from time import sleep
from var_pack import msg
from datetime import datetime

# Wait time controller
sleep_time = 1

# Classes to process
classes = ['Offer']

# Constants
pages = ['computrabajo.com/']
countries = ['Mexico', 'Colombia', 'Argentina', 'Chile']
currencies = ['mxp', 'cop', 'ars', 'clp']

# Selected options
pag = int()
dom = str()
cur_currency = str()

# Request Query
pag = "computrabajo.com/"
dom = "ar"
pos =  "desarrollador"
num_offers = "25"

def time_bar():
    now = datetime.now()
    ct = now.strftime("%H:%M:%S")
    print("\n" + msg.bar + ct + "\n")

def step0():
    """ Prints a Welcome Message to the screen """
    print("\n" + msg.welcome + "\n" + msg.bar + "\n")
    print(msg.intro1)
    print(msg.intro2)

def step1():
    """ Method used to select the URL WebScrapper to use """
    global pag;
    time_bar()
    print(msg.quest1)

    for i, page in enumerate(pages):
        print(i + 1, page)

    answer1 = input("\n" + "R// ")

    if answer1 == '':
        print(msg.not_typed)
        step1()

    if answer1 != '1':
        print(msg.bad_selection)
        step1()

    if answer1 == '1':
        pag = pages[0]
        print(msg.selection + pag)

def step2():
    """ Method used to select the country to set a currency """
    global dom, cur_currency;
    time_bar()
    print(msg.quest2)
    print(msg.opt_count + str(len(countries)) + " options:")

    for i, country in enumerate(countries):
        print(i + 1, country)

    answer = input("\n" + "R// ")

    if answer == '':
        print(msg.not_typed)
        step2()

    while type(answer) != int:
        try:
            answer = int(answer)
        except:
            print(msg.not_int)
            step2()

    if answer > len(countries) or answer == 0:
        print(msg.bad_selection)
        step2()

    else:
        dom = countries[answer - 1]
        cur_currency = currencies[answer - 1]
        print(msg.selection + dom)
        print(msg.currency_format + (cur_currency).upper())

    return None

def step3():
    """ Method used to get the Position or Role to search """
    global pos, my_url;
    time_bar()
    print(msg.quest3)

    answer = input("\n" + "R// ")

    if answer == '':
        print(msg.not_typed)
        step3()

    answer = ''.join(filter(lambda x: not x.isdigit(), answer))
    pos = answer
    print(msg.typed + pos)

def step4():
    """ Method used to get the number of offers to request """
    global num_offers, num_pages;
    time_bar()
    print(msg.quest4)

    answer = input("\n" + "R// ")

    if answer == '':
        print(msg.not_typed)
        step4()

    while type(answer) != int:
        try:
            answer = int(answer)
        except:
            print(msg.not_int)
            step4()

    else:
        num_offers = answer

step0();
step1();
step2();
step3();
url_builder(dom, pag, pos);
step4();

request_trigger(num_offers);

if __name__ == '__main__':
    welcome()


import socket
import sys
import os

cl = socket.socket()
host = '192.168.0.101'
port = 8888

try:
	cl.connect((host,port))
	print('Successfull Connect')
except socket.error as e:
	print (str(e))

while True:
	print('Welcome to the calculator')
	print('1-Log expression')
	print('2-Square root')
	print('3-Exponential expression')
	print('0-exit')

	ans = input('Enter your choice:')
	cl.send(ans.encode())
	os.system('clear')
	if ans == '1':
		#log
		print('Log fucntion')
		num=input('Enter number:')
		b = input('Enter base:')
		cl.send(num.encode())
		cl.send(b.encode())
		total=cl.recv(1024)

		print('Answer :'+ str(total.decode('utf-8')))
	elif ans == '2':
		# root
		cod = True
		while cod:
			print('Square root function')
			num =input('Enter number:')
			if int(num)> -1:
				cod = False
				cl.send(num.encode())
				total=cl.recv(1024)
			else:
				print('Enter positive number')

		print('Answer :'+ str(total.decode('utf-8')))

	elif ans == '3':
		#exponen
		print('Exponential funciton')
		num=input('Enter number:')
		cl.send(num.encode())
		total=cl.recv(1024)
		print('Answer :'+ str(total.decode('utf-8')))

	elif ans == '0':
		#eixt

		cl.close()
		sys.exit()
	else:
		print('Invalid input')


import random
import time
a = 0
b = 0
luckynum = 0
list1 = []
list2 = set()
while True:
    new = input('请输入姓名：')
    if new.strip()=="" :
        break
    else:
        list1.append(new)
print('请确认抽奖名单')
print(list1)
people = int(input('请输入中奖人数：'))
total = len(list1)
input('回车以开始抽奖')
while len(list2) < people:
    luckynum = random.randint(0,total-1)
    list2.add(list1[luckynum])

#抽奖动画
print('正在抽奖',end='')
time.sleep(0.5)
while a < 6:
    print('.',end='')
    time.sleep(0.5)
    a += 1
print()
print('中奖名单如下：')
print(list2)
input()


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# --------------------------------------
# Created by Konfido on 2020-07-16
# --------------------------------------

import re

import Config
from Items import Items, Display
from Utils import Utils as U

C = Config.Config().configs

class File():
    def __init__(self):
        self.path = ""
        self.file_name = ""
        self.yaml = ""
        self.content = ""
        self.title = ""

    @staticmethod
    def get_yaml_item(item, content):
        match = re.search(
            r'^---.*?\b{}s?: (.*?)\n.*?---'.format(item), content, re.I | re.S)
        return match.group(1) if match is not None else None

    def get_file_title(self, path):
        """ yaml_title > level_one_title > file_name """
        self.path = path
        self.file_name = U.get_file_name(self.path)
        all_text = U.get_file_content(self.path)
        match = re.search(r'(---.*?---)([\s\S]+)', all_text, re.I | re.S)
        if match and len(match.groups()) == 2:
            self.yaml = match.group(1)
            self.content = match.group(2).strip()
        else:
            U.log(self.file_name)
            self.yaml, self.content = "", all_text
        yaml_title = self.get_yaml_item("title", self.yaml)
        level_one_title = re.search(r'^# (\s+)', self.content)
        self.title = yaml_title or level_one_title or self.file_name or ""
        return self.title

    @classmethod
    def get_file_info(cls, path):
        """ get file's info in a dict """
        cls.get_file_title(cls, path)
        folder = path.split("/")[-2] if len(path.split('/'))>2 else "<root>"
        size = U.get_file_meta(cls.path, "st_size")
        ctime_float = U.get_file_meta(cls.path, "st_birthtime")
        mtime_float = U.get_file_meta(cls.path, "st_mtime")
        cdate_string = U.format_date(ctime_float, "%Y-%m-%d")
        mdate_string = U.format_date(mtime_float, "%Y-%m-%d")
        file_infos = {
            'path': cls.path,
            'file_name': cls.file_name,
            'yaml': cls.yaml,
            'content': cls.content,
            'title': cls.title,
            'folder': folder,
            'cdate': cdate_string,
            'mdate': mdate_string,
            'ctime': ctime_float,
            'mtime': mtime_float,
            'size': size,
            'synonyms': cls.get_yaml_item('synonyms', cls.yaml),
            'hidden': cls.get_yaml_item('hidden', cls.yaml)
        }
        return file_infos

class Search():
    """ Handle all search problems"""

    @classmethod
    def get_sorted_files(cls, paths, reverse=True):
        """Get info_list of all files sorted by modification time in reserve """
        all_paths = U.get_all_files_path(paths)
        if not all_paths:
            return None
        else:
            matched_list = list()
            for path in all_paths:
                info = File.get_file_info(path)
                if not info["hidden"] == 'True':
                    matched_list.append(info)
            sorted_files = sorted(
                matched_list, key=lambda k: k['mtime'], reverse=reverse)
            return sorted_files

    @classmethod
    def title_search(cls, search_terms, dicted_files):
        """Only refer to the first word of search terms"""
        def _synonyms_search(search_terms):
            # Return a list of matched notes' title
            synonyms = U.json_load(U.path_join(Config.CONFIG_DIR, 'synonyms.json'))
            key = []
            for k in list(synonyms.keys()):
                for s in synonyms[k]:
                    if search_terms[0].lower() in s.lower():
                        key.append(k)
            return key

        matched_list = []
        for f in dicted_files:
            if f['title'].lower() in [t.lower() for t in _synonyms_search(search_terms)]:
                matched_list.append(f)
            elif search_terms[0].lower() in f['title'].lower():
                matched_list.append(f)
        return matched_list

    @classmethod
    def and_search(cls, search_terms, dicted_files):
        def _matched(terms, string):
            for term in terms:
                if not re.search(term, string, re.I):
                    return False
            return True

        matched_list = []
        for f in dicted_files:
            if _matched(search_terms, f['content']):
                matched_list.append(f)
        return matched_list

    @classmethod
    def or_search(cls, search_terms, dicted_files):
        def _matched(terms, file):
            for term in terms:
                if re.search(term, file, re.I):
                    return True
            return False

        matched_list = []
        for f in dicted_files:
            if _matched(search_terms, f['content']):
                matched_list.append(f)
        return matched_list

    @classmethod
    def metric_search(cls, metric, keys, dicted_files):
        # Search notes by keys of specific metrics (tag, snippet ...)
        matched_notes = []
        for f in dicted_files:
            has_keys = []
            # Check YAML frontier to get note's assigned metrics
            match = File.get_yaml_item(metric, f["content"])
            if match:
                has_keys.extend(match.strip('[]').split(', '))
            # Check content to get note's specific metrics
            if metric in ["tag","tags"] and not C["search_tag_yaml_only"]:
                has_keys.extend(re.findall(r'\b#(.*?)\b', f['content'], re.I))
            elif metric == "language" and not C["search_snippet_yaml_only"]:
                has_keys.extend(re.findall(r'```(\S+)', f['content'], re.I))

            if not has_keys:
                continue
            else:
                for k in keys:
                    if k in has_keys:
                        matched_notes.append(f)
        return matched_notes

    @staticmethod
    def markdown_links_search(path, filename=False):
        "Get a list of Markdown links which contained in the file (by given path/filename)"
        abs_path = path if not filename else U.get_abspath(path, query_dict=True)
        content = U.get_file_content(abs_path)
        # exclude images link: ![]() and url: [](https://)
        links_info = re.findall(
            r'(?<!!)(\[(.*?)\]\(((?!http).*?md)\))', content)
        link_list = [l[2] for l in links_info]
        return link_list

    @staticmethod
    def backlinks_search(filename):
        "Query dict with path/filename to get a backlink list"
        filename = U.get_file_name(filename, with_ext=True)
        backlinks = U.json_load(U.path_join(Config.CONFIG_DIR, 'backlinks.json'))
        matched_list = backlinks[filename] if backlinks.__contains__(filename) else []
        return matched_list


from flask import Flask, render_template, request
import requests

app = Flask(__name__)

@app.route('/')
def home():
    return render_template('home.html')

@app.route('/vaccination_status', methods=['POST'])
def vaccination_status():
    reg_no = request.form['reg_no']
    url = 'http://database-service:5001/vaccination_status'
    data = {'reg_no': reg_no}
    response = requests.post(url, data=data)
    return response.text

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000)


"""To Do
- other learning algorithms
- learning rate adjust
- experience memory size increase (in the paper they suggest 1m)
- test dueling dqn

# agent can stop
# increase grid size
# increase size and change shape of target
# geographical realistic region
# calc least cost path to compare with
"""

from routing import *
from utils import *

from keras.models import Sequential
from keras.layers import Dense, Activation, Flatten, Conv2D, Permute
from keras.optimizers import Adam

from rl.agents.dqn import DQNAgent
from rl.policy import BoltzmannQPolicy, LinearAnnealedPolicy, EpsGreedyQPolicy
from rl.memory import SequentialMemory

# env = Navigation(grid_size=40)
# env = NavV2(grid_size=30)
env = NavigationV2(grid_size=30,random_land=.05,inc_mvng_hzd=True)
env.max_steps

mem_len = 3

nb_actions = env.action_space.n

# Next, we build a very simple model.
model = Sequential()
model.add(Permute((2, 3, 1), input_shape=(mem_len,) + env.observation_space.shape))
# model.add(Conv2D(32, (8, 8), strides=(4, 4)))
# model.add(Activation('relu'))
model.add(Conv2D(64, (4, 4), strides=(2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3), strides=(1, 1)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dense(nb_actions))
model.add(Activation('linear'))
print(model.summary())

# Finally, we configure and compile our agent. You can use every built-in Keras optimizer and
# even the metrics!
memory = SequentialMemory(limit=500000, window_length=mem_len)

# policy = BoltzmannQPolicy(tau=0.05)
policy = LinearAnnealedPolicy(EpsGreedyQPolicy(), attr='eps', value_max=1., value_min=.1, value_test=.05,
                              nb_steps=1e7)

agent = DQNAgent(model=model, nb_actions=nb_actions, policy=policy, memory=memory,
                 nb_steps_warmup=50000, gamma=.99, target_model_update=10000,
                 train_interval=4, delta_clip=1.)
agent.compile(Adam(lr=.00025), metrics=['mae'])

# Okay, now it's time to learn something! We visualize the training here for show, but this
# slows down training quite a lot. You can always safely abort the training prematurely using
# Ctrl + C.
# agent.fit(env, nb_steps=1e4, log_interval=10000,verbose=1)
# agent.save_weights('dqn_nav2_30x30x1_2conv_1e7',overwrite=True)
agent.load_weights('model8_6c01ba5f786ebd5938ca8e8f75008a63d2fe11bd/dqn_nav2_30x30x3_2conv_1e7_mvhz')
#

# Finally, evaluate our algorithm for 20 episodes.
for i in range(1,21):
    print(i)
    agent.test(env, nb_episodes=1,visualize=True)
    makegif('images/','model8_6c01ba5f786ebd5938ca8e8f75008a63d2fe11bd/movie'+str(i),delete_files=True)


#!/usr/bin/env python3
import os
from flask import Flask, request, make_response, redirect, jsonify, render_template
from urllib.parse import urlparse
import requests
import markdown
if(__name__) == 'encors':
    from encors_allowed_origins import ALLOWED_ORIGINS
    from encors_conf import *
else:
    from src.encors_allowed_origins import ALLOWED_ORIGINS
    from src.encors_conf import *

# initialize the Flask app using a customized template folder
app = Flask(__name__, template_folder='templates')

@app.route('/<path:url_src>')
def encors_catch_all(url_src):
    return encors_proxy(url_src)

@app.route('/', methods=['GET', 'POST'])
def encors_proxy(url_src=''):
    try:
        encors_target = request.headers.get('encors-target', default = url_src, type = str)
        if(encors_target == ''):
            return defaultOutput()
        # filter by ALLOWED_ORIGINS
        origin = urlparse(request.url_root)
        if len(ALLOWED_ORIGINS) > 0 and origin.hostname not in ALLOWED_ORIGINS:
            return outputUnauthorizedAccess()
        src_url = urlparse(encors_target)
        res = requests.get(encors_target, stream = True)
        if res.encoding is None:
            res.encoding = 'utf-8'
        stream_content = res.text # will it read the whole data here already?
        if(CHUNK_SIZE_LIMIT_IN_BYTE > 0):
            stream_size = 0
            for chunk in res.iter_content(CHUNK_SIZE_LIMIT_IN_BYTE):
                stream_size += len(chunk)
                if(CONTENT_SIZE_LIMIT_IN_BYTE > 0 and (stream_size + CHUNK_SIZE_LIMIT_IN_BYTE > CONTENT_SIZE_LIMIT_IN_BYTE)):
                    return outputError('Source exceeds size limit: ' + str(CONTENT_SIZE_LIMIT_IN_BYTE) + ' bytes')
        response = make_response(stream_content)
        # forward its original headers
        for key in res.headers.keys():
            response.headers[key] = res.headers[key]
        # add the CORS control header
        response.headers['Access-Control-Allow-Origin'] = '*'
        return response
    except Exception as e:
        #show error traceback information only when Flask debug mode is on
        if(app.debug):
            raise e
        else:
            return outputError(e)

# output html or markdown
def output(template_path, **kwargs):
    if(kwargs and kwargs['markdown'] == True):
        return markdown.markdown(render_template(template_path))
    else:
        return render_template(template_path)

# default output
def defaultOutput():
    return output('index.html')

# output unified error json object
def outputError(e):
    return jsonify({'error': True, 'message': str(e)})

def outputUnauthorizedAccess():
    return make_response('Unauthorized access.', 401, {'WWW-Authenticate':'Basic realm="Encors access control"'})


# !/usr/bin/python
# -*- coding: UTF-8 -*-

year = int(input('year:\n'))
month = int(input('month:\n'))
day = int(input('day:\n'))

days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

def getDays(year, month, day):
    '''
        获取一年的第几天
    '''
    daySum = 0
    if month < 0 or month >12:
        print("月份错误")
    else:
        for i in range(month-1):
            daySum += days[i]

        if isleapyear(year):
            daySum += 1

        daySum += day

        return daySum

def isleapyear(year):
    if year % 400 == 0 or ((year % 4 == 0) and (year % 100 != 0)):
        return True
    else:
        return False

print("{} 年 {} 月 {} 日 是一年中的第{} 天".format(year, month, day, getDays(year, month, day)))


import logging
import threading
import time
import concurrent.futures

def thread_function(x, result):
    # print(x)
    logging.info("Thread %s: starting", x)
    time.sleep(2)
    logging.info("Thread %s: finishing", x)
    result[0] = x

if __name__ == "__main__":
    format = "%(asctime)s: %(message)s"
    logging.basicConfig(format=format, level=logging.INFO,
                        datefmt="%H:%M:%S")

    logging.info("Main    : before creating thread")
    result = [None]
    x = threading.Thread(target=thread_function, args=(1, result)) # daemon = True thread will die if the program exits
    logging.info("Main    : before running thread")
    x.start()
    logging.info("Main    : wait for the thread to finish")
    x.join() # main will wait for x to complete
    print(result[0])
    logging.info("Main    : all done")


# 5. Longest Palindromic Substring
class Solution:
    def longestPalindrome(self, s: str) -> str:
        n = len(s)
        mx = ""
        for i in range(n):
            j = 0
            while i-j >= 0 and i+j < n and s[i-j] == s[i+j]:
                if len(mx) < len(s[i-j:i+j+1]): mx = s[i-j:i+j+1]
                j += 1

        for i in range(n-1):
            j = 0
            while i-j >= 0 and i+j+1 < n and s[i-j] == s[i+j+1]:
                if len(mx) < len(s[i-j:i+j+2]): mx = s[i-j:i+j+2]
                j += 1

        return mx

leetcode/0-250/296-5. Longest Palindromic Substring.py


import sys
from PyQt5.QtWidgets import QWidget, QPushButton, QApplication
from PyQt5.QtCore import  QObject

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        quit_btn = QPushButton('Quit', self)
        quit_btn.clicked.connect(self.print_msg)  # QApplication.instance().quit

        quit_btn.resize(quit_btn.sizeHint())
        quit_btn.move(50, 50)

        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Quit button')
        self.show()

    def print_msg(self):
        print(QApplication.instance())
        print(QApplication.instance().datacenter)

class DataCenter(QObject):
    def __init__(self):
        super().__init__()
        self.name = 'test'

app = QApplication(sys.argv)
app.datacenter=DataCenter()
print(app)
ex = Example()
sys.exit(app.exec_())


# Import modules
import os, requests, re, sys
import pandas as pd
import xml.etree.ElementTree as ET

# Define class
class DSD:
    def __init__(self, dataset_id):
        self.dataset_id = dataset_id
        self.lang = 'en'
        self.download_dsd()
        self.set_dsd()

    def download_dsd(self):
        datastructure = f'https://stats.oecd.org/restsdmx/sdmx.ashx/GetDataStructure/{self.dataset_id}'
        # Send request
        response = requests.get(datastructure)
        # Terminate program if there is no such dataset id
        if response.status_code!=200:
            print(f"There is no such an id ({self.dataset_id})! Look for available datasets in the 'id' attributes " \
                     f"of 'KeyFamily' tags on https://stats.oecd.org/restsdmx/sdmx.ashx/GetDataStructure/all. " \
                     "When you find one, run the program again with a correct dataset id.")
            sys.exit()
        dsd = response.text
        # Fixing XML format
        regex = re.compile(r"<message:Structure(.*?)>")
        m = re.search(regex, dsd)
        del_part = m.group(1)
        dsd_fixed = dsd.replace(r'{}'.format(del_part), "")
        dsd_fixed = re.sub(r' xmlns="http://www.SDMX.org/resources/SDMXML/schemas/v2_0/message"', "", dsd_fixed)
        dsd_fixed = dsd_fixed.replace('message:', '')
        dsd_fixed = dsd_fixed.replace('xml:lang', 'lang')
        # Get formatted dsd
        self.dsd_xml = dsd_fixed

    def set_dsd(self):
        # Inner functions
        # Choose specific child element
        def child_el(el, el_tag = None):
            for i in el:
                if (i.get('lang') == self.lang) and not el_tag:
                    return i
                elif (i.get('lang') == self.lang) and el_tag:
                    if el_tag == i.tag:
                        return i
        # Add element info to dictionary
        def add_el_to_dic(el, el_tag = None):
            # Add attributes
            def add_attrs(a, e):
                dic = {}
                for attr in a.keys():
                    dic[attr] = a[attr]
                if el.text:
                    try:
                        dic[e.tag] = attrs[e.text]
                    except:
                        pass
                if e.tag in ['Code']:
                    dic['description'] = child_el(e).text
                return dic
            #Process element
            attrs = el.attrib
            # Do not process element if it does not have desired tag name
            if el_tag:
                if el_tag == el.tag:
                    return add_attrs(attrs, el)
                else:
                    pass
            # Process element if tag name is not specified
            else:
                return add_attrs(attrs, el)
        # Add elements info to dictionary
        def add_els_to_dic(p_el, tags=None, el_tag = None):
            arr = []
            for el in p_el:
                dic = add_el_to_dic(el, el_tag)
                if dic:
                    if tags:
                        dic[tags] = el.tag
                    arr.append(dic)
            return arr
        # Define dimensions, attributes, and time dimension
        def transform(dic):
            list_ = []
            key = dic['conceptRef']
            val = dic.get('codes', None)
            if val is None:
                list_ = [key,val]
            else:
                val_arr = []
                for i in val:
                    val_arr.append(i['value'])
                list_ = [key,val_arr]
            return list_

        # Define future attributes
        self.agency_id = ''
        self.description = ''
        self.concepts = {}
        self.dimensions = []
        self.attributes = []
        self.time_dimension = []

        # Get xml root
        root = ET.fromstring(self.dsd_xml)
        # Key family info
        key_family = root.find('./KeyFamilies/KeyFamily')
        self.agency_id = key_family.attrib['agencyID']
        key_family_desc = root.findall("./KeyFamilies/KeyFamily/")
        self.description = child_el(key_family_desc).text
        # Add a dictionary with concepts and their codes
        concepts = add_els_to_dic(root.findall('./KeyFamilies/KeyFamily/Components/'), tags='concept')
        self.concepts = concepts
        # Add codes to concepts
        for el in root.findall('./CodeLists/'):
            for concept_i in range(len(self.concepts)):
                try:
                    if el.get('id') == self.concepts[concept_i]['codelist']:
                        codes = add_els_to_dic(el, el_tag = 'Code')
                        self.concepts[concept_i]['codes'] = codes
                except:
                    continue
        # Add description to concepts
        for el in root.findall('./Concepts/'):
            for concept_i in range(len(self.concepts)):
                try:
                    if el.get('id') == self.concepts[concept_i]['conceptRef']:
                        desc = child_el(el).text
                        self.concepts[concept_i]['description'] = desc
                except:
                    continue
        # Define dimensions, attributes, and time dimension
        for i in self.concepts:
            concept = i['concept']
            if concept == 'Dimension':
                self.dimensions.append(transform(i))
            elif concept == 'Attribute':
                self.attributes.append(transform(i))
            elif concept == 'TimeDimension':
                self.time_dimension.append(transform(i))

    # dsd to string
    def to_string(self):
        print(f"\nDSD - {self.dataset_id}\nDSD name - {self.description}\nDSD agency - {self.agency_id}\n\nConcepts:")
        just_num = 30
        for i in range(len(self.concepts)):
            concept_type = self.concepts[i]['concept']
            concept_ref = self.concepts[i]['conceptRef']
            desc = self.concepts[i]['description']
            code_num = str(len(self.concepts[i].get('codes', [])))
            print('{}{}{}{}'.format(concept_type.ljust(just_num), concept_ref.ljust(just_num), desc.ljust(just_num), code_num.ljust(just_num)))


'''
           DISPLAY.PY
=====================================
Contains data & functions for composing & displaying the data/GUI for the game.

TABLE OF CONTENTS
    [0] IMPORTS & INITIALIZATIONS
    [1] DISPLAY FRAME: coords and loads the ASCII text file into runtime as a variable
    [2] GENERAL UTILITY FUNCTIONS: Used for more than one screen
    [3] SCREEN FUNCTIONS: Used for only one specific screen
    [X] JUNK CODE: Various bits and pieces and materials that were replaced/revised.

'''

############################################################################################

import os
from blessed import Terminal
from math import floor
from statistics import mean

term = Terminal()

############################################################################################

#declare constants for frame display position. X, Y refer to the .move_xy positions for terminal().  Width and height refers to the maximum character dimensions for the zone.
DISPLAY_COORDS = {
    'title':{'x':12, 'y':10},
    'title_max':{'width':55, 'height':1},
    'body':{'x':13, 'y':13},
    'body_max':{'width':53, 'height':20},
    'footnote':{'x':14, 'y':34},
    'footnote_max':{'width':53, 'height':1},
}

#load in display frame so that the file isn't continuously read
DISPLAY_FRAME = []
with open('display_frame_tall.txt', 'r') as f:
    for line in f.read().splitlines():
        DISPLAY_FRAME.append(line)

############################################################################################
'''GENERAL UTILITY FUNCTIONS
These functions are used agnostic to any particular screen.
'''

def cleanify(string):
    '''
    Strips underscores and capitalizes for programatic name > display appropriate name
    '''
    return string.capitalize().replace('_', ' ')

def wrap_text(data, limits):
    '''
    Accepts a longer string and returns a wrapped string.
    Wrap text is mutually exclusive with v_just and h_just at the moment, and prints a single block of wrapped text in a frame that's slightly smaller than the maximum bounding limits.  Because of how print_pipeline by convention expects a list for data_group_n ['assembled'] but that this may not parse later with the specific assembly functions, this function will check to see if it is being passed a string or a list.  If it is a list, it expects a one-item list and grabs the first item from it.

    DANGER: if any word exceeds the limit of width and is not broken by a space, this function cannot work.
    '''
    if type(data) == list:
        data = data[0]

    #establishes function-specific variables for the wrap process
    height = limits['height']- 2
    width = limits['width'] - 2
    data = data.split()

    #Safety check: aborts function early if nonfunctional parameters are reached.
    for word in data:
        if len(word) >= width-1:
            return ['ERROR: WORD IN TEXT','EXCEEDS WIDTH LIMIT.']

    def line_assemble(data):
        #puts together each line for the wrapped text
        string = ''
        while len(string) <= width:
            #send empty strings home
            if data == []:
                return string, data

            #catches overflow and ensures end spaces aren't butting out words
            if len(string + data[0]) == width:
                string+= data.pop(0)
                return string, data
            if len(string + data[0]) > width:
                return string, data

            string += data.pop(0) + ' '
        return string, data

    refactored = []
    while data != []:
        newline, data = line_assemble(data)
        refactored.append(newline)

    #finally, h&v justify the new list to be properly set forward
    y_pad = [' ']
    refactored = [' '+line for line in refactored]

    #final safety check:
    if len(refactored) > height+2:
        return ['ERROR: HEIGHT OF','TEXT EXCEEDS LIMIT.']

    if len(refactored) > height:
        return refactored
    else:
        return y_pad + refactored

def v_justify(height, data):
    '''
    This function centers the display text vertically.
        height: max lines value
        data: the data printed in the frame
    Returns a list of strings with justified spacing.
    '''
    v_difference = height - len(data)
    front_pad = [' ' for i in range(floor(v_difference/2))]
    back_pad = [' ' for i in range(v_difference - len(front_pad))]

    return front_pad + data + back_pad

def h_justify(width, data):
    '''
    This function centers the display text horizontally.
        width: max character width of the display
        data: the data printed in the frame
    Returns a list of strings with justified spacing.
    '''
    autosetback = 3 #something of a magic constant - justifies further left for a more 'natural' centered look.
    #average_width = floor(mean([len(line) for line in map(term.strip_seqs, data)]))
    average_width = floor(mean(map(len, map(term.strip_seqs, data))))

    front_pad = [' ' * (floor((width - average_width)/2)-autosetback) for i in range(width)]
    back_pad = []

    for line in map(term.strip_seqs, data):
        back_pad.append(' ' * (width - len(line) - len(front_pad[0])))

    return [a+b+c for a, b, c in zip(front_pad, data, back_pad)]

def tab_header(tabs, position):
    '''
    Constructs a header that is incorporated into the print pipeline for additional display.
    Function returns an array of 3 strings each of length header_max; the keys are the position
    WARNING: This function assumes that the tabs display will always be 3 high.  Even if length or display frame changes, this dimension is unlikely to change.

    tabs: list of strings that will be displayed in header.
    position: integer that MUST be in the possible index range for tabs. Current position.
    '''

    header_max = DISPLAY_COORDS['title_max']['width']
    total_width = 1+sum([len(s) +1 for s in tabs]) #totals length of tabs and ║s
    spare_spaces = header_max-total_width
    header_array = ['╔', '║', '╚'] #print array

    #Catch case where total width exceed space limits.
    if header_max < total_width:
        raise Exception(f"Cannot print.  Width ({total_width}) exceeds maximum permissible ({header_max}).")

    def _get_shortest(lst):
        #Returns the index of the shortest length string from a list of strings.
        return lst.index(min(lst, key=len))

    def _outline(tabline, l_corner, middle_t, r_corner):
        '''
        This function requires the centre tabline to have already been constructed
        For top:     l_corner = '╔', middle_t = '╦', r_corner = '╗'
        For bottom:  l_corner = '╚', middle_t = '╩', r_corner = '╝'
        tabline = header['tabs'] /after/ it is complete
        '''
        bar_index = [i for i, c in enumerate(tabline) if c=='║']
        bar_index.pop(0) #remove index=0 (║ in first place) so the while loop works
        line = l_corner #initialize start of line

        while len(line) < (len(tabline)-1):

            if len(line) < bar_index[0]:
                line += '═'
            elif len(line) == bar_index[0]:
                line += middle_t
                bar_index.pop(0)
        line += r_corner

        return line

    #Initial 'even' space padding if there's lots of pads to be handed out:
    if spare_spaces >= 2*len(tabs):
        for i in range(len(tabs)):
            tabs[i] = ' ' + tabs[i] + ' '
        spare_spaces -= 2*len(tabs)

    #Thereafter, space pads the shortest item first:
    while spare_spaces >= 1:
        if spare_spaces == 1:
            tabs[_get_shortest(tabs)] = tabs[_get_shortest(tabs)] + ' '
            spare_spaces -= 1
        else:
            tabs[_get_shortest(tabs)] = ' ' + tabs[_get_shortest(tabs)] + ' '
            spare_spaces -= 2

    #finalize array structure
    for t in tabs:
        header_array[1] += t + '║' #Middle line of tabs (with text)
    header_array[0] = _outline(header_array[1], '╔', '╦', '╗') #Top (first) line
    header_array[2] = _outline(header_array[1], '╚', '╩', '╝') #Bottom (last) line

    #The unfortunate quality of having to construct the tabs line twice.  The first must be WITHOUT term.method, in order to have the proper index locations for top and bottom.  The second must be to add 'bold_black_on_white' method.  You can see this in that the ['tabs'] line will be len+20 compared to top and bottom *programmatically* but the difference NOT visually displayed to the monitor.
    header_array[1] = '║'
    for t in tabs:
        if tabs[position]==t:
            header_array[1] += term.bold_black_on_white(t) + '║'
        else: header_array[1] += t + '║'

    #print the tab header in the correct location
    x = DISPLAY_COORDS['title']['x']
    y = DISPLAY_COORDS['title']['y']
    for i in header_array:
        print(term.move_xy(x, y) + i)
        y+=1

def footnote(text, coords):
    '''
    Thus function prints information in the footnote at the bottom of the display frame.  Text length to not exceed 53.
    '''
    print(term.move_xy(coords['x'], coords['y']) + term.bold(text))

def print_pipeline(data_group_1, data_group_2=None):
    '''
    This function aggregates data & print functions and return a list of strings that print out within the current display frame (as declared at the beginning of the file).  The data group variables are the data that is to be printed; it will automatically split into windows if group 2 != None.  The details of how data groups should be formatted is as below:
    group = {
        assembly_func: Unique function for each menu screen that assembles the pre-spaced and pre-justified data (such as REF, FOR, and the dots preceding them) and returns a list.
        v_just: Boolean; whether this group will be vertically justified.
        h_just: Boolean; whether this group will be horizontally justified.
        wrap: Boolean; whether this group is a long string that will need to wrap around.  Currently mutually exclusive with v/h justification
    }
    NOTE that this function, largely, currently does not check to see if the data will display past limit boundaries.  Validation occurs in data group assembly.
    NOTE that this function deals with neither the header nor the footnote.
    '''

    #Automatically defines limits based on whether there are two groups or not.
    limits = DISPLAY_COORDS['body_max'].copy()
    if data_group_2 != None:
        limits['width'] = floor(limits['width']/2)

    #apply print pipeline to each group
    for group in [data_group_1, data_group_2]:
        #initial check to see if there are two groups
        if group == None:
            break

        data = group['assembled']
        group['preprint'] = None

        #Returns a wrapped string
        if group['wrap']:
            group['preprint'] = wrap_text(data, limits)
            v_distance = limits['height'] - len(group['preprint'])
            for i in range(v_distance):
                group['preprint'].append(' ' * limits['width'])
            continue

        #vertically justifies; or appends appropriate number of lines
        if group['v_just']:
            data = v_justify(limits['height'], data)
        else:
            v_distance = limits['height'] - len(data)
            for i in range(v_distance):
                data.append(' ')

        #horizontally justifies; or pads spaces to the right
        if group['h_just']:
            data = h_justify(limits['width'], data)
        else:
            for i in range(len(data)):
                data[i] += (' ' * (limits['width']-len(data[i])))

        #Casts the refactored display data.
        group['preprint'] = data

    #Return a combined list if two sides; otherwise return a single list.
    if data_group_2 != None:
        return [i+'║'+j for i, j in zip(data_group_1['preprint'], data_group_2['preprint'])]
    else:
        return data_group_1['preprint']

############################################################################################
'''SCREEN FUNCTIONS
These functions are used for specific screens within the game.

TABLE OF CONTENTS:
    [0] Character generation displays
    [1] Inventory displays
    [2] Shop displays
    [3] Character improvement displays
    [4] Game data displays
    [5] Combat displays
'''

# ZONE [0] - CHARACTER GENERATION DISPLAYS ----------------

def box_logic(num):
    '''
    Returns filled or empty boxes for the attribute selection.  Arg must be an int in 1-4
    '''
    return ('●' * num) + ('○' * (4-num))

def attributes_display(cursor, options, points):
    '''
    Cursor is an integer IN the index of options.
    Options is the full list of attribute namedtuples.
    Points is the points remaining to spend and is only used in the footnote.
    '''
    #Clear screen and print current display frame + tabs.
    os.system('clear')
    for line in DISPLAY_FRAME:
        print(line)

    #Assemble left side display list from current cursor and options data.
    left_disp = []
    for i, opt in enumerate(options):
        if cursor != i:
            left_disp.append(f'{box_logic(opt.value)}  {opt.name}')
        else:
            left_disp.append(term.bold_black_on_white(f'{box_logic(opt.value)}  {opt.name}'))

    #Assemble right side display list from current cursor and options data.
    right_disp = options[cursor].desc

    #Construct display groups 1 and 2.
    group1 = {
        'assembled':left_disp,
        'v_just':True,
        'h_just':True,
        'wrap':False,
    }
    group2 = {
        'assembled':right_disp,
        'v_just':False,
        'h_just':False,
        'wrap':True,
    }

    #Use preprint for the finalized display.
    x = DISPLAY_COORDS['body']['x']
    y = DISPLAY_COORDS['body']['y']
    total_body = print_pipeline(group1, group2)

    for i in range(len(total_body)):
        print(term.move_xy(x, y+i) + total_body[i])

    footnote(f'Remaining Points:  {points}', DISPLAY_COORDS['footnote'])

def equipment_display(cursor, options, points):
    '''
    Cursor is an integer IN the index of options.
    Options is the full list of equipment namedtuples.
    Points is the points remaining to spend and is only used in the footnote.
    '''
    #Clear screen and print current display frame.
    os.system('clear')
    for line in DISPLAY_FRAME:
       print(line)

    #Assemble left side display list from current cursor and options data.
    left_disp = []
    for i, opt in enumerate(options):
        option_string = f'{cleanify(opt.name)}' + ' ' * (16-len(opt.name)) + f'{opt.value}'
        if opt.selected:
            option_string = f'[{term.bold(option_string)}]'
        else:
            option_string = f' {option_string} '
        if cursor == i:
            option_string = f'{term.bold_black_on_white(option_string)}'

        left_disp.append(option_string)

    #Assemble right side display list from current cursor and options data.
    right_disp = options[cursor].desc

    #Construct display groups 1 and 2.
    group1 = {
        'assembled':left_disp,
        'v_just':True,
        'h_just':True,
        'wrap':False,
    }
    group2 = {
        'assembled':right_disp,
        'v_just':False,
        'h_just':False,
        'wrap':True,
    }

    #Use preprint for the finalized display.
    x = DISPLAY_COORDS['body']['x']
    y = DISPLAY_COORDS['body']['y']
    total_body = print_pipeline(group1, group2)

    for i in range(len(total_body)):
        print(term.move_xy(x, y+i) + total_body[i])

    footnote(f'Remaining Points:  {points}', DISPLAY_COORDS['footnote'])

def skill_display(cursor, options, points):
    '''
    Cursor is an integer IN the index of options.
    Options is the full list of skill namedtuples.
    Points is the points remaining to spend, ==1 and is implicit.
    '''
    #Clear screen and print current display frame.
    os.system('clear')
    for line in DISPLAY_FRAME:
       print(line)

    #Assemble left side display list from current cursor and options data.
    left_disp = []
    for i, opt in enumerate(options):
        option_string = f'{cleanify(opt.name)}'
        if opt.selected:
            option_string = f'[{term.bold(option_string)}]'
        else:
            option_string = f' {option_string} '
        if cursor == i:
            option_string = f'{term.bold_black_on_white(option_string)}'

        left_disp.append(option_string)

    #Assemble right side display list from current cursor and options data.
    right_disp = options[cursor].desc

    #Construct display groups 1 and 2.
    group1 = {
        'assembled':left_disp,
        'v_just':True,
        'h_just':True,
        'wrap':False,
    }
    group2 = {
        'assembled':right_disp,
        'v_just':False,
        'h_just':False,
        'wrap':True,
    }

    #Use preprint for the finalized display.
    x = DISPLAY_COORDS['body']['x']
    y = DISPLAY_COORDS['body']['y']
    total_body = print_pipeline(group1, group2)

    for i in range(len(total_body)):
        print(term.move_xy(x, y+i) + total_body[i])

# ZONE [1] - INVENTORY DISPLAYS ---------------------------


import requests
from os import getenv

def get_rancher_projects(rancher_url, rancher_auth, verify_ssl):
    projects = {}
    session = requests.session()
    response = session.get(f'{rancher_url}/projects/', auth=rancher_auth, verify=verify_ssl)
    for project in response.json()["data"]:
        if project["state"] is "inactive":
            pass
        else:
            projects[project["id"]] = {"env": project["name"], "hosts": {}}

    return projects

def get_rancher_hosts (rancher_url, rancher_auth, verify_ssl, limit):
    session = requests.session()
    response = session.get(f'{rancher_url}/hosts?limit={limit}', auth=rancher_auth, verify=verify_ssl)

    return response.json()["data"]

def map_rancher_hosts_to_project (hosts, projects):
    for host in hosts:
        if host["state"] == 'active':
            pass
        else:
            project = host["accountId"]
            host_id = host["id"]
            hostname = host["data"]["fields"]["hostname"]
            state = host["state"]

            if "crate.region" in host["data"]["fields"]["labels"]:
                region = host["data"]["fields"]["labels"]["crate.region"]
            else:
                region = "NotFound"
            if "crate.host.name" in host["data"]["fields"]["labels"]:
                short_name = host["data"]["fields"]["labels"]["crate.host.name"]
            else:
                short_name = "NotFound"
            if state == 'disconnected':
                projects[project]["hosts"][host_id] = {
                    "hostname"  : hostname,
                    "region"    : region,
                    "short_name": short_name,
                    "state"     : state
                }
            else:
                pass
    return projects

def disconnected_hosts_list(disconnected_hosts):
    disconnects = {}
    hosts = []
    for project in disconnected_hosts:
        if disconnected_hosts[project]['hosts'] == {}:
            pass
        else:
            disconnects[project] = disconnected_hosts[project]
            disconnects[project]['hosts'] = disconnected_hosts[project]['hosts']
            for host in disconnects[project]['hosts']:
                hosts.append(f"{disconnects[project]['hosts'][host]['short_name']}({disconnects[project]['env']}) in "
                             f"{disconnects[project]['hosts'][host]['region']}")
    return hosts

def send_slack_notification(webhook_url, slack_channel, slack_user, disconnected_hosts):
    channel = slack_channel
    webhook = webhook_url
    user = slack_user
    flattened_list = ", ".join(map(str, disconnected_hosts))
    text = f"The following hosts are disconnected: `{flattened_list}`"
    payload = {
        "channel": channel,
        "username": user,
        "text": text
    }
    session = requests.session()
    if flattened_list == '':
        return
    else:
        response = session.post(webhook, json=payload)
        return response

if __name__ == '__main__':
    rancher_url = getenv('RANCHER_URL', 'https://console.ciscocrate.com/v2-beta')
    rancher_access_key = getenv('RANCHER_ACCESS_KEY')
    rancher_secret_key = getenv('RANCHER_SECRET_KEY')
    rancher_auth = (rancher_access_key, rancher_secret_key)
    verify_ssl = True
    limit = 1500
    slack_channel = getenv('SLACK_CHANNEL', '#notify-ops')
    webhook_url = getenv('SLACK_WEBHOOK_URL')
    slack_user = 'Disconnected Host Notifier'

    projects = get_rancher_projects(rancher_url, rancher_auth, verify_ssl)
    rancher_hosts = get_rancher_hosts(rancher_url, rancher_auth, verify_ssl, limit)
    disconnected_host_map = map_rancher_hosts_to_project(rancher_hosts, projects)
    disconnected_list = disconnected_hosts_list(disconnected_host_map)
    send_slack_notification(webhook_url, slack_channel, slack_user, disconnected_list)


from math import sqrt

def seidel(A, b, eps):
    n = len(A)
    r = range(n)
    x = [0 for i in r]

    converge = False
    while not converge:
        x_new = x.copy()
        for i in r:
            s1 = sum(A[i][j] * x_new[j] for j in range(i))
            s2 = sum(A[i][j] * x[j] for j in range(i + 1, n))
            x_new[i] = (b[i] - s1 - s2) / A[i][i]

        converge = sqrt(sum((x_new[i] - x[i]) ** 2 for i in r)) <= eps
        x = x_new

    return x

print("Seidel method")
print("Enter the alpha: ", end="")
alpha = int(input())
print("Enter the epsilon: ", end="")
eps = float(input())

A = ((7 + alpha, 2.5, 2, 1.5, 1),
     (2.5, 8 + alpha, 2.5, 2, 1.5),
     (2, 2.5, 9 + alpha, 2.5, 2),
     (1.5, 2, 2.5, 10 + alpha, 2.5),
     (1, 1.5, 2, 2.5, 11 + alpha))
b = (1, 1, 1, 1, 1)

x = seidel(A, b, eps)
print("Solution: ", end="")
for i in range(len(x) - 1):
    print('{:.8f}'.format(x[i]), end=" ")
print('{:.8f}'.format(x[len(x) - 1]))