I want to check out if org-mode could be a good replacement for Jupyter notebooks.
Is there a way to export all variables from a code block to other code blocks?
Example:
#+BEGIN_SRC python
a = 1
b = 2
#+END_SRC
How could I use this in other code block? For example I'd like the following to evaluate so that c = 3
#+BEGIN_SRC python
c = a + b
#+END_SRC
It can be achieved using session feature:
#+NAME b1
#+BEGIN_SRC python :session example :results output
a = 1
b = 2
#+END_SRC
#+BEGIN_SRC python :session example :results output
c = a + b
print(c)
#+END_SRC
Will return
#+RESULTS:
: 3
Related
Hi Below is some simple code that displays the benchmark results form a Julia REPL. In VSCode I have tried
launching the Julia REPL from the Command Pallet and Running the file without Debugging
Execute the active File in Repl from the drop down menu top right
In both cases the println statements are displayed but not the benchmark results. Is this to be expected or have I messed up?
using DifferentialEquations, BenchmarkTools
A = rand(1000,1000); B = rand(1000,1000); C = rand(1000,1000)
println("TX 1 and 2")
test(A,B,C) = A + B + C
#benchmark test(A,B,C)
println("T 1 End")
t(A,B,C) = A .+ B .+ C
#benchmark t(A,B,C)
println("TX 2 End")
readline()
println("After read")
I found a workaround : remove or comment out the #benchmark from the file and
run them directly in the REPL.
This should depend on which setting you have for result type (Julia > Execution: Result Type in the Settings GUI or julia.execution.resultType in settings.json).
With "inline" result type I get:
Hovering over the BenchmarkTools.Trial box, I get:
Note the println line just shows a tick as it has been executed but didn't return anything, instead it printed to the REPL, the terminal at the bottom now looks like this:
Suppose I have a these properties defined:
:PROPERTIES:
:a: 1
:b: 2
:END:
How do I define a property c such that the value is the sum of the value of property a and the value of property b? I have tried :c: (+ a b) but the value of c is just the string "(+ a b)".
Is it possible to define a property in this way or do I have to have a code-block that is then evaluated? (Using the Properties API for instance)
You could define a code block which executes on export, using the Property API:
* Code
#+NAME: PropertyCalculator
#+BEGIN_SRC emacs-lisp
(let* ( (rootval (string-to-number (org-entry-get nil "root")))
(squareval (number-to-string (* rootval rootval))) )
(org-entry-put nil "square" squareval)
)
#+END_SRC
* Content
** Property Data
:PROPERTIES:
:root: 2
:square: 5
:END:
#+CALL: PropertyCalculator()
This would leave any existing entry in place in the buffer, but overwrite in the export.
You could also correct in-buffer with (org-babel-load-file).
I'd like to write a simple macro that shows the names & values of variables. In Common Lisp it would be
(defmacro dprint (&rest vars)
`(progn
,#(loop for v in vars
collect `(format t "~a: ~a~%" ',v ,v))))
In Julia I had two problems writing this:
How can I collect the generated Expr objects into a block? (In Lisp, this is done by splicing the list with ,# into progn.) The best I could come up with is to create an Expr(:block), and set its args to the list, but this is far from elegant.
I need to use both the name and the value of the variable. Interpolation inside strings and quoted expressions both use $, which complicates the issue, but even if I use string for concatenation, I can 't print the variable's name - at least :($v) does not do the same as ',v in CL...
My current macro looks like this:
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println(string(:($v), " = ", $v))) for v in vars]
ex
end
Looking at a macroexpansion shows the problem:
julia> macroexpand(:(#dprint x y))
quote
println(string(v," = ",x))
println(string(v," = ",y))
end
I would like to get
quote
println(string(:x," = ",x))
println(string(:y," = ",y))
end
Any hints?
EDIT: Combining the answers, the solution seems to be the following:
macro dprint(vars...)
quote
$([:(println(string($(Meta.quot(v)), " = ", $v))) for v in vars]...)
end
end
... i.e., using $(Meta.quot(v)) to the effect of ',v, and $(expr...) for ,#expr. Thank you again!
the #show macro already exists for this. It is helpful to be able to implement it yourself, so later you can do other likes like make one that will show the size of an Array..
For your particular variant:
Answer is Meta.quot,
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println($(Meta.quot(v)), " = ", $v)) for v in vars]
ex
end
See with:
julia> a=2; b=3;
julia> #dprint a
a = 2
julia> #dprint a b
a = 2
b = 3
oxinabox's answer is good, but I should mention the equivalent to ,#x is $(x...) (this is the other part of your question).
For instance, consider the macro
macro _begin(); esc(:begin); end
macro #_begin()(args...)
quote
$(args...)
end |> esc
end
and invocation
#begin x=1 y=2 x*y
which (though dubiously readable) produces the expected result 2. (The #_begin macro is not part of the example; it is required however because begin is a reserved word, so one needs a macro to access the symbol directly.)
Note
julia> macroexpand(:(#begin 1 2 3))
quote # REPL[1], line 5:
1
2
3
end
I consider this more readable, personally, than pushing to the .args array.
I know we can use Babel to evaluate code block in org-mode. But it seems that Babel can not handle "cin". Like this
int a;std::cin >> a;std::cout << a;
The Babel doesn't ask me to input the value of a, and it output the value 0.
Can Babel handle this problem? Or some other tools can do this.
I can think of two different approaches for this. The first approach is to create a file like input.data with content of, say, 4 in the home directory. This will be supplied to std::cin. Then, write the code as follows:
#+begin_src C++ :results output :includes <iostream> :cmdline < ~/input.data
int a;
std::cin >> a;
std::cout << a;
#+end_src
#+RESULTS:
: 4
The second approach, which is more interesting, is to use a little bit of lisp code for interactivity:
#+name: input
#+begin_src elisp
(completing-read "Enter a number: " nil)
#+end_src
#+begin_src C++ :results output :var input=input
#include <iostream>
#include <string>
int main() {
int a = std::atoi(input);
std::cout << a;
}
#+end_src
#+RESULTS:
: 3
In this approach, you will be prompted inside emacs to enter a number, which will be used in the C++ code.
I am reading Ocaml Style guide on nested let-in of Ocaml.
http://www.seas.upenn.edu/~cis341/programming_style.html#16
It is suggested that
Indenting nested let expressions: Blocks of code that have nested let expressions should not be indented.
Bad:
let x = exp1 in
let y = exp2 in
x + y
Good:
let x = exp1 in
let y = exp2 in
x + y
However, what do you think about how to indent my following program.
let f =
let g = 3 in
g + 2
The above is indented by emacs. But apparently, this indenting of emacs violates the style guide I cited earlier. To follow the style, shouldn' t it be more like this one?
let f =
let g = 3 in
g + 2
Thank you for your ideas.
#Gilles: In my current default Tuareg mode, I get such indenting, which is diffrent from yours
let f =
let g = 3 in
let h = 4 in
g + 2
could you explain which configuration should I do to make my Tuareg mode indent as yours?
The official caml-mode (part of the standard Ocaml distribution) defaults to not intenting the body of a let expression:
let f =
let g = 3 in
let h = 4 in
g + 2
This is the style used by the authors of Ocaml (hence the Right style). In my experience the official mode matches the official style very well (unsurprising since it's from the same people). If you're getting something different, you (or the person or distribution who installed the mode on your machine) must have configured it.
Tuareg mode puts the same indentation on the snippet above on my machine (Debian squeeze). Different versions have different indentation defaults; in particular, this is the docstring for tuareg-in-indent on 2.0.1:
How many spaces to indent from a in keyword.
Upstream recommends 0, and this is what we default to since 2.0.1 instead of the historical tuareg-default-indent.
I think Tuareg does have some strange behavior indenting nested let-in. add these lines to come back to "default" ocaml indenting style, suggested by
C. TROESTLER
(add-hook 'tuareg-mode-hook
(function (lambda ()
(setq tuareg-in-indent 0)
(setq tuareg-let-always-indent t)
(setq tuareg-let-indent tuareg-default-indent)
(setq tuareg-with-indent 0)
(setq tuareg-function-indent 0)
(setq tuareg-fun-indent 0)
(setq tuareg-parser-indent 0)
(setq tuareg-match-indent 0)
(setq tuareg-begin-indent tuareg-default-indent)
(setq tuareg-parse-indent tuareg-default-indent); .mll
(setq tuareg-rule-indent tuareg-default-indent)
(setq tuareg-font-lock-symbols nil)
)))