0

I saw a python code block example to output an array as an org-table. An example would be,

#+BEGIN_SRC python :results value
  r = 3389.5 # km average radius
  re = 3396.2 # equatorial radius in km
  rp =  3376.2 # polar radius in km 
  m = 6.4171 * 10**(23) # kg

  return[["Parameter", "Value"],
   None,
   ["Mass Mars (kg)", "{:.5g}".format(m)],
   ["Mean Radius (km)", "{:.5g}".format(r)],
   ["Polar Radius (km)", "{:.5g}".format(rp)],
   ["Equatorial Radius (km)", "{:.5g}".format(re)]]

#+END_SRC

#+RESULTS:
| Parameter              |      Value |
|------------------------+------------|
| Mass Mars (kg)         | 6.4171e+23 |
| Mean Radius (km)       |     3389.5 |
| Polar Radius (km)      |     3376.2 |
| Equatorial Radius (km) |     3396.2 |

This is almost perfect for me. I would like to be able to use ipython in session mode in order to pull results from various other code blocks without naming them individually with :var headers.

However, with ipython I get the error:

SyntaxError: 'return' outside function

I'm not sure why there is this difference in behavior between python and ipython code blocks. If I remove "return" from the ipython code block, I get the following output (no table):

#+BEGIN_SRC ipython :session mars :results value
   [["Parameter", "Value"],
   ["Mass Mars (kg)", "{:.5g}".format(m)],
   ["Mean Radius (km)", "{:.5g}".format(r)],
   ["Polar Radius (km)", "{:.5g}".format(rp)],
   ["Equatorial Radius (km)", "{:.5g}".format(re)]]

#+END_SRC

#+RESULTS:
:RESULTS:
# Out[109]:
# text/plain
: [['Parameter', 'Value'],
:  ['Mass Mars (kg)', '6.4171e+23'],
:  ['Mean Radius (km)', '3389.5'],
:  ['Polar Radius (km)', '3376.2'],
:  ['Equatorial Radius (km)', '3396.2']]
:END:

Using the header argument ":results value table" doesn't work either:

 #+BEGIN_SRC ipython :session mars :results value table
       [["Parameter", "Value"],
       ["Mass Mars (kg)", "{:.5g}".format(m)],
       ["Mean Radius (km)", "{:.5g}".format(r)],
       ["Polar Radius (km)", "{:.5g}".format(rp)],
       ["Equatorial Radius (km)", "{:.5g}".format(re)]]

    #+END_SRC

    #+RESULTS:
    :RESULTS:
    | # Out[1]: |
    :END:

In this case, is the best option just to do something like following? Am I missing a better solution? My end use scenario is exporting the org-file to pdf with a mixture of latex formulas as well as ipython code blocks and text.

#+BEGIN_SRC ipython :session mars 

print("|-")
print("| Parameter | Value |")
print("|-")
print(f"|Mass Mars (kg) | {m}|")
print(f"|Mean Radius (km) | {r}|")
print(f"|Polar Radius (km) | {rp}|")
print(f"|Equatorial Radius (km) | {re}|")
print(f"|-")
print("#+TBLFM: $2=$0;%0.5g")
#+END_SRC

#+RESULTS:
:RESULTS:
# Out[116]:
# output
|------------------------+------------|
| Parameter              |      Value |
|------------------------+------------|
| Mass Mars (kg)         | 6.4171e+23 |
| Mean Radius (km)       |     3389.5 |
| Polar Radius (km)      |     3376.2 |
| Equatorial Radius (km) |     3396.2 |
|------------------------+------------|
#+TBLFM: $2=$0;%0.5g
0

You don't need to format things as tables to pass information between blocks with ipython in scimax; each block is "connected" via the kernel that is running in the background, so variables created in one block are available in another block. You might still want to output a table of results for easy reading, and a nice way to do this is with the tabulate package.

You can make a table like this:

#+BEGIN_SRC ipython
import tabulate

r = 3389.5 # km average radius
re = 3396.2 # equatorial radius in km
rp =  3376.2 # polar radius in km
m = 6.4171 * 10**(23) # kg

print(tabulate.tabulate([["Mass Mars (kg)", "{:.5g}".format(m)],
                         ["Mean Radius (km)", "{:.5g}".format(r)],
                         ["Polar Radius (km)", "{:.5g}".format(rp)],
                         ["Equatorial Radius (km)", "{:.5g}".format(re)]],
                        ["Parameter", "Value"],
                        tablefmt='orgtbl'))
#+END_SRC

#+RESULTS:
:results:
# Out [8]:
# output
| Parameter              |      Value |
|------------------------+------------|
| Mass Mars (kg)         | 6.4171e+23 |
| Mean Radius (km)       |     3389.5 |
| Polar Radius (km)      |     3376.2 |
| Equatorial Radius (km) |     3396.2 |

:end:

Later in a new cell you can reuse one of the previously defined variables like this:

#+BEGIN_SRC ipython
m
#+END_SRC

#+RESULTS:
:results:
# Out [9]: 
# text/plain
: 6.417099999999999e+23
:end:

Each buffer has its own automatic session in scimax, so I don't recommend you use the :session header argument without some good reason.

  • Thank you, John. This is perfect. And thanks for your work on scimax! – debby Apr 15 at 6:42
0

[Not a complete answer, but too long for a comment.]

The main problem above is that session and non-session evaluation of python code blocks is different: in non-session, the code block is wrapped in a phantom function, hence the return makes sense; but no such thing happens in session evaluation. You will probably be better off changing the header args to :results output table :session mars and then changing the code block to print the value, rather than return it:

#+BEGIN_SRC python :results output table :session mars
  r = 3389.5 # km average radius
  re = 3396.2 # equatorial radius in km
  rp =  3376.2 # polar radius in km 
  m = 6.4171 * 10**(23) # kg

  print([["Parameter", "Value"],
   None,
   ["Mass Mars (kg)", "{:.5g}".format(m)],
   ["Mean Radius (km)", "{:.5g}".format(r)],
   ["Polar Radius (km)", "{:.5g}".format(rp)],
   ["Equatorial Radius (km)", "{:.5g}".format(re)]])

#+END_SRC

This does not address the ipython question at all, because I don't know enough about it to offer any useful advice. What I do know is that, by default, org-mode does not provide an ob-ipython implementation, so you must have installed something extra to get ipython code blocks to "work" (for some value of "work": in my case, if I change the source language tag to ipython in my setup, I get an error: No org-babel-execute function for ipython!).

  • Thanks for the response. For me this output doesn't format as a table, and just appears as a text array. But if using a python block and needing to copy all the variables into the source block, I can just use the working example I first indicated. I'll keep looking for a better way to tabulate ipython block results. You're correct about ob-ipython. I am using [scimax] (github.com/jkitchin/scimax). – debby Apr 13 at 17:37
  • Did you use :results output table? – NickD Apr 13 at 22:37
  • Yes, I copied and pasted it directly. It may be the result of some other settings I changed. John's tabulate method above does the trick. Thank you for your help. – debby Apr 15 at 6:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.