Updating Structure Input for Functions
3 views (last 30 days)
Show older comments
Hello,
Let's say I have a structure for fruit:
fruit.appleMass = 0.15; %kg
fruit.appleHeight = 4; %m
Let's say I also have another structure for other variables:
otherParams.gravity = 9.81; %m/s^2
otherParams.newtonHeight = 1.68; %m
I have a simple function to calculate the force of a falling fruit and another simple function to calculate the maximum velocity of a falling fruit based on the apocryphal Isaac Newton tale:
ouch = fruitForce(fruit, otherParams);
yikes = fruitVelocity(fruit, otherParams);
function [ouch] = fruitForce(fruit, otherParams)
ouch = fruit.appleMass*otherParams.gravity;
end
function [yikes] = fruitVelocity(fruit, otherParams)
deltaHeight = fruit.appleHeight - otherParams.newtonHeight;
yikes = sqrt(2*deltaHeight*otherParams.gravity);
end
However, if later I discover I need to add another fruit to my structure, like a coconut, and need to perform the same calculations (poor Newton), I need to update the code.
Creating fields for coconuts is straightforward. Obviously, I could rewrite my functions to replace instances of apples with coconuts or add lines to calculate both apples and coconuts simultaneously. However, updating my functions each time I have a new fruit seems very ineffcient and seems highly prone to issues if I later have several function files calling fields from my fruit structure.
I think there is an easy way to update the code for an arbitrary number of fruits but not sure what that entails. What would be the best way to update and future proof the code? Should I have written the initial code differently before knowing there would be other fruits besides apples?
I have searched for similar questions and answers but didn't see anything similar (not sure what keyword I am missing). Insight would be much appreciated.
3 Comments
Stephen23
on 8 Jan 2024
Edited: Stephen23
on 9 Jan 2024
Don't feel silly. I am just trying to show that a change of perspective helps: MATLAB is based on arrays, so you should always try to solve tasks first using arrays... and only if that does not work (unlikely) try something else.
This applies to all programming languages of course: if language X is based on Y... then it makes sense to use Y when writing code in X (at least as a starting point).
"I appreciate that you addressed many of the points in my inquiry."
Let me know what I missed, I am happy to clarify or provide examples.
Accepted Answer
Stephen23
on 8 Jan 2024
Edited: Stephen23
on 9 Jan 2024
Do not use nested structures.
Definitely do NOT use lots of variables each named after a fruit! Ugh, no.
Use a structure array:
S(1).name = 'apple'
S(1).mass = 0.15; %kg
S(1).height = 4; %m
S(2).name = 'banana'
S(2).mass = 0.1; %kg
S(2).height = 2; %m
- You can have any number of fruit (the structure array can have any number of elements).
- Each element is uniquely identified with a name and any other fields (i.e. data) that you want.
- You can loop over the fruit trivially using very basic indexing: https://www.mathworks.com/help/matlab/matlab_prog/access-multiple-elements-of-a-nonscalar-struct-array.html
- Bonus: use comma-separated lists to allocate or access data in the structure array: https://de.mathworks.com/matlabcentral/answers/1656435-tutorial-comma-separated-lists-and-how-to-use-them
Do not make your data any more complex than that.
Do not force meta-data (e.g. names of fruit) into fieldnames or variable names (unless you want to force yourself into writing slow, complex, inefficient, buggy code that is hard to debug). Meta-data is data: data belongs in your variables, not in the variable/field names. Data in variables makes it much easier to write expandable, generalizable, efficient code. See also Steven Lord's comment here: https://www.mathworks.com/matlabcentral/answers/2067801-updating-structure-input-for-functions#comment_3022366
Understand that meta-data is data. Then you would avoid the situation that you have gotten yourself into.
5 Comments
Stephen23
on 9 Jan 2024
Edited: Stephen23
on 9 Jan 2024
"The intent of the function name question was to ask whether or not function names should be as generic as possible or as specific as desired (including metadata like "fruit" in the name). I think for the falling fruit problem, a very generic function name could be "fallingObjectForce" compared to "fruitForce"."
Ah, I see. That is actually a good question. Personally, I would keep functions (and their names) as general as is reasonable**: it often happens that once you do that, other ways to use your functions or approaches to processing your data will appear.
But for a start just focus on robust data design and efficient code.
** You will note that this just shifts the question to "what is reasonable?" Like all other types of engineering, writing code is ultimately a matter of compromise between many many many factors (e.g. correctness, readability, understandability, debuggability, complexity, expandability, generalizability, runtime, maintenance time, etc.) How to balance those priorities depends on you, your projects, your experience, your goals, etc.
If my answer helped you to resolve your original question then please remember to click the accept button!
More Answers (2)
Walter Roberson
on 8 Jan 2024
Moved: Walter Roberson
on 8 Jan 2024
What if you did something like
fruit.apple.Mass = 0.15; %kg
fruit.apple.Height = 4; %m
fruit.coconut.Mass = 0.89; %kg
fruit.coconut.Height = 4; %m
then you could use dynamic field name references:
fn = fieldnames(fruit);
for fi = 1 : length(fn)
thisfruit = fn{fi};
deltaHeight = fruit.(thisfruit).Height - otherParams.newtonHeight;
yikes.(thisfruit) = sqrt(2*deltaHeight*otherParams.gravity);
end
and the output would be a struct array with one field for each fruit.
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!