# Doug's MATLAB Video Tutorials

## Top 10 MATLAB code practices that make me cry

I was chatting with the Application Support Engineers here at MathWorks about what kind of coding practices cause avoidable pain for MATLAB users.

Without further ado: The top ten and quick ways to not do them:

10.) Not using left hand zeros

Certain things must be learned the hard way. I learned this one bleary eyed evening as an undergraduate. Well into the night working on a MATLAB homework assignment that would “take ten minutes, fifteen if you type slow.” (yes, Dr. P, 13 years later I still remember that one! -smile-)

It is really easy to mistake a .5 for a 5. That is why I always use a left hand zero like 0.5.

9.) Plotting enormous amounts of data

My computer monitor has 2.3 million pixels, total. If I try to plot datasets with huge amounts of data in them, they will very often just look like a blob and slow the machine down in the process.

There is very often a better visualization available. Here is an example of changing the visualization to make it clearer and less taxing on memory.

8.) GUIs with garish color schemes

In an effort to emphasize certain buttons on their GUI, people will change the colors of them. Very quickly they end up with several different colored buttons, a non-standard background color, extra big buttons, etc…

Sticking with the default colors is a good move. Most professionally produced software sticks with the defaults, it ends up looking better.

7.) Using ans, or any other MATLAB function as a variable name or function.

When you do this, MATLAB will call whichever one is higher on the path. Some strange behavior can occur when you redefine a function like that. Unfortunately, MATLAB does not catch you doing this for the most part.

I try to avoid using variables and function names that are common terms like, mean, filter, etc… If there is any doubt, use the which command to find out if a function exists of a given name.

6.) Not using white space to good effect in code.

Even though you can put several commands on one line if separated by a semicolon, these lines can often be hard to notice. Not putting blank lines between sections of code can also make it harder to read.

White space is free, use it to make your code look good.

Variable names are often the only commenting that gets added to people’s code. Meaningful variable names are a great opportunity to make the meaning of your code more clear and to some degree, self-documenting.

Avoid using variable names like temp, aaa, r247899921. These just do not convey as much information to people that have to read your code as flagPassedInspection, centroidX, fidCurrentFile.

4.) Hard coding data into the MATLAB code file

Some people like to put some of their variables directly into the MATLAB code. That makes sense for small variables (I will let you define what small means for you). For instance, I would feel fine putting a 3×3 matrix into my code. I would think twice about a 10×10, and I would start using one of our file readers for a 100 x 100.

The worst instance I ever saw of this was some MATLAB code where the .M file was 4 GIG (not a mistake) long. All but a small amount of that was data written out in ASCII. This makes your code hard to read, maintain and understand.

3.) Exceptionally long files

Even if not hard coding data into a MATLAB code file, it is easy to just add on “just a few more lines of code” until you have thousands of lines of code in a single script. This makes your code hard to understand.

I try to use the rule that I should be able to see an entire script or function in one screen. This is not entirely practical, so I will at least break the code into logical sections that do fit on screen all at once.

2.) Globals

I have never seen MATLAB code where globals were the right thing to do. Exception: functions TIC and TOC use them quite nicely. Most of the time I have seen globals being used it was a situation where the code author did not understand scoping of variables. Rather than pass variables from one function to another, they were just being made global.

Why are people cautioned against using global variables? I will leave that to the consensus on Wikipedia.

1.) Eval

EVAL is right up there with globals. MATLAB user will often string together MATLAB commands to get sequential variable names s1, s2, s3… only to then have to use another EVAL statement to work with the sequential variable names! Very often, a cell array indexed with s{1}, s{2}, s{3}… would work much better.

I will also find that people use EVAL to get at certain fields in a structure (for example data.alpha) when they do not know at the time of writing the code what field they will want. Now the “.parens” notation makes that easier.

The other most common place to see people use EVAL when it is not needed is when they are trying to load a file or some other function like that. Very often they are trying to EVAL a string like “load filename.mat” not realizing that there is a functionsl form where you can use fileNameString = ‘filename.mat’; load(fileNameString)

### 59 Responses to “Top 10 MATLAB code practices that make me cry”

1. matt fig replied on :

Given some of your previous writings, I am surprised that you left out premature and/or unnecessary optimization. You know, where a person spends 3 hours to vectorize a code that is intended to only run once or twice at 2 seconds per shot. Number 11?

