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

C++ Figure 4.4. Contacts a. Figure 4.4 describes a model [39] for a Contact syst

ID: 3698533 • Letter: C

Question

C++

Figure 4.4. Contacts

a. Figure 4.4 describes a model[39] for a Contact system. ContactList can derive from or reuse any Qt container that you like, as long as it supports the operations listed.

getPhoneList(int category) accepts a value to be compared with a Contact's category member for selection purposes. It returns a QStringList containing, for each selected Contact, the name and phone number, separated by the tab symbol: " ".

getMailingList() has a similar selection mechanism and returns a QStringList containing address label data.

b. Write a ContactFactory class that generates random Contact objects. Example 4.4 contains a substantial hint.

Example 4.4. src/containers/contact/testdriver.cpp

Adds a Contact into the ContactList.

<include src="src/containers/contact/testdriver.cpp" mode="cpp" link="false" id="testdriver" segid="createcontacts"/>

There are many ways to generate random names/addresses. One way is to have the ContactFactory create lists of typical first names, last names, street names, city names, and so forth.[40] When it is time to generate a Contact, it can pick a random element from each list, add randomly generated address numbers, zip codes, etc. We demonstrate the use of the random() function in Section 1.13.3

c. Write client code to test your classes. In particular, the client code should generate some random contacts. After that, it should test the two query methods (getPhoneList() and getMailingList()) to ensure that they return the proper sublists. Print the original list and the query results to standard output. Summarize the results by listing the number of elements in the original ContactList compared to the query results.

C++

Adds a Contact into the ContactList.

Contact ContactList category :int firstName QString lastName QString streetAddress : QString zipCode QString city: QString -phoneNumber QString +toString:QString + add(c : Contact) remove(c Contact) +getPhoneList(category : int) : QStringList + getMailingList(category : int): QStringList QtContainerClass

Explanation / Answer

main.cpp

#include <QCoreApplication>
#include "contact.h"
#include "contactlist.h"
#include <QDebug>
#include "contactfactory.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
  
    ContactList MyContactList;

    Contact ContactA(FRIENDS, "Osheen", "Bárðr", "555-5555", "123 Main Drive", "11111");
    Contact ContactB(FRIENDS, "Wigheard", "David", "666-6666", "456 Loop Drive", "22222");
    Contact ContactC(FAMILY, "Finnegan", "Ali", "777-7777", "789 Func Drive", "33333");

    MyContactList.add(&ContactA);
    MyContactList.add(&ContactB);
    MyContactList.add(&ContactC);

    QStringList phoneList = MyContactList.getPhoneList(FRIENDS);

    foreach (const QString &str, phoneList) {
        qDebug() << QString(" [%1] ").arg(str);
    }

    QStringList mailList = MyContactList.getMailingList(FAMILY);

    foreach (const QString &str, mailList) {
        qDebug() << QString(" [%1] ").arg(str);
    }


    return a.exec();
}


contact.cpp

#include "contact.h"
#include <QString>

/**
* @brief Contact::Contact
* @param category
* @param firstName
* @param lastName
* @param phoneNumber
* @param streetAddress
* @param zipCode
* @param city
*/
Contact::Contact(int category, QString firstName, QString lastName, QString phoneNumber, QString streetAddress, QString zipCode, QString city):
    m_category(category), m_firstName(firstName), m_lastName(lastName), m_streetAddress(streetAddress), m_city(city), m_phoneNumber(phoneNumber), m_zipCode(zipCode)
{
}

/**
* @brief Contact::~Contact
*/
Contact::~Contact()
{
}

/**
* @brief Contact::toString
* @return
*/
QString Contact::toString() const
{
    return "";
}

/**
* @brief Contact::category getter
* @return
*/
int Contact::category() const
{
    return m_category;
}

/**
* @brief Contact::firstName getter
* @return
*/
QString Contact::firstName() const
{
    return m_firstName;
}

/**
* @brief Contact::lastName getter
* @return
*/
QString Contact::lastName() const
{
    return m_lastName;
}

/**
* @brief Contact::streetAddress getter
* @return
*/
QString Contact::streetAddress() const
{
    return m_streetAddress;
}

/**
* @brief Contact::zipCode getter
* @return
*/
QString Contact::zipCode() const
{
    return m_zipCode;
}

/**
* @brief Contact::city getter
* @return
*/
QString Contact::city() const
{
    return m_city;
}

/**
* @brief Contact::phoneNumber getter
* @return
*/
QString Contact::phoneNumber() const
{
    return m_phoneNumber;
}

contact.h

#ifndef CONTACT_H
#define CONTACT_H

