Пример #1
0
    def makeFunctionProgram(self, function_name, inputs, outputs):
        """
    Creates a function for the table
    :param function_name: string name of the function to be created
    :param inputs: list of column names that are input to the function
    :param outputs: list of columns that are output from the function
    :return str program: Program as a string
    """
        # Initializations
        sa = StatementAccumulator()
        # Program Prologue
        # TODO: This won't work with nested columns
        statement = """# Export of the table %s

    """ % self._table.getName(
            is_global_name=False
        )
        sa.add(statement)
        sa.add("")
        # Make the function definition. This must enclose the prologue
        # and epilogue
        sa.add(_makeFunctionStatement(function_name, inputs))
        sa.indent(1)
        sa.add(self._makeAPIPluginInitializationStatements(function_name))
        excludes = list(inputs)
        excludes.extend(outputs)
        sa.add(self._makePrologue(excludes=excludes))
        # Assign the column values to function variables.
        # Note that inputs and outputs are not assigned.
        #
        sa.add(self._makeFormulaEvaluationStatements(excludes=excludes))
        sa.add(self._makeClosingException())
        sa.add(self._makeEpilogue())
        sa.add(_makeReturnStatement(outputs))
        return sa.get()
Пример #2
0
    def _makeFormulaEvaluationStatements(self, **kwargs):
        """
    Constructs a script to evaluate table formulas.
    :return str: statements
    Notes: (1) Iterate N (#formulas) times to handle dependencies
               between formulas
    """
        # Initializations
        sa = StatementAccumulator()
        formula_columns = self._formulaColumns()
        num_formulas = len(formula_columns)
        if num_formulas == 0:
            return []
        # Statements that evaluate the formulas
        # Iteratively evaluate the formulas. The iteration
        # terminates under three conditions:
        #  1. No exception and no change in table data since the
        #     last iteration.
        #  2. No exception and the iteration count is equal to the
        #     number of columns.
        #  3. The iteration count exceeds a maximum value.
        statement = """
# Formula evaluation loop
%s.controller.initializeLoop()
while not %s.controller.isTerminateLoop():
""" % (
            API_OBJECT,
            API_OBJECT,
        )
        sa.add(statement)
        sa.indent(1)
        sa.add("%s.controller.startAnIteration()" % API_OBJECT)
        # Formula Evaluation block header
        sa.add("# Formula Execution Blocks")
        # Formula Evaluation block formulas
        for column in formula_columns:
            sa.add("try:")
            sa.indent(1)
            colnm = column.getName(is_global_name=False)
            sa.add("# Column %s" % colnm)
            statement = "%s.controller.startBlock('%s')" % (API_OBJECT, colnm)
            sa.add(statement)
            statement = column.getFormulaStatement()
            sa.add(statement)
            sa.add("%s.controller.endBlock()" % API_OBJECT)
            if column.isExpression():
                sa.add("%s = %s.coerceValues('%s', %s)" % (colnm, API_OBJECT, colnm, colnm))
            sa.indent(-1)
            sa.add("except Exception as exc:")
            sa.indent(1)
            sa.add("%s.controller.exceptionForBlock(exc)" % API_OBJECT)
            sa.indent(-1)
            sa.add(" ")
        # Formula Evaluation block footer
        # End of loop
        statement = self._makeClosingOfFormulaEvaluationLoop(**kwargs)
        sa.add(statement)
        return sa.get()
Пример #3
0
  def _wrapProgram(self):
    """
    Puts a wrapper around the program so that an exception can
    be caught and its location determined within the program.
    :returns str: program wrapped in try/catch blocks
    :sideeffects: puts CONTROLLER object in the namespace
    """
    self._namespace[CONTROLLER] =  self._controller
    sa = StatementAccumulator()
    sa.add("try:")
    sa.indent(1)
    statement = "%s.startBlock('%s')" % (CONTROLLER, self._program_name)
    sa.add(statement)
    sa.add(self._program)
    statement = "%s.endBlock()" % CONTROLLER
    sa.add(statement)
    sa.indent(-1)
    statement = """
except Exception as exc:
  %s.exceptionForBlock(exc)""" % CONTROLLER
    sa.add(statement)
    return sa.get()
