$29
All 3 components (Cloud9 workspace, Moodle Coderunner attempts, and zip file) must be completed and submitted by Wednesday, March 13, at 6 pm for your homework to receive points.
1. Objectives
• Define classes and create objects
• Array operations: initialization, search
• Create arrays of an object type
• Use filestream objects to read data from text files
• Continue building on what will become your Project 2
2. Submission Requirements
All three steps must be fully completed by the submission deadline for your homework to be graded.
1. Create Hmwk7 directory on your Cloud 9 workspace: Your recitation TA will review your code by going to your Cloud9 workspace. TAs will check the last version that was saved before the submission deadline.
◦ Create a directory called Hmwk7 and place all your file(s) for this assignment in this directory.
◦ Make sure to save the final version of your code (File > Save). Verify that this version displays correctly by going to File > File Version History.
◦ The file(s) should have all of your functions, test cases for the functions in main() function(s), and adhere to the style guide. Please read the
submission file instructions under Week 4. You must include a test case for each one of your member functions for your classes.
2. Submit to the Moodle CodeRunner: Head over to Moodle to the link Homework 7 CodeRunner. You will find one programming quiz question for each problem in the assignment. Submit your solution for the first problem and press the Check button. You will see a report on how your solution passed the tests, and the resulting score for the first problem. You can modify your code and re-submit (press Check again) as many times as you need to, up until the assignment due date. Continue with the rest of the problems.
3. Submit a .zip file to Moodle: After you have completed all 9 questions from the Moodle assignment, zip all 15 files you compiled in Cloud9, and submit the zip file through the Homework 7 (File Submission)link on Moodle.
3. Rubric
Aside from the points received from the Homework 7 CodeRunner quiz problems, your TA will look at your solution files (zipped together) as submitted through the Homework 7 (File Submission)link on Moodle and assign points for the following:
Style and Comments (5 points):
• The style guideis posted on Moodle under Week 6.
• Your code should be well-commented. Please review the standard for well-commented code, presented in more detail in previous homework write-ups.
• Please also include a comment at the top of your solution with the following format:
◦ CS1300 Spring 2019
◦ Author: my name
◦ Recitation: 123 – Favorite TA
◦ Cloud9 Workspace Editor Link: https://ide.c9.io/…
◦ Homework 7 - Problem # ...
Global variables (use will result in a 5 point deduction):
• Later in the semester, we will learn about global variables and the joys and dangerous therein. To keep things simple, straightforward, and easy to debug and test, you may not use global variables in this homework.
Algorithm (5 points):
• Before each function that you define, you should include a comment that describes the inputs and outputs of your function and what algorithms you are using inside the function. Please review the standard for including your algorithm for each function, presented in more detail in previous homework write-ups.
Test Cases (30 points):
1. Code compiles and runs(10 points):
◦ All the files you submit on Moodle under the zip file submission should compile and be free of bugs. It is important that your programs can be compiled and run on Cloud9 with no errors. The class files and the functions included in these programs should match those submitted to the CodeRunner on Moodle.
2. Test cases(20 points):
For this week’s homework, every problem is asking you to define a class and/or some of its member functions, or functions to make use of your classes. In addition to the class files (.h and .cpp), you will need to create a driver/tester program, with a main() function, where you must have test cases for each function or member function. Your test cases should follow the guidelines, Writing Test Cases, posted on Moodle under Week 3.
Please make sure that your submission files follow the the submission file instructionsunder Week 6.
4. Part One: Syntax
Classes
When writing complex programs, sometimes the built in data types (such as int, char, string) don’t offer all of the functionality or flexibility that may be desired or necessary for the problem being solved. A solution to this is for the developer (you - yes, you!) to create your own custom data types to use, called classes. Classes are user-defined data types, which hold their own data members and member functions, which can be
accessed and used by creating an instance of that class. A class is like a blueprint for an object, customized for whatever particular problem a programmer is working on. Below is an example of the basic definition of a class in C++.
Let’s break down the main components of this diagram:
Class Name:
A class is defined in C++ using the keyword class followed by the name of class. The body of the class is defined inside the curly brackets and terminated by a semicolon at the end. This class name will be how you reference any variables or objects you create of that type. For example:
ClassName objectName;
The above line would create a new object (variable) with name objectName and of type ClassName, and this object would have all the properties that you have defined within the class ClassName.
Access Specifiers:
Access specifiers in a class are used to set the accessibility of the class members. That is, it sets some restrictions on the class members not to get directly accessed by outside functions. Let’s consider an analogy to describe access specifiers. Imagine an intelligence agency, like the CIA, that has 10 senior members. Such an organization would have various sorts of information, and would need to have some way of determining who has access to any given piece of information.
Some information may only be accessible to the 10 senior members of the agency, and any other person would be unable to access it directly. This may be the secret operations of the agency or information that would be dangerous if everyone could see it. This data would be private. In a class, like in our intelligence agency, private data is available only to specific data members and member functions. They are not allowed to be accessed directly by any object or function outside the class. Only member functions are allowed to access the private data members of a class.
Some other information may be available to anyone who wants to know about it. This would be public data. Even people outside the CIA would be able to know about it, such as press releases by the agency. In terms of our class, this public data can be accessed by any member function of the class, as well as outside functions and objects. The data members and member functions declared public can be accessed by other classes too. The public members of a class can be accessed from anywhere in the program using the direct member access operator (.) with the object of that class.
Data Members and Member Functions:
Data members are the data variables and member functions are the functions used to manipulate these variables and together these data members and member functions defines the properties and behavior of the objects in a Class. The data members which are declared in any class definition are created by using any fundamental data types (like int, char, float etc). For example, strings objects the data member would be the char array[] that holds all of the individual letters of your string. Some of a string’s member functions would be functions like .substr(), .find(), and .length().
Accessing Data Members:
Keeping with our intelligence agency example, the code below would define a class that holds information for any general agency. In main, we then create a new intelligenceAgency object called CIA, and we set its organizationName to “CIA” by using the access operator (.) and the corresponding data member’s name. However, if we wanted to access the classifiedIntelligence data member, we would not be able to do it in the same way. Not everyone has access to that data. We would need to use a member function of the agency getClassifiedIntelligence() in order to see that information. However, this function may modify the information such that more sensitive bits are removed. This makes sure that there is still some control of the private information that is released by our intelligenceAgency.
class intelligenceAgency
{
public:
intelligenceAgency(); // Default constructor intelligenceAgency(string s); // Parameterized constructor string organizationName;
string getClassifiedIntelligence();
void setClassifiedIntelligence(string s);
private:
string classifiedIntelligence;
};
int main()
{
intelligenceAgency CIA;
CIA.organizationName = “CIA”;
cout << CIA.classifiedIntelligence; //gives an error cout << CIA.getClassifiedIntelligence();
}
Defining Member Functions:
Something you may have noticed is that we declared various member functions in our class definition, but that we didn’t specify how they will work when called. The body of the function still needs to be written. The immediate solution is to define a function, such as getClassifiedIntelligence(), corresponding to our class’s functions. But how does our program know that these functions are the same as the ones we declared in our class? You as the developer need to explicitly tell the computer that these functions you are defining are the same ones you declared earlier.
string intelligenceAgency::getClassifiedIntelligence() {
return classifiedIntelligence;
}
void intelligenceAgency::setClassifiedIntelligence(string s) {
classifiedIntelligence = s;
}
We start the definition as we do any function: with the return type. Then, we have to add a specifier intelligenceAgency:: that lets our program know that this function and the one we declared inside the class are the same. We can see that this function returns the class’s classifiedIntelligence to the user. Functions like getClassifiedIntelligence() are called accessor, or “getter”, functions. This is because they retrieve or ‘get’ the private data members of a class object and return it to the program so that these values may be used elsewhere. The second function, setClassifiedIntelligence(string s), is called a mutator, or “setter”, function. These allow functions from other parts of our program to modify or ‘set’ the private data members of our class objects. Getters and setters are the functions that our program uses to interact with the private data members of our class objects.
Header and Source files
Creating our own classes with various data members and functions increases the complexity of our program. Putting all of the code for our classes as well as the main functionality of our program into one .cpp file can become confusing for you as a programmer, and we need ways of reducing the visual clutter that this creates. This is why, as we increase the complexity of a program, we might need to create multiple files: headerand sourcefiles.
Header file
Header files will have “.h” as their filename extensions. In a header file, we declare one or more of the complex structures (classes) we want to develop. In a class, we define member functions and member attributes. These functions and attributes are the building blocks of the class.
#include <iostream>
using namespace std;
class className
{
public:
.
.
.
private:
.
.
.
};
Source file
Source files are recognizable by the “.cpp” extension. In a source file we implement the complex structures (class) defined in the header file. Since we are splitting the development of actual code for the class into a definition (header file) and an implementation (source file), we need to link the two somehow.
#include “className.h”
In the source file we will include the header file that defines the class so that the source file is “aware” of where we can retrieve the definition of the class. We must define the class definition in every source that wants to use our user defined data type (our class). When implementing each member function, our source files must tell the compiler that these functions are actually the methods defined in our class definition using the syntax that we showed earlier.
How to compile multiple .cpp and .h files:
In this homework, it will be necessary to write multiple files (.h and .cpp) and test them before submitting them. You need to compile and execute your code using the command line. This means you need to type commands into a bash window instead of pressing the Runbutton as you may have been doing.
Make sure that you start by changing directories so that you are in the folder where your solution’s files are stored. In this example, our folder will be called hmwk7. To change to this directory, use:
cd hmwk7/
When compiling from the command line, you need to specify each of the .cpp files in your project. This means that when you call the g++ compiler, you need to explicitly name the files you’re compiling:
g++ -std=c++11 file1.cpp file2.cpp main.cpp
The compiling command results in the creation of an executable file. If you did not specify a name for this executable, it will be named a.out by default. To execute this file, use the command:
./a.out
You can add the -o flag to your compiling command to give the output file a name:
g++ -o myName.out -std=c++11 file1.cpp file2.cpp main.cpp
And then run the file with
./myName.out
Example 1:
Compiling book.cpp and Hmwk7.cpp. The picture below shows a bashwindow.
Example 2:
Here, we have named the executable hmwk7
5. Problem Set
Note: To stay on track for this homework set, we recommend to finish/make considerable progress on Problems 1-6 by Friday. Come to recitation with questions!
The first 2 problems of this homework have been designed to help you practice creating and using classes, as well as to build upon the work that you’ve been doing with arrays. These problems will require you to make separate header and source files for your class, as well as a “driver” file which will test the class and functions that you’ve created. For these first 2 problems, you will need to turn in 4 files: your header file for the Planet class (Planet.h), a source file for the definitions of the getters and setters of the Planet class (Planet.cpp), and a source file for each individual problem in this section (planetDriver.cpp (Problem 1)andmaxRadiusDriver.cpp (Problem 2)).
5.1. Stretch first!
Problem 1 (10 points) planet class
Create a class Planet, with separate interface file (Planet.h) and implementation file (Planet.cpp), comprised of the following attributes:
Data members (private):
string: planetName
Name of the planet
double: planetRadius
Radius of the planet
Member functions (public):
Default constructor
Sets planetNameto empty string, and planetRadius to 0.0
Parameterized
Takes a string and double initializing planetNameand
constructor
planetRadius, in this order
getName()
Returns planetNameas a string
setName(string)
(void) Assigns planetNamethe value of the input string
getRadius()
Returns planetRadius as a double
setRadius(double)
(void) Assigns planetRadiusthe value of the input double
getVolume()
Calculates and returns the volume of the planet as a double
It is advisable to write your own test cases for each class. Test your class in Cloud9 before submitting to the CodeRunner autograder.
The zip submission should have three files for this problem: Planet.h, Planet.cpp, and a driver called planetDriver.cpp to test your member functions. For Coderunner, in the Answer Box, paste your Planet class and its implementation (contents of Planet.h and Planet.cpp). Do not include yourmain() function fromplanetDriver.cpp that you used for testing.
In your main() function, the test cases should include the creation of class objects with both the default and parameterized constructors. You must also test each of the getter and setter member functions by creating and manipulating class objects and displaying output to verify that things are working properly. For reference, follow the cashRegister example from lecture 22 materials, and the Worked Example 9-1 from the textbook (Implementing a Bank Account Class- step 6: Test your class).
Problem 2 (10 points) maxRadius
Write a function, maxRadius, to find the index of the planet with the largest radius in the array. The function should:
• Be named maxRadius
• Take twoarguments in the following order
◦ An array of planetobjects
◦ An integer, the size of the array (possibly partially filled, so this would be the number of actual planet elements in the array)
• Return the index of the planet in the array with the largest radius.
• If multiple planets in the array share the largest radius, your function should return the index of the first planet.
• If the array of Planet objects is empty, your function should return -1
Examples:
Function call
Output
Planet planets[5];
Bird World
planets[0] = Planet(“On A Cob Planet”,1234);
4321
planets[1] = Planet(“Bird World”,4321);
3.37941e+11
int idx
= maxRadius(planets, 2);
cout <<
planets[idx].getName() << endl;
cout <<
planets[idx].getRadius() << endl;
cout <<
planets[idx].getVolume() << endl;
Planet planets[3];
Nebraska
planets[0] = Planet(“Nebraska”,13.3);
13.3
planets[1] = Planet(“Flarbellon-7”,8.6);
9854.7
planets[2] = Planet(“Parblesnops”,6.8);
int idx
= maxRadius(planets, 3);
cout <<
planets[idx].getName() << endl;
cout <<
planets[idx].getRadius() << endl;
cout <<
planets[idx].getVolume() << endl;
Planet planets[3];
-1
int idx
= maxRadius(planets, 0);
cout <<
idx << endl;
Planet planets[3];
Delphi 6
planets[0] = Planet(“Planet Squanch”,6.8);
8.6
planets[1] = Planet(“Delphi 6”,8.6);
2664.31
Planet newPlanet;
newPlanet.setName(“Cronenberg World”);
newPlanet.setradius(8.6);
planets[2] = newPlanet;
int idx
= maxRadius(planets, 3);
cout <<
planets[idx].getName() << endl;
cout << planets[idx].getRadius() << endl; cout << planets[idx].getVolume() << endl;
The zip submission should have three files for this problem: Planet.h, Planet.cpp, and a driver called maxRadiusDriver.cpp, with your maxRadius() function and a main() function to test your maxRadius()function.
For the Problem 2 Coderunner, paste your Planet class, its implementation, and your maxRadius function. (Submit what you did for Problem 1, and add your maxRadius function.) Do not include your main() function from maxRadiusDriver.cpp that you used for testing your function.
5.2. Part Two: Let’s do this.
For the remaining 7 problems, we will be updating our solutions from Homework 6 in preparation for Project 2, where we will create a book recommender system. For the purposes of this assignment, we will be re-organizing the functions you’ve created to read and store users and ratings by creating classes for both users and books. For this portion of the homework, you will be asked to submit 11 separate files (a recap of the list of required files can be found on Chapter 6, page 35 of this write up): a header and source for both the user and books classes (Book.h and Book.cpp, and User.h and User.cpp), a driver to test the basic functionality of each class (bookDriver.cpp, userDriver.cpp), as well as a source file that will be the driver for each of the individual functions you write for problems 3-9 (readBooksDriver.cpp, printAllBooksDriver.cpp, readRatingsDriver.cpp, getRatingDriver.cpp). Lastly, you will need to submit a driver that will use all of the functionality of your classes (HW7.cpp).
Problem 3 (10 points) Book Class
Create a Book class, with separate interface file (Book.h) and implementation file (Book.cpp), comprised of the following attributes:
Data members (private):
string: title
string: author
Member functions (public):
Default constructor
Sets both titleand authorto empty strings
Parameterized
Takes two strings for initializing titleand author, in
constructor
this order
getTitle()
Returns titleas a string
setTitle(string)
(void) Assigns titlethe value of the input string
getAuthor()
Returns author as a string
setAuthor(string)
(void) Assigns authorthe value of the input string
The zip submission should have three files for this problem: Book.h, Book.cpp, and a driver called bookDriver.cpp, with a main() function to test your member functions. For Coderunner, paste your Book class and its implementation (the contents of Book.h and Book.cpp). Do not include the main()function, nor the line #include "Book.h”
In your main() function, the test cases should include the creation of class objects with both the default and parameterized constructors. You must also test each of the getter and setter member functions by creating and manipulating class objects and displaying output to verify that things are working properly. For reference, follow the cashRegister example from the Lecture 22 materials, and the Worked Example 9-1 from the textbook (Implementing a Bank Account Class- step 6: Test your class).
Problem 4 (20 points) User Class
Create a User class, with separate interface (User.h) and implementation (User.cpp), comprised of the following attributes:
Data members (private):
string: username
int array: ratings
Number of elements should be size
int: numRatings
Number of books in the database
Int: size
The capacity of the ratings array (50). Constant
Member functions (public):
Default constructor
Sets usernameto an empty string, numRatingsto 0,
size to 50, and all the elements of ratingsarray
to the value 0
Parameterized
Takes a string, an array of integers, and one integer for
constructor
initializing username, ratings, and numRatings,
respectively. Make sure the value passed into the
constructor for numRatingsdoes not exceed the
value of the data member size
getUsername()
Returns usernameas a string
setUsername(string)
(void) Assigns usernamethe value of the input string
getRatingAt(int)
Parameter: int index. Returns the rating stored at
the specified index. If indexis larger than the size of
the ratingsarray, returns -1.
setRatingAt(int,int)
Parameters: int index,int value. Sets the rating
to valueat the specified index,if indexis within
the bounds of the array and valueis between 0 and 5.
Returns a boolean value, trueif the rating is
successfully updated and falseotherwise.
getNumRatings()
Returns numRatings as an integer
setNumRatings(int)
(void) Assigns numRatingsthe value of the input int
getSize()
Returns size as an integer
The zip submission should have three files for this problem: User.h, User.cpp, and a driver called userDriver.cpp, with a main() function to test your member functions. For Coderunner, paste your User class and its implementation (the contents of User.h and User.cpp). Do not include the main() function.
In your main() function, the test cases should include the creation of class objects with both the default and parameterized constructors. You must also test each of the getter and setter member functions by creating and manipulating class objects and displaying output to verify that things are working properly. For reference, follow the cashRegister example from lecture 22 materials, and the Worked Example 9-1 from the textbook (Implementing a Bank Account Class- step 6: Test your class).
Problem 5 (15 points) readBooks
Update the readBooks function from Homework 6 to now fill an array of Book objects instead of having separate titles array and authors array. The functionality stays the same as the one from the previous homework. This function should:
• Accept four input arguments in this order:
◦ stringfileName: the name of the file to be read.
◦ array books: array of Bookobjects.
◦ int numBooksStored: the number of books currently stored in the arrays. You can always assume this is the correct number of actual elements in the arrays.
◦ int booksArrSize: capacity of the books array. The default value for this data member is 50.
• Use ifstream and getline to read data from the file, making an instance of the Book object for each line, and placing it into the booksarray.
• You can use the split() function from Problem 3 in Homework 6, with comma (‘,’) as the delimiter. When you copy your code to the coderunner, make sure you put in the Answer Box your Bookclass, readBooks()function, split() function.
• The function should return the following values depending on cases:
◦ Return the total number of booksin the system, as an integer.
◦ When the file is not opened successfully, return -1.
◦ When numBooksStoredis equal to the size, return -2.
◦ The priority of the return code -2 is higher than -1, i.e., in cases when numBooksStored is equal to the size and the file cannot be opened, the function should return -2.
◦ When numBooksStored is smaller than size, keep the existing elements in books, then read data from the file and add (append) the data to the array. The number of books stored in the array cannot exceed the sizeof the books array.
• Empty lines should not be added to the arrays.
Example 1:The booksarray is empty, so for this example numBooksStoredis zero.
fileName.txt
Author A,Book 1
Author B,Book 2
Function call
Book books[10] = {};
readBooks(“fileName.txt”,books, 0, 10);
Return value
2
Testing the data
// Code to print the values
member author
cout<<books[0].getAuthor()<<endl;
cout<<books[1].getAuthor()<<endl;
// Expected Output
Author A
Author B
Testing the data
// Code to print the values
member title
cout<<books[0].getTitle()<<endl;
cout<<books[1].getTitle()<<endl;
// Expected Output
Book 1
Book 2
Example 2: Suppose there’s already one book in the books array, so numBooksStored is one. Since there is room for 9 more books, all the data read from the new file will be added to the array.
fileName.txt
Author A,Book 1
Author B,Book 2
Function call
Book books[10];
books[0].setAuthor(“Author Z”);
books[0].setTitle(“Book N”);
readBooks(“fileName.txt”,books, 1, 10);
Return value
3
Testing the data
// Code to print the values
member author
cout<<books[0].getAuthor()<<endl;
cout<<books[1].getAuthor()<<endl;
cout<<books[2].getAuthor()<<endl;
// Expected Output
Author Z
Author A
Author B
Testing the data
// Code to print the values
member title
cout<<books[0].getTitle()<<endl;
cout<<books[1].getTitle()<<endl;
cout<<books[2].getTitle()<<endl;
• Expected Output Book N
Book 1 Book 2
Example 3: There’s already one book in the books array, so numBooksStored is one.
However, the array size is only two, so only the first line of the new file is stored.
fileName.txt
Author A,Book 1
Author B,Book 2
Author C,Book 3
Function calls
Book books[2];
books[0].setAuthor(“Author Z”);
books[0].setTitle(“Book N”);
readBooks(“fileName.txt”, books, 1, 2);
Return value
2
Testing the data
// Code to print the values
member author
cout<<books[0].getAuthor()<<endl;
cout<<books[1].getAuthor()<<endl;
// Expected Output
Author Z
Author A
Testing the data
// Code to print the values
member title
cout<<books[0].getTitle()<<endl;
cout<<books[1].getTitle()<<endl;
// Expected Output
Book N
Book 1
Example 4:file does not exist.
Function call
Book books[2];
books[0].setAuthor(“Author Z”);
books[0].setTitle(“Book N”);
readBooks(“badFileName.txt”,books, 1, 2);
Return value
-1
Testing the data
// Code to print the values
member author
cout<<books[0].getAuthor()<<endl;
// Expected Output
Author Z
Testing the data
//
Code to print the values
member title
cout<<books[0].getTitle()<<endl;
//
Expected Output
Book N
Example 5:numBookStoredequals sizemeans the array is already full.
fileName.txt
Author A,Book 1
Author B,Book 2
Author C,Book 3
Function call
Book books[1];
books[0].setAuthor(“Author Z”);
books[0].setTitle(“Book N”);
readBooks(“fileName.txt”,books, 1, 1);
Return value
-2
Testing the data
// Code to print the values
member author
cout<<books[0].getAuthor()<<endl;
// Expected Output
Author Z
Testing the data
// Code to print the values
member title
cout<<books[0].getTitle()<<endl;
// Expected Output
Book N
The zip submission should have three files for this problem: Book.h, Book.cpp and a driver program called readBooksDriver.cpp to test your member functions and readBooks function. For Coderunner, paste your Book class (both the header and implementation), and your readBooks function, not the entire program. After developing in Cloud9, this function will be one of the functions you include at the top of HW7.cpp.
Problem 6 (10 points) printAllBooks
The printAllBooks function from Homework 6 was very useful, so let’s do it again, but with an array of Book objects this time! Write a new printAllBooks function which will be useful in displaying the contents of your library. This function should:
• Accept two arguments in this order:
◦ array books: array of Bookobjects.
◦ int: number of books in the array (Note: this value might be less than the capacity of 50 books)
• This function does notreturn anything
• If the number of books is 0, print “No books are stored”
• Otherwise, print “Here is a list of books” and then each book in a new line using the following statement
cout << books[i].getTitle() << " by "; cout << books[i].getAuthor() << endl;
Note: In the test case, you can always assume that the number of books matches the number of elements in the booksarray.
Expected output (assuming you have read the data from books.txt)
Here is a list of books
The Hitchhiker's Guide To The Galaxy by Douglas Adams Watership Down by Richard Adams
The Five People You Meet in Heaven by Mitch Albom Speak by Laurie Halse Anderson ...
The zip submission should have three files for this problem: Book.h, Book.cpp and a driver program called printAllBooksDriver.cpp to test your member functions and printAllBooks function. For Coderunner, paste only your Book class implementation and printAllBooks function, not the entire program. After developing in Cloud9, this function will be one of the functions you include at the top of HW7.cpp.
Problem 7 (20 points) readRatings
We will now update the readRatings from last week to use an array of User objects instead of having a usernames array and a ratings array. The functionality stays the same as the one from last week.
Write a function readRatings that loads the user ratings by reading the ratings.txt file. The first value of each line in ratings.txt is the username. Each username is followed by a list of ratings of the user for each book in books.txt.
For example, let us say there are in total 3 books. The ratings.txt file would be of the format:
ratings.txt
ritchie,3,3,3
stroustrup,0,4,5
gosling,2,2,3
rossum,5,5,5
...
This function should:
• Accept five arguments in this order:
◦ string filename: the name of the file to be read
◦ array users: array of Userobjects
◦ intnumUsersStorednumber of users currently stored in the arrays
◦ int usersArrSize: capacity of the users arrays. The default value for this data member is 100.
◦ int maxCol: maximum number of columns. The default value for this data member is 50.
• Use ifstream and getline to read data from the file, making an instance of a Userobject for each line, and placing it in the users array.
• Hint: You can use the split() - function from Problem 3 in Homework 6, with comma (“,”) as the delimiter. When you copy your code in the Answer Box on Moodle Coderunner, make sure you copy Users class, readBooks() function, and split() function.
• You can use stoi to convert each rating value (a string, as read from the text file) into an integer value.
• The function should return the following values depending on cases:
◦ Return the total number of users in the system, as an integer.
◦ If the file cannot be opened, return -1
◦ When numUsersStored is greater than or equal to the usersArrSize, return -2
◦ The priority of the return code -2 is higher than -1, i.e., in cases when numUsersStored is equal to the size and the file cannot be opened, the function should return -2
◦ When numUsersStored is smaller than the size of users array, keep the existing elements in users array, then read data from file and add (append) the data to the arrays. The number of users stored in the arrays cannot exceed the size of the users array.
◦ Empty lines should not be added to the arrays.
Example 1:The usersarray is empty, so numUsersStoredis 0.
ratings.txt
Ninja,0,1,2,3,4
Myth,2,2,4,5,1
Sphyer,3,1,0,0,5
Daequan,0,0,0,0,2
Function call
User users[10];
int numUsers = 0;
int usersArrSize = 10;
readRatings(“ratings.txt”, users, numUsersStored,
usersArrSize, 50);
Return value
4
Testing the data
// Code to print the values
member
cout<<users[0].getUsername()<<endl;
username
cout<<users[1].getUsername()<<endl;
cout<<users[2].getUsername()<<endl;
cout<<users[3].getUsername()<<endl;
// Expected Output
Ninja
Myth
Sphyer
Daequan
Testing the data
// Code to print the values
memberratings
cout<<users[0].getRatingAt(0)<<endl;
cout<<users[0].getRatingAt(1)<<endl;
cout<<users[0].getRatingAt(2)<<endl;
cout<<users[0].getRatingAt(3)<<endl;
cout<<users[0].getRatingAt(4)<<endl;
.
.
// Expected Output
0
1
2
3
4
.
.
Example 2:The usersarray is empty, so numUserStoredis 0 and a bad file is given
Function call
User users[10];
int numUsersStored = 0;
int usersArrSize = 10;
readRatings(“badFile.txt”, users, numUserStored,
usersArrSize, 50);
Return value
-1
Testing the data
// Code to print the values
member
cout<<users[0].getUsername()<<endl;
username
cout<<users[1].getUsername()<<endl;
.
.
// Expected Output
“”
“”
.
.
Testing the data memberratings
◦ Code to print the values cout<<users[0].getRatingAt(0)<<endl; cout<<users[0].getRatingAt(1)<<endl; cout<<users[0].getRatingAt(2)<<endl; cout<<users[0].getRatingAt(3)<<endl; cout<<users[0].getRatingAt(4)<<endl;
.
.
• Expected Output
0
0
0
0
0
.
.
Example 3:The usersarray is already full, so readRatingsreturns -2.
moreRatings.txt
alpha,0,1,2,3,4
beta,0,1,2,3,4
gamma,0,1,2,3,4
delta,0,1,2,3,4
Function call
User users[2] = {“Ninja”, “Myth”};
users[0].setUsername(“Ninja”);
users[1].setUsername(“Myth”);
users[0].setRatingAt(0,0);
users[0].setRatingAt(1,1);
users[0].setRatingAt(2,2);
users[0].setRatingAt(3,3);
users[0].setRatingAt(4,4);
users[1].setRatingAt(0,2);
users[1].setRatingAt(1,2);
users[1].setRatingAt(2,4);
users[1].setRatingAt(3,5);
users[1].setRatingAt(4,5);
int numUsersStored = 2;
int usersArrSize = 2;
readRatings(“moreRatings.txt”, users, numUsersStored,
usersArrSize, 50);
Return value
-2
Testing the data
// Code to print the values
member
cout<<users[0].getUsername()<<endl;
username
cout<<users[1].getUsername()<<endl;
// Expected Output
Ninja
Myth
Testing the data
// Code to print the values
memberratings
cout<<users[0].getRatingAt(0)<<endl;
cout<<users[0].getRatingAt(1)<<endl;
cout<<users[0].getRatingAt(2)<<endl;
cout<<users[0].getRatingAt(3)<<endl;
cout<<users[0].getRatingAt(4)<<endl;
cout<<users[1].getRatingAt(0)<<endl;
.
.
// Expected Output
0
1
2
3
4
2
.
.
Example 4: There is already 1 user in the users array, so the value of numUsers is 1. However, the array size is only two, so only the first line of the file is stored and the function returns the sizeof the array.
ratings.txt
stroustrup,0,4,5
gosling,2,2,3
rossum,5,5,5
Function calls
User users[2];
users[0].setUsername(“ritchie”);
users[0].setRatingAt(0,0);
users[0].setRatingAt(1,1);
users[0].setRatingAt(2,2);
int numUsers = 1;
int usersArrSize = 2;
readRatings(“ratings.txt”, users, numUsers,
usersArrSize, 50);
Return value
2
Testing the data
// Code to print the values
member
cout<<users[0].getUsername()<<endl;
username
cout<<users[1].getUsername()<<endl;
// Expected Output
ritchie
stroustrup
Testing the data
// Code to print the values
memberratings
cout<<users[0].getRatingAt(0)<<endl;
cout<<users[0].getRatingAt(1)<<endl;
cout<<users[0].getRatingAt(2)<<endl;
cout<<users[1].getRatingAt(0)<<endl;
cout<<users[1].getRatingAt(1)<<endl;
cout<<users[1].getRatingAt(2)<<endl;
// Expected Output
0
1
2
0
4
5
The zip submission should have three files for this problem: User.h, User.cpp, and a driver called readRatingsDriver.cpp, with a main() function to test your member functions. For CodeRunner, paste your User class and its implementation (the contents of User.h and User.cpp), and your readRatings function. Do not include the main() function. After developing in Cloud9, this function will be one of the functions you include at the top of HW7.cpp.
Problem 8 (20 points) getRating
We now have a list of books (in the form of an array of Book objects) and a list of users and their ratings for these books (in the form of an array of Userobjects).
We now update the getRating function from Homework 6 to use these arrays of User and Book objects , to search for a particular user’s rating for a particular book title. Write a function that, given a user’s name and a book’s title, returns the rating that the user gave for that book.
• Your function MUSTbe named getRating.
• Your function should take 6 input arguments in the following order:
◦ string: username
◦ string: title of the book
◦ Array of User objects: users
◦ Array of Book objects: books
◦ int: number of users currently stored in the usersarray
◦ int: number of books currently stored the booksarray
• The username and book title search should be case insensitive. For example, “Ben, “ben” and “BEN” are one and the same user.
• If both the user name and the book title are found in the arrays, then the function should return the user’s rating value for that book title.
• The function should return the following values depending on cases:
◦ Return the rating value if both user and title are found
◦ Return -3 if the user or the title are not found
Setting the values in
//Creating 3 books
books
Book books[3];
//Setting book title and author for book 1
books[0].setTitle("Title1");
books[0].setAuthor("Author1");
//Setting book title and author for book 2
books[1].setTitle("Title2");
books[1].setAuthor("Author2");
//Setting book title and author for book 3
books[2].setTitle("Title3");
books[2].setAuthor("Author3");
Printing the values in
//Printing values in each book object
books
cout<<"Books: "<<endl;
cout<<books[0].getTitle()<<” by
"<<books[0].getAuthor()<<endl;
cout<<books[1].getTitle()<<" by
"<<books[1].getAuthor()<<endl;
cout<<books[2].getTitle()<<" by
"<<books[2].getAuthor()<<endl;
//Expected Output
Books:
Title1 by Author1
Title2 by Author2
Title3 by Author3
Setting the values in
//Creating 2 users
users
User users[2];
//Setting username and ratings for User1
users[0].setUsername("User1");
users[0].setNumRatings(3);
users[0].setRatingAt(0,1);
users[0].setRatingAt(1,4);
users[0].setRatingAt(2,2);
//Setting username and ratings for User2
users[1].setUsername("User2");
users[1].setNumRatings(3);
users[1].setRatingAt(0,0);
users[1].setRatingAt(1,5);
users[1].setRatingAt(2,3);
Printing the values in
//Values in each user object
users
cout<<"Users and their ratings: "<<endl;
cout<<users[0].getUsername()<<":
"<<users[0].getRatingAt(0)<<",
"<<users[0].getRatingAt(1)<<",
"<<users[0].getRatingAt(2)<<endl;
cout<<users[1].getUsername()<<":
"<<users[1].getRatingAt(0)<<",
"<<users[1].getRatingAt(1)<<",
"<<users[1].getRatingAt(2)<<endl;
• Expected Output Users and their ratings: User1: 1, 4, 2
User2: 0, 5, 3
Example 1:Both the userNameand bookTitleexists, and the value of rating is non-zero
Function call
getRating("User1", "Title2", users, books, 2, 3);
Return value
4
Example 2:The userNamedoes not exist, it returns - 3
Function call
getRating("User4", "Title1", users, books, 2, 3);
Return value
-3
Example 3:The bookTitledoes not exist, it returns - 3
Function call
getRating("User1", "Title10", users, books, 2, 3);
Return value
-3
Example 4:The userNameand the bookTitledo not exist
Function call
getRating("User12", "Title10", users, books, 2, 3);
Return value
-3
The zip submission should have five files for this problem: Book.h, Book.cpp, User.h, User.cpp, and a driver called readRatingDriver.cpp, with a main() function to test your member and getRating functions. For CodeRunner, paste your User and Book classes (the contents of the four Book and User files mentioned above) and your getRating function. Do not include the main() function. After developing in Cloud9, this function will be one of the functions you include at the top of HW7.cpp.
Problem 9 (10 points) driver
Now, let’s modify our HW6.cpp from Homework 6 to use the Book class, User class, and the other functions we have updated for Homework 7. Make a copy of your old HW6.cpp and rename it to HW7.cpp, to modify for this problem so we can show off to our parents, significant others, pets or annoyed roommates how much cool stuff we’re doing!
Note that the function definitions for Problems 5-8 will go in this file as well. The zip file submission should have five files for this problem: Book.h, Book.cpp, User.h, User.cpp, and a driver called HW7.cpp, with a main() function to test your menu interface. Note that the submitted HW7.cpp file should not have the class definitions in it. They should be contained in their respective modules (Book.h+Book.cpp, or User.h+User.cpp) and #include’ed in HW7.cpp.
For CodeRunner, however, paste your entire HW7.cpp driver function with the class definitions from Problems 3 and 4. For Problem 9, you need to submit the the entire program HW7.cpp, including the Book and User classes, in the answer box of the Coderunner auto-grader on Moodle.
The menu will run on a loop, continually offering the user five options until they opt to quit. You need to fill in the code for each of the options. You should make use of the functions you wrote previously, call them, and process the values they return.
• In your driver function, you must declare your arrays with the appropriate size. The capacity of the booksarray is 50 and usersarray is 100.
◦ In your template function the sizes have been declared. Match them accordingly
▪ const static int usersArrSize = 100;
▪ const static int booksArrSize = 50;
• Option 1: Initialize library
◦ Prompt the user for a file name.
◦ Pass the file name to your readBooksfunction.
◦ Print the total number of books in the database in the following format:
▪ Total books in the database: <numberOfBooks>
◦ If the function returned -1, then print the following message:
▪ No books saved to the database.
◦ If the function returned -2, print
▪ Database is already full. No books were added.
◦ When numberOfBooks is equal to size of the array print the following message:
▪ Database is full. Some books may have not been added.
• Option 2: Initialize user catalog
◦ Prompt the user for a file name.
◦ Pass the file name to your readRatingsfunction
◦ Print the total number of users in the database in the following format:
▪ Total users in the database: <numUsers>
◦ If the function returned -1, then print the following message:
▪ No users saved to the database.
◦ If the function returned -2, print
▪ Database is already full. No users were added.
◦ When numUsersis equal to size of the array print the following message:
▪ Database is full. Some users may have not been added.
• Option 3: Display library
◦ Call your printAllBooksfunction.
• Option 4: Get a rating
◦ Prompt the user for a username.
◦ Prompt the user for a title
◦ Pass the username and the title to your getRatingfunction
◦ If the user exists in the system, print the result in the following format:
▪ <name> rated <title> with <rating>
◦ If the function returns 0, print the result in the following format:
▪ <name> has not rated <title>
◦ If the function returns -3, print the result in the following format:
▪ <name> or <title> does not exist
• Option 5: Quit
◦ Print “good bye!”before exiting
Below is an example of running the HW7program:
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
1
Enter a book file name:
badFile.txt
No books saved to the database.
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
1
Enter a book file name:
books.txt
Database is full. Some books may have not been added.
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
1
Enter a book file name:
books2.txt
Database is already full. No books were added.
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
2
Enter a user file name:
ratings.txt
Total users in the database: 86
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
3
Here is a list of books
The Hitchhiker's Guide To The Galaxy by Douglas Adams Watership Down by Richard Adams ...
...
...
Maus: A Survivor's Tale by Art Spiegelman The Joy Luck Club by Amy Tan
The Lord of the Rings by J R R Tolkien
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
4
Enter username:
Punith
Enter book title:
XKCD 1739
Punith or XKCD 1739 does not exist
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
4
Enter username:
amy
Enter book title:
The Lord of the Rings
amy rated The Lord of the Rings with 2
Select a numerical option:
======Main Menu=====
1. Read book file
2. Read user file
3. Print book list
4. Get rating
5. Quit
5
good bye!
6. Homework 7 checklist
Here is a checklist for submitting the assignment:
1. Complete the code Homework 7 Coderunner
2. Submit one zip file to Homework 7 (File Submission). The zip file should be named, <firstName>_<lastName>_homework7.zip., and have following 15 files:
1. Planet.h
2. Planet.cpp
3. planetDriver.cpp
4. maxRadiusDriver.cpp
5. Book.h
6. Book.cpp
7. bookDriver.cpp
8. User.h
9. User.cpp
10. userDriver.cpp
11. readBooksDriver.cpp
12. printAllBooksDriver.cpp
13. readRatingsDriver.cpp
14. getRatingDriver.cpp
15. HW7.cpp
7. Homework 7 point summary
Criteria
CodeRunner (problem 1 - 9)
Style and Comments
Algorithms
Test cases
Recitation attendance (Mar 5 or Mar 7)*
Not using classes in the driver
Using global variables
Total
5% early submission bonus
Pts
125
5
5
30
-40
-10
-5
165
+5%
* if your attendance is not recorded, you will lose points. Make sure your attendance is recorded on Moodle.