Repository 'table_compute'
hg clone https://toolshed.g2.bx.psu.edu/repos/iuc/table_compute

Changeset 2:02c3e335a695 (2019-09-13)
Previous changeset 1:dddadbbac949 (2019-08-30) Next changeset 3:60ff16842fcd (2019-10-18)
Commit message:
"planemo upload for repository https://github.com/galaxyproject/tools-iuc/tree/master/tools/table_compute commit d00a518202228b990aeeea2ec3f842501fd2ec09"
modified:
scripts/safety.py
scripts/table_compute.py
table_compute.xml
b
diff -r dddadbbac949 -r 02c3e335a695 scripts/safety.py
--- a/scripts/safety.py Fri Aug 30 05:28:18 2019 -0400
+++ b/scripts/safety.py Fri Sep 13 14:54:41 2019 -0400
[
@@ -11,7 +11,6 @@
         '(', ')', 'if', 'else', 'or', 'and', 'not', 'in',
         '+', '-', '*', '/', '%', ',', '!=', '==', '>', '>=', '<', '<=',
         'min', 'max', 'sum',
-        'str', 'int', 'float'
     )
     __allowed_ref_types = {
         'pd.DataFrame': {
@@ -177,12 +176,13 @@
         # ['vec.median', '(', ')', '+', 'vec.sum', '(', ')']
         tokens = [
             e for e in re.split(
-                r'("[a-zA-Z%0-9_.]+"|[a-zA-Z0-9_.]+|[^a-zA-Z0-9_.() ]+|[()])', self.expr
+                r'([a-zA-Z0-9_.]+|[^a-zA-Z0-9_.() ]+|[()])', self.expr
             ) if e.strip()
         ]
 
         # 2. Subtract allowed standard tokens
         rem = [e for e in tokens if e not in self.__allowed_tokens]
+
         # 3. Subtract allowed qualified objects from allowed modules
         #    and whitelisted references and their attributes
         rem2 = []
@@ -194,32 +194,18 @@
             if len(parts) == 2:
                 if parts[0] in self.these:
                     parts[0] = '_this'
-                elif parts[0] == "":
-                    # e.g. '.T' gives ['','.T']
-                    # Here we assume that the blank part[0] refers to the
-                    # self.ref_type (e.g. "pd.DataFrame"), and that
-                    # the second part is a function of that type.
-                    if parts[1] in self.allowed_qualified['_this']:
-                        continue
-
                 if parts[0] in self.allowed_qualified:
                     if parts[1] in self.allowed_qualified[parts[0]]:
                         continue
-
             rem2.append(e)
 
-        # Debug
-        # for x in (tokens, rem, rem2):print(x)
-
         # 4. Assert that rest are real numbers or strings
         e = ''
         for e in rem2:
             try:
                 _ = float(e)
             except ValueError:
-                # e.g. '"TEXT"' is okay.
-                if not(e[0] == '"' and e[-1] == '"'):
-                    safe = False
-                    break
+                safe = False
+                break
 
         return safe, e
b
diff -r dddadbbac949 -r 02c3e335a695 scripts/table_compute.py
--- a/scripts/table_compute.py Fri Aug 30 05:28:18 2019 -0400
+++ b/scripts/table_compute.py Fri Sep 13 14:54:41 2019 -0400
[
@@ -4,7 +4,7 @@
 """
 
 
-__version__ = "0.9.1"
+__version__ = "0.9.2"
 
 import csv
 import math
@@ -265,7 +265,12 @@
         mode = params["element_mode"]
         if mode == "replace":
             replacement_val = params["element_replace"]
-            out_table = data.mask(bool_mat, replacement_val)
+            out_table = data.mask(
+                bool_mat,
+                data.where(bool_mat).applymap(
+                    lambda x: replacement_val.format(elem=x)
+                )
+            )
         elif mode == "modify":
             mod_op = Utils.getOneValueMathOp(params["element_modify_op"])
             out_table = data.mask(
@@ -300,7 +305,9 @@
     elif user_mode_single == "fulltable":
         general_mode = params["mode"]
 
-        if general_mode == "melt":
+        if general_mode == "transpose":
+            out_table = data.T
+        elif general_mode == "melt":
             melt_ids = params["MELT"]["melt_ids"]
             melt_values = params["MELT"]["melt_values"]
 
b
diff -r dddadbbac949 -r 02c3e335a695 table_compute.xml
--- a/table_compute.xml Fri Aug 30 05:28:18 2019 -0400
+++ b/table_compute.xml Fri Sep 13 14:54:41 2019 -0400
[
b'@@ -1,7 +1,7 @@\n <tool id="table_compute" name="Table Compute" version="@VERSION@">\n     <description>computes operations on table data</description>\n     <macros>\n-        <token name="@VERSION@">0.9.1</token>\n+        <token name="@VERSION@">0.9.2</token>\n         <token name="@COPEN@"><![CDATA[<code>]]></token>\n         <token name="@CCLOSE@"><![CDATA[</code>]]></token>\n         <import>allowed_functions.xml</import>\n@@ -23,7 +23,7 @@\n             <sanitizer sanitize="false" />\n         </macro>\n         <macro name="validator_functiondef">\n-            <validator type="regex" message="An expression is required and is allowed to contain only letters, numbers and the characters \'_ !-+=/*%.&lt;&gt;()\'">^[\'"\\w !\\-+=/*%,.&lt;&gt;()]+$</validator>\n+            <validator type="regex" message="An expression is required and is allowed to contain only letters, numbers and the characters _ !-+=/*%.&lt;&gt;()">^[\\w !\\-+=/*%,.&lt;&gt;()]+$</validator>\n             <sanitizer sanitize="false" />\n         </macro>\n         <!-- macro for main input tests -->\n@@ -51,8 +51,9 @@\n             <yield />\n             <conditional name="user" >\n                 <param name="mode" value="element" />\n-                <param name="element_op" value="gt" />\n-                <param name="element_value" value="0" />\n+                <conditional name="elem_val">\n+                    <param name="element_op" value="None" />\n+                </conditional>\n                 <conditional name="element" >\n                     <param name="mode" value="custom" />\n                     <param name="custom_expr" value="-math.log(1 - elem/4096) * 4096 if elem != 4096 else elem - 0.5" />\n@@ -133,6 +134,7 @@\n }\n \n #if str($singtabop.use_type) == "single":\n+  #set $op_mode = str($singtabop.user.mode)\n Data = {\n     "tables": [\n         {\n@@ -159,12 +161,12 @@\n         }\n     ],\n     "params": {\n-      "user_mode_single": \'$singtabop.user.mode.value\',\n-    #if $singtabop.user.mode.value == \'precision\':\n+      "user_mode_single": \'$op_mode\',\n+    #if $op_mode == \'precision\':\n         ## Literally do nothing, the user just sets the precision slider\n         ## at the top default level\n     }\n-    #elif $singtabop.user.mode.value == \'select\':\n+    #elif $op_mode == \'select\':\n         "select_cols_unique": #echo \'select_cols_keepdupe\' in str($singtabop.user.select_keepdupe)#,\n         "select_rows_unique": #echo \'select_rows_keepdupe\' in str($singtabop.user.select_keepdupe)#,\n       #if $singtabop.user.select_cols_wanted:\n@@ -178,24 +180,25 @@\n         "select_rows_wanted": None,\n       #end if\n     }\n-    #elif $singtabop.user.mode.value == \'filtersumval\':\n-        "filtersumval_mode": \'$singtabop.user.filtersumval_mode.use.value\',\n-        "filtersumval_axis": $singtabop.user.axis.value,\n-      #if $singtabop.user.filtersumval_mode.use.value == \'operation\':\n-        "filtersumval_compare": \'$singtabop.user.filtersumval_mode.compare_op.value\',\n-        "filtersumval_op": \'$singtabop.user.filtersumval_mode.operation.value\',\n+    #elif $op_mode == \'filtersumval\':\n+      #set $filter_type = str($singtabop.user.filtersumval_mode.use)\n+        "filtersumval_mode": \'$filter_type\',\n+        "filtersumval_axis": $singtabop.user.axis,\n+      #if $filter_type == \'operation\':\n+        "filtersumval_compare": \'$singtabop.user.filtersumval_mode.compare_op\',\n+        "filtersumval_op": \'$singtabop.user.filtersumval_mode.operation\',\n         "filtersumval_against": $singtabop.user.filtersumval_mode.against,\n         "filtersumval_minmatch": None,\n-      #elif $singtabop.user.filtersumval_mode.use.value == \'element\':\n+      #elif $filter_type == \'element\':\n         "filtersumval_compare": None,\n-        "filtersumval_op": \'$singtabop.user.filtersumval_mode.operation.value\',\n+        "filtersumval_op": \'$singtabop.user.filtersumval_mode.operation\',\n         ## against could be string or float, so we parse this in the code\n         "filtersumval_against": \'$singtabop.user.filtersumv'..b'9;ab" />\n+                    <not_has_text text="g3&#009;ab" />\n+                    <not_has_text text="g4&#009;ab" />\n+                </assert_contents>\n+            </output>\n+        </test>\n+        <test expect_num_outputs="1" expect_failure="true">\n+            <!-- Test 41: Test safety of custom expression free text\n+            Tries to escape/reenter config file quoting.\n+\n+            This test is expected to fail if either\n+            - a validator disallows the use of single quotes or\n+            - the single quotes get sanitized (which is unlikely to result in a\n+              valid expression); note that in this situation, it cannot be\n+              guaranteed that the single quote sanitization is safe with\n+              *every* input\n+\n+            If the test succeeds unexpectedly, this shows that Python\n+            has performed string concatenation upon importing the config file\n+            resulting in each element of the test table being retained.\n+             -->\n+            <conditional name="singtabop" >\n+                <param name="use_type" value="single" />\n+                <param name="input" value="examples.4.tsv" />\n+                <param name="col_row_names" value="has_col_names,has_row_names" />\n+                <conditional name="user" >\n+                    <param name="mode" value="element" />\n+                    <conditional name="element" >\n+                        <param name="mode" value="custom" />\n+                        <param name="custom_expr" value="el\'+\'em" />\n+                    </conditional>\n+                    <conditional name="elem_val" >\n+                        <param name="element_op" value="All" />\n+                    </conditional>\n+                </conditional>\n+            </conditional>\n+        </test>\n     </tests>\n     <help><![CDATA[\n This tool computes table expressions on the element, row, and column basis. It can sub-select,\n duplicate, as well as perform general and custom expressions on rows, columns or elements.\n \n-Only a single operation can be performed on the data. Multiple operations can be performed by\n-chaining successive runs of this tool. This is to provide a more transparent workflow for complex operations.\n+.. class:: infomark\n+\n+    Only a single operation can be performed on the data. Multiple operations\n+    can be performed by chaining successive runs of this tool. This is to\n+    provide a more transparent workflow for complex operations.\n \n \n \n@@ -1582,6 +1609,14 @@\n \n     table1 / min(np.max(np.max(table2)), np.max(np.max(table3)))\n \n+.. class:: infomark\n+\n+   Complex operations (like ones that would benefit from specifying nested\n+   attributes) can often be broken into subsequent runs ot the tool, in\n+   which the first run generates an intermediate table representing the result\n+   of the "inner" operation that the second run can then use as input to\n+   perform the "outer" operation.\n+\n Also note that, currently `min()`, `max()` and `sum()` are the only built-in\n Python functions that can be used inside expressions. If you want to use\n additional functions, these have to be qualified functions from the `math`,\n@@ -1702,11 +1737,17 @@\n \n  * *Type of table operation* \xe2\x86\x92  **Manipulate selected table elements**\n \n-   * *Operation to perform* \xe2\x86\x92 **Custom**\n+   * *Operation to perform* \xe2\x86\x92 **Replace values**\n+\n+     * *Replacement value* \xe2\x86\x92 ::\n+\n+         chr{elem:.0f}\n \n-     * *Custom Expression* \xe2\x86\x92 ::\n-\n-         "chr%.f" % elem\n+       Here, the placeholder ``{elem}`` lets us refer to each element\'s\n+       current value, while the ``:.0f`` part is a format specifier that makes\n+       sure numbers are printed without decimals (for a complete description of\n+       the available syntax see the\n+       `Python Format Specification Mini-Language <https://docs.python.org/3/library/string.html#formatspec>`_).\n \n      * *Operate on elements* \xe2\x86\x92 **Specific Rows and/or Columns**\n      * *List of columns to select* \xe2\x86\x92 "2"\n'