Tips on optimizing this code that loads multiple files in Matlab? - matlab

fname = dir('*sir');
dayH = zeros(length(fname),1360,3600);
for i=1:length(fname)
dayH(i,:,:) = loadsir(fname(i).name);
end
fname = dir('*sir');
dayH = cell(1,length(fname));
for i=1:2
dayH{i} = loadsir(fname(i).name);
end
Basically it loads all my files. I have a separate .m file called loadsir that loads those specialized files. The output of the .sir files will be an array 1360x3600.
Right now that code is crashing saying, "Cannot display summaries of variables with more than 524288 elements." I guess it's because 1360X3600 = 5,000,000 about?

Putting Serg's comment as an answer:
Most likely you missed a semicolon (;) somewhere in loadsir. Matlab then thinks you want to print the output, which it won't do due to the large number of elements.
Additionally, to prevent such things from happening in the future:
Matlab is an interpreted language, meaning, no compilation is necessary. Any and all code can be parsed while you type it, which allows for things like auto-correct. Of course, this sort of thing is included already in standard Matlab. If you don't already, code in Matlab's own editor every now and then. It warns you of such silly mistakes/errors (and a lot more), including but not limited to, via the right vertical bar in the editor. The little square at the top right of the window should always be green. If it's orange or red, there's things to be improved or corrected, respectively.
The right vertical bar is an overview of all the lines in your file that leave room for improvement. If a small orange/red bar appears somewhere, a mouseover will tell you what's wrong with what line. Clicking it will navigate the editor to the line, which will likely be wavy-underlined in either orange or red. Mouse-over the line often gives useful suggestions, and <alt>+<enter> is often enough to fix the simple mistakes. I find it an indispensable tool when developing larger applications in Matlab.
You can of course configure which errors/warnings this tool ("code analyzer", formerly "mlint") displays. Sometimes, there will be a warning about an inefficiency that you simply cannot work around. Add an OK-directive behind the line to suppress it (%#ok), but don't make a habit of suppressing anything and everything "annoying" because that will of course completely beat the purpose of the code analyzer :)

Related

Can I give "static" input on VSCode?

My college has a proprietary IDE for C programming. It is very simple: Half the screen for the code, and the other half has the input and output (as you can see here).
The input works in a way you only have to type it once, and the program will read each line on every scanf there is. I find this a convenient way of testing, instead of giving the input every time I compile the program, and I'm wondering if there's any way to do something similar on VSCode.

How to display static analysis warnings in MATLAB?

I've noticed the MATLAB editor will often show quite helpful warnings for ".m" files. As I tend to run my MATLAB code remotely I prefer not to use the MATLAB editor, instead keeping open a long running emacs session. It would be great if these warnings could be printed out when running a script, perhaps if some setting was enabled (I could imagine not wanting to do that by default for performance). Is this possible?
I believe you're looking for checkcode. From the documentation:
checkcode(filename) displays messages about filename that report potential problems and opportunities for code improvement. These messages are sometimes referred to as Code Analyzer messages. The line number in the message is a hyperlink that you can click to go directly to that line in the Editor. The exact text of the checkcode messages is subject to some change between versions.
...
info = checkcode(___,'-struct') returns the information as an n-by-1 structure array, where n is the number of messages found.

Clear part of an IPython cell's output

Before I get reamed for this, I know there are some posts detailing how to clear ALL the output from a cell, but I'm interested in only clearing part of it.
Let me provide some background. I am creating a word-guessing game like LINGO where the user is prompted to guess a five-letter word, then using CSS to provide some visual feedback as to which letters are in the correct position, and which letters are in the word but in the wrong position. The way my program is structured, it displays the feedback after each guess and then prompts the user again and displays the guess. So something like this:
Guess a word: word
FEEDBACK
guess again: word
FEEDBACK
...
You get the picture. My goal is to come as close to duplicating LINGO as possible, which would mean removing the user input from the screen after it has been submitted and having it show a sequence of feedback. This to me means one of three things:
1) Find a way to clear part of the output
2) Find a way to prompt the user for text input without displaying it on the screen
3) Cache the user input, delete the all the output after each iteration, and display the cached guesses.
I've researched 1 and 2 and haven't been able to find anything. 3 would be a PITA so before I went to the trouble I thought I would ask.
1 think is either not possible or very difficult - it's hard in regular python, never mind Jupyter. In regular python, you'd probably use something like curses but I tried it in Jupyter and it affects the console Jupyter is running from - not the stdout in the notebook.
If you really wanted 2, you could probably write your own version of input that uses carriage return \r after stripping the trailing newline via writing a function that loops listening for keystrokes and submitting once a newline is pressed. The carriage return should mean that the next line overwrites the previous line.
3 Caching the input shouldn't be too difficult though I presume? Just store them in an array or something then you can display them back to the user after using IPython.display.clear_output.

