Updating Structure Input for Functions
Ältere Kommentare anzeigen
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 Kommentare
"Obviously, I could rewrite my functions to replace instances of apples with coconuts or add lines to calculate both apples and coconuts simultaneously."
Both of those options are best avoided.
"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."
Yep, so don't do that.
"I think there is an easy way to update the code for an arbitrary number of fruits but not sure what that entails."
Hint: you are using a language which is based around arrays and indexing...
"What would be the best way to update and future proof the code?"
Use arrays.
"Should I have written the initial code differently before knowing there would be other fruits besides apples?"
Yes.
As soon as you force meta-data into variable or fieldnames like that then you make "future-proofing" your code much harder. Easily avoided by using arrays, matrices, and vectors.
"I have searched for similar questions and answers but didn't see anything similar (not sure what keyword I am missing)."
Indexing.
"Insight would be much appreciated."
Use arrays.
You are overthinking this.
Jekazu
am 8 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.
Akzeptierte Antwort
Weitere Antworten (2)
If you had as follows, it would work for any fruit, wouldn't it?
fruit.Mass = 0.15; %kg
fruit.Height = 4; %m
6 Kommentare
Jekazu
am 8 Jan. 2024
Don't hard-code the type of fruit in the names. It's a piece of data so store it as data.
fruit.type = 'apple';
fruit.Mass = 0.15; %kg
fruit.Height = 4; %m
describeFruit(fruit)
fruit2 = struct('type', 'watermelon', 'Mass', 2, 'Height', 3.75);
describeFruit(fruit2)
function describeFruit(F)
fprintf("The %s has a mass of %g kg and falls from a height of %g meters.\n", ...
F.type, F.Mass, F.Height)
end
While true, that would mean losing the identity of the particular fruit, i.e. that fruit.Mass and fruit.Height could be for any number of fruit.
That's what variable names are for,
apple.Mass = 0.15; %kg
apple.Height = 4; %m
coconut.Mass = 0.23; %kg
coconut.Height = 5; %m
ouch = fruitForce(apple, otherParams);
yikes = fruitVelocity(coconut, otherParams);
Matt J
am 8 Jan. 2024
If the name of the fruit is meta-data...
Stephen23
am 8 Jan. 2024
"If the name of the fruit is meta-data..."
It is.
Walter Roberson
am 8 Jan. 2024
Verschoben: Walter Roberson
am 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.
1 Kommentar
Jekazu
am 8 Jan. 2024
Kategorien
Mehr zu MATLAB finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!