et181:endterm test, fall 2010 (200 points) name: Closed notes, open book, two hour test. You may use any graded program of your choice. There are four sections on eight pages. Each section is worth 50 points. Section A (50 points) The following program constructs a spherical Ball object based on the diameter d entered from the keyboard, and then determines its volume, surface area, and major circumference from the following three formulas: volume = π*d 3 /6 area = π*d 2 circum = π*d #include <iostream> using namespace std; float const PI = (355.0/113.0); class Ball{ private: float diam; // diameter of the ball public: Ball(float d0 = 1) { // Constructor diam = d0; cout << "ball diameter = " << diam << endl; void find(float& vol, float& area, float& circum); // evaluate volume, surface area, major circumference ; // testing the class Ball: int main() { float diam, vol, area, circum; cout << "enter ball diameter:\n"; cin >> diam; // In this box write the two statements that // 1. creates a Ball object and // 2. invokes the class method 'find' cout << " volume is " << vol << " cubic units\n"; cout << " surface area is " << area << " sq. units\n"; cout << " major circumference is " << circum << " units\n"; return 0; The following is a typical execution run of this program: enter ball diameter:10 ball diameter = 10 volume is 523.599 cubic units surface area is 314.159 sq. units major circumference is 31.4159 units 1
In the following box complete the definition of the method find according to the following formulas: volume = π*d 3 /6 area = π*d 2 circum = π*d Notice from the method prototype in the class Ball that since the method has to assign values to three arguments, they are passed by reference. The function should be complete, including commented pre- and post- conditions 2
Section B (50 points) A leap year is a year that is evenly divisible by 4, other than a century year (such as 1900). However a century year that is evenly divisible by 400 (such as 2000) is also a leap year. Complete the following program by writing the boolean method leap of the class Date in the box below. Method leap returns the value true if the private variable year is a leap year and false if it is not. #include <iostream> #include <cmath> using namespace std; class Date{ private: int year; public: Date(int yr = 2008) { // Constructor year = yr; cout << "year " << year << endl; //############################################## // method to determine if year is a leap year bool leap(); //############################################## ; int main() { int year; // the year in question cout << "enter a year (all four digits):\n"; cin >> year; Date my_year(year); if(my_year.leap()) { cout << " is a leap year\n; else cout << "is NOT a leap year\n"; return 0; 3
Hint: The conditional expression should check that either (year is evenly divisible by 4) and (not (evenly divisible by 100)) or that (year is evenly divisible by 400). Note that "evenly divisible" means divisible without any remainder. This is conveniently checked using the mod (%) operator. Note the logical operators are: and, or and not, and the relevant relational operators are == (equal) and!= (not equal). The function should be complete, and should include pre and post conditions. 4
Sections C and D (100 points) In a lab experiment we wish to determine the value of an unknown resistor R by measuring a number of voltage-current pairs. The voltage V(volts) is linearly related to the current I(amps) by Ohm's law, as shown below. Using the Least Squares approach we can use the n experiments to reduce the uncertainty and obtain the 'best fit' value of R, as follows: V Linear Least Squares fit of the data Vj I j V = R*I I leads to: R = n-1 j = 0 n-1 j = 0 (V j *I j ) (I j *I j ) Notice that when n = 1 then the Least Squares summation reduces to Ohm's law as shown on the graph. The experimental VI data is saved on a file which can be read into two arrays and then analyzed as above. The main program shown below has two function prototypes: getvi to get the data from the file to the volts[] and amps[] arrays, and findr to evaluate the least squares formula shown above. In the following two sections we wish to complete the program by writing both function definitions. // Evaluate the resistance from voltage/current experiments #include <iostream> #include <iomanip> #include <fstream> #include <cassert> using namespace std; void getvi(float volts[], float amps[], int& n, int max); // get VI data from file into volts, amps arrays float findr(float volts[], float amps[], int n); // determine resistance by Least Squares int main() { const int SIZE = 15; float volts[size], amps[size]; float resistance; int n = 0; getvi(volts, amps, n, SIZE); if(n > 0) { cout << fixed << showpoint << setprecision(2); cout << " volts amps\n"; for(int i = 0; i < n; i++) cout << setw(7)<< volts[i]<< setw(7)<< amps[i] << endl; resistance = findr(volts, amps, n); cout<< "resistance is approx. "<< resistance << " ohms\n"; else cout << "no data in file\n"; return 0; // the function definitions getvi and findr go here. 5
Section C (50 points) Assume that the experimental data required for the program above has been saved in two columns on a text file named VI.data as follows: 89.40 2.20 119.40 2.70 194.50 4.61 23.30 0.65 134.80 3.10 63.40 1.50 213.70 5.20 127.80 3.00 first column: voltage (volts) second column: current (amps) voltage/current data of a resistor Using this data file, the output resulting from execution of this program follows: volts amps 89.40 2.20 119.40 2.70 194.50 4.61 23.30 0.65 134.80 3.10 63.40 1.50 213.70 5.20 127.80 3.00 resistance is approx. 42.08 ohms In this section we wish to develop the function getvi, designed to get the values from the data file into the volts and amps arrays, as well as determine the number of data values (n) read from the file. 6
In the box below, write the C++ function getvi, which gets the data from the VI.data file to the volts and amps arrays and determines the number of data items read. Be sure not to overfill the arrays, and to have the computer respond suitably if the file could not be opened. No comments are required. The following represent typical file statements and functions that you may wish to use in your function: ifstream infile("my.data"); declares a file variable infile for getting data and associates infile with a disk file named my.data for input note that if the file could not be opened then infile will have the boolean value false thus we can check for opening of a file using the assert function or an if statement. assert(infile); a void function that aborts the program with a message if its argument is false, i.e. if the file could not be opened. infile >> x >> y; reading numerical data from the file into two declared variables x, and y. These could be either ordinary scalar variables or array elements. Statement will return the value false if the file does not contain numerical data, or if we have reached the end-of-file, thus this expression (without the trailing semicolon) can be used as the condition in an if statement or a while loop, as needed. Note that the while loop has the form: while(condition) {statements Thus the group of statements are repeatedly executed until the condition becomes false. infile.close(); closes the file after use. 7
Section D (50 points) In the box below write the C++ coding of a function named findr which evaluates the above Least Squares approximation to the data. It should return a float value (representing the resistance R) and has three arguments. The first two arguments are the float arrays volts and amps (representing V and I respectively), and the third argument is the integer n which represents the number of experiments. The Least Squares formula is repeated for your convenience: V Linear Least Squares fit of the data Vj I j V = R*I I leads to: R = n-1 j = 0 n-1 j = 0 (V j *I j ) (I j *I j ) The function should protect itself against a zero value of n by means of a displayed message and not allowing a division by zero to occur within the function. In this case the function should return the value zero. No comments are required. Hint: Evaluate the two summation terms (amps i 2 ), (volts i * amps i ) separately in a for loop, and then apply them to the formula before returning the result. Do not forget to initialize each summation, and to trap the exception condition (n equals zero). 8