Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

C++ programming The assignment is to input iClicker data for one class session,

ID: 3883264 • Letter: C

Question

C++ programming

The assignment is to input iClicker data for one class session, and then analyze this data to see how many questions were given, how many students answered, how many students answered correctly, and so on. The input file is a text file in XML format.

Here’s a screenshot for the input file “L1709081300.xml”, which can be downloaded from the course web page.


The user inputs the filename, and then the program opens the file, reads the data, performs the analysis, and outputs the results. Your program must match this output exactly since it will be auto-graded using the repl.it system.

Notice that the filename is where you will obtain the date and time. For example, the file shown here --- “L1709081300.xml” --- denotes the year 17, the month 09, the day 08, the hour 13, and the minute 00.

The program takes a single input file. The input file is a text file in XML format. You’ll need to open the file using a text editor, or a programming environment (such as Visual Studio) and learn your way around the format. Here’s a short overview of the file “L1709081300.xml”:

<!--**************** Naming Convention **********-->
<!--qn : Question Name-->
<!--quuid : Question Universally Unique Identifier-->
.
.
.
<ssn cdts="" perf="-1" ... ssnn="Session 4" ...>
<p resp_c="19||0.00" isDel="N" isap="N" ... cans="B" ...>
<v att="4" scr="0.00" fans="A" ans="B" .../>
<v att="1" scr="0.00" fans="B" ans="B" .../>
<v att="3" scr="0.00" fans="A" ans="A" .../>
.
.
.
</p>
.
.
.
</ssn>

XML is like HTML in that it is a tag-based language. The file denotes a single session, which begins with the tag <ssn …> and ends with the tag </ssn>. The <ssn …> tag is where you’ll find the session name attribute ssnn="…".

A session may contain 0 or more questions. Each question begins with the <p …> tag and ends with </p>. The correct answer is denoted by the attribute cans="…". The correct answer can be a single letter such as “B”, or multiple letters each separated by |, e.g. “A|B”.

For each question, the answer by each student is given by the <v …/> tag. The student’s final answer is contained in the attribute ans="…" --- if this string is empty then the student did not answer the question. The id attribute is the clicker ID, and how we identify the student.

As is the case with all assignments in CS 341, how you solve the problem is just as important as simply getting the correct answers. You are required to solve the problem the “proper” way, which in this case means using modern C++ techniques: classes, objects, built-in generic algorithms and data structures, lambda expressions, etc. It’s too easy to fall back on existing habits to just “get the assignment done.”

In this assignment, your solution is required to do the following:
• Use ifstream to open / close the input file; see lecture #01 for an example of using ifstream, and then getline(file, line) to read lines from the file.
• When parsing the input file, use only standard C++. There is no XML parser in standard C++, so my recommendation is to use the find() and substr() functions in the std::string class. In other words, use find to search for the attribute, and then substr to extract the value.
• Use one or more classes to store the input — at a minimum you must have a Student class that contains data about each student: their clicker ID, the # of questions answered, and the # of questions answered correctly. The design of that class is up to you, but at the very least (1) all data members must be private, (2) the class contains a constructor to initialize the data members, and (3) getter/setter functions are used to access/update the data members.
• Use std::vector<T> to store your objects (yes, there are other containers, but in this assignment you must use std::vector<T>).
• When searching the vector, use the built-in linear search function std::find_if. No looping and searching yourself --- use std::find_if.
• When counting the # of students who answered questions, use std::count_if. No explicit looping and counting yourself --- use std::count_if.
• In fact, the only loops you should have are (1) to input the data, and (2) to output the clicker ids of students who either didn’t answer at least half, or didn’t answer any correctly. All other iteration should be performed by library functions.
• No explicit pointers of any kind — no char *, no NULL, no C-style pointers
• No global variables whatsoever; use functions and parameter passing.

Writing code that is not modern C++ will result in a score of 0. Using a container other than std::vector? 0. No classes? 0. Using global variables? 0. Using a 3rd-party library such as Boost? 0.

A student answer that is blank --- i.e. the empty string "" --- means he/she did not answer the question. If there are N questions, then a student must answer N/2 or more to have answered at least half of them. If N is even, e.g. 4, this means a student must answer 2 or more. If N is odd, e.g. 5, this means a student must answer 3 or more. Assuming N is an integer, an easy way to handle both cases is to check to see if the # of answers is >= ((N+1)/2).

We’ve talked about std::count_if, but not std::find_if. The two are similar in that they both take a predicate function for the lambda expression, but std::find_if returns an iterator if it finds what you are looking for. Here’s an example. Suppose we want to search a vector of students for the first student named “Venky”:

std::string name = "Venky";

auto result = std::find_if(students.begin(), students.end(),
[=](const Student& s) {
   if (s.getName() == name) // found what we are looking for, return true!
       return true;
   else // not a match, return false so alg keeps searching:
       return false; } );


Note that the lambda expression takes a *single* element of the container — a student in this case — and returns true if this student is a match and false if not. The std::find_if function calls the lambda expression with different elements of the container, until either a match is found or all elements have been checked.

How do we know if the search was successful? If a match is found, std::find_if returns an iterator that “points” to the first object that successfully matched the search. You check by comparing std::find_if’s return value to the end of the container:

if (result == students.end()) // search did *not* find matching student:
   cout << "Student not found" << endl;
else
   cout << result->getName() << ": avg=" << result->getExamAvg() << endl;

Since result is an iterator, and iterators are like pointers, the -> operator must be used to call the underlying functions in the Student object.

Explanation / Answer

#include #include #include #import rename_namespace(_T("MSXML")) int main(int argc, char* argv[]) { HRESULT hr = CoInitialize(NULL); if (SUCCEEDED(hr)) { try { MSXML::IXMLDOMDocument2Ptr xmlDoc; hr = xmlDoc.CreateInstance(__uuidof(MSXML::DOMDocument60), NULL, CLSCTX_INPROC_SERVER); // TODO: if (FAILED(hr))... if (xmlDoc->load(_T("input.xml")) != VARIANT_TRUE) { printf("Unable to load input.xml "); } else { printf("XML was successfully loaded "); xmlDoc->setProperty("SelectionLanguage", "XPath"); MSXML::IXMLDOMNodeListPtr wheels = xmlDoc->selectNodes("/Car/Wheels/*"); printf("Car has %u wheels ", wheels->Getlength()); MSXML::IXMLDOMNodePtr node; node = xmlDoc->createNode(MSXML::NODE_ELEMENT, _T("Engine"), _T("")); node->text = _T("Engine 1.0"); xmlDoc->documentElement->appendChild(node); hr = xmlDoc->save(_T("output.xml")); if (SUCCEEDED(hr)) printf("output.xml successfully saved "); } } catch (_com_error &e) { printf("ERROR: %ws ", e.ErrorMessage()); } CoUninitialize(); } return 0; }
Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote