<commit_before>from __future__ import absolute_import
#from __future__ import print_function
import theano
import theano.tensor as T
import numpy as np
import warnings, time, copy

from . import optimizers
from . import objectives
from . import callbacks as cbks
from .utils.generic_utils import Progbar, printv
from .layers import containers
from six.moves import range

def standardize_y(y):
    if not hasattr(y, 'shape'):
        y = np.asarray(y)
    if len(y.shape) == 1:
        y = np.reshape(y, (len(y), 1))
    return y

#return a list with tuple element which are begin and end of each batch
def make_batches(size, batch_size):
    nb_batch = int(np.ceil(size/float(batch_size)))
    return [(i*batch_size, min(size, (i+1)*batch_size)) for i in range(0, nb_batch)]

#wrap a numpy.array with []
def standardize_X(X):
    if type(X) == list:
        return X
    else:
        return [X]

def slice_X(X, start=None, stop=None):
    if type(X) == list:
        if hasattr(start, '__len__'):
            return [x[start] for x in X]
        else:
            return [x[start:stop] for x in X]
    else:
        if hasattr(start, '__len__'):
            return X[start]
        else:
            return X[start:stop]

class Model(object):

    def compile(self, optimizer, loss, class_mode="categorical", theano_mode=None):
        self.optimizer = optimizers.get(optimizer)
        self.loss = objectives.get(loss)

        # input of model
        self.X_train = self.get_input(train=True)
        self.X_test = self.get_input(train=False)

        self.y_train = self.get_output(train=True)
        self.y_test = self.get_output(train=False)

        # target of model
        self.y = T.zeros_like(self.y_train)

        train_loss = self.loss(self.y, self.y_train)
        test_score = self.loss(self.y, self.y_test)

        if class_mode == "categorical":
            #just compare whether the most probable is or not
            train_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_train, axis=-1)))
            test_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_test, axis=-1)))

        elif class_mode == "binary":
            #after make prediction [0,0,1,0] like with round function, compare each class of each sample then accumulate and divide by n*k
            train_accuracy = T.mean(T.eq(self.y, T.round(self.y_train)))
            test_accuracy = T.mean(T.eq(self.y, T.round(self.y_test)))
        else:
            raise Exception("Invalid class mode:" + str(class_mode))
        self.class_mode = class_mode

        updates = self.optimizer.get_updates(self.params, self.regularizers, self.constraints, train_loss)

        if type(self.X_train) == list:
            train_ins = self.X_train + [self.y]
            test_ins = self.X_test + [self.y]
            predict_ins = self.X_test
        else:
            train_ins = [self.X_train, self.y]
            test_ins = [self.X_test, self.y]
            predict_ins = [self.X_test]

        #input is [[x1,x2,x3...],[y1,y2,y3]]   x1 and y1 are both vector
        self._train = theano.function(train_ins, train_loss,
            updates=updates, allow_input_downcast=True, mode=theano_mode)
        self._train_with_acc = theano.function(train_ins, [train_loss, train_accuracy],
            updates=updates, allow_input_downcast=True, mode=theano_mode)
        self._predict = theano.function(predict_ins, self.y_test,
            allow_input_downcast=True, mode=theano_mode)
        self._test = theano.function(test_ins, test_score,
            allow_input_downcast=True, mode=theano_mode)
        self._test_with_acc = theano.function(test_ins, [test_score, test_accuracy],
            allow_input_downcast=True, mode=theano_mode)

    def train(self, X, y, accuracy=False):
        X = standardize_X(X)
        y = standardize_y(y)
        ins = X + [y]
        if accuracy:
            return self._train_with_acc(*ins)
        else:
            return self._train(*ins)

    def test(self, X, y, accuracy=False):
        X = standardize_X(X)
        y = standardize_y(y)
        ins = X + [y]
        if accuracy:
            return self._test_with_acc(*ins)
        else:
            return self._test(*ins)

    def fit(self, X, y, batch_size=128, nb_epoch=100, verbose=1, callbacks=[],
            validation_split=0., validation_data=None, shuffle=True, show_accuracy=False):

        X = standardize_X(X)
        y = standardize_y(y)

        do_validation = False
        if validation_data:
            try:
                X_val, y_val = validation_data
            except:
                raise Exception("Invalid format for validation data; provide a tuple (X_val, y_val). \
                    X_val may be a numpy array or a list of numpy arrays depending on your model input.")
            do_validation = True
            X_val = standardize_X(X_val)
            y_val = standardize_y(y_val)
            if verbose:
                print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))
        else:
            if 0 < validation_split < 1:
                # If a validation split size is given (e.g. validation_split=0.2)
                # then split X into smaller X and X_val,
                # and split y into smaller y and y_val.
                do_validation = True
                split_at = int(len(y) * (1 - validation_split))
                (X, X_val) = (slice_X(X, 0, split_at), slice_X(X, split_at))
                (y, y_val) = (y[0:split_at], y[split_at:])
                if verbose:
                    print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))

        index_array = np.arange(len(y))

        callbacks = cbks.CallbackList(callbacks)
        if verbose:
            callbacks.append(cbks.BaseLogger())
        callbacks.append(cbks.History())

        callbacks._set_model(self)
        callbacks._set_params({
            'batch_size': batch_size,
            'nb_epoch': nb_epoch,
            'nb_sample': len(y),
            'verbose': verbose,
            'do_validation': do_validation,
            'show_accuracy': show_accuracy
        })
        callbacks.on_train_begin()

        for epoch in range(nb_epoch):
            callbacks.on_epoch_begin(epoch)
            if shuffle:
                np.random.shuffle(index_array)

            batches = make_batches(len(y), batch_size)
            for batch_index, (batch_start, batch_end) in enumerate(batches):
                batch_ids = index_array[batch_start:batch_end]
                X_batch = slice_X(X, batch_ids)
                y_batch = y[batch_ids]

                batch_logs = {}
                batch_logs['batch'] = batch_index
                batch_logs['size'] = len(batch_ids)
                callbacks.on_batch_begin(batch_index, batch_logs)

                ins = X_batch + [y_batch]
                if show_accuracy:
                    loss, acc = self._train_with_acc(*ins)
                    batch_logs['accuracy'] = acc
                else:
                    loss = self._train(*ins)
                batch_logs['loss'] = loss

                callbacks.on_batch_end(batch_index, batch_logs)

                if batch_index == len(batches) - 1: # last batch
                    # validation
                    epoch_logs = {}
                    if do_validation:
                        if show_accuracy:
                            val_loss, val_acc = self.evaluate(X_val, y_val, batch_size=batch_size, \
                                verbose=0, show_accuracy=True)
                            epoch_logs['val_accuracy'] = val_acc
                        else:
                            val_loss = self.evaluate(X_val, y_val, batch_size=batch_size, verbose=0)
                        epoch_logs['val_loss'] = val_loss

            callbacks.on_epoch_end(epoch, epoch_logs)

        callbacks.on_train_end()
        # return history
        return callbacks.callbacks[-1]

    def predict(self, X, batch_size=128, verbose=1):
        X = standardize_X(X)
        batches = make_batches(len(X[0]), batch_size)
        if verbose == 1:
            progbar = Progbar(target=len(X[0]))
        for batch_index, (batch_start, batch_end) in enumerate(batches):
            X_batch = slice_X(X, batch_start, batch_end)
            batch_preds = self._predict(*X_batch)

            if batch_index == 0:
                shape = (len(X[0]),) + batch_preds.shape[1:]
                preds = np.zeros(shape)
            preds[batch_start:batch_end] = batch_preds

            if verbose == 1:
                progbar.update(batch_end)

        return preds

    def predict_proba(self, X, batch_size=128, verbose=1):
        preds = self.predict(X, batch_size, verbose)
        if preds.min() < 0 or preds.max() > 1:
            warnings.warn("Network returning invalid probability values.")
        return preds

    def predict_classes(self, X, batch_size=128, verbose=1):
        proba = self.predict(X, batch_size=batch_size, verbose=verbose)
        if self.class_mode == "categorical":
            return proba.argmax(axis=-1)
        else:
            return (proba > 0.5).astype('int32')

    def evaluate(self, X, y, batch_size=128, show_accuracy=False, verbose=1):
        X = standardize_X(X)
        y = standardize_y(y)

        if show_accuracy:
            tot_acc = 0.
        tot_score = 0.
        seen = 0

        batches = make_batches(len(y), batch_size)
        if verbose:
            progbar = Progbar(target=len(y), verbose=verbose)
        for batch_index, (batch_start, batch_end) in enumerate(batches):
            X_batch = slice_X(X, batch_start, batch_end)
            y_batch = y[batch_start:batch_end]

            ins = X_batch + [y_batch]
            if show_accuracy:
                loss, acc = self._test_with_acc(*ins)
                tot_acc += acc * len(y_batch)
                log_values = [('loss', loss), ('acc.', acc)]
            else:
                loss = self._test(*ins)
                log_values = [('loss', loss)]
            tot_score += loss * len(y_batch)
            seen += len(y_batch)

            # logging
            if verbose:
                progbar.update(batch_end, log_values)

        if show_accuracy:
            return tot_score / seen, tot_acc / seen
        else:
            return tot_score / seen

class Sequential(Model, containers.Sequential):
    '''
        Inherits from Model the following methods:
            - compile
            - train
            - test
            - evaluate
            - fit
            - predict
            - predict_proba
            - predict_classes

        Inherits from containers.Sequential the following methods:
            - add
            - get_output
            - get_input
            - get_weights
            - set_weights
    '''
    def __init__(self):
        self.layers = []
        self.params = [] # learnable
        self.regularizers = [] # same size as params
        self.constraints = [] # same size as params

    def get_config(self, verbose=0):
        layers = []
        for i, l in enumerate(self.layers):
            config = l.get_config()
            layers.append(config)
        if verbose:
            printv(layers)
        return layers

    def save_weights(self, filepath, overwrite=False):
        # Save weights from all layers to HDF5
        import h5py
        import os.path
        # if file exists and should not be overwritten
        if not overwrite and os.path.isfile(filepath):
            import sys
            get_input = input
            if sys.version_info[:2] <= (2, 7):
                get_input = raw_input
            overwrite = get_input('[WARNING] %s already exists - overwrite? [y/n]' % (filepath))
            while overwrite not in ['y', 'n']:
                overwrite = get_input('Enter "y" (overwrite) or "n" (cancel).')
            if overwrite == 'n':
                return
            print('[TIP] Next time specify overwrite=True in save_weights!')

        f = h5py.File(filepath, 'w')
        f.attrs['nb_layers'] = len(self.layers)
        for k, l in enumerate(self.layers):
            g = f.create_group('layer_{}'.format(k))
            weights = l.get_weights()
            g.attrs['nb_params'] = len(weights)
            for n, param in enumerate(weights):
                param_name = 'param_{}'.format(n)
                param_dset = g.create_dataset(param_name, param.shape, dtype=param.dtype)
                param_dset[:] = param
        f.flush()
        f.close()

    def load_weights(self, filepath):
        # Loads weights from HDF5 file
        import h5py
        f = h5py.File(filepath)
        for k in range(f.attrs['nb_layers']):
            g = f['layer_{}'.format(k)]
            weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
            self.layers[k].set_weights(weights)
        f.close()

<commit_msg>add comment<commit_after>from __future__ import absolute_import
#from __future__ import print_function
import theano
import theano.tensor as T
import numpy as np
import warnings, time, copy

from . import optimizers
from . import objectives
from . import callbacks as cbks
from .utils.generic_utils import Progbar, printv
from .layers import containers
from six.moves import range

def standardize_y(y):
    if not hasattr(y, 'shape'):
        y = np.asarray(y)
    if len(y.shape) == 1:
        y = np.reshape(y, (len(y), 1))
    return y

#return a list with tuple element which are begin and end of each batch
def make_batches(size, batch_size):
    nb_batch = int(np.ceil(size/float(batch_size)))
    return [(i*batch_size, min(size, (i+1)*batch_size)) for i in range(0, nb_batch)]

#wrap a numpy.array with []
def standardize_X(X):
    if type(X) == list:
        return X
    else:
        return [X]

def slice_X(X, start=None, stop=None):
    if type(X) == list:
        if hasattr(start, '__len__'):
            return [x[start] for x in X]
        else:
            return [x[start:stop] for x in X]
    else:
        if hasattr(start, '__len__'):
            return X[start]
        else:
            return X[start:stop]

class Model(object):

    def compile(self, optimizer, loss, class_mode="categorical", theano_mode=None):
        self.optimizer = optimizers.get(optimizer)
        self.loss = objectives.get(loss)

        # input of model
        self.X_train = self.get_input(train=True)
        self.X_test = self.get_input(train=False)

        self.y_train = self.get_output(train=True)
        self.y_test = self.get_output(train=False)

        # target of model
        self.y = T.zeros_like(self.y_train)

        train_loss = self.loss(self.y, self.y_train)
        test_score = self.loss(self.y, self.y_test)

        if class_mode == "categorical":
            #just compare whether the most probable is or not
            train_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_train, axis=-1)))
            test_accuracy = T.mean(T.eq(T.argmax(self.y, axis=-1), T.argmax(self.y_test, axis=-1)))

        elif class_mode == "binary":
            #after make prediction [0,0,1,0] like with round function, compare each class of each sample then accumulate and divide by n*k
            train_accuracy = T.mean(T.eq(self.y, T.round(self.y_train)))
            test_accuracy = T.mean(T.eq(self.y, T.round(self.y_test)))
        else:
            raise Exception("Invalid class mode:" + str(class_mode))
        self.class_mode = class_mode

        updates = self.optimizer.get_updates(self.params, self.regularizers, self.constraints, train_loss)

        if type(self.X_train) == list:
            train_ins = self.X_train + [self.y]
            test_ins = self.X_test + [self.y]
            predict_ins = self.X_test
        else:
            train_ins = [self.X_train, self.y]
            test_ins = [self.X_test, self.y]
            predict_ins = [self.X_test]

        #input is [[x1,x2,x3...],[y1,y2,y3]]   x1 and y1 are both vector
        self._train = theano.function(train_ins, train_loss,
            updates=updates, allow_input_downcast=True, mode=theano_mode)
        self._train_with_acc = theano.function(train_ins, [train_loss, train_accuracy],
            updates=updates, allow_input_downcast=True, mode=theano_mode)
        self._predict = theano.function(predict_ins, self.y_test,
            allow_input_downcast=True, mode=theano_mode)
        self._test = theano.function(test_ins, test_score,
            allow_input_downcast=True, mode=theano_mode)
        self._test_with_acc = theano.function(test_ins, [test_score, test_accuracy],
            allow_input_downcast=True, mode=theano_mode)

    def train(self, X, y, accuracy=False):
        X = standardize_X(X)
        y = standardize_y(y)
        ins = X + [y]
        if accuracy:
            return self._train_with_acc(*ins)
        else:
            return self._train(*ins)

    def test(self, X, y, accuracy=False):
        X = standardize_X(X)
        y = standardize_y(y)
        ins = X + [y]
        if accuracy:
            return self._test_with_acc(*ins)
        else:
            return self._test(*ins)

    def fit(self, X, y, batch_size=128, nb_epoch=100, verbose=1, callbacks=[],
            validation_split=0., validation_data=None, shuffle=True, show_accuracy=False):

        X = standardize_X(X)
        y = standardize_y(y)

        '''
        set validation set
        '''
        do_validation = False
        if validation_data:
            try:
                X_val, y_val = validation_data
            except:
                raise Exception("Invalid format for validation data; provide a tuple (X_val, y_val). \
                    X_val may be a numpy array or a list of numpy arrays depending on your model input.")
            do_validation = True
            X_val = standardize_X(X_val)
            y_val = standardize_y(y_val)
            if verbose:
                print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))
        else:
            if 0 < validation_split < 1:
                # If a validation split size is given (e.g. validation_split=0.2)
                # then split X into smaller X and X_val,
                # and split y into smaller y and y_val.
                do_validation = True
                split_at = int(len(y) * (1 - validation_split))
                (X, X_val) = (slice_X(X, 0, split_at), slice_X(X, split_at))
                (y, y_val) = (y[0:split_at], y[split_at:])
                if verbose:
                    print("Train on %d samples, validate on %d samples" % (len(y), len(y_val)))

        index_array = np.arange(len(y))

        '''
        add callbacks
        '''
        callbacks = cbks.CallbackList(callbacks)
        if verbose:
            callbacks.append(cbks.BaseLogger())
        callbacks.append(cbks.History())

        callbacks._set_model(self)
        callbacks._set_params({
            'batch_size': batch_size,
            'nb_epoch': nb_epoch,
            'nb_sample': len(y),
            'verbose': verbose,
            'do_validation': do_validation,
            'show_accuracy': show_accuracy
        })
        callbacks.on_train_begin()

        '''
        really train
        '''
        for epoch in range(nb_epoch):
            callbacks.on_epoch_begin(epoch)
            if shuffle:
                np.random.shuffle(index_array)

            '''
            this step make a list of[(begin1,end1),(begin2,end2),....]
            '''
            batches = make_batches(len(y), batch_size)
            for batch_index, (batch_start, batch_end) in enumerate(batches):
                batch_ids = index_array[batch_start:batch_end]
                X_batch = slice_X(X, batch_ids)
                y_batch = y[batch_ids]

                batch_logs = {}
                batch_logs['batch'] = batch_index
                batch_logs['size'] = len(batch_ids)
                callbacks.on_batch_begin(batch_index, batch_logs)

                ins = X_batch + [y_batch]
                if show_accuracy:
                    #the param with * means self._train_with_acc(ins[0],ins[1]) if ins is a longer list then more
                    loss, acc = self._train_with_acc(*ins)
                    batch_logs['accuracy'] = acc
                else:
                    loss = self._train(*ins)
                batch_logs['loss'] = loss

                callbacks.on_batch_end(batch_index, batch_logs)

                if batch_index == len(batches) - 1: # last batch
                    # validation
                    epoch_logs = {}
                    if do_validation:
                        if show_accuracy:
                            val_loss, val_acc = self.evaluate(X_val, y_val, batch_size=batch_size, \
                                verbose=0, show_accuracy=True)
                            epoch_logs['val_accuracy'] = val_acc
                        else:
                            val_loss = self.evaluate(X_val, y_val, batch_size=batch_size, verbose=0)
                        epoch_logs['val_loss'] = val_loss

            callbacks.on_epoch_end(epoch, epoch_logs)

        callbacks.on_train_end()
        # return history
        return callbacks.callbacks[-1]

    def predict(self, X, batch_size=128, verbose=1):
        X = standardize_X(X)
        batches = make_batches(len(X[0]), batch_size)
        if verbose == 1:
            progbar = Progbar(target=len(X[0]))
        for batch_index, (batch_start, batch_end) in enumerate(batches):
            X_batch = slice_X(X, batch_start, batch_end)
            batch_preds = self._predict(*X_batch)

            if batch_index == 0:
                shape = (len(X[0]),) + batch_preds.shape[1:]
                preds = np.zeros(shape)
            preds[batch_start:batch_end] = batch_preds

            if verbose == 1:
                progbar.update(batch_end)

        return preds

    def predict_proba(self, X, batch_size=128, verbose=1):
        preds = self.predict(X, batch_size, verbose)
        if preds.min() < 0 or preds.max() > 1:
            warnings.warn("Network returning invalid probability values.")
        return preds

    def predict_classes(self, X, batch_size=128, verbose=1):
        proba = self.predict(X, batch_size=batch_size, verbose=verbose)
        if self.class_mode == "categorical":
            return proba.argmax(axis=-1)
        else:
            return (proba > 0.5).astype('int32')

    def evaluate(self, X, y, batch_size=128, show_accuracy=False, verbose=1):
        X = standardize_X(X)
        y = standardize_y(y)

        if show_accuracy:
            tot_acc = 0.
        tot_score = 0.
        seen = 0

        batches = make_batches(len(y), batch_size)
        if verbose:
            progbar = Progbar(target=len(y), verbose=verbose)
        for batch_index, (batch_start, batch_end) in enumerate(batches):
            X_batch = slice_X(X, batch_start, batch_end)
            y_batch = y[batch_start:batch_end]

            ins = X_batch + [y_batch]
            if show_accuracy:
                loss, acc = self._test_with_acc(*ins)
                tot_acc += acc * len(y_batch)
                log_values = [('loss', loss), ('acc.', acc)]
            else:
                loss = self._test(*ins)
                log_values = [('loss', loss)]
            tot_score += loss * len(y_batch)
            seen += len(y_batch)

            # logging
            if verbose:
                progbar.update(batch_end, log_values)

        if show_accuracy:
            return tot_score / seen, tot_acc / seen
        else:
            return tot_score / seen

