help tidying my code

1 view (last 30 days)
Takhyung Seon
Takhyung Seon on 8 Dec 2017
Commented: Takhyung Seon on 8 Dec 2017
Hi everyone, I am creating a matlab script to process an accelerometer's orientation data from a text file and graph the information for further analysis. If you look at the graph I attached, you can see several "plateaus." I am trying to manually select 5 data points from each (equally spaced by 1, i.e. 30:1:35) and average the 5 points together. I am trying to repeat that method for 5 different "plateaus" and 3 different lines (roll, pitch, yaw). The code I have provided works, but I am worried when I duplicate the code for a second sensor's data, the variables (a-o) will be repeated and the code will not work properly. I have thought of making the second sensor's variables capitalized (i.e A-O), but I was wondering if there was a way to tidy up the bottom half of my code, starting at "%mean value for each plateau" (maybe by using for loops, if-then statements, etc). Any help will be appreciated!
%orientation data for sensor a
filename = 'exampleLogfile-000.txt';
fileIDa = fopen(filename);
Aa = textscan(fileIDa, '%f %f %f %f ', 'Headerlines', 5);
Rolla = Aa{1,2};
Pitcha = Aa{1,3};
Yawa = Aa{1,4};
plot(Rolla);
hold on
plot(Pitcha);
hold on
plot(Yawa);
%Manually select ranges for 5 plateaus
v = 30:35;
w = 160:165;
x = 320:325;
y = 500:505;
z = 650:655;
%Mean value for each plateau
a = mean(Rolla(v)); f = mean(Pitcha(v)); k = mean(Yawa(v));
b = mean(Rolla(w)); g = mean(Pitcha(w)); l = mean(Yawa(w));
c = mean(Rolla(x)); h = mean(Pitcha(x)); m = mean(Yawa(x));
d = mean(Rolla(y)); i = mean(Pitcha(y)); n = mean(Yawa(y));
e = mean(Rolla(z)); j = mean(Pitcha(z)); o = mean(Yawa(z));
% sensor 1 data for 5 different points
data1 (1:5, 1:3) = [a f k;b f l;c h m; d i n; e j o];
  1 Comment
Stephen23
Stephen23 on 8 Dec 2017
@Takhyung Seon: if you are creating a whole long sequence of variable names like a, b, c, etc, then your approach is wrong. You should simply create one array (which could be a cell array).
Put the range index limits into two vectors, loop over the vectors, and extract those parts of Rolla into a cell array or ND array: simpler, expandable, and much more generalized.

Sign in to comment.

Accepted Answer

Guillaume
Guillaume on 8 Dec 2017
It's good that you are worried about the cleanliness of your code. This will make you a better programmer. A good program is not only a program that works but one that is easy to maintain, debug, and understand.
With regards to the naming of variables, if you start numbering variables, or distinguishing them by case, or going through the alphabet, you are doing it wrong. A good variable name is one that is self-documenting, explaining what is in the variable. A variable called a doesn't tell you anything about what it may contain. A variable called meanpitch does.
With regards to code structure as soon as you starts copy pasting code, you are doing it wrong. There's always a better way. A loop at a minimum, sometimes vectorisation of the code is possible. For example, you could simply your code greatly with:
plateaus = {30:35;
160:165;
320:325;
500:505;
650:655;}; %just one variable for all the plateaus
meanrollpitchyaw = zeros(numel(plateaus), 3); %much better name than data1
for plateauidx = 1:numel(plateaus)
meanrollpitchyaw(plateauidx, 1) = mean(Rolla(plateaus{plateauidx}));
meanrollpitchyaw(plateauidx, 2) = mean(Pitcha(plateaus{plateauidx}));
meanrollpitchyaw(plateauidx, 3) = mean(Yawa(plateaus{plateauidx}));
end
Even the 3 duplicate mean lines could be removed if you stored your roll, pitch and yaw in a 2d matrix instead of individual vectors:
rollpitchyaw = cell2mat(Aa(2:4)); %Aa is a poor name for a variable!
plateaus = {30:35; 160:165; 320:325; 500:505; 650:655;};
meanrollpitchyaw = zeros(numel(plateaus), size(rollpitchyaw, 2));
for plateauidx = 1:numel(plateaus)
meanrollpitchyaw(plateauidx, :) = mean(rollpitchyaw(plateaus{plateauidx}, :), 1);
end
If you're adding more sensors, assuming you're using the same plateaus for all the sensors, then use 3d matrices instead of 2d. The pages of your matrices would then correspond to the sensors
filenames = {'exampleLogfile-000.txt'; 'exampleLogfile-001.txt'; 'exampleLogfile-002.txt'}; %for example
for fileidx = 1:numel(filenames)
fid = fopen(filenames{fileidx});
filecontent = textscan(fileIDa, '%f %f %f %f ', 'Headerlines', 5);
rollpitchyaw(:, :, fileidx) = cell2mat(filecontent(2:4));
end
plateaus = {30:35; 160:165; 320:325; 500:505; 650:655;};
meanrollpitchyaw = zeros(numel(plateaus), size(rollpitchyaw, 2), size(rollpitchyaw, 3));
for plateauidx = 1:numel(plateaus)
meanrollpitchyaw(plateauidx, :) = mean(rollpitchyaw(plateaus{plateauidx}, :, :), 1);
end
  1 Comment
Takhyung Seon
Takhyung Seon on 8 Dec 2017
Wow, thank you very much for your detailed help! It was very helpful and now my code is a lot easier to follow.

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!