How to check source code for certain strings? [Base MATLAB] [Cody Courseware]

2 views (last 30 days)
Hi,
I'm a TA at my university, and I'm currently developing a course in Cody Courseware as a supplement to our curriculum. I've been playing around with asserts to give user feedback in various use cases, but I'm looking to see if there exists a way to check the source code for particular strings. For you UNIX types out there, I basically want something akin to 'grep' in bash.
As an example, one question in our textbook involves an introduction to nesting 'for' loops, and requires using two nested for loops to add two same-size arrays, cell-by-cell. The expected solution is something like
function z = foo(x,y)
z = zeros(size(x,1),size(x,2));
for i = 1:size(x,1)
for j = 1:size(x,2)
z(i,j) = x(i,j) + y(i,j);
end
end
end
but
function z = foo(x,y)
z = x+y;
end
obviously gives the correct output array, but isn't implemented in the requested manner. I suppose I could modify the question and add some second requirement to it, but I'd prefer a more elegant solution.
Any ideas?

Answers (1)

Peter O
Peter O on 15 Apr 2016
If you can check the source code on submission, you could use a regex to look for the existence of the nested for loop, identify the loop index variables, and require that the output variable is assigned within the innermost loop. Note that this will be ugly, unreadable, and very likely bug-prone. :)
For the example you've given, I think this would work in 99% of cases:
% Here's the source code
S = sprintf(['function z = foo(x,y)\n'...
'z = zeros(size(x,1),size(x,2));\n'...
'for i = 1:size(x,1)\n'...
'for j = 1:size(x,2)\n'...
'z(i,j) = x(i,j) + y(i,j);\n' ...
'end\n'...
'end\n'...
'end\n']);
% Find output variable
outvar = '^.*function\s(?<ov>\w+)\s+=';
[m1 tk, ext] = regexp(S,outvar,'match','tokens');
%Find the nested loop
nloops = ['\s+for\s+(?<lp1>\w+)\s+=.*\s+for\s+(?<lp2>\w+)\s+.*\s+' tk{1}{1} '(\(\k<lp1>,\k<lp2>\)|\(\k<lp2>,\k<lp1>\))' '\s+=.*\s+end.*\s+end'];
[m2 tk2, ext] = regexp(S,nloops,'match','tokens')
good_code = (~isempty(m1) && ~isempty(m2))
I make no warranty to the edge cases that the regex above will miss, but you can see how it's possible to get it working. There are also some drag-n-drop generators out there, which I think are compatible with MATLAB's regexp syntax, and they let you work in conditions instead of battalions of parentheses. Good luck!

Categories

Find more on Historical Contests in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!