class TestStatementAccumulator(unittest.TestCase):

  def setUp(self):
    self.sa = StatementAccumulator()

  def testAdd(self):
    statement = "This is a test."
    self.sa.add(statement)
    self.assertEqual(self.sa._statements[0], statement)
    statement = "This is another test."
    self.sa.add(statement)
    self.assertEqual(self.sa._statements[1], statement)

  def testAddWithIndent(self):
    statement = "This is a test."
    self.sa.add(statement)
    self.sa.indent(1)
    statement = "This is another test."
    self.sa.add(statement)
    self.assertEqual(self.sa._statements[1], "  %s" % statement)
    self.sa.indent(1)
    statement = "This is another test."
    self.sa.add(statement)
    self.assertEqual(self.sa._statements[2], "    %s" % statement)
    self.sa.indent(-1)
    statement = "This is another test."
    self.sa.add(statement)
    self.assertEqual(self.sa._statements[3], "  %s" % statement)

  def testGet(self):
    first_statement = "This is a test."
    self.sa.add(first_statement)
    self.assertEqual(self.sa.get(), first_statement)
    self.sa.indent(1)
    second_statement = "This is a test."
    self.sa.add(second_statement)
    expected_result ="%s\n  %s" % (first_statement, second_statement)
    self.assertEqual(self.sa.get(), expected_result)

  def testExtra(self):
    statement = '''# Evaluation of the table %s.

    ''' % "aName"
    self.sa.add(statement)
Пример #5
0
    def makeEvaluationScriptProgram(self, create_API_object=False):
        """
    Creates a python script that evaluates the table formulas
    when there is a change to the scisheet
    :param bool create_API_object: True means that code will be generated
                                 that creates the API object.
    :return str program: Program as a string
    """
        sa = StatementAccumulator()
        # TODO: This won't work with nested columns
        statement = """# Evaluation of the table %s.

    """ % self._table.getName(
            is_global_name=False
        )
        sa.add(statement)
        sa.add(self._makeAPIInitializationStatements(create_API_object=create_API_object))
        sa.add("try:")
        sa.indent(1)
        sa.add(self._makePrologue())
        sa.add(self._makeFormulaEvaluationStatements())
        statement = "if %s.controller.getException() is None:" % API_OBJECT
        sa.add(statement)
        sa.indent(1)
        sa.add(self._makeEpilogue())
        sa.indent(-2)
        # Handle exceptions in the Prologue and Epilogue
        statement = (
            """
except Exception as exc:
  %s.controller.exceptionForBlock(exc)"""
            % API_OBJECT
        )
        sa.add(statement)
        sa.add(self._makeClosingException(is_absolute_linenumber=False))
        return sa.get()
Пример #6
0
    def makeTestProgram(self, function_name=None, inputs=None, outputs=None):
        """
    Creates a program that tests the function exported for the table
    :param function_name: string name of the function to be created
    :param inputs: list of column names that are input to the function
    :param outputs: list of columns that are output from the function
    :return (str error, str program):
    """
        sa = StatementAccumulator()
        prefix = "self."
        output_str = _makeOutputStr(outputs)
        statement = '''"""
Tests for %s
"""

from scisheets.core import api as api
from %s import %s
import unittest


#############################
# Tests
#############################
# pylint: disable=W0212,C0111,R0904
class Test%s(unittest.TestCase):
''' % (
            function_name,
            function_name,
            function_name,
            function_name,
        )
        sa.add(statement)
        # Construct setup method
        sa.indent(1)
        sa.add("def setUp(self):")
        sa.indent(1)
        statement = self._makeAPIPluginInitializationStatements(function_name, prefix=prefix)
        sa.add(statement)
        sa.indent(-1)
        # Construct the test function header
        sa.add("def testBasics(self):")
        sa.indent(1)
        # Assign values to the columns
        sa.add(self._makeVariableAssignmentStatements(prefix=prefix, only_includes=inputs))
        # Construct the call to the function being tested
        statement = _makeOutputStr(outputs)
        statement += " = %s(" % function_name
        statement += ",".join(inputs)
        statement += ")"
        sa.add(statement)
        # Construct the tests
        for column_name in outputs:
            statement = "self.assertTrue(self.%s.compareToColumnValues('%s', %s))" % (
                API_OBJECT,
                column_name,
                column_name,
            )
            sa.add(statement)
        sa.indent(-2)
        # Construct the program epilogue
        statement = """

if __name__ == '__main__':
  unittest.main()"""
        sa.add(statement)
        return sa.get()