Creative Commons License Copyright © Michael Richmond. This work is licensed under a Creative Commons License.

Checking the values of input arguments

One of the first homework assignments in this course is to write a program which computes the motion of a ball tossed upwards gently from the Earth's surface. The situation is very simple -- no air resistance, a constant force due to gravity -- and so it might seem that one can satisfy the assignment with a short, simple program. For example,

Does the program work? Let's try giving it some reasonable input:


>> ball_euler1(20, 1)
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     1.000  y    20.000  vy    10.200  E 2.480200e+02  f 2.4010e-01 
 t     2.000  y    30.200  vy     0.400  E 2.960400e+02  f 4.8020e-01 
 t     3.000  y    30.600  vy    -9.400  E 3.440600e+02  f 7.2030e-01 
 t     4.000  y    21.200  vy   -19.200  E 3.920800e+02  f 9.6040e-01 
 t     5.000  y     2.000  vy   -29.000  E 4.401000e+02  f 1.2005e+00 
 t     6.000  y   -27.000  vy   -38.800  E 4.401000e+02  f 1.2005e+00 
>> 

Yes, that's correct.

But -- what if we give the program some unreasonable input values?


>> ball_euler1(20, 0)
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
 
        (continues forever)

Whoops. The program became stuck in an infinite loop. That's no good.

Or what if the user makes an even worse mistake?


>> ball_euler1(20, 'ten seconds')
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
Error using  * 
Inner matrix dimensions must agree.

Error in ball_euler1 (line 55)
     ke = 0.5*m*vy*vy;
 
>> 

Huh? The program crashes somewhere in the midst of its calculations. That's no good, either, especially since it did print out one line of valid output, which might confuse some person or program analyzing the results later.

The problem here is that we haven't been checking the input arguments for validity before using them. That's bad programming practice. A well-made scientific program will always, always examine the values of its input arguments carefully before it starts to calculate anything. If it finds any error or ambiguity, it should print an error message and return control to its calling procedure immediately.

Let's continue using the trajectory-of-a-ball program to illustrate this point. The relevant section of the code lies here, between the end of the initial comment block and the start of the real calculations:

% Usage: ball (initial_velocity, timestep)
%
%    where
%             initial_velocity       is initial speed of ball
%                                    vertically upward (m/s)
%
%             timestep               is size of steps in time (s)
%
% Returns: nothing
%
% MWR 11/28/2012


      Should check input arguments here 


% initialize variables
%    current height above the ground (m)
y = 0;

We need to add a block of argument-checking code before any of the real calculations begin. In general, this block will contain a set of if-then statements; in case any of the checks fail, the code will print an error message and then use the return statement to stop execution.

Below is a version of the program with some minimal checking of the input arguments. Note that this version also includes statements in the "help comments" which tell the user about the conditions attached to the input arguments. In this manner, any user who types help ball_euler1 will see that it is illegal to give a negative initial velocity for the ball.

% Usage: ball (initial_velocity, timestep)
%
%    where
%             initial_velocity       is initial speed of ball
%                                    vertically upward (m/s)
%                                    Must be >= 0 m/s
%
%             timestep               is size of steps in time (s)
%                                    Must be >= 0 s
%
% Returns: nothing
%
% MWR 11/28/2012

% check input arguments
if (initial_velocity <= 0) 
    fprintf(1, 'error: initial velocity must be greater than zero \n');
    return;
end
if (timestep <= 0)
    fprintf(1, 'error: timestep must be greater than zero \n');
    return;
end

% initialize variables
%    current height above the ground (m)
y = 0;

But is this improved version really solid? No. It still fails if the user provides a string as one of the arguments.


>> ball_euler1(20, 'foo');
 t     0.000  y     0.000  vy    20.000  E 2.000000e+02  f 0.0000e+00 
Error using  * 
Inner matrix dimensions must agree.

Error in ball_euler1_checkarg (line 65)
     ke = 0.5*m*vy*vy;
 
>> 

A really paranoid programmer will check to make sure that each argument is a numeric value, and THEN verify that all supplied values fall into an acceptable range.


% Usage: ball (initial_velocity, timestep)
%
%    where
%             initial_velocity       is initial speed of ball
%                                    vertically upward (m/s)
%                                    Must be >= 0 m/s
%
%             timestep               is size of steps in time (s)
%                                    Must be >= 0 s
%
% Returns: nothing
%
% MWR 11/28/2012

% check input arguments
if (isnumeric(initial_velocity) ~= 0) 
    fprintf(1, 'error: initial velocity argument must be a number \n');
    return;
end
if (initial_velocity <= 0) 
    fprintf(1, 'error: initial velocity must be greater than zero \n');
    return;
end
if (isnumeric(timestep) ~= 0) 
    fprintf(1, 'error: timestep argument must be a number \n');
    return;
end
if (timestep <= 0)
    fprintf(1, 'error: timestep must be greater than zero \n');
    return;
end

% initialize variables
%    current height above the ground (m)
y = 0;

There. Now even a truly clueless user will be given the feedback he needs to get things right:



>> balll_euler1(20, 'foo');
error: initial velocity argument must be a number 
>> 


For more information

You can find the programs used as examples in this document in the examples directory , and listed below.


Creative Commons License Copyright © Michael Richmond. This work is licensed under a Creative Commons License.