Presentation is loading. Please wait.

Presentation is loading. Please wait.

Chapter 3 Working with Batches of Data. Objectives Understand vector class and how it can be used to collect, store and manipulate data. Become familiar.

Similar presentations


Presentation on theme: "Chapter 3 Working with Batches of Data. Objectives Understand vector class and how it can be used to collect, store and manipulate data. Become familiar."— Presentation transcript:

1 Chapter 3 Working with Batches of Data

2 Objectives Understand vector class and how it can be used to collect, store and manipulate data. Become familiar with the implementation of sentinel loops. Investigate the and headers from the standard library. Introduce file input and output. Explore the use of vector objects. Become familiar with the ternary operator.

3 C++ “C++ is like jamming a helicopter inside a Miata and expecting some sort of improvement.” – Drew Olbrich “I invented the term Object-Oriented, and I can tell you I did not have C++ in mind.” – Alan Kay

4 Computing Course Grade Suppose you are taking a course where the final is 40% of the grade, the midterm is 20% and homework is 40%. Suppose we do not know the number of homework assignments, we will just read until the user enters and null string. Then we will compute the homework average.

5 Beginning the Grade Program Our program begins with include and using commands. #include using std::cin; using std::cout; using std::endl; using std::setprecision; using std::string; using std::streamsize;

6 ios and iomanip defines streamsize, which is the type the input-output library uses to define sizes. defines setprecision which we will use to format our output.

