Edit this page on our live server and create a PR by running command !create-pr in the console panel

Script format of function calls

  • Difficulty level: easy
  • Time need to lean: 10 minutes or less
  • Key points:
    • A Python function with a string as the first parameter can be written in a script style
    • Scripts are dedented, and included in verbatim by default
    • expand=True turns the script into a Python f-string
    • expand="l r" can be used to specify an alternative delimiter for string interpolation

SoS "actions"

SoS defines a number of actions, which are simply Python functions that follow a specific set of conventions. For example, an action sh is a python function that executes its first parameter as a shell script:

In [1]:
Hello world

When you execute a SoS script from command line or SoS Notebook, these functions are automatically imported and can be used directly, and you can use them just like any other Python functions. For example, you can compose a script using Python string formatting:

In [2]:
Hello world

Here we define a Python string greeting and use the sh action to execute a shell script. A Python f-string is used to compose the script with the defined variable.

When the scripts get longer, you can use Python multi-line strings to pass them to the action. Here is an example for the use of a R action to execute a longer R script:

In [3]:
[1] "Non-negative number"

The use of format string in these cases become more complicated. First, you will need to use multi-line f-string (f'''x''' and f"""x"""). Second, when the script itself contains braces, they will need to be doubled to avoid being interpreted as Python expressions.

Consequently, a R script that uses a Python variable my_num needs to be written as follows:

In [4]:
[1] "Negative number"

Script style function calls

The f-string in the last example is not quite readable, error-prone, and difficult to maintain, especially when the script contains multiple braces and variables. For this reason, SoS introduces a special syntax that allows you to write Python functions that accept a script (string) as the first parameter in a special script format.

For example,

In [5]:
[1] "Non-negative number"

can be written as

In [6]:
WARNING: Embedding script "x <- 5..." without indentation is error-prone and will be deprecated in the future.
[1] "Non-negative number"

but as the warning message shows, better included with indentation:

In [7]:
[1] "Non-negative number"

When option expand=True is specified, the included script will be treated as a Python f-string. For example,

In [8]:
[1] "Negative number"

can be written as

In [9]:
[1] "Negative number"

Note that SoS Notebook automatically highlights the interpolated parts of the included script, which makes it much easier to differentiate Python expressions from the original R script.

Because the included script has two pairs of braces, it is necessary to double them so that they are not treated as Python expressions. In these cases, it is actually easier to use a different set of sigil (delimiters) for string interpolation. This can be done using the expand option as follows:

In [10]:
[1] "Negative number"

The sigil should be specified as a string with left and right sigil separated by a space. You can use any pair of sigils as long as they do not cause confusion.

Indented script format

What you have seen so far are function calls without Python control structure. Because SoS allows you to execute the same statements repeatedly for different inputs (substeps and stop the execution of substeps through actions such as skip_if and done_if, there is rarely a need to call SoS actions within the if...else... block or for or while loops.

However, if you do need to call SoS actions inside a Python control structure, you can still use the script format for it. For example, instead of writing

In [11]:
0
1
2

You can write the sh action in the format of

In [12]:
0
1
2

or in more complex case

In [13]: