In this program, one can enter any number up to three digit maximum, and the program will convert it into audio and play it.
Vishakha Patel (2020). Num2Speak (https://www.mathworks.com/matlabcentral/fileexchange/61304-num2speak), MATLAB Central File Exchange. Retrieved .
A nice idea let down by bad code practices.
The implementation leaves a lot to be desired.
Although it is nicely commented the code is very badly aligned: the correct IF nesting is only clear after selecting all code and pressing ctrl+i. Consistent formatting would make the code clearer.
The next bad practice is the fact that this is a script: it would be much better to have written a function which would allow for a simple input argument, and would keep the internal operations and the many variables separate from the outside workspace. That begs the question: why are there so many variables? Partly because of the bad practice of LOAD-ing into the workspace (much better is to LOAD into a structure). Partly because of so many unnecessary variables: why write |y = d2*10| when |y| is only used once on the next line?
The next bad practice pops up just a few lines later: a seven line WHILE loop just to measure the length of a string, including one EVAL call to dynamically name variables, and a counter variable. This is MATLAB: why use such ugly and inefficient code? Given that the number of digits can be a maximum of three, why dynamically name variables when indexing would be much simpler, faster, and more robust? Simply use a vector and indexing.
The rest of the code uses these dynamically named variables to access sound data stored in the mat file. In total EVAL is used seven times in this script. And none of those calls are required! Why beginners love to use inefficient, slow, and buggy EVAL is not clear to me, because this code would be simpler if they avoided awful EVAL and used indexing instead.
One example of why EVAL is such an awful way to write code is illustrated by this code: when the user inputs a decimal value then a cryptic error message pops up, such as
??? Undefined function or variable 'd2'.
or with words:
??? Undefined function or variable 'cat'.
??? Error: Unexpected MATLAB expression.
because of the totally insecure use of INPUT and the totally fragile idea of using user input to define variable names. This is such an unreliable practice because it makes error checking difficult, input checking almost impossible, and makes code open to user errors. All because some beginners think that using EVAL solves problems. It doesn't, it just makes other problems.
Well, here is one much simpler function, with about half the number of lines of code, simpler to read, no EVAL, no WHILE loops, and with reliable input checking:
assert(isnumeric(val)&&isscalar(val),'Value must be a numeric scalar')
assert(isreal(val)&&isfinite(val)&&fix(val)==val,'Value must be a finite integer')
assert((val>0)&&(val<1000),'Value must be greater than zero and less than 1000')
ddm = load('DigitData.mat');
str = sprintf('%3d',val);
prv = 0;
if str(1)>'0' % hundreds
prv = 1;
if str(2)>'1' % tens
prv = 1;
if str(2)=='1' % teens
elseif str(3)>'0' % ones
Summary: two stars for making it work. Two stars for needing a lot of improvement.
Inspired by: audio