Computer Science 121
Scientific ComputingWinter 2012
Chapter 7Conditionals
Conditionals: Motivation
• Consider absolute value algorithm:
1. If number is negative, negate it.2. Otherwise, leave it alone.
• We need a way to express “if” and “otherwise”.
7.1 The if Statementfunction res = absvalV1(x)% absolute value, version 1
if x < 0 % the test condition
res = -x; % the YES block
else
res = x; % the NO blockend
• Any amount of code can go inside YES/NO blocks:
function [smaller,bigger] = arrange2(a, b)if a < b
smaller = a;bigger = b;
elsesmaller = b;bigger = a;
end
Style• Don't need as many blank lines as in example:
function res = abs(x)if x < 0
res = -x;else
res = x;end
• But indentation is very important: editor will do this for you automagically (or highlight and use CTRL-I)
7.2 More Than Two Cases• Consider finding max of three numbers a, b, c
Condition Outcome
a ≥ b and a ≥ c ab ≥ a and b ≥ c bc ≥ a and c ≥ b c
• With only if and else, we end up with a lot of indentation (embedding), not reflecting structure of problem (3 cases)....
7.2 More Than Two Cases
function res = max3V0(a, b, c)% max of three inputs, version 0if a >= b && a >= c % why is a here, but ...
res = a;else
if b >= a && b >= c % b and c here?res = b;
elseres = c;
endend
7.2 More Than Two Cases
• We can give each case equal status by using elseif:
function res = max3V1(a, b, c)
if a >= b && a >= cres = a;
elseif b >= a && b >= cres = b;
elseres = c;
end
7.3 Completeness and Exclusivity
• Sometimes we can leave out the “do nothing” case (like abs. val. of a positive number):
function res = absvalV2(x)res = x; % does this have to go first?if x < 0
res = -x;end
• A statement like this is called “incomplete” - no case of the conditional is executed. This can lead to trouble...
A Note on & …
• For logical AND, book uses &, but Matlab now expects you to use && (you’ll get a warning).
• Same for logical OR: use || instead of |
Completeness
function res = max3V2(a, b, c)% © 2008 Stewie Griffin (broken)
if a > b && a > cres = a;
elseif b > a && b > cres = b;
elseres = c;
end
Completeness
>> max3v2(1, 2, 3)ans = 3
>> max3v2(3, 2, 1)ans = 3
>>max3v2(2, 3, 1)ans = 3
>> max3v2(3, 3, 1)ans = 1 % Ruh roh!
• A safer strategy is to make sure that we reach our else case only in an “impossible” situation:
function res = max3V2(a, b, c)% saferif a > b && a > c
res = a;elseif b > a && b > c
res = b;elseif c > a && c > b
res = c;else
error('What the deuce?!')end
Completeness
Completeness
• It might be more sensible to handle the equality case(s) without an error, but the principle is important – make your bugs “shallow”. • Of course, we have to be realistic:
• It is impossible to make anything foolproof, because fools are so ingenious. - Robert Heinlein
• If you make your system more idiot-proof the idiots will build a bigger idiot. - Anonymous
Exclusivity
• Conditionals are exclusive: only one case will be executed
• Again, can lead to problems...
function res = convert_grade_V1(score)% percent to letter-grade conversion
if score >= 90res = 'A';
elseif score >= 80 && score <= 89res = 'B';
elseif score >= 70 && score <= 79res = 'C';
elseif score >= 60 && score <= 69res = 'D';
elsescore = 'F';
end
Exclusivity
Exclusivity
>> convert_grade_V1(89.5)ans = F
• Problem is conflict between exclusivity (computer) and redundancy (human) : people like more information (upper and lower ends of range), but this can be catastrophic when turned into an algorithm.
• Eliminating redundancy can give us a less intuitive, but correct, algorithm....
Exclusivity: Eliminating Redundancy
function res = convert_grade_V2(score)% percent to letter-grade conversion
if score >= 90res = 'A';
elseif score >= 80res = 'B';
elseif score >= 70res = 'C';
elseif score >= 60res = 'D';
elsescore = 'F';
end
Conditionals can get crowded with the repetition of the same operation on the same data:
function res = conversion_factor_meters_V1(unit)% return equivalent one one UNIT in meters
if strcmp(unit, 'yards') | strcmp(unit, 'yd')res = 0.9144;
elseif strcmp(unit, 'inches') | strcmp(unit, 'in')res = 0.0254;
elseif strcmp(unit, 'miles') | strcmp(unit, 'mi')res = 1609.0;
...else
res = 0;end
7.4 Switch / Case
7.4 Switch / Case
Switch / case statement eliminates repetition:
function res = conversion_factor_meters_V2(unit)
switch(unit)case {'yards', 'yd'}
res = 0.9144;case {'inches', 'in'}
res = 0.0254;case {'miles', 'mi'}
res = 1609.0;...otherwise % unrecognized units
res = 0;end
Safety via error
function res = conversion_factor_meters_V3(unit)
switch(unit)case {'yards', 'yd'}
res = 0.9144;case {'inches', 'in'}
res = 0.0254;case {'miles', 'mi'}
res = 1609.0;...otherwise
error('Unrecognized units … ohhhh snap!')end