In Julia, how do I display the contents of a macro? - macros

For example, I want to see what's "inside" of the #time macro. How would I do this?

While it doesn't show you the macro itself, you can see the results of the macro expansion with macroexpand. For example:
julia> macroexpand(:(#time rand(10)))
:(begin # util.jl, line 38:
local #60#b0 = Base.gc_bytes() # line 39:
local #61#t0 = Base.time_ns() # line 40:
local #62#val = rand(10) # line 41:
local #63#t1 = Base.time_ns() # line 42:
local #64#b1 = Base.gc_bytes() # line 43:
Base.println("elapsed time: ",Base./(Base.-(#63#t1,#61#t0),1.0e9)," seconds (",Base.-(#64#b1,#60#b0)," bytes allocated)") # line 44:
#62#val
end)
In this case, it also shows you where it is defined (util.jl, line 38), but that doesn't always happen. Since macros aren't first class objects themselves, the utilities such as which/edit/less (or their macro equivalents) don't work.

I don't think there's a built in way to do this, but you can search the codebase for "macro X".
This sounds like it would be a useful feature, so unless someone corrects me and it already exists, you could always open an issue requesting it.

At least since 0.5, you can #less macros too:
julia> #less #time x
will open up an editor, which shows the code
macro time(ex)
quote
local stats = gc_num()
local elapsedtime = time_ns()
local val = $(esc(ex))
elapsedtime = time_ns() - elapsedtime
local diff = GC_Diff(gc_num(), stats)
time_print(elapsedtime, diff.allocd, diff.total_time,
gc_alloc_count(diff))
val
end
end

Related

How to stop autofilter macro failing intermittently

I have a macro which is designed to autofilter for certain criteria and then hide certain columns and copy what is left to the appropriate file. Sometimes the file filters correctly, but sometimes it stops on the Selection.AutoFilter line with a RE 1004 error, "Method of range class failed". This usually happens if I run the macro immediately after opening the file. If I reset the entire sheet with a macro I have to unhide everything, it filters correctly.
If it does filter correctly, it omits certain columns when pasting to the destination file. Those columns are the first one right after a handful of blank ones. I need it to copy either all visible columns except the header, or can even be changed to columns A - X, as that is the extent of the information required.
Here is the macro
Sub OO_Away_Lay_1()
'
' OO Away Lay v1 Macro
' This macro will filter for 1x2
'
Dim ws As Worksheet, lc As Long, lr As Long
Set ws = ActiveSheet
'range from A1 to last column header and last row
lc = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
lr = ws.Cells.Find("*", after:=ws.Range("A1"), LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
With ws.Range("A1", ws.Cells(lr, lc))
.HorizontalAlignment = xlCenter
Selection.AutoFilter
.AutoFilter Field:=24, Criteria1:="Draw", Operator:=xlFilterValues
If .Rows.Count - 1 > 0 Then
On Error Resume Next
.Columns("L:S").EntireColumn.Hidden = True
.Columns("U:W").EntireColumn.Hidden = True
.Columns("Y:CK").EntireColumn.Hidden = True
.Offset(1, 0).Resize(.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Copy
On Error GoTo 0
Else
Exit Sub
End If
End With
Workbooks("Predictology_Trading Template v3.1.xlsm").Sheets("OO Away Lay v1") _
.Range("A" & Rows.Count).End(xlUp).Offset(1).PasteSpecial xlPasteValues
Application.CutCopyMode = False
End Sub
Any thoughts on fixing it so it autofilters all the time and also copies all of the required data?
cheers

Having trouble conditionally moving files based on their names

I am trying to write a script that will auto sort files based on the 7th and 8th digit in their name. I get the following error: "Argument must be a string scalar or character vector". Error is coming from line 16:
Argument must be a string scalar or character vector.
Error in sort_files (line 16)
movefile (filelist(i), DirOut)
Here's the code:
DirIn = 'C:\Folder\Experiment' %set incoming directory
DirOut = 'C:\Folder\Experiment\1'
eval(['filelist=dir(''' DirIn '/*.wav'')']) %get file list
for i = 1:length(filelist);
Filename = filelist(i).name
name = strsplit(Filename, '_');
newStr = extractBetween(name,7,8);
if strcmp(newStr,'01')
movefile (filelist(i), DirOut)
end
end
Also, I am trying to make the file folder conditional so that if the 10-11 digits are 02 the file goes to DirOut/02 etc.
First, try avoid using the eval function, it is pretty much dreaded as slow and hard to understand. Specially if you need to create variables. Instead do this:
filelist = dir(fullfile(DirIn,'*.wav'));
Second, the passage:
name = strsplit(Filename, '_');
Makes name a list, so you can access name{1} or possibly name{2}. Each of these are strings. But name isn't a string, it is a list. extractBetween requires a string as an input. That is why you are getting this problem. But note that you could have simply done:
newStr = name(7:8);
If name was a string, which in Matlab is a char array.
EDIT:
Since it has been now claimed that the error occurs on movefile (filelist(i), DirOut), the likely cause is because filelist(i) is a struct. Wheres a filena name (char array) should have been given at input. The solution should be replacing this line with:
movefile(fullfile(filelist(i).folder, filelist(i).name), DirOut)
Now, if you want to number the output folders too, you can do this:
movefile(fullfile(filelist(i).folder, filelist(i).name), [DirOut,filesep,name(7:8)])
This will move a file to /DirOut/01. If you wanted /DirOut/1, you could do this:
movefile(fullfile(filelist(i).folder, filelist(i).name), [DirOut,filesep,int2str(str2num(name(7:8)))])

Printing a warning message over multiple lines

I am trying to print a warning message that is a little long and includes 2 variable calls. Here's my code:
warning( 'MATLAB:questionable_argument', ...
'the arguments dt (%d) and h (%d) are sub-optimal. Consider increasing nt or decreasing nx.', ...
dt, h )
Obviously, the line of text extends to the right when viewing the MATLAB code. How can I break it so it wraps nicely? I've tried multiple things but keep getting syntax errors.
As suggested in comments, just insert a \n where you want to break the line. You can also use a variable for the text, to make it easy to read also within the code:
txt = sprintf(['the arguments dt (%d) and h (%d) are sub-optimal.\n'...
'Consider increasing nt or decreasing nx.'],dt,h);
warning( 'MATLAB:questionable_argument',txt)
If you just embed escape characters such as \n in a warning string, it will not work:
warning('Hi there.\nPlease do not do that.')
will just print out:
Warning: hi there.\nPlease do not do that
However, if you pre-format the text using sprintf , then all the escape characters will work. For instance:
warnText = sprintf('Hi there.\nPlease do not do that.');
warning(warnText)
Produces what you want:
Warning: Hi there.
Please do not do that.
A more simple version than EBH had provided is as shown:
str1 = 'text 1';
str2 = 'text 2';
str3 = 'etc.';
str = sprintf('\n%s \n%s \n%s \n',str1,str2,str3);
warning(str)

Why is $ split valid syntax? [duplicate]

I just discovered that perl ignores space between the sigil and its variable name and was wondering if someone could tell me if this was the expected behaviour. I've never run into this before and it can result in strange behaviour inside of strings.
For example, in the following code, $bar will end up with the value 'foo':
my $foo = 'foo';
my $bar = "$ foo";
This also works with variable declarations:
my $
bar = "foo\n";
print $bar;
The second case doesn't really matter much to me but in the case of string interpolation this can lead to very confusing behaviour. Anyone know anything about this?
Yes, it is part of the language. No, you should not use it for serious code. As for being confusing in interpolation, all dollar signs (that are not part of a variable) should be escaped, not just the ones next to letters, so it shouldn't be a problem.
I do not know if this is the real reason behind allowing whitespace in between the sigil and the variable name, but it allows you to do things like
my $ count = 0;
my $file_handle_foo = IO::File->new;
which might be seen by some people as handy (since it puts the sigils and the unique parts of the variable names next to each other). It is also useful for Obfu (see the end of line 9 and beginning of line 10):
#!/usr/bin/perl -w # camel code
use strict;
$_='ev
al("seek\040D
ATA,0, 0;");foreach(1..3)
{<DATA>;}my #camel1hump;my$camel;
my$Camel ;while( <DATA>){$_=sprintf("%-6
9s",$_);my#dromedary 1=split(//);if(defined($
_=<DATA>)){#camel1hum p=split(//);}while(#dromeda
ry1){my$camel1hump=0 ;my$CAMEL=3;if(defined($_=shif
t(#dromedary1 ))&&/\S/){$camel1hump+=1<<$CAMEL;}
$CAMEL--;if(d efined($_=shift(#dromedary1))&&/\S/){
$camel1hump+=1 <<$CAMEL;}$CAMEL--;if(defined($_=shift(
#camel1hump))&&/\S/){$camel1hump+=1<<$CAMEL;}$CAMEL--;if(
defined($_=shift(#camel1hump))&&/\S/){$camel1hump+=1<<$CAME
L;;}$camel.=(split(//,"\040..m`{/J\047\134}L^7FX"))[$camel1h
ump];}$camel.="\n";}#camel1hump=split(/\n/,$camel);foreach(#
camel1hump){chomp;$Camel=$_;y/LJF7\173\175`\047/\061\062\063\
064\065\066\067\070/;y/12345678/JL7F\175\173\047`/;$_=reverse;
print"$_\040$Camel\n";}foreach(#camel1hump){chomp;$Camel=$_;y
/LJF7\173\175`\047/12345678/;y/12345678/JL7F\175\173\0 47`/;
$_=reverse;print"\040$_$Camel\n";}';;s/\s*//g;;eval; eval
("seek\040DATA,0,0;");undef$/;$_=<DATA>;s/\s*//g;( );;s
;^.*_;;;map{eval"print\"$_\"";}/.{4}/g; __DATA__ \124
\1 50\145\040\165\163\145\040\157\1 46\040\1 41\0
40\143\141 \155\145\1 54\040\1 51\155\ 141
\147\145\0 40\151\156 \040\141 \163\16 3\
157\143\ 151\141\16 4\151\1 57\156
\040\167 \151\164\1 50\040\ 120\1
45\162\ 154\040\15 1\163\ 040\14
1\040\1 64\162\1 41\144 \145\
155\14 1\162\ 153\04 0\157
\146\ 040\11 7\047\ 122\1
45\15 1\154\1 54\171 \040
\046\ 012\101\16 3\16
3\15 7\143\15 1\14
1\16 4\145\163 \054
\040 \111\156\14 3\056
\040\ 125\163\145\14 4\040\
167\1 51\164\1 50\0 40\160\
145\162 \155\151
\163\163 \151\1
57\156\056

embed a number and extension in a variable file name

I want to save data to files that have consecutive numbers in these file names within a for-loop.
first I have a function "SetConfeguration.m" in which I specifie the input directory and the file name as fields in a structure as below
StrConf.InputDirectory = 'C:/ElastixMatlab/elx_input';
StrConf.ParameterFilename = 'parameter.%d.txt';
the structure "StrConf" will be used as a parameter in the main function as below
ParameterFilename = fullfile(Conf.InputDirectory, Conf.ParameterFilename);
for Cpt = 1:NbParameterFiles
TmpParameterFilename = sprintf(ParameterFilename, Cpt - 1);
disp('ParameterFilename: '); disp(ParameterFilename);
end
I have the following error:
Warning: Invalid escape sequence appears in format string. See help sprintf for
valid escape sequences.
> In elxElastix at 153
In elxExampleStreet at 93
ParameterFilename :
C:\ElastixMatlab\elx_input\parameter.%d.txt
TmpParameterFilename :
C:
I think you forgot to call the structure StrConf to access the parameters
TmpParameterFilename = sprintf(StrConf.ParameterFilename, Cpt - 1);
disp('ParameterFilename: '); disp(StrConf.ParameterFilename);
Also, i suggest you to make a little change in the for loop, since it loops from 0 to n-1.
ParameterFilename = fullfile(Conf.InputDirectory, Conf.ParameterFilename);
for Cpt = 0:NbParameterFiles-1
TmpParameterFilename = sprintf(StrConf.ParameterFilename, Cpt);
disp('ParameterFilename: '); disp(StrConf.ParameterFilename);
end
This way you save an operation in every iteration, since you don't make the substraction of Cpt - 1, making your code a little bit more efficient.
You need to use sprintf before fullfile. The problem is that fullfile is normalizing your path separator from / used in your code, to \ which is the standard on Windows. But \ is also used for escape sequences which sprintf recognizes.
This will work better:
for Cpt = 1:NbParameterFiles
TmpParameterFilename = fullfile(Conf.InputDirectory, ...
sprintf(StrConf.ParameterFilename, Cpt - 1));
disp('ParameterFilename: '); TmpParameterFilename;
end
I think you want
TmpParamterFilename = sprinf('%s%d.txt',ParameterFilename, Cpt-1);
And then ParameterFilename wouldn't have .txt at the end.