7 Getting a Name int main() { // ask for and read the student's name cout << "Please enter your first name: "; string name; cin >> name; cout << "Hello " << name << "!" << endl; // ask for and read the midterm and final grades cout << "Please enter your midterm and final exam grades: "; double midterm, final; cin >> midterm >> final; Notice how we use one statement but two >> to read in multiple values. double is a floating point number but uses twice as much space for more accuracy.

8 Sentinel Loop // ask for the homework grades cout << "Enter all your homework grades, "; cout << "followed by end-of-file (ctrl-Z (PC) or ctrl-D (Mac)): "; // the number and sum of grades read so far int count = 0; double sum = 0; // a variable into which to read double x; // invariant: // we have read count grades so far, and // num is the sum of the first count grades while (cin >> x){ ++count; sum += x; }

9 Sentinel Loop Notice the loop while (cin >> x){ //loop stuff } This reads until there are no more numbers to read. – The stream is empty. – The next input to read cannot be converted to a double. The user indicates the stream is empty using the end-of-file character. – Control z (windows) – Control d (Linux, Unix, Macintosh)

10 >> Notice that the >> operator is doing two things here. If there is valid data to be read in the cin stream then it has the side-effect of modifying the value of the variable x. – In this case the actual value of the expression is true, so the body of the loop executes. – If the read fails there is no side-effect and the return value is false, so the loop terminates.

11 End-of-File The end-of-file character is a standard way of marking the end of either a data file or input from the keyboard. Once the end-of-file character is encountered, that input stream can not longer be used. All attempts to read from it will fail (return false and have no effect on the variables involved).

12 Printing Output // write the result int prec = int(cout.precision()); cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * sum / count << setprecision(prec) << endl; system("pause"); return 0; }

13 Setting Precision We want to print the output with 3 significant digits. To do this we use setprecision. Like endl this is a manipulator. After it is used, all the output from the stream will appear with the specified number of significant digit. Since this is a permanent change it is a good idea to change it back to what it was before when we are done. This is why precision was used to store the previous precision in an int.

14 Type Casting Notice the line int prec = int(cout.precision()); This line calls a function, cout.precision(), that has a return type of streamsize. Instead of dealing with this type, we used type casting to turn convert it to an int.

15 Reading From a File Our program is designed so that the input could come from a file with little modification. To do file input and output the first step is to include. We create an input stream associated with our file by creating an ifstream object. ifstream infile(“in”) ; Here infile is our variable name for the stream and “in” is the name of the file on the hard drive.

16 Reading From a File We read from the stream in the same manner as before. infile >> x; The only modification is that cin is replaced with infile. When we are done with the file we should close it. infile.close();

17 Writing to a File As with input, output is similar if we want to output to a file. We create an output stream associated with our file by creating an ofstream object. ofstream outfile(“out”) ; If the file does not already exist it will be created. If it does exist it will be overwritten. Here outfile is our variable name for the stream and “out” is the name of the file on the hard drive.

18 Writing to a File We write to the stream in the same manner as before. outfile << x; The only modification is that cout is replaced with outfile. Again, when we are done writing we should close the file. outfile.close();

19 Stream I/O We often try to set up our input and output so that it will not be hard to change from manual to file input/output. This is why we are using end-of-file as the sentinel for our loop. We will also often pass the appropriate stream to functions that do input or output. That way we can switch without rewriting the functions.

20 Medians Suppose we want to calculated the median of the homework grades instead of the average. We will need to remember and sort the homework grades. To store the grades we will use a vector. This is similar to a sequence in Python.

21 Vectors Unlike in Python, vectors in C++ are homogeneous. They can only contain entries of a single type. For our code this might look like this. vector homework; This creates a vector that is a container (can contain) values of type double. vector is a template class. We specify what it will contain inside angle brackets.

22 Reading Entries into the Vector vector homework; double x; while (cin >> x) homework.push_back(x); This is similar to sentinel loop from before but we use the push_back method of the vector class. This appends the new value to the end of the vector, increasing its size by 1.

23 Getting the Size of the Vector The size of the vector has its own type (you may have noticed C++ does a lot of that). vector ::size_type Since we don’t want to type this too often let us create our own type using typedef. typedef vector ::size_type vec_sz We can now create a variable of this type and initialize it using the size method. vec_sz size = homework.size();

24 Checking for Empty Vector Next, we check to see if the vector is empty. if (size == 0) { cout << endl << "You must enter your grades. " "Please try again." << endl; return 1; } Notice that returning 1 indicates a problem occurred.

25 Sorting the Vector Next we need to sort the entries in the vector into increasing order. sort(homework.begin(), homework.end()); Sort is defined in the header. The vector class has accessor methods begin and end. The arguments of sort specify the list to be sorted.

26 Computing the Median Computing the median involves using indexing to access elements in the list and a new operator. vec_sz mid = size/2; double median; median = size % 2 == 0 ? (homework[mid] + homework[mid-1]) / 2 : homework[mid]; The indexes of elements of a vector begin at 0. Notice that if both operands are integer types then the / operator performs integer division. If one is a floating point type then / performs floating point division. The remainder of integer division is calculated using the % operator.

27 Ternary Operator Probably the strangest operator in C++ is the ternary operator ? :. This operator takes three operands in the following syntax. condition ? statement1 : statement2 If the condition is true then statement1 is used to replace the entire expression, including all side- effects and return values. If the condition is false then statement2 is executed.

28 Ternary Operator median = size % 2 == 0 ? (homework[mid] + homework[mid-1]) / 2 : homework[mid]; The line could be replaced with the following. if (size % 2 == 0) median = (homework[mid] + homework[mid-1]) / 2; else median = homework[mid]; It is a matter of opinion if the compactness of the ternary operator is worth the penalty in clarity. – Some programmers find it clear, easy to use, and more compact. – Some programmers avoid it completely.

29 Complete Program #include using std::cin; using std::sort; using std::cout; using std::streamsize; using std::endl; using std::string; using std::setprecision; using std::vector; int main() { // ask for and read the student's name cout << "Please enter your first name: "; string name; cin >> name; cout << "Hello, " << name << "!" << endl; // ask for and read the midterm and final grades cout << "Please enter your midterm and final exam grades: "; double midterm, final; cin >> midterm >> final;

30 Complete Program // ask for and read the homework grades cout << "Enter all your homework grades, " "followed by end-of-file (ctrl-Z (PC) or ctrl-D (Mac)): "; vector homework; double x; // invariant: `homework' contains all the homework grades read so far while (cin >> x) homework.push_back(x); // check that the student entered some homework grades typedef vector ::size_type vec_sz; vec_sz size = homework.size(); if (size == 0) { cout << endl << "You must enter your grades. " "Please try again." << endl; return 1; }

31 Complete Program // sort the grades sort(homework.begin(), homework.end()); // compute the median homework grade vec_sz mid = size/2; double median; median = size % 2 == 0 ? (homework[mid] + homework[mid-1]) / 2 : homework[mid]; // compute and write the final grade int prec = int(cout.precision()); cout << "Your final grade is " << setprecision(3) << 0.2 * midterm + 0.4 * final + 0.4 * median << setprecision(prec) << endl; system("pause"); return 0; }

32 Reading Past the End of a Vector It is important that we not try to access undefined elements of a vector. The following would produce unpredictable results. vector homework; cout << homework[0]; The vector has been created but not initialized. In particular we have not assigned a value to homework[0]. We will get whatever happens to be in that memory location. Vectors do not check whether the index is in range.

33 Unsigned Integer Types All standard-library size types (like vector ::size_type) are unsigned integers and cannot be negative. Consider homework.size()-100 This will produce an unsigned integer as well. It cannot be negative even if homework.size() < 100.

34 Homework Chapter 3 (page 49) Total 50 pts possible. – 3-0 – 3-2 (email. 15 pts) – 3-4 (email, 15 pts) – 3-6 (paper and email, 15 pts) – Modify the grade program so that the grade input and output is done to files. Create the input file necessary to test your program. (20 pts)


Download ppt "Chapter 3 Working with Batches of Data. Objectives Understand vector class and how it can be used to collect, store and manipulate data. Become familiar."

Similar presentations


Ads by Google