Skip to main content

Any ergonomic tools for the command line kernel?


Mathematica on the command-line (invoked by running 'wolfram' on bash shell) seems bereft of all modern usability features. I'd like a list of the best third-party packages available (if any exist) for command line work.



At a bare minimum, I'm looking for a way get a textual Monitor or ProgressIndicator to inspect non-instantaneous computation:


n = 1; Monitor[While[True, n++], n]

command line Mathematica


This trick from python of years ago might help: using the carriage return ('\r') character to return to the start of the line without advancing to the next line to achieve "dynamic" updates in the shell prompt:


for x in range(10):
print '{0}\r'.format(x),
print

Python



Perhaps something similar for Mathematica is possible?


Details:



  • I'm using Ubuntu 18 Linux MMA 11.3

  • I'd like to see an exhaustive list of symbols that require front end

  • In Python (or iPython) there are many ergonomic tools for the command line REPL like auto-completion or textual progress bars (tqmd):


Python



Answer



As I said in my comments, it is hard to implement this correctly if you aim for some advanced Dynamic features that work in the command line. However, you can surely use the carriage-return trick on the command line.



The only obstacle here is that Print puts everything on a new line. However, if you write directly to stdout, you don't have this problem. Consider the following small example:


progress[n_, max_] := WriteString["stdout", 
"\r[" <> StringJoin@Table["#", n] <>
StringJoin@Table[" ", max - n] <> "]"
]

n=0; While[n++<20, Pause[0.2];progress[n,20]]

enter image description here





Is there any way to make this sensitive to the terminals window size?



Hmm, it's difficult, because you would need feedback from your window how large it is. I don't see a way to do this from the top of my head.



Would be nice to show additional information! Like ETA, Time Taken Already, Percentage



One downside of using \r is that it doesn't delete the line and you have to ensure that your output is either of the same size or longer. Or you use another function to delete the line after an iteration.


Beside this obstacle, running time, ETA, or percentage can be implemented using a closure because you need to remember the starting time and other things.


An implementation for ETA could look like this



Module[{start = Missing, eta, iter = 0},
ETA[max_Integer] := Module[{},
If[start === Missing, start = AbsoluteTime[]];
iter++;
eta = (AbsoluteTime[] - start)/iter;
WriteString["stdout",
"\r" <> ToString[Round[max*eta - iter*eta]] <> " Seconds left"]
]
]


and is then used like this


n = 0; While[n++ < 100, ETA[100]; Pause[.1]] 

As you can see, on the first call it initializes the starting time and then, on each iteration, it updates the ETA.


An implementation for a sine-perculator can also be created but it requires that you have many, short iterations so that the display is updated often. However, I don't recommend something like this because it's hard to ensure that the progress display doesn't slow down your overall loop too much.


enter image description here


ProgressBar[] := With[{initTime = AbsoluteTime[]},
Function[
Module[{curr = AbsoluteTime[] - initTime, percolate},
percolate = Round[10*Cos[2*curr] + 10];

percolate = Append[ConstantArray[" ", percolate], "#"];
percolate =
StringJoin@
Join[percolate, ConstantArray[" ", 21 - Length[percolate]]];
Print[
TemplateApply[
"[`perc`] `time` Seconds",
<|
"perc" -> percolate,
"time" -> Round[curr, 0.1]

|>
]
]
]
]
]

pbar=ProgressBar[]; n=0; While[n++<12^4, pbar[]]

Comments

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

What is and isn't a valid variable specification for Manipulate?

I have an expression whose terms have arguments (representing subscripts), like this: myExpr = A[0] + V[1,T] I would like to put it inside a Manipulate to see its value as I move around the parameters. (The goal is eventually to plot it wrt one of the variables inside.) However, Mathematica complains when I set V[1,T] as a manipulated variable: Manipulate[Evaluate[myExpr], {A[0], 0, 1}, {V[1, T], 0, 1}] (*Manipulate::vsform: Manipulate argument {V[1,T],0,1} does not have the correct form for a variable specification. >> *) As a workaround, if I get rid of the symbol T inside the argument, it works fine: Manipulate[ Evaluate[myExpr /. T -> 15], {A[0], 0, 1}, {V[1, 15], 0, 1}] Why this behavior? Can anyone point me to the documentation that says what counts as a valid variable? And is there a way to get Manpiulate to accept an expression with a symbolic argument as a variable? Investigations I've done so far: I tried using variableQ from this answer , but it says V[1...