The function Triangle()
is clearly a script that you turned into a function. I personally don't like putting clc
, clear
and close
at the top of my scripts, but I see this a lot, and it's not a terrible thing to do. In a function they are very much out of place.
A function has its own workspace (it cannot see variables defined outside of it), so there really is no need for a clear
. This is the point of using functions instead of scripts: each function has its own workspace ("scope" in other programming languages), which is cleared the moment the function ends. The base workspace doesn't get cluttered with variables if you use functions instead of scripts, and the code inside the function will not accidentally be using variables from a different scope (which makes finding bugs easier).
Given that Triangle()
asks for user input, a clc
is not terrible, but you could accomplish the same effect (make the input prompt more visible) by first printing some empty lines.
close all
closes all figure windows. Your program doesn't deal with figure windows, why attack any existing ones? Just let them be!
force_positive_finite()
is fine. Of course there are other ways to implement it. Instead of break
, for example, you could return
. This makes it a bit easier (IMO) to read the function, because I don't need to look for additional code below the loop. I know this is where the function ends. But simpler would be:
function output = force_positive_finite(var_name) % Ask/force the user to enter a positive number output = -1; while ~input_error_response(output) output = input("Enter in "+var_name+" (m): "); end end
while
tests a condition. Instead of invalidating that test by testing true
, and adding an additional if
statement, use that test to do what your if
statement does.
Similarly, input_error_response()
can be simplified a bit. The construct if <test>, v = true, else, v = false
is a typical anti-pattern, better written as v = <test>
. You do a bit more inside your if
statement, still you can avoid assigning true
or false
to your response
variable:
function response = input_error_response(in) % Warns user if input is invalid response = ~isempty(in) && in >= 0 && isfinite(in) if ~response disp("Enter a value: {0 <= VALUE < inf}"); end end
Note that your comment "Value must be a non-empty positive number" comes next to a test for the number being non-negative, which is not the same as positive. Positive: in > 0
. Non-negative: in >= 0
. [Your original test, in < 0
is negated as in >= 0
, as I put into my version of the function.]
I changed the in == inf
test to ~isfinite(in)
. This catches also the case where in == -inf
(which you already tested for with the non-negativity test), and the case where in
is NaN.
Finally: What if the user inputs "foo"
? What if the user inputs [4, 6]
? You should probably also test that the input is a double array (isnumeric(in)
or isfloat(in)
or isa(in,'double')
), and scalar (isscalar(in)
).
input()
interaction is usually something you want to confine to the very top-level application, and keep it out of utility functions.\$\endgroup\$clc
, thank you\$\endgroup\$