Updating Structure Input for Functions
古いコメントを表示
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 件のコメント
"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
2024 年 1 月 8 日
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.
採用された回答
その他の回答 (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 件のコメント
Jekazu
2024 年 1 月 8 日
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
2024 年 1 月 8 日
If the name of the fruit is meta-data...
Stephen23
2024 年 1 月 8 日
"If the name of the fruit is meta-data..."
It is.
Walter Roberson
2024 年 1 月 8 日
移動済み: Walter Roberson
2024 年 1 月 8 日
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.
カテゴリ
ヘルプ センター および File Exchange で MATLAB についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!