This is a Julia related question. But to give some context, I'm not the best programmer, so my python workflow is to write some half complete code in a function, then debug the code in pycharm and use the interactive debug console to help me figure out how to complete the function. For example
def cartesian_product():
a = ['1', '2', '3']
b = ['a', 'b', 'c', 'd']
# I want to compute the cartesian product of two lists but I don't quite know how
# it's done so I google a bit attach the debugger here and explore the various
# approaches eventually settling with the itertools.product() approach.
return list(itertools.product(a, b))
Now I was wondering if there is a similar approach possible in Julia using visual studio code?
When I create my semi complete julia function
function cartesian_product()
a = ['1', '2', '3']
b = ['a', 'b', 'c', 'd']
# attach debugger here and try figure out the rest using the vs code interactive
# debugger
end
The problem with this approach is that I can't create new variables in the debug console. Possibly because julia is a compiled language?
For example if I set a breakpoint at the b statement, the variable a has loaded in memory but b has not. So in the debug console I define b just like in the python debug console. But now when I try to referrence b I get an UndefVarError: b not define
So my question is if this type of workflow is not possible (that is figure things out in the debug console), what are the alternatives?
I've tried these approaches:
Write code in .jl files. Then run them in the REPL - but this kind of get's messy when you have lot's of custom modules and functions (setup code) that run before the point of the code you are interested in.
Had a quick look at revise but I don't think it quite does what I want.
Do I just have to suck it up and adopt a different approach to programming?
If you want to experiment or code something up quickly in an interactive environment, you may want to use the Julia REPL as your debug console, especially if you have time to learn some of its more advanced features.
But if your code already spans several modules, it should already have its own .jl file, if not its own package. If the code you're actively working on depends on those modules and functions, there's no getting around that, but you can supress output to make it less messy.
You could try using Debugger than you can use #enter macro:
julia> #enter cartesian_product()
In cartesian_product() at REPL[2]:1
1 function cartesian_product()
>2 a = ['1', '2', '3']
3 b = ['a', 'b', 'c', 'd']
4
5 # attach debugger here and try figure out the rest using the vs code interactive
6 # debugger
7 end
About to run: (Base.vect)('1', '2', '3')
1|debug>
With this tool you can interact with running code and in particular manipulate the values of variables (to go to julia mode press apostrophe ``` and ENTER). See this sample session:
julia> function printc()
c=5
println(c)
end
printc (generic function with 1 method)
julia> #enter printc()
In printc() at REPL[5]:1
1 function printc()
2 c=5
>3 println(c)
4 end
About to run: (println)(5)
1|julia> c=17
17
1|debug> n
17
In printc() at REPL[5]:1
1 function printc()
2 c=5
>3 println(c)
4 end
About to run: return
1|debug>
You can see that the c variable was mutated.
The full set of options is described at https://github.com/JuliaDebug/Debugger.jl.
Another good route is to use Visual Studio Code and breakpoints as described in https://www.julia-vscode.org/docs/stable/userguide/debugging/
In IDE debugger you can change variable values in the runtime - just double click the variable when being stopped on a breakpoint:
Related
I think Julia is a great Language, but I find that there is a total lack of any error detection in VsCode.
Look at this code example:
I would expect that red squiggly lines show up in these places:
StructABCNotDefined is not a valid type
|> operator not defined for Integers
Should not be able to call fun with a String as an argument
fun does not return something of type StructABCNotDefined
Without proper type checking working it's a total mess like python only that it runs a bit faster. What am I doing wrong? Is it possible to setup VsCode to have these type checking abilities for Julia?
The Julia VSCode extension highlights at least some of your issues.
Note that linting is only active when the Julia file is inside a workspace (see https://github.com/julia-vscode/julia-vscode/issues/1105).
With JET.jl more issues can be identified:
julia> #report_call fun(5)
═════ 2 possible errors found ═════
┌ # c:\Users\d90394\Downloads\Untitled-1.jl:2 NonExistingStruct
│ `Main.NonExistingStruct` is not defined
└─────────────────────────────────────────────
┌ # c:\Users\d90394\Downloads\Untitled-1.jl:2 n |> 2
│┌ # operators.jl:911 f(x)
││ no matching method found `(::Int64)(::Int64)`: f::Int64(x::Int64)
│└────────────────────
Environment: Linux CentOS 7 #HPC
Interface: command interface, no GUI
My PERL scripts have a logic error. It does not go through in a "foreach" loop. I use debugger command below:
perl -d /scripts_location/perlscripts.pl
However, it is run step by step. My scripts have almost thousand lines. Here is my questions:
How to debug my scripts from specific line?
How to figure out the loop cannot be run? And why the loop cannot be run?
Is there any resource to show debugger skills in a whole process?
I searched online. Most of them explain the commands. But few introduce the debug from the very beginning. I mean that first a simple program is given, set breakpoint or other label in the program, check output or trace error, and so on. After viewing websites, I am unable to know how to start debugging using PERL debugger. I used to debugging my program using output at specific lines to check the output is correct or not. However, current logic error cannot be figured out in this way.
Any further suggestion and help would be highly appreciated.
After starting the debugger, you can tell it to continue until it reaches a given line, e.g.
c 124
To figure out why a foreach loop isn't entered, check the loop's list before entering it. You can tell the debugger to evaluate the expression like this:
x #values
if the loop is something like foreach my $value (#values). It will probably tell you
empty array
To discover why the array is emtpy, you can try to "watch" the array
w #values
and then run the script with r. It will stop once any watched value changes.
Use h to view the help.
I'm new to scripting Minitab 17 and have run into a snag that I can't find any documentation for, including an error message that brings up no hits on Google. All I want to do is generate macros that perform simple nonlinear regressions automatically, all of which execute just fine in the GUI or through Session Commmands. If I follow the directions on p. 10 of the Minitab Macros documentation and copy the commands I've successfully run from the
Project Manager/History folder, copy them into a .MAC file and surround them with GMACRO and ENDMACRO commands, I end up with the code below:
GMACRO
NLinear;
Response 'MyColumn1';
Continuous 'MyOtherColumn2';
Parameter "Theta1" 0.5;
Parameter "Theta2" 0.2;
Expectation Theta1 * ln (MyOtherColumn2 - Theta2 );
NoDefault;
TMethod;
TStarting;
TConstraints;
TEquation;
TParameters;
TSummary;
TPredictions.
ENDMACRO
The code between the MACRO statements runs OK from the GUI or as a Session Command. When I run the resulting macro file from the session prompt in Minitab, however, I invariably receive the following error: "Arguments not allowed in all global macro mode." I also receive syntax errors for every column that includes quote marks, even though that is standard session window syntax; I can eliminate these by substituting the column heading from my open worksheet, such as "C1", but can't get past the other error.
I'm obviously using some kind of incorrect syntax element(s) but can't pin them down - does anyone have any ideas? There are plenty of instructional materials on Minitab macros on the Web, but I haven't yet encountered any that deal with either this particular error or that delve much into how to execute ordinary Minitab tests of this kind. My goal is merely to write batch files that will do all my nonlinear regressions on off-hours etc. Thanks in advance.
Re-read pages 10-11 of http://support.minitab.com/en-us/minitab/18/macros-help/#page10.
The line after GMACRO should be the name of the macro, not a command.
Also, note that in a global macro the column names in 'single quotes' must exist in the active worksheet.
the better way to learn Minitab macro is to do the job by the menu and then to go to the SESSION WINDOW and to look at how Minitab uses the function.
Do your Nonlinear Regression with your data and then in the SESSION WINDOW (first icon of the Project Manager bar) you will see the code. After that it is more easy to do macro.
In this case I think about an issue I had sometimes: I don't know why but sometimes I had to switch the regional setting ('.' instead of ',' for numeric values) or to write ',' instead of ';' in the macro.
You can try this.
I have a rather bulky program that I've been running as a script from the MATLAB command line. I decided to clean it up a bit with some nested functions (I need to keep everything in one file), but in order for that to work it required me to also make the program itself a function. As a result, the program no longer runs in the base workspace like it did when it was a script. This means I no longer have access to the dozens of useful variables that used to remain after the program runs, which are important for extra calculations and information about the run.
The suggested workarounds I can find are to use assignin, evalin, define the variables as global, or set the output in the definition of the now function-ized program. None of these solutions appeal to me, however, and I would really like to find a way to force the workspace itself to base. Does any such workaround exist? Or is there any other way to do this that doesn't require me to manually define or label each specific variable I want to get out of the function?
Functions should define clearly input and output variables. Organizing the code differently will be much more difficult to understand and to modify later on. In the end, it will most likely cost you more time to work with an unorthodox style than investing in some restructuring.
If you have a huge number of output variables, I would suggest organizing them in structure arrays, which might be easy to handle as output variables.
The only untidy workaround I can imagine would use whos, assignin and eval:
function your_function()
x = 'hello' ;
y = 'world' ;
variables = whos ;
for k=1:length(variables)
assignin('base',variables(k).name,eval(variables(k).name))
end
end
But I doubt that this will help with the aim to clean up your program. As mentioned above I suggest ordering things manually in structures:
function out = your_function()
x = 'hello' ;
y = 'world' ;
out.x = x ;
out.y = y ;
end
If the function you would like to define are simple and have a single output, one option is to use anonymous functions.
Another option is to store all the variable you would like to use afterwards in a struct and have your big function return this struct as an output.
function AllVariables = GlobalFunction(varargin);
% bunch of stuff
AllVariables= struct('Variable1', Variable1, 'Variable2', Variable2, …);
end
How to call a function with simple inputs in several MATLAB sessions automatically?
The manual way to do it would be:
Open three sessions
Call magic(t) where t is 1, 2 or 3 respectively
So, my question is: How can I do this all programatically?
In case it is relevant, I do not want to use the parallel processing toolbox.
Note that I don't think a parfor loop can do what I want. First of all that would require the parallel processing toolbox, and secondly I want to be able to debug as soon as one of these operations fails, without bothering the other sessions.
First of all a way must be found to open sessions programatically.
Based on this and this it is found you can do it as follows (works on windows as well):
% Opening 3 matlab sessions
for t = 1:3
!matlab &
end
Besides simply opening them, a simple command can also be given
!matlab -r "magic(5)" &
Now, to finally combine this just a small trick remains:
for t = 1:3
str = ['!matlab -r "magic(' num2str(t) ')" &'];
eval(str)
end
Note that if you want to use more complicated inputs you can simply save them in a struct and call them with this index by using a wrapper script as called function.
You could try Multicore, which uses several instances of Matlab to do what parfor does by passing information via a common directory. If you can rewrite your code loop to call a function that returns values then Multicore might do what you are looking for.
http://www.mathworks.com/matlabcentral/fileexchange/13775-multicore-parallel-processing-on-multiple-cores