2. dhull replied on :

@Matt,

There was that and eight others that did not make the list. Premature optimization is often indistinguishable from just hard to read code! I don’t always recognize it as an optimization! :)

I was hoping to hear from people to see what theirs were. Top 19 did just not have the same ring to it! I guess if I think of one more, I can have the “top ten that make me cringe (instead of cry)” :)

3. Ryan Gray replied on :

6. Whitespace – YES! So much code I see seems to be from when a blank line meant a blank (wasted) card, spaces in the line meant your code took more cards to print, and more cards were a burden to carry and keep ordered. For a younger generation, it seems to be from when you only had 80×25 character screens, and whitespace meant you couldn’t see much code at once. Let go of the old habits because you don’t have those constraints. Let your code breathe, and be amazed at how many errors you can spot now.

4. Ryan Gray replied on :

5. Bad variable names – I often see bad variable names with copious accompanying comments that are having to explain what each variable’s purpose is.

5. Ryan Gray replied on :

One common thread to many of these things is feature discovery. It’s natural that you start to learn a new language’s basic parts. With that small kernel you can usually cobble together anything you need to do, given enough time and dwelling on doing it rather than taking a time to see if there’s another way to do it, knowing it will save you time over-and-over later rather than now.

MATLAB’s active M-Lint in the editor helps with some discovery. Good examples and cross-referencing in the documentation also help.

6. Matt Whitaker replied on :

Great Topic:
My personal peeves:
1) People who ignore mlint messages. Repeat after me : mlint is your friend, mlint is your friend.

2) Untidy code and crummy variable names: a simple ctrl-A, ctrl-I will clean up 99% of the code that gets messy as you edit. And for the love of all that is holy do not give me variable names that start with ‘my’ anything.

3) Hard coding just about any non-trivial data (and some seemingly trivial) in the code will bite you down the line.

7. Oleg replied on :

Using i and j in a loop: for i = 1:10; disp(i); end.

8. Petter replied on :

Using i in a loop is fine to me. I would say the opposite: always use the notation “1+1i” when writing complex numbers.

9. Jayveer Thakoor replied on :

i disagree with not using globals. Global variables are very practical when you have large data sets that are being modified within a function. The moment you change a variable inside a function, matlab makes a copy which implies using a lot more memory. that’s a big problem when you have 800MB sized variables! In such cases, global is extremely convenient – preallocate and update the same one all the time using logical indexing. Far more memory efficient, wouldn’t you agree?

10. dhull replied on :

@Jayveer,

That is an excellent point. That is one of the good uses of globals. I have heard of people using them that way, but I have never seen it!

I think it is one of those situations where 99% of all global variables give the other 1% a bad name!

Doug

11. StephenLL replied on :

Just an fyi…

Rather then use globals I created a handle class with dynamic properties.

This way you can pass the class around of big variables.

classdef dynoclss < dynamicprops

end

Then you can do this:

x = dynoclss;
x.foo=rand(1e7,1);

pass x to your functions and go crazy.

Stephen

12. Petros Mpogiatzis replied on :

I needed to store the arrival times of wavefronts and I used variable (2D array) with the name “times”. Well, in Matlab “times” is the name of a function for multiplication… I accidentally figured out the mistake

13. Doug replied on :

@Stephen

Nice!

@Petros

The reason all (except global) are on here is because I made ALL of these mistakes in the past. Experience is a great teacher!

Doug

14. Matt Whitaker replied on :

@Stephen
Very Nice! In the pre classdef days one trick I used was storing large common data in the root’s appdata.
bigData = rand(1e7,1);
setappdata(0,’CommonData’,bigData);

then when you need it
bigData = getappdata(0,’CommonData’);

Had to build some framework for managing it but all in all worked pretty well.

Matt

15. OysterEngineer replied on :

Matt Whitaker is correct. When a code module is complete, the M-Lint should be silent.

16. OysterEngineer replied on :

@Doug,

Many of these items are already covered in some of the various MatLab coding style guides. Maybe you could reference your favorite ones.

17. Ken Garrard replied on :

Nice list. I would add two items which are practices of omission, i.e., not doing the right thing.

11. Not validating function arguments and return values.

