コード例 #1
0
ファイル: expressions.py プロジェクト: carriercomm/qc-toolkit
class Expression(Serializable):
    def __init__(self, ex: str) -> None:
        self.__string = str(ex)  # type: str
        self.__expression = Parser().parse(ex.replace("**", "^"))  # type: py_expression_eval.Expression

    @property
    def string(self) -> str:
        return self.__string

    def variables(self) -> Iterable[str]:
        return self.__expression.variables()

    def evaluate(self, **kwargs) -> float:
        if USE_NUMEXPR:
            return numexpr.evaluate(self.__string, global_dict={}, local_dict=kwargs)
        else:
            return self.__expression.evaluate(kwargs)

    def get_serialization_data(self, serializer: "Serializer") -> Dict[str, Any]:
        return dict(type="Expression", expression=self.__string)

    @staticmethod
    def deserialize(serializer: "Serializer", **kwargs) -> Serializable:
        return Expression(kwargs["expression"])

    @property
    def identifier(self) -> Optional[str]:
        return None
コード例 #2
0
ファイル: Expressions.py プロジェクト: terrorfisch/qc-toolkit
class Expression(Serializable):
    def __init__(self, ex: str):
        ex = str(ex)
        self._string = ex
        self._expression = Parser().parse(ex.replace('**', '^'))

    @property
    def string(self):
        return self._string

    def variables(self):
        return self._expression.variables()

    def evaluate(self, parameters):
        if USE_NUMEXPR:
            return numexpr.evaluate(self._string, global_dict={}, local_dict=parameters)
        else:
            return self._expression.evaluate(parameters)

    def get_serialization_data(self, serializer: 'Serializer'):
        return dict(type='Expression', expression=self._string)

    @staticmethod
    def deserialize(serializer: 'Serializer', **kwargs):
        return Expression(kwargs['expression'])

    @property
    def identifier(self):
        return None
コード例 #3
0
    def set_conditions(self,
                       conditions: str,
                       action: Union[callable, int, float, str] = 0):
        self.conditions = None
        if conditions is not None:
            # TODO: add parsing exceptions here
            expr = Parser().parse(conditions)
            self.conditions = {
                "string": conditions,
                "expr": expr,
                "vars": expr.variables()
            }

        self.action = None
コード例 #4
0
 def __init__(self, expression, sample_points):
     """Initialize the Evaluator
     :param expression: string of a math expression
     :param sample_points: list of sample points (tuples)
     """
     expression = Parser().parse(expression)
     variables = expression.variables()
     super().__init__(len(variables), 1)
     self.inputs = sample_points
     inputs_dicts = [
         dict(zip(variables, sample_point))
         for sample_point in sample_points
     ]
     self.outputs = [
         expression.evaluate(input_dict) for input_dict in inputs_dicts
     ]
コード例 #5
0
def generateNetwork(network_file_name):
    
    V = [] # vertices
    E = [] # edges
    F = {} # cost functions
    OD = [] # OD pairs
    
    lineid = 0
    for line in open(network_file_name, 'r'):
        
        lineid += 1
        
        # ignore \n
        line = line.rstrip()
        
        # ignore comments
        hash_pos = line.find('#')
        if hash_pos > -1:
            line = line[:hash_pos]
        
        # split the line
        taglist = line.split()
        if len(taglist) == 0:
            continue
        
        if taglist[0] == 'function':
            
            # process the params
            params = taglist[2][1:-1].split(',')
            if len(params) > 1:
                raise Exception('Cost functions with more than one parameter are not yet acceptable! (parameters defined: %s)' % str(params)[1:-1])
            
            # process the function
            expr = taglist[3]
            function = Parser().parse(expr)
            
            # handle the case where the parameter is not in the formula
            # (this needs to be handled because py-expression-eval does
            # not allows simplifying all variables of an expression) 
            if taglist[1] not in function.variables():
                expr = '%s+%s-%s' % (taglist[3], params[0], params[0])
                function = Parser().parse(expr)
            
            # process the constants
            constants = function.variables()
            if params[0] in constants: # the parameter must be ignored
                constants.remove(params[0]) 
            
            # store the function
            F[taglist[1]] = [params[0], constants, expr]
            
        elif taglist[0] == 'node':
            V.append(Node(taglist[1]))
            
        elif taglist[0] == 'dedge' or taglist[0] == 'edge': # dedge is a directed edge
            
            # process the function
            func_tuple = F[taglist[4]] # get the corresponding function
            param_values = dict(zip(func_tuple[1], map(float, taglist[5:]))) # associate constants and values specified in the line (in order of occurrence)
            function = Parser().parse(func_tuple[2]) # create the function
            function = function.simplify(param_values) # replace constants
            
            # create the edge(s)
            E.append(Edge(taglist[1], taglist[2], taglist[3], function, func_tuple[0]))
            if taglist[0] == 'edge':
                E.append(Edge('%s-%s'%(taglist[3], taglist[2]), taglist[3], taglist[2], function, func_tuple[0]))
            
        elif taglist[0] == 'od':
            OD.append(taglist[1])
        
        else:
            raise Exception('Network file does not comply with the specification! (line %d: "%s")' % (lineid, line))
    
    
    return V, E, OD