class Sequential(Model, containers.Sequential):
    '''
        Inherits from Model the following methods:
            - compile
            - train
            - test
            - evaluate
            - fit
            - predict
            - predict_proba
            - predict_classes

        Inherits from containers.Sequential the following methods:
            - add
            - get_output
            - get_input
            - get_weights
            - set_weights
    '''
    def __init__(self):
        self.layers = []
        self.params = [] # learnable
        self.regularizers = [] # same size as params
        self.constraints = [] # same size as params

    def get_config(self, verbose=0):
        layers = []
        for i, l in enumerate(self.layers):
            config = l.get_config()
            layers.append(config)
        if verbose:
            printv(layers)
        return layers

    def save_weights(self, filepath, overwrite=False):
        # Save weights from all layers to HDF5
        import h5py
        import os.path
        # if file exists and should not be overwritten
        if not overwrite and os.path.isfile(filepath):
            import sys
            get_input = input
            if sys.version_info[:2] <= (2, 7):
                get_input = raw_input
            overwrite = get_input('[WARNING] %s already exists - overwrite? [y/n]' % (filepath))
            while overwrite not in ['y', 'n']:
                overwrite = get_input('Enter "y" (overwrite) or "n" (cancel).')
            if overwrite == 'n':
                return
            print('[TIP] Next time specify overwrite=True in save_weights!')

        f = h5py.File(filepath, 'w')
        f.attrs['nb_layers'] = len(self.layers)
        for k, l in enumerate(self.layers):
            g = f.create_group('layer_{}'.format(k))
            weights = l.get_weights()
            g.attrs['nb_params'] = len(weights)
            for n, param in enumerate(weights):
                param_name = 'param_{}'.format(n)
                param_dset = g.create_dataset(param_name, param.shape, dtype=param.dtype)
                param_dset[:] = param
        f.flush()
        f.close()

    def load_weights(self, filepath):
        # Loads weights from HDF5 file
        import h5py
        f = h5py.File(filepath)
        for k in range(f.attrs['nb_layers']):
            g = f['layer_{}'.format(k)]
            weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
            self.layers[k].set_weights(weights)
        f.close()

<|endoftext|>


<commit_before><commit_msg>Delete __init__.py<commit_after><|endoftext|>


<commit_before>#!/usr/bin/env python

import os
import sys
import signal
import socket
import webbrowser

# For python 2 and python 3 compatibility
if sys.version_info < (3, 0):
    from SimpleHTTPServer import SimpleHTTPRequestHandler
    from BaseHTTPServer import HTTPServer
else:
    from http.server import SimpleHTTPRequestHandler
    from http.server import HTTPServer
    raw_input = input

__all__ = ['Server']

class StoppableHTTPServer(HTTPServer):
    """
    Overrides BaseHTTPServer.HTTPServer to include a stop
    function.
    """

    def server_bind(self):
        HTTPServer.server_bind(self)
        self.socket.settimeout(1)
        self.run = True

    def get_request(self):
        while self.run:
            try:
                sock, addr = self.socket.accept()
                sock.settimeout(None)
                return (sock, addr)
            except socket.timeout:
                pass

    def stop(self):
        self.run = False

    def serve(self):
        while self.run:
            try:
                self.handle_request()
            except TypeError:
                # When server is being closed, while loop can run once
                # after setting self.run = False depending on how it
                # is scheduled.
                pass

class Server(object):
    """
    Parameters
    ----------
    port : integer
        Defines the port on which the server will run.
    scene_file : name of the scene_file generated for visualization
        A Valid PyDy generated scene file in 'directory'.
    directory : absolute path of a directory
        Absolute path to the directory which contains scene_file with
        all other static files.

    Example
    -------
    >>> server = Server(scene_file=_scene_json_file)
    >>> server.run_server()

    """
    def __init__(self, scene_file, directory=None, port=None):
        self.scene_file = scene_file

        if directory:
            self.directory = directory
        else:
            self.directory = "static/"

        if port:
            self.port = port
        else:
            self.port = 8000

    def run_server(self):
        # Change dir to static first.
        os.chdir(self.directory)
        # Get a free port
        while self._check_port(self.port):
            self.port += 1
        handler_class = SimpleHTTPRequestHandler
        server_class = StoppableHTTPServer
        protocol = "HTTP/1.0"
        server_address = ('127.0.0.1', self.port)
        handler_class.protocol_version = protocol
        self.httpd = server_class(server_address, handler_class)
        sa = self.httpd.socket.getsockname()
        print("Serving HTTP on", sa[0], "port", sa[1], "...")
        print("To view visualization, open:\n")
        url = "http://localhost:"+str(sa[1]) + "/index.html?load=" + \
              self.scene_file
        print(url)
        webbrowser.open(url)
        print("Hit Ctrl+C to stop the server...")
        signal.signal(signal.SIGINT, self._stop_server)
        self.httpd.serve()

    def _check_port(self, port):
        soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        result = soc.connect_ex(('127.0.0.1', port))
        return result == 0

    def _stop_server(self, signal, frame):
        """
        Confirms and stops the visulisation server
        signal:
            Required by signal.signal
        frame:
            Required by signal.signal

        """
        res = raw_input("Shutdown this visualization server ([y]/n)? ")
        res = res.lower()[0:1]
        if res == '' or res == 'y':
            print("Shutdown confirmed")
            print("Shutting down server...")
            self.httpd.stop()
        else:
            print("Resuming operations...")
<commit_msg>Addressed some minor fixes in pydy-viz server<commit_after>#!/usr/bin/env python

import os
import sys
import signal
import socket
import webbrowser

# For python 2 and python 3 compatibility
if sys.version_info < (3, 0):
    from SimpleHTTPServer import SimpleHTTPRequestHandler
    from BaseHTTPServer import HTTPServer
else:
    from http.server import SimpleHTTPRequestHandler
    from http.server import HTTPServer
    raw_input = input

__all__ = ['Server']

class StoppableHTTPServer(HTTPServer):
    """
    Overrides BaseHTTPServer.HTTPServer to include a stop
    function.
    """

    def server_bind(self):
        HTTPServer.server_bind(self)
        self.socket.settimeout(1)
        self.run = True

    def get_request(self):
        while self.run:
            try:
                sock, addr = self.socket.accept()
                sock.settimeout(None)
                return (sock, addr)
            except socket.timeout:
                pass

    def stop(self):
        self.run = False

    def serve(self):
        while self.run:
            try:
                self.handle_request()
            except TypeError:
                # When server is being closed, while loop can run once
                # after setting self.run = False depending on how it
                # is scheduled.
                pass