12. Inadequate comments, especially if the variable names are not descriptive (#5).

t1F = @(b,a) b+a;
t2F = @(b,a) asin(N1/N2*sin(t1F(b,a)));
t3F = @(b,a) t2F(b,a)-a;
t4F = @(b,a) asin(N2/N3*sin(t3F(b,a)));
y1F = @(x,y,b,a) y(1);
y2F = @(x,y,b,a) y1F(x,y,b,a) + (x(2)-x(1))*tan(b);
y3F = @(x,y,b,a) y2F(x,y,b,a) + (x(3)-x(2))*tan(t3F(b,a));
y4F = @(x,y,b,a) y3F(x,y,b,a) + (x(4)-x(3))*tan(t4F(b,a));


It was obvious what the function y4F did when I wrote this 3 years ago and isn’t too hard to figure out now. But why figure it out again? Perhaps nested anonymous function calls should be added to the list.

Also to two of eval’s cousins, str2num and feval, can be very useful and safe. I frequently use str2num, which of course calls eval in a try-catch block, to allow a user to enter parameters such as plot scaling factors as a expressions. Why make someone pull out a calculator when there’s a great big one (MATLAB) behind that GUI you wrote for them?

Ken

18. Doug replied on :

@ken

Eval’s cousins. Yes, they are safer. It is kind of like they are a lawnmower where EVAL is a lawnmower you pick up and use to trim your hedges!

http://www.snopes.com/legal/trimmer.asp

Doug

19. Doug replied on :

@Oyster,

I actually do not have any favorite MATLAB coding style guides. Do you?

Doug

20. Steve L replied on :

@Ken,

Nested anonymous functions aren’t a bad coding practice … as long as it’s clear why you’ve nested them and what each contributes. In your case, I would argue the problem occurs not in the nesting of the functions but in the names of the variables in which you store them.

Therefore I’d expand item 5 on the list — it’s not just bad _variable names_ that can cause problems, but bad _identifiers_, which includes things like variable names, function names, struct array field names, and even MAT-file (or other data file) names.

Will you remember what’s stored in mat123.mat six months from now?

How about what’s stored in financialDataQ1Y2010.mat?

21. Markus replied on :

Hi,

I don’t like the use of some relatively new features of Matlab:

1. The use of anonymous functions, see the list of Ken Gerrard for some horribly unreadable examples.

2. The use of nested functions, they are confusing regarding variable scope.

3. The use of functions like bsxfun without very detailed comments describing what happens. Too bad that the far better understandable for-loops are still soooo slow in Matlab…

Markus

22. Torsten Pietrek replied on :

There is also a use of classes for avoiding global constants: Use constant properties of classes. They are initialized at first time use of the class, so you can make them dependent on a config file, elaborate one time calculations etc. You can group the constants by meaningful class names, use the meta information in the class for validation purposes etc.

23. Luigi replied on :

I like this post,

Why don’t you open a wiki page dedicated to MATLAB, I guess the mathworks will find interesting things in there.

I agree with most of the things you wrote,

These are the things that cause a lot of pain to me:

- lack of MACROS, why not include #define operator like in c++ ?

- huge overhead time in function calls, especially nested ones.

- I would like to pass arrays to function as reference.

- globals: why not leaving a dedicated space in the header for globals? wouldn’t that be easier?

- can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me.

- the rotate command in figures is not arc-balled! it only rotates on the centroid. You can spend most of your time rotating the figure like a dog trying to bite his tail, no way to focus what you want to see.

- there is no built-in library for data structure like stl containers. This can be very painful when you need it.

- HELP MEMORY ERROR: in my opinion it occurs for too small arrays.

If I remember something else I will add it later

Luigi

24. Arthur replied on :

Regarding #7, the reuse of MATLAB-defined identifiers, the chief problem with this is that you can’t know what functions are defined by MATLAB. I may be working with bare MATLAB at one computer, while another computer may have Simulink and a whole slew of additional toolboxes. From the bare installation, I have no way to know what other functions are floating around out there without checking the website. Fortunately, MATLAB’s name resolution rules work in the programmer’s favor such that mystery functions you’ve never heard of in super-awesome-toolbox usually do not cause problems.

I’ve also had the misfortune of needing this behavior to suppress calls to “keyboard” in code I inherited for testing. Add that to the list of things that will make you cry — using keyboard() instead of assert() or error(). That really messes things up when trying to write automated tests.

The converse of #7 is that it is difficult to figure out what toolboxes a piece of code actually uses.

25. Benjamin Kraus replied on :

One of my personal annoyances is to see an m-file script with the following at the top:

close all; clear all;


This is especially bad when you send your code to other people, who may not realize that your script will wipe out anything they may currently be working on.

- Ben

26. Jason replied on :

I hate when people hard code inputs that are meant to be changed each time, especially file names! Why not just use inputdlg or input functions? They’re just as fast to code, especially if you’re not doing any error checking on the hard-coded file name anyway. I even see times where multiple lines contain the different file names and commenting and uncommenting occurs.

Quite often, the person goes through the trouble of using Windows Explorer to find the file name, copy it, and paste it, save the file, then run the script. At that point, just use uigetfile and be done with it!

27. Mikhail replied on :

@Luigi

My impression is that you try to code Matlab with C++ techniques.

- lack of MACROS, why not include #define operator like in c++ ?
>> You do not need it in Matlab (also not in Python, not in Ruby, not in Java, not in C#).

- huge overhead time in function calls, especially nested ones.
>> Agree! That’s the cost of using a dynamically typed interpreted language, do not ever try to compare it to C++. But Matlab and C++ have completely different purposes. And with all ultra-efficient build-in Matlab functions your Matlab code programmed properly can be made very fast.

- I would like to pass arrays to function as reference.
>> Just do it.
http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/
http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/

- globals: why not leaving a dedicated space in the header for globals? wouldn’t that be easier?
>> I think this is a very minor point.

- can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me.
>> What do you want???

- the rotate command in figures is not arc-balled! it only rotates on the centroid. You can spend most of your time rotating the figure like a dog trying to bite his tail, no way to focus what you want to see.
>> You are probably right.

- there is no built-in library for data structure like stl containers. This can be very painful when you need it.
>> Why? You do not need it in Matlab. Newer Matlab Versions have even Hash tables.

- HELP MEMORY ERROR: in my opinion it occurs for too small arrays.
>> It is also about memory fragmentation.

28. John replied on :

Fun list. My pet peeves are:
-Hyper-dense lines of code. My coworker likes to do this, packing fifteen different function calls into one line. I’m impressed, OK, but I can’t read it.
-Haphazard indentation. As mentioned above it’s so easy to do this right.
-Repeating giant chunks of code, but changing one little thing. It’s called a “for” loop — use it!

29. Jim Maneval replied on :

“One of my personal annoyances is to see an m-file script with the following at the top:


close all; clear all;



This is especially bad when you send your code to other people, who may not realize that your script will wipe out anything they may currently be working on.”

Very true if you are not expecting the commands. Unless your script is supposed to be working on the problem that is contained in the (assumed base) workspace, I think that all scripts aimed at answering a particular question should start with at least the “clear” command. So many errors can occur when there is some dependency on workspace contents (whether by design or not) for a script to run correctly. Starting from scratch ensures repeatable results wherever the code is run.

30. Andrew Janke replied on :

My pet peeve is try/catch blocks used for normal control flow. For example, testing whether a struct has a certain field by trying to dereference it and catching the “no such field” error instead of first using a non-erroring test like isfield(). Bad in any language with exceptions, but particularly bad for Matlab because “dbstop if all error” is so useful, and try/catch in the normal control flow will hobble it by triggering spurious error breakpoints.

31. Kay-Uwe replied on :

Regarding #7: I agree with Arthur, it is difficult to assure not overriding MATLAB functions (I don’t really like typing “which” all the time, when coding). That is why I usually put all my code in its own namespace, e.g. work.myfun(..) or for the lazy guys: w.myfun(), so I am at least save in using the function names I like. The additional typing is not an issue to me, thanks to TAB completition.

32. OysterEngineer replied on :

@Doug,

Although it is some 7.5 years old now, I’ve used Richard Johnson’s Style Guidelines to good profit. It is available on the MathWorks File Exchange:

http://www.mathworks.com/matlabcentral/fileexchange/2529-matlab-programming-style-guidelines

I’ve found that style guides written for other languages have some application to MatLab. Your item #6 on white space fall into this category.

33. Doug replied on :

Wow, you all had a lot to say while I was on vacation!

Some of this does come down to “religious issues”. I personally advocate putting

clear
close all
clc

at the top of every script because I want things reproducible. I am never worried about clearing out the workspace since everything I do is in a script or function, so I should be able to get back to that point easily.

34. J.R.! replied on :

I’m gree with Doug on #33!

and overall I find very important that things must be reproducible.

Another point is the difference between ‘clear all’ and his good cousin ‘clear’, because the first one clear also the breakpoints on ALL the functions and scripts you have opened on the M-Editor.

but I disagree with ‘clc’, because with it you clear past error messages, there is enough memory for this.

35. dhull replied on :

@J.R.

It is funny, I use clc specifically because I want to clear the old error messages. I am running the code for a second time specifically to see if my changes fixed the errors. I would not want to confuse myself by thinking that the old error message corresponds to the new code!

Doug

36. P replied on :

Re eval: How would you treat conversion w/o eval?

For instance:

c=class(a);

a=double(a);% to perform some arithmetic on a
do something to a

a=eval([c '(a);']);

–P

37. dhull replied on :

@P

I did not know, but Loren did!

>> a = uint8(1)

a =

1

>> className = class(a)

className =

uint8

>> a = double(a)

a =

1

>> a = cast(a,className)

a =

1

38. Matt Fig replied on :

I mostly agree with Doug’s list, although there are a few exceptions. One that comes to mind is hard-coding the Gauss points and weights into an M-File for integration. I have seen this done and it made sense to do it.
Here are some of my pet peeves.

- clear all,clc at the start of a function M-File. I do sometimes use HOME instead of CLC.
- Use of i or j as a loop index. I always (and only) use double letters as a loop index. For example, ii or jj or kk. That way there is no overwriting of built-ins, and these variables always are known as a loop index.
- Many blank spaces between lines in a M-File.
- Massive IF-ELSEIF chains instead of a SWITCH.
- Not pre-allocating arrays which then grow in a loop.
- Recursion. I know, it has it’s place, I just can’t bring myself to like it.
- No help in a function M-File
- Dumping intermediate results to the command window. I see this one often.
- Programming as if we have infinite precision. Yikes!

39. dhull replied on :

@Matt,

I like the idea of HOME instead of CLC. I will have to try that for a while.

ii, jj, kk. That is a nice little convention. Mush like I use vi (Valid Indices) as the output from a find operation. I always know what means. After many goofed up indices with i in a loop, out of frustration, I made up GAPLI (Generic All Purpose Looping Index)

I wish I understood recursion better, it often confuses me!

I might have to make up a follow up post to this one “ten more MATLAB coding practices that make blog commenters cry!”

Thanks!
Doug

40. Benjamin Kraus replied on :

@Matt, @Doug, and @J.R.,

Regarding ‘close all’ and ‘clear all’ at the top of scripts, it sounds like Matt (comment #38) has the same coding practice as I do. In order to make things reproducible I almost always write functions instead of m-file scripts. This way I always know exactly what I’m passing in and what I’m passing out, and I know that the function is starting from a clean workspace of it’s own (and I refuse to use ‘global’ variables). While I’m writing/debugging I may put a “keyboard” as the last line of code, so I can see what’s happening before that workspace gets cleared. Once I’m satisfied the function works as desired, I just remove the “keyboard” line.

My big reason for *not* wanting “clear all” is that I keep the data I’m working with in structs in the workspace. The data sets tend to be rather large and take a non-negligible amount of time to load from the .mat file I store them in (at least 10-30 seconds to load, if not longer). If the meat of the function only takes 1-2 seconds, it’s a lot of overhead to clear the struct then reload it again every time.

- Ben

41. Ross Hatton replied on :

I am very much in agreement with Ben. I work almost exclusively in functions instead of scripts, and often have scratch data in my workspace or extensive state in my open figures. Running a script that has “close all; clear all” at the beginning (or, even worse, buried inside it) nukes all of this state without warning.

-Ross

42. Jonathan replied on :

Put me in the “no clear or close all” camp. I usually have lots of figures open and things in the base workspace and scripts that clear those without warning are no fun.

When I start coding something new, I usually test some things at the command line first. If that works out, I put it into a .m function file and continue working. I usually put a debugger breakpoint at the last line so I can inspect the results, and if I want to, I dump relevant variables to the base workspace using assignin(‘base’,….).

I reuse the figure numbers each time I run the script. (I usually turn off most figure creation when things look right, but keep a switch so I can use them for diagnostics.) I created a “number increment function”, next_function, for this purpose, that works in the following way:

next = next_function(10); % generate the increment function next, that will start at 10
figure(next()); clf; % creates and clears figure(10)
plot stuff
figure(next()); clf; % creates and clears figure(11)
plot more stuff
etc.

In that way, I can easily put new figures in between others, and still keep the figure numbers in order following the order they appear in the code.

43. Alan B replied on :

I just wanted to mention that I totally agree with Luigi regarding the problem with the 3D rotate command.

Another problem for me is that the elevation angle rotation is constrained to (-90 90]. I don’t see any reason for this – the azimuth angle is not limited in this way, so why limit the elevation? Also, I can not reach elevation = -90; -88 works, -89 works, but when I reach what should be -90, the plot snaps back to +90, which can be pretty frustrating.

I’m stuck with 2007a, so maybe these have been addressed recently, I wouldn’t know.

44. Steve L (MathWorks) replied on :

“- can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me.”

It’s easy to build either a structure whose fields are arrays:

b = struct('Name', 'Steve', 'BowlingScores', [90 103 86 117]);

or to build an array of structures. Two ways to do so:

s1(1) = struct('Name', 'Steve L', 'Blogger', false);
s1(2) = struct('Name', 'Loren', 'Blogger', true);
s1(3) = struct('Name', 'Doug', 'Blogger', true);

s2 = struct('Name', {'Steve L', 'Loren', 'Doug'}, 'Blogger', {false true true});
isequal(s1, s2) % returns true

Note that while I’ve used STRUCT to construct these struct arrays, you can do so using normal subscripting.

s3.Name = 'Steve L'; s3.Blogger = false;
s3(2).Name = 'Loren'; s3(2).Blogger = true;
s3(3).Name = 'Doug'; s3(3).Blogger = true;
isequal(s1, s3) % also returns true
45. Petro Khoroshyy replied on :

Thanks.
I am a “heavy user” of eval function. Got some tips to avoid it.
Thanks

46. dhull replied on :

@petro,

Show a couple of use cases and we will find alternatives.

Doug

47. Juliette replied on :

Hello Doug,
Regarding not using global variables. What is your opinion about using global variables to prevent this type of thing:

function a=myFunction(b,c,d,physicalParameters)
mass=physicalParameters{1};
density=physicalParameters{2};
speed=physicalParameters{3};
kernel=physicalParameters{4};
....


I don’t like REDEFINING the mass and the density and all that because it takes up so much extra space. Is it dangerous to have mass and density and all those as global variables ?

48. dhull replied on :

@Juliette,

Are these huge variables? Are you running out of memory? I doubt they are. Making them global is not a recommended practice, it can cause debugging problems later and takes away on of the reasons for using functions- scoping of variables.

Doug

49. Bill Cheatham replied on :

I use globals for debugging and plotting switches. Usually, I’ll have one called ‘debugYN’ and one called ‘plotYN’. By changing these booleans at the global level, I can change is my programs will or will not plot, or deliver debugging info. Other options include changing the level of verbosity etc.

50. Caitlyn replied on :

Doug,

I have to agree that using global is horrible, but I have a hard time getting around it most of the time. Currently I’m working on a GUI which requires three script files to run. I’m dealing with 60+ variables that must be passed from one script to the next. From my perspective, it doesn’t seem practical to use a function that requires more than 60 inputs. It drives me crazy to see lines of code that extend off to the right of the editor. So is there a way to pass that many varibles without using global? It just seems way more convenient…But I hate using them, so if you have any insight, that’d be great!

Caitlyn

51. doug replied on :

When you say script, I think you mean function as you do not pass variables to a script.

If these are all related variables, would it be better to save them into a structure? Then you can pass around a few structures. This has the added advantage of being able to keep the same function signature yet add more fields to the structure as you need more data sent to those functions.

Doug

52. Christine replied on :

Hi Doug,
I am working on a GUI right now, that contains a huge number of buttons and panels etc. and all the callback functions are in the .m file. Even if for every callback I write a separate function, that is called by the callback, the .m file is still huge and confusing. Is there a way to structure such .m files logically?

53. Matt Eicholtz replied on :

@Christine,
I sometimes find that putting callbacks (and other subfunctions I may need) in separate m-files makes them more manageable. I’m not sure what you mean by “the .m file is still huge and confusing”? It should be much shorter if you remove the callbacks! Just to be clear, you don’t need a callback function in the main m-file to call a separate callback function elsewhere; just make sure the separate m-file is referenced properly for the uicontrol, uipanel, etc.

54. Christine replied on :

@ Matt
Thanks for your response! Can you give me an example how to reference the separate m-file properly for a uicontrol? Maybe you know some sample program, that I could have a look at. By the way, I am using guide to create the GUI.

55. Roger replied on :

How would you avoid using eval when you have to rename a variable using the string from a cell array and then have to save the new variable as a mat file?
example:

[pathstr name]=fileparts(Cellarray{i});
exp1=[name,'=varname'];
eval(exp1);
clear varname pathstr
exp2=['save ',name,'.mat ',name];
eval(exp2);

where Cellarray is cell array that contains only the filename.ext not the path and varname is a matrix from loop. Also function should not require user interaction other than initial function call, hence the need for eval. any suggestions would be much appreciated.

56. Doug replied on :

Roger,

So the save part is easy:

save(filename, name)

The other bit about making a variable of a name known only as a string is more challenging. Often I would think there is just a better thing to do than that. However, you can use the command assignin to do something like this.

Doug

57. Roger replied on :

Thanks Doug!
After seeing what assignin did, I can see how it can replace what I wrote earlier. The modified lines are now:

[ pathstr NAME ] = fileparts( Cellarray { i });
assignin ( ‘base’, [NAME, 'string1'], VAR)
save( [NAME, 'string2', '.mat'], NAME2)
clearvars -except Cellarray __ __ __

It just takes the filename.ext stored in Cellarray and then the fileparts function is used to get the name of the ith cell. Then assignin is used here to create a new variable NAME that has the same values as variable VAR. Then that new variable created called NAME2 (=[name, 'string1'] above) is saved as a .mat file. Then all variables are cleared except for Cellarray and other necessary variables shown as ___. The name of both the new variable and the .mat file can be easily changed based on string operations. But I only needed to add an extra string to the new variable name. Thanks again and hope others find this useful.

58. Steve L replied on :

Roger:

Use dynamic field names (Doug’s “.parens notation”) in conjunction with SAVE’s -struct flag.

% Create a string for the “variable name”
str = ‘myvariable’;

% Dynamic field names
mydata.(str) = magic(5);

% SAVE the structure
save mymatfile.mat -struct mydata;

% The previous step could be written using
% the function form of SAVE if the MAT-file
% name was stored in a variable.
%
% matfilename = ‘mymatfile.mat’;
% save(matfilename, ‘-struct’, ‘mydata’);

% Check that the MAT-file contains the “variable”
whos -file mymatfile.mat

To avoid “poofing” the variable into the workspace when you LOAD, call LOAD with an output argument and refer to the variable using dynamic field names again.

str = ‘myvariable’;
y = mydata.(str);

59. Kjas replied on :

To me, the worst code practice I can imagine is use of function handles. I use matlab practically every day, and it is my main tool since 1996. Matlab was always very consistent in syntax – outputs to the left of =, function name, arguments in brackets. Other operators were also very clear and math-mind oriented. That all changed to me when function handles were introduced. The idea is great, but the syntax implementation is so awful and out of line relative to the rest of matlab that to day I still don’t know how to use them properly. Part of it is me refusing to learn it because I don’t want to accept that monster of ill-conceived syntax as part of my coding. The @, followed by brackets with list of input variables, that don’t have to be there either but could, followed by space! followed by function name (that doesn’t have to be there either but could), followed by inline code or not, just horrible, and it feels like someone was trying hard to make it as far from the good old consistent matlab logic as possible.

 Name (required) E-mail (required, will not be published) Website (optional) Spam protection (required): What is 7 + 9 ?

Wrap code fragments inside <pre> tags, like this:

<pre class="code">
a = magic(3);
sum(a)
</pre>


If you have a "<" character in your code, either follow it with a space or replace it with "&lt;" (including the semicolon).

Doug Hull is a proud MathWorker who is on a mission to help you with MATLAB.

These postings are the author's and don't necessarily represent the opinions of MathWorks.