Can the MATLAB editor show the file from which text is displayed? [duplicate]

In MATLAB, how do you tell where in the code a variable is getting output?
I have about 10K lines of MATLAB code with about 4 people working on it. Somewhere, someone has dumped a variable in a MATLAB script in the typical way:
foo
Unfortunately, I do not know what variable is getting output. And the output is cluttering out other more important outputs.
Any ideas?
p.s. Anyone ever try overwriting Standard.out? Since MATLAB and Java integration is so tight, would that work? A trick I've used in Java when faced with this problem is to replace Standard.out with my own version.
Ooh, I hate this too. I wish Matlab had a "dbstop if display" to stop on exactly this.
The mlint traversal from weiyin is a good idea. Mlint can't see dynamic code, though, such as arguments to eval() or string-valued figure handle callbacks. I've run in to output like this in callbacks like this, where update_table() returns something in some conditions.
uicontrol('Style','pushbutton', 'Callback','update_table')
You can "duck-punch" a method in to built-in types to give you a hook for dbstop. In a directory on your Matlab path, create a new directory named "#double", and make a #double/display.m file like this.
function display(varargin)
builtin('display', varargin{:});
Then you can do
dbstop in double/display at 2
and run your code. Now you'll be dropped in to the debugger whenever display is implicitly called by the omitted semicolon, including from dynamic code. Doing it for #double seems to cover char and cells as well. If it's a different type being displayed, you may have to experiment.
You could probably override the built-in disp() the same way. I think this would be analagous to a custom replacement for Java's System.out stream.
Needless to say, adding methods to built-in types is nonstandard, unsupported, very error-prone, and something to be very wary of outside a debugging session.
This is a typical pattern that mLint will help you find:
So, look on the right hand side of the editor for the orange lines. This will help you find not only this optimization, but many, many more. Notice also that your variable name is highlighted.
If you have a line such as:
foo = 2
and there is no ";" on the end, then the output will be dumped to the screen with the variable name appearing first:
foo =
2
In this case, you should search the file for the string "foo =" and find the line missing a ";".
If you are seeing output with no variable name appearing, then the output is probably being dumped to the screen using either the DISP or FPRINTF function. Searching the file for "disp" or "fprintf" should help you find where the data is being displayed.
If you are seeing output with the variable name "ans" appearing, this is a case when a computation is being done, not being put in a variable, and is missing a ';' at the end of the line, such as:
size(foo)
In general, this is a bad practice for displaying what's going on in the code, since (as you have found out) it can be hard to find where these have been placed in a large piece of code. In this case, the easiest way to find the offending line is to use MLINT, as other answers have suggested.
I like the idea of "dbstop if display", however this is not a dbstop option that i know of.
If all else fails, there is still hope. Mlint is a good idea, but if there are many thousands of lines and many functions, then you may never find the offender. Worse, if this code has been sloppily written, there will be zillions of mlint flags that appear. How will you narrow it down?
A solution is to display your way there. I would overload the display function. Only temporarily, but this will work. If the output is being dumped to the command line as
ans =
stuff
or as
foo =
stuff
Then it has been written out with display. If it is coming out as just
stuff
then disp is the culprit. Why does it matter? Overload the offender. Create a new directory in some directory that is on top of your MATLAB search path, called #double (assuming that the output is a double variable. If it is character, then you will need an #char directory.) Do NOT put the #double directory itself on the MATLAB search path, just put it in some directory that is on your path.
Inside this directory, put a new m-file called disp.m or display.m, depending upon your determination of what has done the command line output. The contents of the m-file will be a call to the function builtin, which will allow you to then call the builtin version of disp or display on the input.
Now, set a debugging point inside the new function. Every time output is generated to the screen, this function will be called. If there are multiple events, you may need to use the debugger to allow processing to proceed until the offender has been trapped. Eventually, this process will trap the offensive line. Remember, you are in the debugger! Use the debugger to determine which function called disp, and where. You can step out of disp or display, or just look at the contents of dbstack to see what has happened.
When all is done and the problem repaired, delete this extra directory, and the disp/display function you put in it.
You could run mlint as a function and interpret the results.
>> I = mlint('filename','-struct');
>> isErrorMessage = arrayfun(#(S)strcmp(S.message,...
'Terminate statement with semicolon to suppress output (in functions).'),I);
>>I(isErrorMessage ).line
This will only find missing semicolons in that single file. So this would have to be run on a list of files (functions) that are called from some main function.
If you wanted to find calls to disp() or fprintf() you would need to read in the text of the file and use regular expresions to find the calls.
Note: If you are using a script instead of a function you will need to change the above message to read: 'Terminate statement with semicolon to suppress output (in scripts).'
Andrew Janke's overloading is a very useful tip
the only other thing is instead of using dbstop I find the following works better, for the simple reason that putting a stop in display.m will cause execution to pause, every time display.m is called, even if nothing is written.
This way, the stop will only be triggered when display is called to write a non null string, and you won't have to step through a potentially very large number of useless display calls
function display(varargin)
builtin('display', varargin{:});
if isempty(varargin{1})==0
keyboard
end
A foolproof way of locating such things is to iteratively step through the code in the debugger observing the output. This would proceed as follows:
Add a break point at the first line of the highest level script/function which produces the undesired output. Run the function/script.
step over the lines (not stepping in) until you see the undesired output.
When you find the line/function which produces the output, either fix it, if it's in this file, or open the subfunction/script which is producing the output. Remove the break point from the higher level function, and put a break point in the first line of the lower-level function. Repeat from step 1 until the line producing the output is located.
Although a pain, you will find the line relatively quickly this way unless you have huge functions/scripts, which is bad practice anyway. If the scripts are like this you could use a sort of partitioning approach to locate the line in the function in a similar manner. This would involve putting a break point at the start, then one half way though and noting which half of the function produces the output, then halving again and so on until the line is located.
I had this problem with much smaller code and it's a bugger, so even though the OP found their solution, I'll post a small cheat I learned.
1) In the Matlab command prompt, turn on 'more'.
more on
2) Resize the prompt-y/terminal-y part of the window to a mere line of text in height.
3) Run the code. It will stop wherever it needed to print, as there isn't the space to print it ( more is blocking on a [space] or [down] press ).
4) Press [ctrl]-[C] to kill your program at the spot where it couldn't print.
5) Return your prompt-y area to normal size. Starting at the top of trace, click on the clickable bits in the red text. These are your potential culprits. (Of course, you may need to have pressed [down], etc, to pass parts where the code was actually intended to print things.)
You'll need to traverse all your m-files (probably using a recursive function, or unix('find -type f -iname *.m') ). Call mlint on each filename:
r = mlint(filename);
r will be a (possibly empty) structure with a message field. Look for the message that starts with "Terminate statement with semicolon to suppress output".