class Server(object):
    """
    Parameters
    ----------
    port : integer
        Defines the port on which the server will run. If this port is
        already bind, then it increment 1 until it finds a free port.
    scene_file : name of the scene_file generated for visualization
        A Valid PyDy generated scene file in 'directory' parameter.
    directory : absolute path of a directory
        Absolute path to the directory which contains scene_file with
        all other static files.

    Example
    -------
    >>> server = Server(scene_file=_scene_json_file)
    >>> server.run_server()

    """
    def __init__(self, scene_file, directory=None, port=None):
        self.scene_file = scene_file

        if directory is None:
            self.directory = directory
        else:
            self.directory = "static/"

        if port is None:
            self.port = port
        else:
            self.port = 8000

    def run_server(self):
        # Change dir to static first.
        os.chdir(self.directory)
        # Get a free port
        while self._check_port(self.port):
            self.port += 1
        handler_class = SimpleHTTPRequestHandler
        server_class = StoppableHTTPServer
        protocol = "HTTP/1.0"
        server_address = ('127.0.0.1', self.port)
        handler_class.protocol_version = protocol
        self.httpd = server_class(server_address, handler_class)
        sa = self.httpd.socket.getsockname()
        print("Serving HTTP on", sa[0], "port", sa[1], "...")
        print("To view visualization, open:\n")
        url = "http://localhost:"+str(sa[1]) + "/index.html?load=" + \
              self.scene_file
        print(url)
        webbrowser.open(url)
        print("Hit Ctrl+C to stop the server...")
        signal.signal(signal.SIGINT, self._stop_server)
        self.httpd.serve()

    def _check_port(self, port):
        soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        result = soc.connect_ex(('127.0.0.1', port))
        return result == 0

    def _stop_server(self, signal, frame):
        """
        Confirms and stops the visulisation server
        signal:
            Required by signal.signal
        frame:
            Required by signal.signal

        """
        res = raw_input("Shutdown this visualization server ([y]/n)? ")
        res = res.lower()[0]
        if res == '' or res == 'y':
            print("Shutdown confirmed")
            print("Shutting down server...")
            self.httpd.stop()
        else:
            print("Resuming operations...")
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""This module builds mutation functions that are bound to a manager"""

from . import expand_node_neighborhood
from ..pipeline import in_place_mutator, uni_in_place_mutator

__all__ = [
    'build_expand_node_neighborhood_by_hash',
    'build_delete_node_by_hash',
]

def build_expand_node_neighborhood_by_hash(manager):
    """Makes a expand function that's bound to the manager

    :param pybel.manager.Manager manager: A BEL manager
    :rtype: (pybel.BELGraph, pybel.BELGraph, str) -> None
    """

    @uni_in_place_mutator
    def expand_node_neighborhood_by_hash(universe, graph, node_hash):
        """Expands around the neighborhoods of a node by identifier

        :param pybel.BELGraph universe: A BEL graph
        :param pybel.BELGraph graph: A BEL graph
        :param str node_hash: The node hash
        """
        node = manager.get_node_tuple_by_hash(node_hash)
        return expand_node_neighborhood(universe, graph, node)

    return expand_node_neighborhood_by_hash

def build_delete_node_by_hash(manager):
    """Makes a delete function that's bound to the manager

    :param pybel.manager.Manager manager: A BEL manager
    :rtype: (pybel.BELGraph, str) -> None
    """

    @in_place_mutator
    def delete_node_by_hash(graph, node_hash):
        """Removes a node by identifier

        :param pybel.BELGraph graph: A BEL graph
        :param str node_hash: A node hash
        """
        node = manager.get_node_tuple_by_hash(node_hash)
        graph.remove_node(node)

    return delete_node_by_hash
<commit_msg>Fix import<commit_after># -*- coding: utf-8 -*-

"""This module builds mutation functions that are bound to a manager"""

from .expansion import expand_node_neighborhood
from ..pipeline import in_place_mutator, uni_in_place_mutator

__all__ = [
    'build_expand_node_neighborhood_by_hash',
    'build_delete_node_by_hash',
]

def build_expand_node_neighborhood_by_hash(manager):
    """Makes a expand function that's bound to the manager

    :param pybel.manager.Manager manager: A BEL manager
    :rtype: (pybel.BELGraph, pybel.BELGraph, str) -> None
    """

    @uni_in_place_mutator
    def expand_node_neighborhood_by_hash(universe, graph, node_hash):
        """Expands around the neighborhoods of a node by identifier

        :param pybel.BELGraph universe: A BEL graph
        :param pybel.BELGraph graph: A BEL graph
        :param str node_hash: The node hash
        """
        node = manager.get_node_tuple_by_hash(node_hash)
        return expand_node_neighborhood(universe, graph, node)

    return expand_node_neighborhood_by_hash

def build_delete_node_by_hash(manager):
    """Makes a delete function that's bound to the manager

    :param pybel.manager.Manager manager: A BEL manager
    :rtype: (pybel.BELGraph, str) -> None
    """

    @in_place_mutator
    def delete_node_by_hash(graph, node_hash):
        """Removes a node by identifier

        :param pybel.BELGraph graph: A BEL graph
        :param str node_hash: A node hash
        """
        node = manager.get_node_tuple_by_hash(node_hash)
        graph.remove_node(node)

    return delete_node_by_hash
<|endoftext|>


<commit_before>from flask_admin.contrib.peewee import ModelView
from flask.ext.admin import Admin
from flask_admin.contrib.peewee.form import CustomModelConverter
from flask_admin.form.widgets import DateTimePickerWidget
from playhouse.postgres_ext import ArrayField, DateTimeTZField
from wtforms import fields
from wtforms.widgets import TextInput

from redash import models
from redash.permissions import require_permission

class ArrayListField(fields.Field):
    widget = TextInput()

    def _value(self):
        if self.data:
            return u', '.join(self.data)
        else:
            return u''

    def process_formdata(self, valuelist):
        if valuelist:
            self.data = [x.strip() for x in valuelist[0].split(',')]
        else:
            self.data = []

class PasswordHashField(fields.PasswordField):
    def _value(self):
        return u''

    def process_formdata(self, valuelist):
        if valuelist:
            self.data = models.pwd_context.encrypt(valuelist[0])
        else:
            self.data = u''

class PgModelConverter(CustomModelConverter):
    def __init__(self, view, additional=None):
        additional = {ArrayField: self.handle_array_field,
                      DateTimeTZField: self.handle_datetime_tz_field}
        super(PgModelConverter, self).__init__(view, additional)
        self.view = view

    def handle_array_field(self, model, field, **kwargs):
        return field.name, ArrayListField(**kwargs)

    def handle_datetime_tz_field(self, model, field, **kwargs):
        kwargs['widget'] = DateTimePickerWidget()
        return field.name, fields.DateTimeField(**kwargs)

class BaseModelView(ModelView):
    model_form_converter = PgModelConverter

    @require_permission('admin')
    def is_accessible(self):
        return True

class UserModelView(BaseModelView):
    column_searchable_list = ('name', 'email')
    form_excluded_columns = ('created_at', 'updated_at')
    column_exclude_list = ('password_hash',)

    form_overrides = dict(password_hash=PasswordHashField)
    form_args = {
        'password_hash': {'label': 'Password'}
    }

def init_admin(app):
    admin = Admin(app, name='re:dash')

    views = {
        models.User: UserModelView
    }

    for m in models.all_models:
        if m in views:
            admin.add_view(views[m](m))
        else:
            admin.add_view(BaseModelView(m))
<commit_msg>Dedicated view for data source<commit_after>import json
from flask_admin.contrib.peewee import ModelView
from flask.ext.admin import Admin
from flask_admin.contrib.peewee.form import CustomModelConverter
from flask_admin.form.widgets import DateTimePickerWidget
from playhouse.postgres_ext import ArrayField, DateTimeTZField
from wtforms import fields
from wtforms.widgets import TextInput

from redash import models
from redash import query_runner
from redash.permissions import require_permission

class ArrayListField(fields.Field):
    widget = TextInput()

    def _value(self):
        if self.data:
            return u', '.join(self.data)
        else:
            return u''

    def process_formdata(self, valuelist):
        if valuelist:
            self.data = [x.strip() for x in valuelist[0].split(',')]
        else:
            self.data = []

class JSONTextAreaField(fields.TextAreaField):
    def process_formdata(self, valuelist):
        if valuelist:
            try:
                json.loads(valuelist[0])
            except ValueError:
                raise ValueError(self.gettext(u'Invalid JSON'))
            self.data = valuelist[0]
        else:
            self.data = ''

class PasswordHashField(fields.PasswordField):
    def _value(self):
        return u''

    def process_formdata(self, valuelist):
        if valuelist:
            self.data = models.pwd_context.encrypt(valuelist[0])
        else:
            self.data = u''

class PgModelConverter(CustomModelConverter):
    def __init__(self, view, additional=None):
        additional = {ArrayField: self.handle_array_field,
                      DateTimeTZField: self.handle_datetime_tz_field}
        super(PgModelConverter, self).__init__(view, additional)
        self.view = view

    def handle_array_field(self, model, field, **kwargs):
        return field.name, ArrayListField(**kwargs)

    def handle_datetime_tz_field(self, model, field, **kwargs):
        kwargs['widget'] = DateTimePickerWidget()
        return field.name, fields.DateTimeField(**kwargs)

class BaseModelView(ModelView):
    model_form_converter = PgModelConverter

    @require_permission('admin')
    def is_accessible(self):
        return True

class UserModelView(BaseModelView):
    column_searchable_list = ('name', 'email')
    form_excluded_columns = ('created_at', 'updated_at')
    column_exclude_list = ('password_hash',)

    form_overrides = dict(password_hash=PasswordHashField)
    form_args = {
        'password_hash': {'label': 'Password'}
    }

def query_runner_type_formatter(view, context, model, name):
    qr = query_runner.query_runners.get(model.type, None)
    if qr:
        return qr.name()

    return model.type

class DataSourceModelView(BaseModelView):
    form_overrides = dict(type=fields.SelectField, options=JSONTextAreaField)
    form_args = dict(type={
        'choices': [(k, r.name()) for k, r in query_runner.query_runners.iteritems()]
    })
    column_formatters = dict(type=query_runner_type_formatter)
    column_filters = ('type',)

def init_admin(app):
    admin = Admin(app, name='re:dash admin')

    views = {
        models.User: UserModelView(models.User),
        models.DataSource: DataSourceModelView(models.DataSource)
    }

    for m in models.all_models:
        if m in views:
            admin.add_view(views[m])
        else:
            admin.add_view(BaseModelView(m))
<|endoftext|>


<commit_before>#!/usr/bin/env python

from __future__ import print_function

import os
import signal
import socket
import webbrowser
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

__all__ = ['Server']

class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
    """
    Overrides BaseHTTPServer.HTTPServer to include a stop
    function.
    """

    def server_bind(self):
        BaseHTTPServer.HTTPServer.server_bind(self)
        self.socket.settimeout(1)
        self.run = True

    def get_request(self):
        while self.run:
            try:
                sock, addr = self.socket.accept()
                sock.settimeout(None)
                return (sock, addr)
            except socket.timeout:
                pass

    def stop(self):
        self.run = False

    def serve(self):
        while self.run:
            try:
                self.handle_request()
            except TypeError:
                # When server is being closed, while loop can run once
                # after setting self.run = False depending on how it
                # is scheduled.
                pass

class Server(object):
    """
    Parameters
    ----------
    :param port : integer
        Defines the port on which the server will run.
    :param scene_file : name of the scene_file generated for visualization
        Used here to display the url
    :param directory : path of the directory which contains static and scene files.
        Server is started in this directory itself.

    Example
    -------
        >>> server = Server(scene_file=_scene_json_file)
        >>> server.run_server()

    """
    def __init__(self, port=8000, scene_file="Null"):
        self.port = port
        self.scene_file = scene_file
        self.directory = "static/"

    def run_server(self):
        # Change dir to static first.
        os.chdir(self.directory)
        handler_class = SimpleHTTPRequestHandler
        server_class = StoppableHTTPServer
        protocol = "HTTP/1.0"
        server_address = ('127.0.0.1', self.port)
        handler_class.protocol_version = protocol
        self.httpd = server_class(server_address, handler_class)
        sa = self.httpd.socket.getsockname()
        print("Serving HTTP on", sa[0], "port", sa[1], "...")
        print("To view visualization, open:\n")
        url = "http://localhost:"+str(sa[1]) + "/index.html?load=" + \
              self.scene_file
        print(url)
        webbrowser.open(url)
        print("Hit Ctrl+C to stop the server...")
        signal.signal(signal.SIGINT, self._stop_server)
        self.httpd.serve()

    def _stop_server(self, signal, frame):
        """
        Confirms and stops the visulisation server
        :param signal:
            Required by signal.signal
        :param frame:
            Required by signal.signal

        """
        res = raw_input("Shutdown this visualization server ([y]/n)? ")
        if res is (None or 'y'):
            print("Shutdown confirmed")
            print("Shutting down server...")
            self.httpd.stop()
<commit_msg>Added resuming operations print statement when server shutdown is cancelled.<commit_after>#!/usr/bin/env python

from __future__ import print_function

import os
import signal
import socket
import webbrowser
import BaseHTTPServer
from SimpleHTTPServer import SimpleHTTPRequestHandler

__all__ = ['Server']

class StoppableHTTPServer(BaseHTTPServer.HTTPServer):
    """
    Overrides BaseHTTPServer.HTTPServer to include a stop
    function.
    """

    def server_bind(self):
        BaseHTTPServer.HTTPServer.server_bind(self)
        self.socket.settimeout(1)
        self.run = True

    def get_request(self):
        while self.run:
            try:
                sock, addr = self.socket.accept()
                sock.settimeout(None)
                return (sock, addr)
            except socket.timeout:
                pass

    def stop(self):
        self.run = False

    def serve(self):
        while self.run:
            try:
                self.handle_request()
            except TypeError:
                # When server is being closed, while loop can run once
                # after setting self.run = False depending on how it
                # is scheduled.
                pass

class Server(object):
    """
    Parameters
    ----------
    :param port : integer
        Defines the port on which the server will run.
    :param scene_file : name of the scene_file generated for visualization
        Used here to display the url
    :param directory : path of the directory which contains static and scene files.
        Server is started in this directory itself.

    Example
    -------
        >>> server = Server(scene_file=_scene_json_file)
        >>> server.run_server()

    """
    def __init__(self, port=8000, scene_file="Null"):
        self.port = port
        self.scene_file = scene_file
        self.directory = "static/"

    def run_server(self):
        # Change dir to static first.
        os.chdir(self.directory)
        handler_class = SimpleHTTPRequestHandler
        server_class = StoppableHTTPServer
        protocol = "HTTP/1.0"
        server_address = ('127.0.0.1', self.port)
        handler_class.protocol_version = protocol
        self.httpd = server_class(server_address, handler_class)
        sa = self.httpd.socket.getsockname()
        print("Serving HTTP on", sa[0], "port", sa[1], "...")
        print("To view visualization, open:\n")
        url = "http://localhost:"+str(sa[1]) + "/index.html?load=" + \
              self.scene_file
        print(url)
        webbrowser.open(url)
        print("Hit Ctrl+C to stop the server...")
        signal.signal(signal.SIGINT, self._stop_server)
        self.httpd.serve()

    def _stop_server(self, signal, frame):
        """
        Confirms and stops the visulisation server
        :param signal:
            Required by signal.signal
        :param frame:
            Required by signal.signal

        """
        res = raw_input("Shutdown this visualization server ([y]/n)? ")
        if res is (None or 'y'):
            print("Shutdown confirmed")
            print("Shutting down server...")
            self.httpd.stop()
        else:
            print("Resuming operations...")
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
# This file is part of the pyMor project (http://www.pymor.org).
# Copyright Holders: Felix Albrecht, Rene Milk, Stephan Rave
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from __future__ import absolute_import, division, print_function

import numpy as np

from pymor.core.interfaces import BasicInterface, abstractmethod, abstractproperty
from pymor.la import VectorArray
from pymor.tools import Named
from pymor.parameters import Parametric

class OperatorInterface(BasicInterface, Parametric, Named):
    '''Interface for parameter dependent discrete operators.

    Every discrete operator is viewed as a map ::

        L(μ): R^s -> R^r

    Attributes
    ----------
    dim_source
        The dimension s of the source space.
    dim_range
        The dimension r of the range space.
    type_source
        The `VectorArray` class representing vectors of the source space.
    type_range
        The `VectorArray` class representing vectors of the range space.
    '''

    dim_source = 0
    dim_range = 0

    type_source = None
    type_range = None

    def __init__(self):
        Parametric.__init__(self)

    @abstractmethod
    def apply(self, U, ind=None, mu=None):
        '''Evaluate L(U, mu).

        Parameters
        ----------
        U : VectorArray
            `VectorArray` of vectors to which the operator is applied.
        ind
            If None, the operator is applied to all elements of U.
            Otherwise an iterable of the indices of the vectors to
            which the operator is to be applied.

        Returns
        -------
        `VectorArray` of shape `(len(ind), self.dim_range)`
        '''
        pass

    def apply2(self, V, U, U_ind=None, V_ind=None, mu=None, product=None, pairwise=True):
        ''' Treat the operator as a 2-form by calculating (V, A(U)).

        If ( , ) is the euclidean scalar product and A is given by
        multiplication with a matrix B, then ::

            L.apply2(V, U) = V^T*B*U

        Parameters
        ----------
        V : VectorArray
            Left arguments.
        U : VectorArray
            Right arguments.
        V_ind
            If None, the operator is applied to all elements of V.
            Otherwise an iterable of the indices of the vectors to
            which the operator is to be applied.
        U_ind
            If None, the operator is applied to all elements of U.
            Otherwise an iterable of the indices of the vectors to
            which the operator is to be applied.
        product
            `Operator` representing the scalar product.
            If None, the euclidean product is chosen.
        pairwise
            If False and V and U are multi-dimensional, then form is applied
            to all combinations of vectors in V and U, i.e. ::

                L.apply2(V, U).shape = (len(V_ind), len(U_ind)).

            If True, the vectors in V and U are applied in pairs, i.e. ::

                L.apply2(V, U).shape = (len(V_ind),) = (len(U_ind),).

        Returns
        -------
        A numpy array of all operator evaluations.
        '''
        assert isinstance(V, VectorArray)
        assert isinstance(U, VectorArray)
        if pairwise:
            lu = len(U_ind) if U_ind is not None else len(U)
            lv = len(V_ind) if V_ind is not None else len(V)
            assert lu == lv
        AU = self.apply(U, ind=U_ind, mu=mu)
        if product is not None:
            AU = product.apply(AU)
        return V.prod(AU, ind=V_ind, pairwise=pairwise)

    def __add__(self, other):
        from pymor.operators.constructions import LincombOperator
        return LincombOperator([self, other])

    __radd__ = __add__

    def __mul__(self, other):
        from pymor.operators.constructions import LincombOperator
        return LincombOperator([self], factors=[other])

    def __str__(self):
        return '{}: R^{} --> R^{}  (parameter type: {}, class: {})'.format(
            self.name, self.dim_source, self.dim_range, self.parameter_type,
            self.__class__.__name__)

class LinearOperatorInterface(OperatorInterface):
    '''Interface for linear parameter dependent discrete operators.
    '''

    def as_vector_array(self):
        raise NotImplementedError

    @abstractmethod
    def _assemble(self, mu=None):
        pass

    def assemble(self, mu=None, force=False):
        '''Assembles the matrix of the operator for given parameter mu.

        Returns an assembled parameter independent linear operator.
        '''
        if self.parameter_type is None:
            assert mu is None
            if force or not self._last_mat:
                self._last_mat = self._assemble(mu)
                return self._last_mat
            else:
                return self._last_mat
        else:
            mu = self.parse_parameter(mu)
            if not force and self._last_mu is not None and self._last_mu.allclose(mu):
                return self._last_mat
            else:
                self._last_mu = mu.copy()  # TODO: add some kind of log message here
                self._last_mat = self._assemble(mu)
                return self._last_mat

    def apply(self, U, ind=None, mu=None):
        return self.assemble(mu).apply(U, ind=ind)

    def __add__(self, other):
        from pymor.operators.constructions import LinearLincombOperator
        return LinearLincombOperator([self, other])

    __radd__ = __add__

    def __mul__(self, other):
        from pymor.operators.constructions import LinearLinearcombOperator
        return LinearLincombOperator([self], factors=[other])

    _last_mu = None
    _last_mat = None
<commit_msg>[operators.interface] allow to add int(0)<commit_after># -*- coding: utf-8 -*-
# This file is part of the pyMor project (http://www.pymor.org).
# Copyright Holders: Felix Albrecht, Rene Milk, Stephan Rave
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from __future__ import absolute_import, division, print_function

import numpy as np

from numbers import Number

from pymor.core.interfaces import BasicInterface, abstractmethod, abstractproperty
from pymor.la import VectorArray
from pymor.tools import Named
from pymor.parameters import Parametric

class OperatorInterface(BasicInterface, Parametric, Named):
    '''Interface for parameter dependent discrete operators.

    Every discrete operator is viewed as a map ::

        L(μ): R^s -> R^r

    Attributes
    ----------
    dim_source
        The dimension s of the source space.
    dim_range
        The dimension r of the range space.
    type_source
        The `VectorArray` class representing vectors of the source space.
    type_range
        The `VectorArray` class representing vectors of the range space.
    '''

    dim_source = 0
    dim_range = 0

    type_source = None
    type_range = None

    def __init__(self):
        Parametric.__init__(self)

    @abstractmethod
    def apply(self, U, ind=None, mu=None):
        '''Evaluate L(U, mu).

        Parameters
        ----------
        U : VectorArray
            `VectorArray` of vectors to which the operator is applied.
        ind
            If None, the operator is applied to all elements of U.
            Otherwise an iterable of the indices of the vectors to
            which the operator is to be applied.

        Returns
        -------
        `VectorArray` of shape `(len(ind), self.dim_range)`
        '''
        pass

    def apply2(self, V, U, U_ind=None, V_ind=None, mu=None, product=None, pairwise=True):
        ''' Treat the operator as a 2-form by calculating (V, A(U)).

        If ( , ) is the euclidean scalar product and A is given by
        multiplication with a matrix B, then ::

            L.apply2(V, U) = V^T*B*U

        Parameters
        ----------
        V : VectorArray
            Left arguments.
        U : VectorArray
            Right arguments.
        V_ind
            If None, the operator is applied to all elements of V.
            Otherwise an iterable of the indices of the vectors to
            which the operator is to be applied.
        U_ind
            If None, the operator is applied to all elements of U.
            Otherwise an iterable of the indices of the vectors to
            which the operator is to be applied.
        product
            `Operator` representing the scalar product.
            If None, the euclidean product is chosen.
        pairwise
            If False and V and U are multi-dimensional, then form is applied
            to all combinations of vectors in V and U, i.e. ::

                L.apply2(V, U).shape = (len(V_ind), len(U_ind)).

            If True, the vectors in V and U are applied in pairs, i.e. ::

                L.apply2(V, U).shape = (len(V_ind),) = (len(U_ind),).

        Returns
        -------
        A numpy array of all operator evaluations.
        '''
        assert isinstance(V, VectorArray)
        assert isinstance(U, VectorArray)
        if pairwise:
            lu = len(U_ind) if U_ind is not None else len(U)
            lv = len(V_ind) if V_ind is not None else len(V)
            assert lu == lv
        AU = self.apply(U, ind=U_ind, mu=mu)
        if product is not None:
            AU = product.apply(AU)
        return V.prod(AU, ind=V_ind, pairwise=pairwise)

    def __add__(self, other):
        if isinstance(other, Number):
            assert other == 0.
            return self
        from pymor.operators.constructions import LincombOperator
        return LincombOperator([self, other])

    __radd__ = __add__

    def __mul__(self, other):
        from pymor.operators.constructions import LincombOperator
        return LincombOperator([self], factors=[other])

    def __str__(self):
        return '{}: R^{} --> R^{}  (parameter type: {}, class: {})'.format(
            self.name, self.dim_source, self.dim_range, self.parameter_type,
            self.__class__.__name__)

class LinearOperatorInterface(OperatorInterface):
    '''Interface for linear parameter dependent discrete operators.
    '''

    def as_vector_array(self):
        raise NotImplementedError

    @abstractmethod
    def _assemble(self, mu=None):
        pass

    def assemble(self, mu=None, force=False):
        '''Assembles the matrix of the operator for given parameter mu.

        Returns an assembled parameter independent linear operator.
        '''
        if self.parameter_type is None:
            assert mu is None
            if force or not self._last_mat:
                self._last_mat = self._assemble(mu)
                return self._last_mat
            else:
                return self._last_mat
        else:
            mu = self.parse_parameter(mu)
            if not force and self._last_mu is not None and self._last_mu.allclose(mu):
                return self._last_mat
            else:
                self._last_mu = mu.copy()  # TODO: add some kind of log message here
                self._last_mat = self._assemble(mu)
                return self._last_mat

    def apply(self, U, ind=None, mu=None):
        return self.assemble(mu).apply(U, ind=ind)

    def __add__(self, other):
        if isinstance(other, Number):
            assert other == 0.
            return self
        from pymor.operators.constructions import LinearLincombOperator
        return LinearLincombOperator([self, other])

    __radd__ = __add__

    def __mul__(self, other):
        from pymor.operators.constructions import LinearLincombOperator
        return LinearLincombOperator([self], factors=[other])

    _last_mu = None
    _last_mat = None
<|endoftext|>


<commit_before>#!/usr/bin/env python
# Made by Multipixelone
# Pump Controller
import RPi.GPIO as GPIO
from time import sleep  # Import Sleep Control

def valveCycle():
    while True:
        GPIO.output(18, GPIO.HIGH)
        print("Valve On")
        sleep(10)
        GPIO.output(18, GPIO.LOW)
        print("Valve is off")
        sleep(1)
<commit_msg>Working on the automation<commit_after>#!/usr/bin/env python
# Made by Multipixelone
# Pump Controller
import RPi.GPIO as GPIO
#import schedule
from time import sleep

def valveOn():
    while True:
        GPIO.output(18, GPIO.HIGH)
        print("Valve On")
def valveOff():
    while True:
        GPIO.output(18, GPIO.LOW)
        print("Valve Off")
def Cycle():
    valveOn()
    sleep(5)  # Some Check of Water...?
    valveOff()
<|endoftext|>


<commit_before>#!/usr/bin/env python
#

# import modules used here -- sys is a very standard one
import sys, argparse, logging, os, re

from subprocess import call, check_output

command_list = ('list', 'delete', 'push', 'add')

git_remote_re = re.compile('((git|ssh|http(s)?)|(git@[\w\.]+))(:(//)?)([\w\.@\:/\-~]+)(\.git)(/)?')

def parse_file(target_file_path):
  with open(target_file_path, 'r') as target_file:
    targets = {}
    for line in target_file:
      entries = [x.strip() for x in line.split(' ') if x.strip() != '']
      if len(entries) < 2:
        continue
      branch = entries[0]
      remotes = entries[1:]
      targets[branch] = remotes
    return targets

def write_file(target_file_path, targets):
  with open(target_file_path, 'w') as target_file:
    for branch, remotes in targets.iteritems():
      target_file.write(branch)
      for remote in remotes:
        target_file.write(" ")
        target_file.write(remote)
      target_file.write("\n")

def print_target(branch, remotes):
  print "{0}{1}".format(branch.ljust(20, ' '), [r.strip() for r in remotes])

def list(targets):
  if len(targets) < 1:
    print 'No targets exist'
    return
  print 'BRANCH'.ljust(19, ' '), 'REMOTES'
  for branch, remotes in targets.iteritems():
      print_target(branch, remotes)

def delete(targets, branch_name):
  if branch_name not in targets:
    print 'No such deploy target'
    return targets
  print 'Warning. You are about to delete the following deploy target:'
  print_target(branch_name, targets[branch_name])
  x = raw_input('Continue? (y/N): ')
  if 'y' not in x.lower():
    print 'Cancelling...'
    return targets
  del targets[branch_name]
  return targets

def push(targets, branch_name):
  # Check that branch_name target exists in target file
  if branch_name not in targets:
    print 'target does not exist: ', branch_name
    return False
  # Check that working tree has not modifications
  if call('git diff --quiet && git diff --cached --quiet', shell=True):
    print 'working tree has modifications'
    return False
  # Check that branch_name git branch exists
  branches = check_output('git branch --list', shell=True)

def add(targets, branch_name, remotes):
  if branch_name in targets:
    print 'target branch already exists. Continuing will overwrite existing target'
    x = raw_input('Continue? (y/N)')
    if 'y' not in x.lower():
      print 'Cancelling...'
      return targets
  for remote in remotes:
    if not git_remote_re.match(remote):
      print 'invalid git remote: ', remote
      return targets
  targets[branch_name] = remotes
  return targets

def process_commands(args):
  command = args.command.lower()
  if command not in command_list:
    print 'invalid command. choices are', command_list
    return False

  targets = parse_file(args.file)

  if command == 'list':
    list(targets)
    return True

  if not args.branch:
    print 'This command requires a target branch'
    return False
  branch_name = args.branch.lower()
  if command == 'delete':
    targets = delete(targets, branch_name)
    write_file(args.file, targets)
    return True
  elif command == 'push':
    push(targets, branch_name)
    return True
  remotes = args.remotes
  if not remotes:
    print 'This command requires at least one remote'
    return False
  if command == 'add':
    targets = add(targets, branch_name, remotes)
    write_file(args.file, targets)
    return True
  return False

# Gather our code in a main() function
def main(args, loglevel):
  logging.basicConfig(format="%(levelname)s: %(message)s", level=loglevel)

  process_commands(args)

# Standard boilerplate to call the main() function to begin
# the program.
if __name__ == '__main__':
  parser = argparse.ArgumentParser(
                                    description = "Does a thing to some stuff.",
                                    epilog = "As an alternative to the commandline, params can be placed in a file, one per line, and specified on the commandline like '%(prog)s @params.conf'.",
                                    fromfile_prefix_chars = '@' )

  parser.add_argument(
                      "command",
                      help = "options: add, list, delete, push",
                      metavar = "command")
  parser.add_argument(
                      "branch",
                      help = "target branch",
                      metavar = "branch",
                      nargs="?")

  parser.add_argument("remotes",
                      metavar='remotes',
                      type=str,
                      nargs='*',
                      help='list of git remotes',
                      )

  parser.add_argument(
                      "-v",
                      "--verbose",
                      help="increase output verbosity",
                      action="store_true")

  parser.add_argument(
                      "-f",
                      "--file",
                      help="file to load/store target branch list. defaults to .resin_targets",
                      default='.resin_targets')

  # subparsers = parser.add_subparsers(dest="subparser_add")

  # add_parser = subparsers.add_parser('add')

  args = parser.parse_args()

  # Setup logging
  if args.verbose:
    loglevel = logging.DEBUG
  else:
    loglevel = logging.INFO

  main(args, loglevel)<commit_msg>remove old deploy script<commit_after><|endoftext|>


<commit_before># -*- coding: utf-8 -*-

# FOGLAMP_BEGIN
# See: http://foglamp.readthedocs.io/
# FOGLAMP_END

import signal
import asyncio
from aiohttp import web

from foglamp.core import routes
from foglamp.core import middleware
from foglamp.core import scheduler

__author__ = "Praveen Garg"
__copyright__ = "Copyright (c) 2017 OSIsoft, LLC"
__license__ = "Apache 2.0"
__version__ = "${VERSION}"

def _make_app():
    """create the server"""
    # https://aiohttp.readthedocs.io/en/stable/_modules/aiohttp/web.html#run_app
    app = web.Application(middlewares=[middleware.error_middleware])
    routes.setup(app)
    return app

def _shutdown(loop):
    scheduler.shutdown()
    for task in asyncio.Task.all_tasks():
        task.cancel()
    loop.stop()

def start():
    """starts the server"""
    loop = asyncio.get_event_loop()
    scheduler.start(loop)

    for signal_name in (signal.SIGINT, signal.SIGTERM, signal.SIGQUIT):
        loop.add_signal_handler(signal_name, _shutdown, loop)

    web.run_app(_make_app(), host='0.0.0.0', port=8082)

<commit_msg>Remove loop parameter from scheduler.start()<commit_after># -*- coding: utf-8 -*-

# FOGLAMP_BEGIN
# See: http://foglamp.readthedocs.io/
# FOGLAMP_END

import signal
import asyncio
from aiohttp import web

from foglamp.core import routes
from foglamp.core import middleware
from foglamp.core import scheduler

__author__ = "Praveen Garg"
__copyright__ = "Copyright (c) 2017 OSIsoft, LLC"
__license__ = "Apache 2.0"
__version__ = "${VERSION}"

def _make_app():
    """create the server"""
    # https://aiohttp.readthedocs.io/en/stable/_modules/aiohttp/web.html#run_app
    app = web.Application(middlewares=[middleware.error_middleware])
    routes.setup(app)
    return app

def _shutdown(loop):
    scheduler.shutdown()
    for task in asyncio.Task.all_tasks():
        task.cancel()
    loop.stop()

def start():
    """starts the server"""
    loop = asyncio.get_event_loop()
    scheduler.start()

    for signal_name in (signal.SIGINT, signal.SIGTERM, signal.SIGQUIT):
        loop.add_signal_handler(signal_name, _shutdown, loop)

    web.run_app(_make_app(), host='0.0.0.0', port=8082)

<|endoftext|>


<commit_before># coding=utf-8
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import (nested_scopes, generators, division, absolute_import, with_statement,
                        print_function, unicode_literals)

from argparse import ArgumentParser
import copy

from pants.option.arg_splitter import GLOBAL_SCOPE
from pants.option.help_formatter import PantsHelpFormatter
from pants.option.legacy_options import LegacyOptions
from pants.option.ranked_value import RankedValue

class RegistrationError(Exception):
  """An error at option registration time."""
  pass

class ParseError(Exception):
  """An error at flag parsing time."""
  pass

# Standard ArgumentParser prints usage and exits on error. We subclass so we can raise instead.
# Note that subclassing ArgumentParser for this purpose is allowed by the argparse API.
class CustomArgumentParser(ArgumentParser):
  def error(self, message):
    raise ParseError(message)

class Parser(object):
  """An argument parser in a hierarchy.

  Each node in the hierarchy is a 'scope': the root is the global scope, and the parent of
  a node is the scope it's immediately contained in. E.g., the 'compile.java' scope is
  a child of the 'compile' scope, which is a child of the global scope.

  Options registered on a parser are also registered transitively on all the scopes it encloses.
  Registration must be in outside-in order: we forbid registering options on an outer scope if
  we've already registered an option on one of its inner scopes. This is to ensure that
  re-registering the same option name on an inner scope correctly replaces the identically-named
  option from the outer scope.

  For migration purposes, this object also interacts with the legacy flags system:

  Recall that the old flags system uses optparse, and scopes the flags using a prefix, e.g.,
  ./pants --compile-scala-foo.

  Whereas  this new system uses argparse and scopes the flags using command-line context, e.g.,
  ./pants compile.scala --foo.

  When registering (scala.compile, --foo), this object can also register it as --scala-compile-foo
  on the old system.  This allows us to transition registration code to the new registration API
  while retaining the old flag names.

  Eventually all usages will switch to the new flag names, and we can remove this migration code.

  :param env: a dict of environment variables.
  :param config: data from a config file (must support config.get(section, name, default=)).
  :param scope: the scope this parser acts for.
  :param parent_parser: the parser for the scope immediately enclosing this one, or
         None if this is the global scope.
  :param legacy_parser: an optparse.OptionParser instance for handling legacy options.
  """
  def __init__(self, env, config, scope, parent_parser, legacy_parser=None):
    self._env = env
    self._config = config
    self._scope = scope

    # If True, no more registration is allowed on this parser.
    self._frozen = False

    # The argparser we use for actually parsing args.
    self._argparser = CustomArgumentParser(conflict_handler='resolve')

    # The argparser we use for formatting help messages.
    # We don't use self._argparser for this as it will have all options from enclosing scopes
    # registered on it too, which would create unnecessarily repetitive help messages.
    self._help_argparser = CustomArgumentParser(conflict_handler='resolve',
                                                formatter_class=PantsHelpFormatter)

    # If True, we have at least one option to show help for.
    self._has_help_options = False

    # Map of external to internal dest names. See docstring for _set_dest below.
    self._dest_forwardings = {}

    # A Parser instance, or None for the global scope parser.
    self._parent_parser = parent_parser

    # List of Parser instances.
    self._child_parsers = []

    if self._parent_parser:
      self._parent_parser._register_child_parser(self)

    # Handles legacy options on our behalf.
    self._legacy_options = LegacyOptions(scope, legacy_parser) if legacy_parser else None

  def parse_args(self, args, namespace):
    """Parse the given args and set their values onto the namespace object's attributes."""
    namespace.add_forwardings(self._dest_forwardings)
    new_args = self._argparser.parse_args(args)
    namespace.update(vars(new_args))
    return namespace

  def format_help(self, legacy=False):
    """Return a help message for the options registered on this object."""
    if legacy:
      return self._legacy_options.format_help()
    else:
      return self._help_argparser.format_help() if self._has_help_options else ''

  def register(self, *args, **kwargs):
    """Register an option, using argparse params."""
    if self._frozen:
      raise RegistrationError('Cannot register option {0} in scope {1} after registering options '
                              'in any of its inner scopes.'.format(args[0], self._scope))

    # Prevent further registration in enclosing scopes.
    ancestor = self._parent_parser
    while ancestor:
      ancestor._freeze()
      ancestor = ancestor._parent_parser

    clean_kwargs = copy.copy(kwargs)  # Copy kwargs so we can remove legacy-related keys.
    kwargs = None  # Ensure no code below modifies kwargs accidentally.
    self._validate(args, clean_kwargs)
    legacy_dest = clean_kwargs.pop('legacy', None)
    dest = self._set_dest(args, clean_kwargs, legacy_dest)

    # Is this a boolean flag?
    if clean_kwargs.get('action') in ('store_false', 'store_true'):
      inverse_args = []
      help_args = []
      for flag in args:
        if flag.startswith('--') and not flag.startswith('--no-'):
          inverse_args.append('--no-' + flag[2:])
          help_args.append('--[no-]{0}'.format(flag[2:]))
        else:
          help_args.append(flag)
    else:
      inverse_args = None
      help_args = args

    # Register the option, only on this scope, for the purpose of displaying help.
    # Note that we'll only display the default value for this scope, even though the
    # default may be overridden in inner scopes.
    raw_default = self._compute_default(dest, clean_kwargs).value
    clean_kwargs_with_default = dict(clean_kwargs, default=raw_default)
    self._help_argparser.add_argument(*help_args, **clean_kwargs_with_default)
    self._has_help_options = True

    # Also register the option as a legacy option, if needed.
    if self._legacy_options and legacy_dest:
      self._legacy_options.register(args, clean_kwargs_with_default, legacy_dest)

    # Register the option for the purpose of parsing, on this and all enclosed scopes.
    if inverse_args:
      inverse_kwargs = self._create_inverse_kwargs(clean_kwargs)
      if self._legacy_options:
        self._legacy_options.register(inverse_args, inverse_kwargs, legacy_dest)
      self._register_boolean(dest, args, clean_kwargs, inverse_args, inverse_kwargs)
    else:
      self._register(dest, args, clean_kwargs)

  def _register(self, dest, args, kwargs):
    """Recursively register the option for parsing."""
    ranked_default = self._compute_default(dest, kwargs)
    kwargs_with_default = dict(kwargs, default=ranked_default)
    self._argparser.add_argument(*args, **kwargs_with_default)

    # Propagate registration down to inner scopes.
    for child_parser in self._child_parsers:
      child_parser._register(dest, args, kwargs)

  def _register_boolean(self, dest, args, kwargs, inverse_args, inverse_kwargs):
    """Recursively register the boolean option, and its inverse, for parsing."""
    group = self._argparser.add_mutually_exclusive_group()
    ranked_default = self._compute_default(dest, kwargs)
    kwargs_with_default = dict(kwargs, default=ranked_default)
    group.add_argument(*args, **kwargs_with_default)
    group.add_argument(*inverse_args, **inverse_kwargs)

    # Propagate registration down to inner scopes.
    for child_parser in self._child_parsers:
      child_parser._register_boolean(dest, args, kwargs, inverse_args, inverse_kwargs)

  def _validate(self, args, kwargs):
    """Ensure that the caller isn't trying to use unsupported argparse features."""
    for k in ['nargs', 'required']:
      if k in kwargs:
        raise RegistrationError('%s unsupported in registration of option %s.' % (k, args))

  def _set_dest(self, args, kwargs, legacy_dest):
    """Maps the externally-used dest to a scoped one only seen internally.

    If an option is re-registered in an inner scope, it'll shadow the external dest but will
    use a different internal one. This is important in the case that an option is registered
    with two names (say -x, --xlong) and we only re-register one of them, say --xlong, in an
    inner scope. In this case we no longer want them to write to the same dest, so we can
    use both (now with different meanings) in the inner scope.

    Note: Modfies kwargs.
    """
    dest = self._select_dest(args, kwargs)
    scoped_dest = '_{0}_{1}__'.format(self._scope or 'DEFAULT', dest)

    # Make argparse write to the internal dest.
    kwargs['dest'] = scoped_dest

    # Make reads from the external dest forward to the internal one.
    self._dest_forwardings[dest] = scoped_dest

    # Also forward all option aliases, so we can reference -x (as options.x) in the example above.
    for arg in args:
      self._dest_forwardings[arg.lstrip('-').replace('-', '_')] = scoped_dest

    # Forward another hop, to the legacy flag, but only if this won't create a forwarding cycle.
    #   Note that this means that *only* the legacy flag is supported for now.
    # This will be removed after we're finished migrating option registration to the new system,
    # and work on migrating the actual runtime command-line parsing.
    if legacy_dest and self._dest_forwardings.get(legacy_dest) != scoped_dest:
      self._dest_forwardings[scoped_dest] = legacy_dest
    return dest

  def _select_dest(self, args, kwargs):
    """Select the dest name for the option.

    Replicated from the dest inference logic in argparse:
    '--foo-bar' -> 'foo_bar' and '-x' -> 'x'.
    """
    dest = kwargs.get('dest')
    if dest:
      return dest
    arg = next((a for a in args if a.startswith('--')), args[0])
    return arg.lstrip('-').replace('-', '_')

  def _compute_default(self, dest, kwargs):
    """Compute the default value to use for an option's registration.

    The source of the default value is chosen according to the ranking in RankedValue.
    """
    config_section = 'DEFAULT' if self._scope == GLOBAL_SCOPE else self._scope
    env_var = 'PANTS_{0}_{1}'.format(config_section.upper().replace('.', '_'), dest.upper())
    value_type = kwargs.get('type', str)
    env_val_str = self._env.get(env_var) if self._env else None

    env_val = None if env_val_str is None else value_type(env_val_str)
    if kwargs.get('action') == 'append':
      config_val_strs = self._config.getlist(config_section, dest, default=[]) if self._config else []
      config_val = [value_type(config_val_str) for config_val_str in config_val_strs]
      default = []
    else:
      config_val_str = self._config.get(config_section, dest, default=None) if self._config else None
      config_val = None if config_val_str is None else value_type(config_val_str)
      default = None
    hardcoded_val = kwargs.get('default')
    return RankedValue.choose(None, env_val, config_val, hardcoded_val, default)

  def _create_inverse_kwargs(self, kwargs):
    """Create the kwargs for registering the inverse of a boolean flag."""
    inverse_kwargs = copy.copy(kwargs)
    inverse_action = 'store_true' if kwargs.get('action') == 'store_false' else 'store_false'
    inverse_kwargs['action'] = inverse_action
    inverse_kwargs.pop('default', None)
    return inverse_kwargs

  def _register_child_parser(self, child):
    self._child_parsers.append(child)

  def _freeze(self):
    self._frozen = True

  def __str__(self):
    return 'Parser(%s)' % self._scope
<commit_msg>Validate that registered args begin with dashes, as appropriate.<commit_after># coding=utf-8
# Copyright 2014 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import (nested_scopes, generators, division, absolute_import, with_statement,
                        print_function, unicode_literals)

from argparse import ArgumentParser
import copy

from pants.option.arg_splitter import GLOBAL_SCOPE
from pants.option.help_formatter import PantsHelpFormatter
from pants.option.legacy_options import LegacyOptions
from pants.option.ranked_value import RankedValue

class RegistrationError(Exception):
  """An error at option registration time."""
  pass

class ParseError(Exception):
  """An error at flag parsing time."""
  pass

# Standard ArgumentParser prints usage and exits on error. We subclass so we can raise instead.
# Note that subclassing ArgumentParser for this purpose is allowed by the argparse API.
class CustomArgumentParser(ArgumentParser):
  def error(self, message):
    raise ParseError(message)

class Parser(object):
  """An argument parser in a hierarchy.

  Each node in the hierarchy is a 'scope': the root is the global scope, and the parent of
  a node is the scope it's immediately contained in. E.g., the 'compile.java' scope is
  a child of the 'compile' scope, which is a child of the global scope.

  Options registered on a parser are also registered transitively on all the scopes it encloses.
  Registration must be in outside-in order: we forbid registering options on an outer scope if
  we've already registered an option on one of its inner scopes. This is to ensure that
  re-registering the same option name on an inner scope correctly replaces the identically-named
  option from the outer scope.

  For migration purposes, this object also interacts with the legacy flags system:

  Recall that the old flags system uses optparse, and scopes the flags using a prefix, e.g.,
  ./pants --compile-scala-foo.

  Whereas  this new system uses argparse and scopes the flags using command-line context, e.g.,
  ./pants compile.scala --foo.

  When registering (scala.compile, --foo), this object can also register it as --scala-compile-foo
  on the old system.  This allows us to transition registration code to the new registration API
  while retaining the old flag names.

  Eventually all usages will switch to the new flag names, and we can remove this migration code.

  :param env: a dict of environment variables.
  :param config: data from a config file (must support config.get(section, name, default=)).
  :param scope: the scope this parser acts for.
  :param parent_parser: the parser for the scope immediately enclosing this one, or
         None if this is the global scope.
  :param legacy_parser: an optparse.OptionParser instance for handling legacy options.
  """
  def __init__(self, env, config, scope, parent_parser, legacy_parser=None):
    self._env = env
    self._config = config
    self._scope = scope

    # If True, no more registration is allowed on this parser.
    self._frozen = False

    # The argparser we use for actually parsing args.
    self._argparser = CustomArgumentParser(conflict_handler='resolve')

    # The argparser we use for formatting help messages.
    # We don't use self._argparser for this as it will have all options from enclosing scopes
    # registered on it too, which would create unnecessarily repetitive help messages.
    self._help_argparser = CustomArgumentParser(conflict_handler='resolve',
                                                formatter_class=PantsHelpFormatter)

    # If True, we have at least one option to show help for.
    self._has_help_options = False

    # Map of external to internal dest names. See docstring for _set_dest below.
    self._dest_forwardings = {}

    # A Parser instance, or None for the global scope parser.
    self._parent_parser = parent_parser

    # List of Parser instances.
    self._child_parsers = []

    if self._parent_parser:
      self._parent_parser._register_child_parser(self)

    # Handles legacy options on our behalf.
    self._legacy_options = LegacyOptions(scope, legacy_parser) if legacy_parser else None

  def parse_args(self, args, namespace):
    """Parse the given args and set their values onto the namespace object's attributes."""
    namespace.add_forwardings(self._dest_forwardings)
    new_args = self._argparser.parse_args(args)
    namespace.update(vars(new_args))
    return namespace

  def format_help(self, legacy=False):
    """Return a help message for the options registered on this object."""
    if legacy:
      return self._legacy_options.format_help()
    else:
      return self._help_argparser.format_help() if self._has_help_options else ''

  def register(self, *args, **kwargs):
    """Register an option, using argparse params."""
    if self._frozen:
      raise RegistrationError('Cannot register option {0} in scope {1} after registering options '
                              'in any of its inner scopes.'.format(args[0], self._scope))

    # Prevent further registration in enclosing scopes.
    ancestor = self._parent_parser
    while ancestor:
      ancestor._freeze()
      ancestor = ancestor._parent_parser

    clean_kwargs = copy.copy(kwargs)  # Copy kwargs so we can remove legacy-related keys.
    kwargs = None  # Ensure no code below modifies kwargs accidentally.
    self._validate(args, clean_kwargs)
    legacy_dest = clean_kwargs.pop('legacy', None)
    dest = self._set_dest(args, clean_kwargs, legacy_dest)

    # Is this a boolean flag?
    if clean_kwargs.get('action') in ('store_false', 'store_true'):
      inverse_args = []
      help_args = []
      for flag in args:
        if flag.startswith('--') and not flag.startswith('--no-'):
          inverse_args.append('--no-' + flag[2:])
          help_args.append('--[no-]{0}'.format(flag[2:]))
        else:
          help_args.append(flag)
    else:
      inverse_args = None
      help_args = args

    # Register the option, only on this scope, for the purpose of displaying help.
    # Note that we'll only display the default value for this scope, even though the
    # default may be overridden in inner scopes.
    raw_default = self._compute_default(dest, clean_kwargs).value
    clean_kwargs_with_default = dict(clean_kwargs, default=raw_default)
    self._help_argparser.add_argument(*help_args, **clean_kwargs_with_default)
    self._has_help_options = True

    # Also register the option as a legacy option, if needed.
    if self._legacy_options and legacy_dest:
      self._legacy_options.register(args, clean_kwargs_with_default, legacy_dest)

    # Register the option for the purpose of parsing, on this and all enclosed scopes.
    if inverse_args:
      inverse_kwargs = self._create_inverse_kwargs(clean_kwargs)
      if self._legacy_options:
        self._legacy_options.register(inverse_args, inverse_kwargs, legacy_dest)
      self._register_boolean(dest, args, clean_kwargs, inverse_args, inverse_kwargs)
    else:
      self._register(dest, args, clean_kwargs)

  def _register(self, dest, args, kwargs):
    """Recursively register the option for parsing."""
    ranked_default = self._compute_default(dest, kwargs)
    kwargs_with_default = dict(kwargs, default=ranked_default)
    self._argparser.add_argument(*args, **kwargs_with_default)

    # Propagate registration down to inner scopes.
    for child_parser in self._child_parsers:
      child_parser._register(dest, args, kwargs)

  def _register_boolean(self, dest, args, kwargs, inverse_args, inverse_kwargs):
    """Recursively register the boolean option, and its inverse, for parsing."""
    group = self._argparser.add_mutually_exclusive_group()
    ranked_default = self._compute_default(dest, kwargs)
    kwargs_with_default = dict(kwargs, default=ranked_default)
    group.add_argument(*args, **kwargs_with_default)
    group.add_argument(*inverse_args, **inverse_kwargs)

    # Propagate registration down to inner scopes.
    for child_parser in self._child_parsers:
      child_parser._register_boolean(dest, args, kwargs, inverse_args, inverse_kwargs)

  def _validate(self, args, kwargs):
    """Ensure that the caller isn't trying to use unsupported argparse features."""
    for arg in args:
      if not arg.startswith('-'):
        raise RegistrationError('Option {0} in scope {1} must begin '
                                'with a dash.'.format(arg, self._scope))
      if not arg.startswith('--') and len(arg) > 2:
        raise RegistrationError('Multicharacter option {0} in scope {1} must begin '
                                'with a double-dash'.format(arg, self._scope))
    for k in ['nargs', 'required']:
      if k in kwargs:
        raise RegistrationError('{0} unsupported in registration of option {1} in '
                                'scope {2}.'.format(k, args, self._scope))

  def _set_dest(self, args, kwargs, legacy_dest):
    """Maps the externally-used dest to a scoped one only seen internally.

    If an option is re-registered in an inner scope, it'll shadow the external dest but will
    use a different internal one. This is important in the case that an option is registered
    with two names (say -x, --xlong) and we only re-register one of them, say --xlong, in an
    inner scope. In this case we no longer want them to write to the same dest, so we can
    use both (now with different meanings) in the inner scope.

    Note: Modfies kwargs.
    """
    dest = self._select_dest(args, kwargs)
    scoped_dest = '_{0}_{1}__'.format(self._scope or 'DEFAULT', dest)

    # Make argparse write to the internal dest.
    kwargs['dest'] = scoped_dest

    # Make reads from the external dest forward to the internal one.
    self._dest_forwardings[dest] = scoped_dest

    # Also forward all option aliases, so we can reference -x (as options.x) in the example above.
    for arg in args:
      self._dest_forwardings[arg.lstrip('-').replace('-', '_')] = scoped_dest

    # Forward another hop, to the legacy flag, but only if this won't create a forwarding cycle.
    #   Note that this means that *only* the legacy flag is supported for now.
    # This will be removed after we're finished migrating option registration to the new system,
    # and work on migrating the actual runtime command-line parsing.
    if legacy_dest and self._dest_forwardings.get(legacy_dest) != scoped_dest:
      self._dest_forwardings[scoped_dest] = legacy_dest
    return dest

  def _select_dest(self, args, kwargs):
    """Select the dest name for the option.

    Replicated from the dest inference logic in argparse:
    '--foo-bar' -> 'foo_bar' and '-x' -> 'x'.
    """
    dest = kwargs.get('dest')
    if dest:
      return dest
    arg = next((a for a in args if a.startswith('--')), args[0])
    return arg.lstrip('-').replace('-', '_')

  def _compute_default(self, dest, kwargs):
    """Compute the default value to use for an option's registration.

    The source of the default value is chosen according to the ranking in RankedValue.
    """
    config_section = 'DEFAULT' if self._scope == GLOBAL_SCOPE else self._scope
    env_var = 'PANTS_{0}_{1}'.format(config_section.upper().replace('.', '_'), dest.upper())
    value_type = kwargs.get('type', str)
    env_val_str = self._env.get(env_var) if self._env else None

    env_val = None if env_val_str is None else value_type(env_val_str)
    if kwargs.get('action') == 'append':
      config_val_strs = self._config.getlist(config_section, dest, default=[]) if self._config else []
      config_val = [value_type(config_val_str) for config_val_str in config_val_strs]
      default = []
    else:
      config_val_str = self._config.get(config_section, dest, default=None) if self._config else None
      config_val = None if config_val_str is None else value_type(config_val_str)
      default = None
    hardcoded_val = kwargs.get('default')
    return RankedValue.choose(None, env_val, config_val, hardcoded_val, default)

  def _create_inverse_kwargs(self, kwargs):
    """Create the kwargs for registering the inverse of a boolean flag."""
    inverse_kwargs = copy.copy(kwargs)
    inverse_action = 'store_true' if kwargs.get('action') == 'store_false' else 'store_false'
    inverse_kwargs['action'] = inverse_action
    inverse_kwargs.pop('default', None)
    return inverse_kwargs

  def _register_child_parser(self, child):
    self._child_parsers.append(child)

  def _freeze(self):
    self._frozen = True

  def __str__(self):
    return 'Parser(%s)' % self._scope
<|endoftext|>