{"id":390,"date":"2016-01-16T02:35:05","date_gmt":"2016-01-16T02:35:05","guid":{"rendered":"https:\/\/blogs.mathworks.com\/developer\/?p=390"},"modified":"2016-01-16T02:35:05","modified_gmt":"2016-01-16T02:35:05","slug":"making-code-usable-useful-and-testable","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/developer\/2016\/01\/16\/making-code-usable-useful-and-testable\/","title":{"rendered":"Making code usable, useful and testable"},"content":{"rendered":"<div class=\"content\"><!--introduction--><p>Writing MATLAB code is seductively <a href=\"https:\/\/blogs.mathworks.com\/developer\/files\/EasyPhoto.png\" target=\"_blank\">easy<\/a>. Polishing the functionality of algorithmic MATLAB code to make it usable, useful and testable requires a bit of design.<\/p><p>Taking the <a href=\"https:\/\/blogs.mathworks.com\/developer\/2015\/12\/18\/open-and-extensible\/\">spellcheck code that I wrote about earlier<\/a> as a strawman example, it is possible to make that functionality usable, useful and testable by wrapping it as an easy-to-use MATLAB object.<\/p><p>Building an API allows more users to use the spellcheck functionality in their code, tools and workflows. In this post, we shall make spellcheck available in MATLAB with an emphasis on making it easy to use.<\/p><p>In order to design a usable, useful and testable API, a few high-level design objectives can be articulated as follows:<\/p><!--\/introduction--><p><b>Installation and access to the dependencies should be easy and automated<\/b><\/p><p>The spellcheck functionality is enabled by a third party library and while I could write a lot of documentation about what needs to be installed and where it goes, it becomes a lot easier to just use MATLAB to automate this.<\/p><p>The class definition for the spellcheck object looks like:<\/p><pre class=\"language-matlab\"><span class=\"keyword\">classdef<\/span> spellcheck\r\n\r\n    <span class=\"keyword\">properties<\/span>\r\n        Dictionary;\r\n        CommentsOnly = true;\r\n    <span class=\"keyword\">end<\/span>\r\n\r\n     <span class=\"keyword\">properties<\/span>(Hidden)\r\n         Handle;\r\n     <span class=\"keyword\">end<\/span>\r\n\r\n     <span class=\"comment\">% Constructor and methods go here<\/span>\r\n \r\n<span class=\"keyword\">end<\/span><\/pre><p>The properties of this class permits the specification of dictionary files and provides storage for the handle to the Jazzy library. Static methods on this class will return a string specifying where the class is located and this allows download of the library to a known relative location.<\/p><p>MATLAB offers a full set of commands to operate on the web and internet. Leveraging these commands, we have:<\/p><pre class=\"language-matlab\">\r\n<span class=\"keyword\">methods<\/span>(Static)\r\n\r\n        <span class=\"comment\">% SPELLROOT Method that will locate the root folder for tooling<\/span>\r\n        <span class=\"keyword\">function<\/span> [sRoot] = spellroot()\r\n            <span class=\"comment\">% Folder path relative to the location of this code<\/span>\r\n            sRoot = fileparts(mfilename(<span class=\"string\">'fullpath'<\/span>));\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"comment\">% DOWNLOADJAZZY Download and provision the Jazzy library<\/span>\r\n        <span class=\"comment\">% Fetches the Java Spell Check library from SourceForge<\/span>\r\n        <span class=\"keyword\">function<\/span> downloadJazzy()\r\n            <span class=\"comment\">% Store the jar file in a known location<\/span>\r\n            jazzyJar = fullfile(spellcheck.spellroot,<span class=\"string\">'lib'<\/span>,<span class=\"string\">'java'<\/span>,<span class=\"string\">'jazzy0-2-1.jar'<\/span>);\r\n            urlwrite(<span class=\"string\">'http:\/\/downloads.sourceforge.net\/project\/jazzy\/OldFiles\/jazzy0-2-1.jar'<\/span>,jazzyJar);\r\n            <span class=\"comment\">% Add the JAR file to the MATLAB path.<\/span>\r\n            <span class=\"keyword\">if<\/span> exist(jazzyJar,<span class=\"string\">'file'<\/span>)\r\n                javaaddpath(jazzyJar);\r\n            <span class=\"keyword\">end<\/span>\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n    <span class=\"keyword\">end<\/span>\r\n\r\n<\/pre><p>These few lines of code now automates the installation of the library directly from SourceForge to the user's MATLAB session.<\/p><p>The real implication is that it took just a few lines of code to empower our MATLAB application with the ability to leverage any of the thousands of projects on SourceForge that may be relevant for the task at hand. The web connectivity and features of the MATLAB platform are not restricted to SourceForge but extends to Github, ProjectLocker, File Exchange, etc.<\/p><p>In a nutshell, everything that the internet has to offer are just a few lines of MATLAB code away. MATLAB can just as easily connect to services (REST, SOAP, etc.) but that is a whole other topic.<\/p><p>The dictionaries that power the tool can also be fetched from SourceForge. Given that the tool is multi-language capable, we will specify the list of available dictionaries in a neutral format (CSV) for simplicity.<\/p><pre class=\"language-matlab\">en_US.zip, http:\/\/downloads.sourceforge.net\/project\/jazzydicts\/jazzydicts\/Dictionaries%201.0\/en_US.zip\r\nen_NZ.zip, http:\/\/downloads.sourceforge.net\/project\/jazzydicts\/jazzydicts\/Dictionaries%201.0\/en_NZ.zip\r\nen_GB.zip, http:\/\/downloads.sourceforge.net\/project\/jazzydicts\/jazzydicts\/Dictionaries%201.0\/en_GB.zip\r\n<\/pre><p>The code for downloading these artifacts is nearly identical to the code for the library and has been omitted from this post for brevity.<\/p><p>Given that all our software artifacts are now in place, we can glue them all together. This brings us to our next design objective.<\/p><p><b>The utility should be usable to our diverse user community<\/b><\/p><p>MATLAB has evolved over 30 years and has a very diverse user community. From the engineer at an automotive OEM to a researcher in a biotech startup and from a student working on his thesis to a team of software professionals developing MATLAB code on Wall Street, the platform and the language has an amazing diversity in its user base.<\/p><p>It is interesting to note that the MATLAB language enables a well designed object to look, feel and work like a typical MATLAB function. In simpler terms, MATLAB classes can do nearly everything your procedural code can do... and some more.<\/p><p>To illustrate this, the design of an entry point to our class is the next step in wrapping our functionality.<\/p><pre class=\"language-matlab\">\r\n<span class=\"keyword\">methods<\/span>\r\n\r\n        <span class=\"comment\">% Constructor<\/span>\r\n        <span class=\"keyword\">function<\/span> obj = spellcheck(varargin)\r\n\r\n            <span class=\"comment\">% Make Jazzy available to MATLAB<\/span>\r\n            import <span class=\"string\">com.mathworks.spellcheck.*<\/span>;\r\n\r\n            <span class=\"comment\">% Setup a default language.<\/span>\r\n            obj.Dictionary = which(<span class=\"string\">'en_USx.dic'<\/span>); <span class=\"comment\">% default<\/span>\r\n\r\n            <span class=\"comment\">% Create a jazzy spellchecker<\/span>\r\n            obj.Handle = SpellCheck();\r\n            obj.Handle.setDictionary(obj.Dictionary);\r\n            obj.Handle.verbose = true;\r\n\r\n            <span class=\"comment\">% Check and call the spellchecker<\/span>\r\n            <span class=\"keyword\">if<\/span> nargin==1\r\n\r\n                <span class=\"comment\">% Filename specified or string specified<\/span>\r\n                filename = which(varargin{1});\r\n\r\n                <span class=\"comment\">% Fire up the spellchecker<\/span>\r\n                <span class=\"keyword\">if<\/span> isempty(filename)\r\n\r\n                    <span class=\"comment\">% We are dealing with a string<\/span>\r\n                    obj.check(varargin{1});\r\n                <span class=\"keyword\">else<\/span>\r\n                    <span class=\"comment\">% We are dealing with a file so read it into a string<\/span>\r\n                    str = fileread(filename);\r\n                    obj.check(str);\r\n                <span class=\"keyword\">end<\/span>\r\n\r\n            <span class=\"keyword\">else<\/span>\r\n                <span class=\"comment\">% Check the contents of the editor<\/span>\r\n                obj.checkEditor();\r\n            <span class=\"keyword\">end<\/span>\r\n        <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"comment\">% The check() and checkEditor() methods go here<\/span>\r\n    <span class=\"keyword\">end<\/span>\r\n<\/pre><p>The constructor serves as a simple switchyard allowing the user to check strings, files or the contents of the editor depending on the inputs and outputs provided to it. In this case, our constructor with no arguments will check the contents of the editor. This is not always desirable but I have left it this way for illustration purposes.<\/p><p>Since, the invocation of the class is identical to the invocation of an identically named MATLAB function, the code provides a familiar interface to users who wish to use this class in their procedural code. Developers who are comfortable with Object Oriented techniques can use the methods of this object for finer grained control over the utility.<\/p>\r\n\r\n<pre class=\"language-matlab\">\r\n        <span class=\"comment\">% CHECK Method to check an input string<\/span>\r\n        <span class=\"keyword\">function<\/span> check(obj, inputStr, varargin)\r\n\r\n            <span class=\"comment\">% If line number is specified use it for the link<\/span>\r\n            <span class=\"keyword\">if<\/span> ~isempty(varargin)\r\n                obj.Handle.linenumber = num2str(varargin{1});\r\n                obj.Handle.checkSpelling(inputStr);\r\n            <span class=\"keyword\">else<\/span>\r\n                obj.Handle.checkSpelling(inputStr);\r\n            <span class=\"keyword\">end<\/span>\r\n\r\n        <span class=\"keyword\">end<\/span>\r\n<\/pre>\r\n\r\n<p>The check() method is where the rubber meets the road. The MATLAB code invokes the Java code and the spelling check is performed. The checkEditor method (omitted for brevity) is similar in that it reads in the current file that is open in the editor and then performs the check.<\/p><p>If a linenumber is specified such as in the case of the checkEditor() code, the output includes a hyperlink to the line using the MATLAB opentoline() function.<\/p><p>Testing our class:<\/p>\r\n<pre>  &gt;&gt; spellcheck          % Checks the content of the editor\r\n  Input (172): github\r\n\t    No suggestions\r\n  Input (174): API\r\n\t    Suggestion: AP\r\n\t    Suggestion: APB\r\n\t    Suggestion: APO<\/pre>\r\n\r\n<p>The class now provides me a single command to check the contents of my editor making it trivially accessible as I author content. For example, the dictionary did not contain the word <i>github<\/i> on line 172 or <i>API<\/i> on line 174 of this post.<\/p><p>Testing the other routes through the constructor:<\/p><pre>  &gt;&gt; spellcheck('majic') % Checks string\r\n  &gt;&gt; spellcheck majic    % Equivalent syntax<\/pre><p>The spellcheck object can also be instantiated and persisted for finer grain control.<\/p><pre>  &gt;&gt; s = spellcheck;\r\n  &gt;&gt; s.check('majic');    % Equivalent syntax\r\n\r\n  Input : majic\r\n\t    Suggestion: magic\r\n\t    Suggestion: manic<\/pre><p>Is this really multi-language capable? I test the code again setting the dictionary to German.<\/p><pre>  &gt;&gt; s.Dictionary = 'c:\\Work\\Spellchecker\\public\\de_DE\\de_DEx.dic';\r\n  &gt;&gt; s.check('seprechen sie deutch')  % Intentional spelling mistake\r\n\r\n  Input : seprechen\r\n\t    Suggestion: sprechen\r\n  Input : deutch\r\n\t    Suggestion: deutsch<\/pre><p>MATLAB returns the corrected version - <i>\"sprechen sie deutsch\"<\/i> which sounds correct (perhaps a native speaker of the language can confirm).<\/p><p>Happy with the way my MATLAB functionality is working, I can finally address the last design requirement.<\/p><p><b>The utility should be testable<\/b><\/p><p>In its simplest form, a unit test that exercises the code looks like:<\/p>\r\n<pre class=\"language-matlab\"><span class=\"keyword\">classdef<\/span> testspellcheck &lt; matlab.unittest.TestCase\r\n<span class=\"comment\">% TESTSPELLCHECK Simple unit test for our spellcheck<\/span>\r\n    <span class=\"keyword\">methods<\/span> (Test)\r\n        <span class=\"keyword\">function<\/span> testSpellCheck(testCase)\r\n\t\ts = spellcheck(<span class=\"string\">'majic'<\/span>);\r\n\t\ttestCase.verifyEqual(char(s.Handle.suggestions.elementAt(0)),<span class=\"string\">'magic'<\/span>);\r\n        <span class=\"keyword\">end<\/span>\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span><\/pre>\r\n<p>I will not go into the details of building a robust regression test suite but rather dwell on the ramifications of the requirement.<\/p><p>The construction and use of an automated test suite is a very important part of integrating with 3rd party libraries and products. The test suite isolates our work from upstream dependency changes. If the Jazzy library changes, evolves or is improved upstream, it would naturally affect our functionality.<\/p><p>Having a fully automated test suite buys the ability to re-test functionality against upstream changes to the Jazzy library. In this particular case, the code is pretty stable but the reason I write about this is oftentimes, the module upstream is very actively maintained and changes very frequently. In such cases, the investment in building a regression test suite very quickly pays off.<\/p><p>In conclusion, as a platform MATLAB is the quintessential melting pot. A variety of technologies and techniques are available right from the language which can be leveraged easily to extend of the platform. As a developer this is useful to know as MATLAB can play well with the best-in-class technologies to create robust solutions with minimal effort.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_136a9c5e21d843dc96a0a3a81cb44b62() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='136a9c5e21d843dc96a0a3a81cb44b62 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 136a9c5e21d843dc96a0a3a81cb44b62';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2016 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_136a9c5e21d843dc96a0a3a81cb44b62()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2015b<br><\/p><\/div><!--\r\n136a9c5e21d843dc96a0a3a81cb44b62 ##### SOURCE BEGIN #####\r\n%% Making code usable, useful and testable\r\n% Writing MATLAB code is seductively easy. Polishing the functionality of\r\n% algorithmic MATLAB code to make it usable, useful and testable requires a\r\n% bit of design. \r\n% \r\n% Taking the <https:\/\/blogs.mathworks.com\/developer\/2015\/12\/18\/open-and-extensible\/ spellcheck code\r\n% that I wrote about earlier> as a strawman example, it is possible to make \r\n% that functionality usable, useful and testable by wrapping it as an easy-to-use MATLAB object. \r\n%\r\n% Building an API (Application Program Interface) allows users to use\r\n% the spellcheck functionality in their code, tools and workflows. In this post, we \r\n% shall make spellcheck available in MATLAB with an emphasis on making it easy to use. \r\n% \r\n% In order to design a usable, useful and testable API, a few high-level design objectives can articulated as follows: \r\n%  \r\n%%\r\n% *Installation and access to the dependencies should easy and automated* \r\n% \r\n% The spellcheck functionality is enabled by a third party library and\r\n% while I could write a lot of documentation about what needs to be\r\n% installed and where it goes, it becomes a lot easier to just use MATLAB\r\n% to automate this. \r\n% \r\n% The class definition for the spellcheck object looks like:\r\n% \r\n%   classdef spellcheck\r\n%       properties\r\n%           Dictionary;\r\n%           CommentsOnly = true;\r\n%       end\r\n% \t\r\n%       properties(Hidden)\r\n%           Handle;\r\n%       end\r\n%       \r\n%       % Constructor and methods go here\r\n%   end\r\n% \r\n% The properties of this class allows for the location of the dictionary files \r\n% as well as the handle to the Jazzy library. Static methods on this class will first locate where\r\n% the class is located and provide a quick way to download the\r\n% library.\r\n% \r\n% MATLAB offers a full set of commands to operate on the web and internet.\r\n% Leveraging these commands, we have:\r\n% \r\n%       methods(Static)\r\n%           % SPELLROOT Method that will locate the root folder for tooling\r\n%           function [sRoot] = spellroot()\r\n%               % Folder path relative to the location of this code\r\n%               sRoot = fileparts(fileparts(fileparts(fileparts(mfilename('fullpath')))));\r\n%           end \r\n% \r\n%           % DOWNLOADJAZZY Download and provision the Jazzy library\r\n%           % Fetches the Java Spell Check library from SourceForge\r\n%           function downloadJazzy()\r\n% \r\n%               % Store the jar file in a known location\r\n%               jazzyJar = fullfile(spellcheck.spellroot,'lib','java','jazzy0-2-1.jar');\r\n%               urlwrite('http:\/\/downloads.sourceforge.net\/project\/jazzy\/OldFiles\/jazzy0-2-1.jar',jazzyJar);\r\n% \r\n%               % Add the JAR file to the MATLAB path.\r\n%               if exist(jazzyJar,'file')\r\n%                   javaaddpath(jazzyJar);\r\n%               end\r\n%           end\r\n%       end\r\n%\r\n% A few lines of code now automates the installation of the library\r\n% directly from SourceForge to the users MATLAB session. \r\n% \r\n% The real implication is that it took just a few lines of code \r\n% and empower our MATLAB application with the ability to leverage any of the \r\n% thousands projects on SourceForge that may be relevant for the task at hand. \r\n% The web connectivity and features of the MATLAB platform are not restricted \r\n% to SourceForge but extends to Github, ProjectLocker, File Exchange, etc. \r\n% \r\n% In a nutshell, everything that the internet has to offer are just a few lines of MATLAB \r\n% code away. MATLAB can just as easily connect to services (REST, SOAP, etc.) but\r\n% that is a whole other topic.\r\n% \r\n% The dictionaries that power the tool can also be fetched from SourceForge. \r\n% Given that the tool is multi-language capable, we will specify the list of available dictionaries in a neutral format\r\n% (CSV) for simplicity. \r\n%\r\n%   en_US.zip, http:\/\/downloads.sourceforge.net\/project\/jazzydicts\/jazzydicts\/Dictionaries%201.0\/en_US.zip\r\n%   en_NZ.zip, http:\/\/downloads.sourceforge.net\/project\/jazzydicts\/jazzydicts\/Dictionaries%201.0\/en_NZ.zip\r\n%   en_GB.zip, http:\/\/downloads.sourceforge.net\/project\/jazzydicts\/jazzydicts\/Dictionaries%201.0\/en_GB.zip\r\n%\r\n% The code for downloading these artifacts is nearly identical to the code for the \r\n% library and has been omitted from this post for brevity.\r\n% \r\n% Given that all our software artifacts are now in place, we can glue them all \r\n% together. This bring us to our next design objective.\r\n%\r\n%% \r\n% *The utility should be usable to our diverse user community*\r\n% \r\n% MATLAB has evolved over 30 years and boasts of a diverse user community. \r\n% From the engineer at an automotive OEM to a researcher in a biotech startup and from a \r\n% student working on his thesis to a team of software professionals developing MATLAB code on Wall Street, \r\n% the platform and the language has an amazing diversity in its user base. \r\n% \r\n% Over the years, there have been many occasions where I have run into\r\n% long time MATLAB users who look upon MATLAB's Class and Object system with\r\n% suspicion. It is interesting to note that the MATLAB language enables a well designed object \r\n% to look, feel and work like a typical MATLAB function. i.e. MATLAB\r\n% classes can do nearly everything your procedural code can do... and some\r\n% more.\r\n% \r\n% To illustrate this, the design of an entry point to our class is the next step in wrapping our functionality.\r\n% \r\n%       methods\r\n%           % Constructor\r\n%           function obj = spellcheck(varargin)\r\n%               % Make Jazzy available to MATLAB\r\n%               import com.mathworks.spellcheck.*;\r\n% \r\n%               % Setup a default language.\r\n%               obj.Dictionary = which('en_USx.dic'); % default\r\n% \r\n%               % Create a jazzy spellchecker\r\n%               obj.Handle = SpellCheck();\r\n%               obj.Handle.setDictionary(obj.Dictionary);\r\n%               obj.Handle.verbose = true;\r\n% \r\n%               % Check and call the spellchecker\r\n%               if nargin==1\r\n%                   % Filename specified or string specified\r\n%                   filename = which(varargin{1});\r\n% \r\n%                   % Fire up the spellchecker\r\n%                   if isempty(filename)\r\n%                       % we are dealing with a string\r\n%                       obj.check(varargin{1});\r\n%                   else\r\n%                       % we are dealing with a file so read it into a string\r\n%                       str = fileread(filename);\r\n%                       obj.check(str);\r\n%                   end\r\n%               else\r\n%                   obj.checkEditor();\r\n%               end\r\n%           end\r\n% \r\n%           % The check() and checkEditor() methods go here\r\n%       end\r\n% \r\n% The constructor serves as a simple switchyard allowing the user to check\r\n% strings, files and an execution path that would operate on the editor. \r\n% \r\n% The MATLAB code in our case allows users to pass in strings, filenames or \r\n% even no arguments. Since, the invocation of the class is identical to the\r\n% invocation of MATLAB functions users that are used to MATLAB function, can \r\n% use this class in their procedural code, whereas developers who are comfortable\r\n% with Object Oriented techniques can use the methods of this object for \r\n% finer grained control over the utility. \r\n% \r\n%       %% CHECK Method to check an input string\r\n%       function check(obj, inputStr, varargin)\r\n% \t\r\n%           % If line number is specified use it for the link\r\n%           if ~isempty(varargin)\r\n%               obj.Handle.linenumber = num2str(varargin{1});\r\n%               obj.Handle.checkSpelling(inputStr);\r\n%           else\r\n%               obj.Handle.checkSpelling(inputStr);\r\n%           end\r\n%       end\r\n% \r\n% The check() method is where the rubber meets the road. The MATLAB code\r\n% invokes the Java code and the spelling check is performed. The\r\n% checkEditor method (omitted for brevity) is similar in that it reads in \r\n% the current file that is open in the editor and then performs the check.\r\n% \r\n% If a linenumber is specified such as in the case of the checkEditor()\r\n% code, the output includes a hyperlink to the line using the MATLAB\r\n% opentoline() function.\r\n% \r\n% Testing our class:\r\n% \r\n%    >> spellcheck          % Checks the content of the editor\r\n%    \r\n%    Input (172): github\r\n% \t    No suggestions\r\n%    Input (174): API\r\n% \t    Suggestion: AP\r\n% \t    Suggestion: APB\r\n% \t    Suggestion: APO\r\n% \r\n% The class now provides me a single command to check the contents of my\r\n% editor making it trivially accessible as I author content.\r\n% \r\n% Testing the other routes through the constructor:\r\n% \r\n%    >> spellcheck('majic') % Checks string\r\n%    >> spellcheck majic    % Equivalent syntax\r\n% \r\n% The spellcheck object can also be instantiated and persisted for finer\r\n% grain control. \r\n% \r\n%    >> s = spellcheck; \r\n%    >> s.check('majic');    % Equivalent syntax    \r\n% \r\n%    Input : majic\r\n% \t    Suggestion: magic\r\n% \t    Suggestion: manic\r\n%\r\n% Is this really multi-language capable? I test the code again setting the dictionary to German. \r\n% \r\n%    >> s.Dictionary = 'c:\\Work\\Spellchecker\\public\\de_DE\\de_DEx.dic';\r\n%    >> s.check('Spricst du deutsh')  % Intentional spelling mistake\r\n% \r\n%    Input : Spricst\r\n% \t    Suggestion: sprichst\r\n%    Input : deutsh\r\n% \t    Suggestion: deutsch\r\n%\r\n% MATLAB returns the corrected version - \"Sprichst du deutsch\" which sounds correct\r\n% (perhaps a native speaker of the language can confirm).\r\n% \r\n% Happy with the way my MATLAB functionality is working, I can finally\r\n% address the last design requirement. \r\n% \r\n%% \r\n% *The utility should be testable*\r\n% \r\n% Andy has some great content on this blog about the testing framework that \r\n% MATLAB provides for the construction of a regression test suite. I will\r\n% not go into the details of building a test suite but rather dwell on the\r\n% ramifications of the requirement.\r\n% \r\n% The construction and use of an automated test suite is a very important \r\n% part of integrating with 3rd party libraries and products. The test suite\r\n% isolates our work from upstream dependency changes. If the Jazzy library\r\n% changes upstream, evolves, improves, upstream, it would naturally affect \r\n% our functionality. \r\n% \r\n% Having a fully automated test suite buys the ability to retest\r\n% functionality against upstream changes to the Jazzy library. In this\r\n% particular case, the code is pretty stable but the reason I write about\r\n% this is oftentimes, the module upstream is very actively maintained and\r\n% evolves, improves, and changes very frequently. In such cases, the \r\n% investment in building a regression test suite very quickly pays off. \r\n% \r\n% In conclusion, as a platform MATLAB is the melting pot. A variety of technologies and\r\n% techniques are available right from the language itself and tooling can \r\n% leverage this inherent strength to extend of the platform. As a developer\r\n% this is useful to know as MATLAB can leverage the best-in-class\r\n% technologies to create robust solutions with minimal effort. \r\n%\r\n% In the spirit of keeping it open, extensible, usable and useful, \r\n% please fork the code behind this example from github [*].\r\n% \r\n% Tag: API Design\r\n##### SOURCE END ##### 136a9c5e21d843dc96a0a3a81cb44b62\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img src=\"https:\/\/blogs.mathworks.com\/developer\/files\/EasyPhoto.png\" class=\"img-responsive attachment-post-thumbnail size-post-thumbnail wp-post-image\" alt=\"Easy button with a product DVD\" decoding=\"async\" loading=\"lazy\" \/><\/div><!--introduction--><p>Writing MATLAB code is seductively <a href=\"https:\/\/blogs.mathworks.com\/developer\/files\/EasyPhoto.png\" target=\"_blank\">easy<\/a>. Polishing the functionality of algorithmic MATLAB code to make it usable, useful and testable requires a bit of design.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/developer\/2016\/01\/16\/making-code-usable-useful-and-testable\/\">read more >><\/a><\/p>","protected":false},"author":135,"featured_media":422,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[11,10],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/390"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/users\/135"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/comments?post=390"}],"version-history":[{"count":30,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/390\/revisions"}],"predecessor-version":[{"id":423,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/390\/revisions\/423"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media\/422"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media?parent=390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/categories?post=390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/tags?post=390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}