Why is it bad to put a space before a semicolon?

The perlstyle pod states
No space before the semicolon
and I can see no reason for that. I know that in English there should not be any space before characters made of 2 parts ( like '?',';','!' ), but I don't see why this should be a rule when writing Perl code.
I confess I personally use spaces before semicolons. My reason is that it makes the statement stands up a bit more clearer. I know it's not a very strong reason, but at least it's a reason.
print "Something\n with : some ; chars"; # good
print "Something\n with : some ; chars" ; # bad??
What's the reason for the second being bad?
From the first paragraph of the Description section:
Each programmer will, of course, have his or her own preferences in regards to formatting, but there are some general guidelines that will make your programs easier to read, understand, and maintain.
And from the third paragraph of the Description section:
Regarding aesthetics of code lay out, about the only thing Larry cares strongly about is that the closing curly bracket of a multi-line BLOCK should line up with the keyword that started the construct. Beyond that, he has other preferences that aren't so strong:
It's just a convention among Perl programmers for style. If you don't like it, you can choose to ignore it. I would compare it to Sun's Java Style guidelines or the suggestions for indenting in the K&R C book. Some environments have their own guidelines. These just happen to be the suggestions for Perl.
As Jon Skeet said in a deleted answer to this question:
If you're happy to be inconsistent with what some other people like, then just write in the most readable form for you. If you're likely to be sharing your code with others - and particularly if they'll be contributing code too - then it's worth trying to agree some consistent style.
This is only my opinion, but I also realize that people read code in different ways so "bad' is relative. If you are the only person who ever looks at your code, you can do whatever you like. However, having looked at a lot of Perl code, I've only seen a couple of people put spaces before statement separators.
When you are doing something that is very different from what the rest of the world is doing, the difference stands out to other people because their brain don't see it in the same way it. Conversely, doing things differently makes it harder for you to read other people's code for the same reason: you don't see the visual patterns you expect.
My standard is to avoid visual clutter, and that I should see islands of context. Anything that stands out draws attention, (as you say you want), but I don't need to draw attention to my statement separators because I usually only have one statement per line. Anything that I don't really need to see should fade into the visual background. I don't like semi-colons to stand out. To me, a semicolon is a minor issue, and I want to reduce the number of things my eyes see as distinct groups.
There are times where the punctuation is important, and I want those to stand out, and in that case the semicolon needs to get out of the way. I often do this with the conditional operator, for instance:
my $foo = $boolean ?
$some_long_value
:
$some_other_value
;
If you are a new coder, typing that damned statement separator might be a big pain in your life, but your pains will change over time. Later on, the style fad you choose to mitigate one pain becomes the pain. You'll get used to the syntax eventually. The better question might be, why don't they already stand out? If you're using a good programmer font that has heavier and bigger punctuation faces, you might have an easier time seeing them.
Even if you decide to do that in your code, I find it odd that people do it in their writing. I never really noticed it before Stackoverflow, but a lot of programmers here put spaces before most punctuation.
It's not a rule, it's one of Larry Wall's style preferences. Style preferences are about what help you and the others who will maintain your code visually absorb information quickly and accurately.
I agree with Larry in this case, and find the space before the semicolon ugly and disruptive to my reading process, but others such as yourself may find the exact opposite. I would, of course, prefer that you use the sort of style I like, but there aren't any laws on the books about it.
Yet.
Like others have said, this is a matter of style, not a hard and fast rule. For instance, I don't like four spaces for indentation. I am a real tab for block level indentation/spaces for lining things up sort of programmer, so I ignore that section of perlstyle.
I also require a reason for style. If you cannot clearly state why you prefer a given style then the rule is pointless. In this case the reason is fairly easy to see. Whitespace that is not required is used to call attention to something or make something easier to read. So, does a semicolon deserve extra attention? Every expression (barring control structures) will end with a semicolon, and most expressions fit on one line. So calling attention to the expected case seems to be a waste of a programmers time and attention. This is why most programmers indent a line that is a continuation of an expression to call attention to the fact that it didn't end on one line:
open my $fh, "<", $file
or die "could not open '$file': $!";
Now, the second reason we use whitespace is make something easier to read. Is
foo("bar") ;
easier to read than
foo("bar");
I would make the claim that is harder to read because it is calling my attention to the semicolon, and I, for the most part, don't care about semicolons if the file is formatted correctly. Sure Perl cares, and if I am missing one it will tell me about it.
Feel free to put a space. The important thing is that you be consistent; consistency allows you to more readily spot errors.
There's one interesting coding style that places , and ; at the beginning of the following line (after indentation). While that's not to my taste, it works so long as it is consistent.
Update: an example of that coding style (which I do not advocate):
; sub capture (&;*)
{ my $code = shift
; my $fh = shift || select
; local $output
; no strict 'refs'
; if ( my $to = tied *$fh )
{ my $tc = ref $to
; bless $to, __PACKAGE__
; &{$code}()
; bless $to, $tc
}
else
{ tie *$fh , __PACKAGE__
; &{$code}()
; untie *$fh
}
; \$output
}
A defense can be found here: http://perl.4pro.net/pcs.html.
(2011 Update: that page seems to have gone AWOL; a rescued copy can be seen here: http://ysth.info/pcs.html)
Well, it's style, not a rule. Style rules are by definition fairly arbitrary. As for why you shouldn't put spaces before semicolons, it's simply because that's The Way It's Done. Not just with Perl, but with C and all the other curlies-and-semicolons languages going back to C and newer C-influenced ones like C++, C#, Objective C, Javascript, Java, PHP, etc.
Because people don't expect it . It looks strange when you do it .
The reason I would cite is to be consistent within a project. I have been in a project where the majority of programmers would not insert the space but one programmer does. If he works on a defect he may routinely add the space in the lines of code he is examining as that is what he likes and there is nothing in the style guide to say otherwise.
The visual diff tools in use can't determine this so show a mass of line changes when only one may have changed and becomes difficult to review. (OK this could be an argument for a better diff tools but embedded work tends to restrict tool choice more).
Maybe a suitable guide for this would be to choose whichever format you want for you semicolon but don't change others unless you modify the statement itself.
I really don't like it. But it's 100% a personal decision and group convention you must make.
Code style is just a set of rules to make reading and maintaining code easier.
There is no real bad style, but some are more accepted than others. And they are of course the source for some "religious battles" (to call curly braces style ;-) ).
To make a real life comparison, we have trafic lights with red, yellow/orange and green. Despite the psychological effects of the colors, it is not wrong to use Purple, Brown and Pink, but just because we are all used to the colors there are less trafic accidents.