#include <QString>

enum Category {FRIENDS, FAMILY, BUSINESS, OTHER, CATEGORY_MAX = OTHER};

class Contact
{
public:
    Contact(int category, QString firstName = "", QString lastName = "", QString phoneNumber = "", QString streetAddress = "", QString zipCode = "", QString city = "");
    virtual ~Contact();
    QString toString() const;

    int category() const;
    QString firstName() const;
    QString lastName() const;
    QString streetAddress() const;
    QString zipCode() const;
    QString city() const;
    QString phoneNumber() const;

private:
    int m_category;
    QString m_firstName;
    QString m_lastName;
    QString m_streetAddress;
    QString m_zipCode;
    QString m_city;
    QString m_phoneNumber;
};

#endif // CONTACT_H


contactfactory.cpp

#include "contactfactory.h"
#include "contact.h"
#include <stdlib.h>

QStringList ContactFactory::m_names = QStringList() << "Fleener"
                                                    << "Das"
                                                    << "Kohlmeier"
                                                    << "Massengill"
                                                    << "Gardella";

QStringList ContactFactory::m_phones = QStringList() << "111-1111"
                                                     << "222-2222"
                                                     << "333-3333"
                                                     << "444-4444"
                                                     << "555-5555";

QStringList ContactFactory::m_streets = QStringList() << "111 A Dr"
                                                      << "222 B Dr"
                                                      << "333 C Dr"
                                                      << "444 D Dr"
                                                      << "555 E Dr";

// Just putting this here till I have a chance to sort this out
void createRandomContacts(ContactList* cl, int n) {
    static ContactFactory cf;
    for (int i=0; i<n; ++i) {
        cf >> *cl;
    }
}

/*
ContactFactory::ContactFactory()
{
}
*/

QString ContactFactory::getRandomName() const
{
    int n = m_names.size();
    return m_names.at((rand()%n)+1);
}

QString ContactFactory::getRandomPhone() const
{
    int n = m_phones.size();
    return m_phones.at((rand()%n)+1);
}

QString ContactFactory::getRandomStreet() const
{
    int n = m_streets.size();
    return m_streets.at((rand()%n)+1);
}

contactfactory.h

#ifndef CONTACTFACTORY_H
#define CONTACTFACTORY_H

#include <QString>
#include <QStringList>
#include "contactlist.h"
#include "contact.h"
#include <iostream>

class ContactFactory
{
public:
    //ContactFactory();

private:
    // Not implementing getRandom of each contact constructor var.... but you get the point
    QString getRandomName();
    QString getRandomPhone();
    QString getRandomStreet();

    static const QStringList m_names;
    static const QStringList m_phones;
    static const QStringList m_streets;

};

#endif // CONTACTFACTORY_H

contactlist.cpp

#include "contactlist.h"
#include "contactfactory.h"

/**
* @brief ContactList::ContactList
*/
ContactList::ContactList()
{
}

/**
* @brief ContactList::add
* Adds a new contact to list via QMap's insertMulti (can have same key)
* @param c
*/
void ContactList::add(Contact *c)
{
    insertMulti(c->category(), c);
}

void ContactList::remove(Contact *c)
{
    QMap<int, Contact*>::iterator i = begin();
    while (i != end()) {
        if (i.value() == c)
            i = erase(i);
        ++i;
    }

}

QStringList ContactList::getPhoneList(int category)
{
    QStringList returnList;
    QMap<int, Contact*>::const_iterator i = find(category);
    while (i != end() && i.key() == category) {
        returnList.append((*i)->firstName() + " " + (*i)->lastName() + " " + (*i)->phoneNumber());
        ++i;
    }
    return returnList;
}

/**
* @brief ContactList::getMailingList
* @param category
* @return
*/
QStringList ContactList::getMailingList(int category)
{
    QStringList returnList;
    QMap<int, Contact*>::const_iterator i = find(category);
    while (i != end() && i.key() == category) {
        returnList.append((*i)->firstName() + " " + (*i)->lastName() + " " + (*i)->streetAddress() + " " + (*i)->zipCode());
        ++i;
    }
    return returnList;
}

contactlist.h

#ifndef CONTACTLIST_H
#define CONTACTLIST_H

#include <QMap>
#include <QStringList>
#include "contact.h"

class ContactList : public QMap<int, Contact*>
{
public:
    ContactList();
    /* Adds contact to map, keyed by category */
    void add(Contact* c);
    void remove(Contact* c);
    QStringList getPhoneList(int category);
    QStringList getMailingList(int category);
};

#endif // CONTACTLIST_H