Part A Create a file called planets.txt with the contents shown below and place
ID: 3847165 • Letter: P
Question
Part A
Create a file called planets.txt with the contents shown below and place it in your working directory:
Mercury: R = 1,516 mi, D = 35.98*10^6 mi, M = 3.285*10^23 kg Venus: R = 3,760 mi, D = 67.24*10^6 mi, M = 4.867*10^24 kg Earth: R = 3,959 mi, D = 92.96*10^6 mi, M = 5.972*10^24 kg Mars: R = 2,106 mi, D = 141.6*10^6 mi, M = 6.4171*10^23 kg Jupiter: R = 42,441 mi, D = 483.8*10^6 mi, M = 1.898*10^27 kg Saturn: R = 36,184 mi, D = 888.2*10^6 mi, M = 5.683*10^26 kg Uranus: R = 15,759 mi, D = 1.787*10^9 mi, M = 8.681*10^25 kg Neptune: R = 15,299 mi, D = 2.795*10^9 mi, M = 1.024*10^26 kg Pluto: R = 737.6 mi, D = 3.67*10^9 mi, M = 1.309*10^22 kg
Observing that each line in the file planets.txt is of the same format, use the function textscan to read the contents of the file into a cell array called planets. The cell array should store planet names, radii, average distances from Sun, and the planet masses. All data should be stored in the cells in the form of strings. Units need not be included.
Part B
Assign to variable n the number of planets contained in the cell array planets created in Part A. Do not assume this number to be 9. Preallocate a vector of structs called ps to be of length n. The fields of the structs should be name, radius, aveD, mass. The field name will store a string corresponding to a planet’s name, while the fields radius, aveD and mass will store real numbers.
Part C
Once the vector of structs ps has been preallocated, by looping through the cell array planets get the stored data and assign it to the corresponding fields of the struct vector ps. Make sure to store in the struct vector ps the radii, average distances from Sun, and masses as real numbers by performing necessary operations on strings.
Part D
From the struct vector ps, determine the combined mass of all the planets and print the result to the screen using fprintf. The output should look something like this: Combined mass of all the planets is: __________ kg. Part E From the struct vector ps, determine which two planets in the solar system are closest to each other. Output to screen their names and average mutual separation using fprintf. Output should look something like this: Planets __________ and _________ are closest to each other. Their seperation is: __________ mi.
Explanation / Answer
Create Data for an Example
I'm only going to consider scalar structures for this post. The contents of each field in this case will also be scalars, for easy illustration. I'd like to create output that increases the value of each entry by 1.
s.a = 1;
s.b = 2;
s.c = 3;
Let me get the field names so I can have the code be reasonably generic.
fn = fieldnames(s)
fn =
'a'
'b'
'c'
First Method - Loop Over Number of Field Names
In the first case, I find out how many fields are in the struct, and then loop over each of them, using dynamic field referencing to access the value in each field.
out1 = zeros(1, length(fn));
for n = 1:length(fn)
out1(n) = s.(fn{n}) + 1;
end
out1
out1 =
2 3 4
Second Method - Loop Over Field Names Themselves
In the second case, I am going to bypass the numeric indexing and loop through the fields themselves. Since the for loop in MATLAB processes the indices a column at a time, I have to turn my column of field names into a row vector. It happens to be a cell array, so I also have to convert the field names to character arrays to use dynamic field referencing. I won't preallocate the output out2 this time, but allow this small array to grow, so I don't need to add a counter to the loop.
out2 = [];
for str = fn'
out2(end+1) = s.(char(str)) + 1;
end
out2
out2 =
2 3 4
Check that the results of the first two methods agree.
isequal(out1,out2)
ans =
1
Third Method - Use structfun
Instead of looping through fields at all, use structfun which iterates over fields in a scalar structure.
out3 = structfun(@(x)x+1,s);
out3 = out3.'
out3 =
2 3 4
Since the results are returned as a column vector, I transpose them so I can compare the output to that of the other methods. Check that the results of the last two methods agree.
isequal(out2,out3)
ans =
1