コード例 #6
0
def generateGraph(graph_file, flow=0.0):
    """
    Adapted version from the KSP repository version 1.44.
    Original is available at: https://github.com/maslab-ufrgs/ksp/releases/tag/V1.44
    Generates the graph from a text file following the specifications(available @
        http://wiki.inf.ufrgs.br/network_files_specification).
    In:
        graph_file:String = Path to the network(graph) file.
        flow:Float = Value to sum the cost of the edges.

    Out:
        V:List = List of vertices or nodes of the graph.
        E:List = List of the edges of the graph.
        OD:List = List of the OD pairs in the network.
    """
    V = []  # vertices
    E = []  # edges
    F = {}  # cost functions
    OD = {}  # OD pairs

    lineid = 0
    for line in open(graph_file, 'r'):
        lineid += 1
        # ignore \n
        line = line.rstrip()
        # ignore comments
        hash_pos = line.find('#')
        if hash_pos > -1:
            line = line[:hash_pos]

        # split the line
        taglist = line.split()
        if len(taglist) == 0:
            continue

        if taglist[0] == 'function':
            # process the params
            params = taglist[2][1:-1].split(',')
            if len(params) > 1:
                raise Exception('Cost functions with more than one parameter are not yet'\
                                'acceptable! (parameters defined: %s)' % str(params)[1:-1])

            # process the function
            function = Parser().parse(taglist[3])

            # process the constants
            constants = function.variables()
            if params[0] in constants:  # the parameter must be ignored
                constants.remove(params[0])

            # store the function
            F[taglist[1]] = [params[0], constants, function]

        elif taglist[0] == 'node':
            V.append(Node(taglist[1]))

        elif taglist[0] == 'dedge' or taglist[
                0] == 'edge':  # dedge is a directed edge
            # process the cost
            function = F[taglist[4]]  # get the corresponding function
            # associate constants and values specified in the line (in order of occurrence)
            param_values = dict(zip(function[1], map(float, taglist[5:])))

            param_values[function[
                0]] = flow  # set the function's parameter with the flow value

            # create the edge(s)
            E.append(
                Edge(taglist[2], taglist[3], function, param_values,
                     function[0]))
            if taglist[0] == 'edge':
                E.append(
                    Edge(taglist[3], taglist[2], function, param_values,
                         function[0]))

        elif taglist[0] == 'od':
            if taglist[2] != taglist[3]:
                OD[taglist[1]] = float(taglist[4])

        else:
            raise Exception('Network file does not comply with the specification!'\
                            '(line %d: "%s")' % (lineid, line))

    return V, E, OD
コード例 #7
0
class VirtualMeter(Contract):
    """ Module that manages a virtual meter"""
    def __init__(self, private_key, abi_file, address, endpoint, formula):
        with open(abi_file) as f:
            abi = json.load(f)['abi']
        super().__init__(private_key, address, abi, endpoint)

        # Check if meter is active
        active = self.contract.functions.isActive(self.account.address).call()
        if not active:
            raise NotAMeter('Check that the meter is enabled by the operator')

        # Get meter ID and connect to the monitoring server
        meter_id = self.contract.functions.getCurrentMeterData(
            self.account.address).call()[0]
        meter_id = meter_id.split(b'\0', 1)[0].decode('ascii')
        self.meter_id = getattr(MeterNames, meter_id)
        # Replace formula with ELT(x) calls.
        self.formula = Parser().parse(formula.replace('x', '*'))
        self.logger = configure_logging(self.meter_id)

        info = 'Initialized!'
        self.logger.info(green(info))

    def start_pinging(self):
        (last_reading, reading) = (0, 0)
        while True:  # Meter loops forever
            last_reading = reading
            (reading, timestamp) = \
                self.calculate_reading()
            # Wait until we get a new reading
            # Perhaps make a call to monitoring server every 15 mins?
            while (reading == last_reading):
                self.logger.warning(red('Sleeping until new reading'))
                time.sleep(20)
                (reading, timestamp) = \
                    self.calculate_reading()

            self.ping(reading, timestamp)

            info = 'Pinged {} kWh at t={}'.format(reading, timestamp)
            self.logger.info(green(info))

    def calculate_reading(self):
        """
            Utilizes Abstract Syntax Trees to parse an equation
            and evaluate ELT readings or Coefficients
            github.com/Axiacore/py-expression-eval
        """

        args = dict()
        coefficients = vars(Coefficients)
        meters = [m for m in self.formula.variables() if not m.startswith('F')]
        for var in self.formula.variables():
            # If it's a known coefficient get it from the constants list
            if var in coefficients:
                args[var] = getattr(Coefficients, var)
            # If it's an ELT or KMZ, get it from the blockchain
            else:
                info = 'Fetching reading for => {}'.format(var)
                self.logger.debug(green(info))
                addr = self.contract.functions.meterAddressById(
                    normalize(var)).call()
                data = self.contract.functions.getCurrentMeterData(addr).call()
                reading = data[1]
                args[var] = reading
        timestamp = data[2]
        info = 'Arguments to be evaluated => {}'.format(args)
        self.logger.debug(yellow(info))

        reading = self.formula.evaluate(args)
        return reading, timestamp

    def ping(self, reading, timestamp):
        """
            Takes reading and timestamp and creates a 
            raw transaction call to `ping` at the target contract
        """
        args = [int(reading), int(timestamp)]
        self.sign_and_send(self.contract.functions.ping, args)
