Skip to content

pythonizing dont know python

Jeff Squyres edited this page Dec 7, 2019 · 19 revisions

Pythonizing: For those who don't know Python

Don't know Python?

No problem!

We're really only using a small amount of Python, but there are a few things you need to know, mostly having to deal with:

  1. Python indenting
  2. How Python handles strings
  3. Line breaks
  4. Escaping (LaTeX vs. Python)
  5. Comments
  6. Boolean values

Specifically: everything inside the {mpi-binding} block must be in valid Python syntax. If the syntax isn't correct, building the LaTeX document will fail.

The following sections discuss a few "gotchas" that you need to watch out for, particularly if you're not familiar with the Python language.

Indenting

Python requires a constant level of indenting. You can indent to any level you want (to include zero indentation), but you must make sure that all of your Python expressions inside a single {mpi-binding} block are indented to the same level.

   # Good indenting
   foo()
   bar()

   # Bad indenting (will cause an error)
       baz()
     yow()

To be clear: each {mpi-binding} block is self-contained. You can indent one {mpi-binding} block to N characters and a different {mpi-binding} block to M characters (where N!=M). But for human readability, we suggest using a common indenting level of 2 or 4 spaces (no tabs!) for each {mpi-binding} block.

You probably won't use any conditionals or have any reason for sub-blocks of code in the MPI standard Pythonizing, but if you do, you use indenting as the delimiter for that block of code. For example:

   foo()
   if value == 3:
       print("Hey, the value was 3!")
       value = 0
       print("I reset the value to 0 for you")

   # Outdented, so now we're back outside the conditional code block
   print("The value is: " + value)

Strings

Strings can be delimited with single ' or double " quote marks. For example:

   # Like many scripting languages, you do not need
   # to declare variables before using them:
   foo = 'Hello, world'
   bar = "Hello, world"

Multi-line strings can be delimited with three single or double quote marks:

  foo = """Hello,
world"""

  bar = '''Hello,
world.
I am awesome.
This is a very long,
       multi
             line
                  string.'''

Note that inside the string, any spacing for indenting is part of the string -- constant indenting is not required. But the string expressions themselves -- the assignments to foo and bar in this case -- must follow proper Python indenting.

The general advice from PEP8 (the Python style guide) for multi-line strings is to use the implied line continuation with parentheses:

string = ('Long string here which does not fit on a single line nicely. '
          'Another long string here using the parentheses.')

This will end up being a single string with ...nicely. Another... (note the space at the end of the first line that turns into a space between nicely. and Another).

Line breaks

Line breaks are allowed inside of (). For the purposes of the MPI standard, this will likely occur within the argument list to one of the MPI Pythonizing functions. Additionally, inside (), the indenting rules are relaxed: you can indent inconsistently. For example:

   # Here's a non-line broken line:
   foo(a, b, c)

   # Here's another with multiple line breaks:
   foo(a,
       b,
       c)

   # Note that the indenting does not need to be consistent within the ().
   # This example is ugly / not very readable, but is valid Python:
   some_really_long_function_name(a,
       b, c, d, e, f,
             g, h, i, j, k)

   # It's much more readable to indent consistently:
   some_really_long_function_name(a,
       b, c, d, e, f,
       g, h, i, j, k)

Escaping

In LaTeX, you have to escape the _ character if you want it to render in the output.

It is unnecessary to escape the _ character in {mpi-binding} blocks. Use it just like any other character (e.g., in strings). The Pythonization functions will take care of escaping the resulting _ characters in LaTeX if it is necessary.

For example:

  function_name('MPI_Dist_graph_create')
  # ...
  parameter('comm_dist_graph', 'COMMUNICATOR', direction='OUT',
            desc='communicator with distributed graph topology added')

Note that MPI_Dist_graph_create and comm_dist_graph did not need to have their _ characters escaped in the Python strings. That being said, in the rendered LaTeX, they will be properly escaped.

Beyond _, sometimes you need to include LaTeX code in Python strings. For example:

function_name('MPI_Group_range_incl')

#...

parameter('newgroup', 'GROUP', direction='out',
          desc='new group derived from above, in the order defined by \mpiarg{ranges}')

Notice the use of \mpiarg{ranges} in the desc parameter string. This is perfectly fine: embedded LaTeX in the desc string will be output with the rest of the emitted LaTeX. The only thing to remember is that the _ rule still applies, even in embedded LaTeX. For example, you'd use \mpiarg{long_multi_word_variable} -- without escaping the _ characters.

Comments

Comments are generally of two flavors: dedicated comments or useless strings.

Dedicated comments start with the # symbol, like many other scripting languages. For example:

# This is a comment line
foo()   # This is a comment at the end of a line

For lengthy, multi-line comments, some Python programmers like to have a "useless" multi-line string. I.e., it's a valid string expression, but it evaluates to no purpose when executing the Python. For example:

   """This is a multi-line string
You can do whatever you want in this string
         Including indenting inconsistently.

Hello, world!"""
   foo()

Note that the string is a valid Python expression, so it must be indentend consistently with other Python expressions. In the example above, note how the opening """ and foo() are indented to the same level.

Logical values: True and False

Python's Boolean type has the constants True and False (spelled and capitalized this way).

They are not integer values -- you cannot use 1 and 0, respectively.

Some of the parameters to parameter() are Booleans. For example:

  parameter('foo', 'RANK', length='n', constant=True, desc='array of ranks')

Putting it all together

Here's a slightly-unrealistic example that shows everything from above. All of this is within \begin{mpi-binding} / \end{mpi-binding}:

  """
This is the binding for MPI_ALLOC_MEM.

It is special in many ways.

But really, I just wanted to show a multi-line string that acts like a
comment."""

  function_name('MPI_Alloc_mem')

  # Use the special ALLOC_MEM_NUM_BYTES type
  # See comment in binding_tool.py for an explanation
  parameter('size', 'ALLOC_MEM_NUM_BYTES',
            desc='size of memory segment in bytes')
  parameter('info', 'INFO')
  # Splitting the "desc" parameter as a multi-line string below
  # is fairly ugly / unreadable; this is show as an example only.
  parameter('baseptr', 'C_BUFFER', direction='out',
            desc='''pointer to beginning of memory
segment allocated''')