コード例 #8
0
ファイル: KSP.py プロジェクト: lisong2019/pyrl
def generateGraph(graph_file):
    V = []  # vertices
    E = []  # edges
    F = {}  # cost functions
    OD = []  # OD pairs

    lineid = 0
    for line in open(graph_file, 'r'):

        lineid += 1

        # ignore \n
        line = line.rstrip()

        # ignore comments
        hash_pos = line.find('#')
        if hash_pos > -1:
            line = line[:hash_pos]

        # split the line
        taglist = line.split()
        if len(taglist) == 0:
            continue

        if taglist[0] == 'function':

            # process the params
            params = taglist[2][1:-1].split(',')
            if len(params) > 1:
                raise Exception(
                    'Cost functions with more than one parameter are not yet acceptable! (parameters defined: %s)'
                    % str(params)[1:-1])

            # process the function
            function = Parser().parse(taglist[3])

            # process the constants
            constants = function.variables()
            if params[0] in constants:  # the parameter must be ignored
                constants.remove(params[0])

            # store the function
            F[taglist[1]] = [params[0], constants, function]

        elif taglist[0] == 'node':
            V.append(Node(taglist[1]))

        elif taglist[0] == 'dedge' or taglist[
                0] == 'edge':  # dedge is a directed edge

            # process the cost
            function = F[taglist[4]]  # get the corresponding function
            param_values = dict(
                zip(function[1], map(float, taglist[5:]))
            )  # associate constants and values specified in the line (in order of occurrence)
            param_values[function[0]] = 0.0  # add the parameter with value 0
            cost = function[2].evaluate(param_values)  # calculate the cost

            # create the edge(s)
            E.append(Edge(taglist[1], taglist[2], taglist[3], cost))
            if taglist[0] == 'edge':
                E.append(Edge(taglist[1], taglist[3], taglist[2], cost))

        elif taglist[0] == 'od':
            OD.append(taglist[1])

        else:
            raise Exception(
                'Network file does not comply with the specification! (line %d: "%s")'
                % (lineid, line))

    return V, E, OD
コード例 #9
0
def generateNetwork(network_file_name):

    V = []  # vertices
    E = []  # edges
    F = {}  # cost functions
    OD = []  # OD pairs

    lineid = 0
    for line in open(network_file_name, 'r'):

        lineid += 1

        # ignore \n
        line = line.rstrip()

        # ignore comments
        hash_pos = line.find('#')
        if hash_pos > -1:
            line = line[:hash_pos]

        # split the line
        taglist = line.split()
        if len(taglist) == 0:
            continue

        if taglist[0] == 'function':

            # process the params
            params = taglist[2][1:-1].split(',')
            if len(params) > 1:
                raise Exception(
                    'Cost functions with more than one parameter are not yet acceptable! (parameters defined: %s)'
                    % str(params)[1:-1])

            # process the function
            expr = taglist[3]
            function = Parser().parse(expr)

            # handle the case where the parameter is not in the formula
            # (this needs to be handled because py-expression-eval does
            # not allows simplifying all variables of an expression)
            if taglist[1] not in function.variables():
                expr = '%s+%s-%s' % (taglist[3], params[0], params[0])
                function = Parser().parse(expr)

            # process the constants
            constants = function.variables()
            if params[0] in constants:  # the parameter must be ignored
                constants.remove(params[0])

            # store the function
            F[taglist[1]] = [params[0], constants, expr]

        elif taglist[0] == 'node':
            V.append(Node(taglist[1]))

        elif taglist[0] == 'dedge' or taglist[
                0] == 'edge':  # dedge is a directed edge

            # process the function
            func_tuple = F[taglist[4]]  # get the corresponding function
            param_values = dict(
                zip(func_tuple[1], map(float, taglist[5:]))
            )  # associate constants and values specified in the line (in order of occurrence)
            function = Parser().parse(func_tuple[2])  # create the function
            function = function.simplify(param_values)  # replace constants

            # create the edge(s)
            E.append(
                Edge(taglist[1], taglist[2], taglist[3], function,
                     func_tuple[0]))
            if taglist[0] == 'edge':
                E.append(
                    Edge('%s-%s' % (taglist[3], taglist[2]), taglist[3],
                         taglist[2], function, func_tuple[0]))

        elif taglist[0] == 'od':
            OD.append(taglist[1])

        else:
            raise Exception(
                'Network file does not comply with the specification! (line %d: "%s")'
                % (lineid, line))

    return V, E, OD