Separating Modules

I separated my program into modules but I got a D on the assignment. Can someone show me what I did wrong? If I can fix it I can resubmit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
  ===============================
    CANDIDATES.CPP
=================================
#include <iostream>
#include <string>
#include <array>


using namespace std;

#include "candidates.h"
#include "states.h"



/**
 * Find the candidate with the indicated name. Returns the array index
 * for the candidate if found, numCandidates if it cannot be found.
 */
int findCandidate (std::string name)
{
  int result = numCandidates;
  for (int i = 0; i < numCandidates && result == numCandidates; ++i)
    if (candidateNames[i] == name)
      result = i;
  return result;
}

/**
 * read the list of candidate names, initializing their delegate counts to 0.
 */
void readCandidatesList ()
{
  cin >> numCandidates;
  string line;
  getline (cin, line);

  for (int i = 0; i < numCandidates; ++i)
    {
      getline (cin, candidateNames[i]);
      delegatesWon[i] = 0;
    }
}



/**
 * For the most recently read primary, determine how many delegates have
 * been won by each candidate.
 */
void assignDelegatesToCandidates ()
{

  int remainingDelegates = delegatesForThisState;
  for (int i = 0; i < numCandidatesInPrimary; ++i)
    {
      int candidateNum = findCandidate(candidate[i]);
      int nDel = (delegatesForThisState * votesForCandidate[i] + (totalVotes-1)) / totalVotes;
      if (nDel > remainingDelegates)
	nDel = remainingDelegates;
      delegatesWon[candidateNum] += nDel;
      remainingDelegates -= nDel;
    }
}


=====================================
CANDIDATES.H
======================================
#ifndef CANDIDATES_H_INCLUDED
#define CANDIDATES_H_INCLUDED
#include <iostream>
#include <string>
#include <array>


const int maxCandidates = 10;
// Names of the candidates participating in this state's primary
string candidate[maxCandidates];

void printPrimaryReport (int candidateNum);

void assignDelegatesToCandidates ();

// Names of all candidates participating in the national election
string candidateNames[maxCandidates];

// How many delegates have been won by each candidate
int delegatesWon[maxCandidates];

// How many candidates in the national election?
int numCandidates;

// How many votes won by each candidate in this state's primary
int votesForCandidate[maxCandidates];

int findCandidate (std::string name);

void readCandidatesList ();


#endif // CANDIDATES_H_INCLUDED
=================================================
STATES.H
=================================================
#ifndef STATES_H_INCLUDED
#define STATES_H_INCLUDED
#include <iostream>
#include <array>

// How many states participate in the election
int numStates;

void readState ();

// How many delegates in the election (over all states)
int totalDelegates = 0;

// How many candidates in the primary for the state being processed
int numCandidatesInPrimary;

// How many votes were cast in the primary for this state
int totalVotes;

// How many delegates are assigned to the state being processed
int delegatesForThisState;



#endif // STATES_H_INCLUDED
========================================================
STATES.CPP
========================================================
#include <iostream>
#include <string>


using namespace std;

#include "states.h"
#include <array>


/**
 * read the info on one state's primaries
 */
void readState ()
{
  totalVotes = 0;
  cin >> numCandidatesInPrimary >> delegatesForThisState;
  totalDelegates += delegatesForThisState;  // "x += y" is a shorthand for "x = x + y"
  string word, line;
  getline (cin, line);
  for (int i = 0; i < numCandidatesInPrimary; ++i)
    {
      cin >> votesForCandidate[i];
      totalVotes = totalVotes + votesForCandidate[i];

      cin >> word;
      getline (cin, line);
      candidate[i] = word + line;
    }
}

============================================
PRIMARIES.CPP
============================================
#include <iostream>
#include <fstream>
#include <string>
#include <array>

using namespace std;

#include "states.h"
#include "candidates.h"


/**
 * Generate the report on the national primary election.
 */
int main(int argc, char** argv)
{
  readCandidatesList();
  int numStates;
  cin >> numStates;
  for (int i = 0; i < numStates; ++i)
    {
      readState();
      assignDelegatesToCandidates();
    }
  for (int i = 0; i < numCandidates; ++i)
    {
      printPrimaryReport(i);
    }
  return 0;
}

/**
 * Print the report line for the indicated candidate
 */
void printPrimaryReport (int candidateNum)
{
  int requiredToWin = (2 * totalDelegates + 2) / 3; // Note: the +2 rounds up
  if (delegatesWon[candidateNum] >= requiredToWin)
    cout << "* ";
  else
    cout << "  ";
  cout << delegatesWon[candidateNum] << " " << candidateNames[candidateNum] << endl;
}

It depends on the requirements whether it is ok or not. So does it fullfill the requirements?

On thing is certainly not good: Having global non const variables in your header files (const like on line 77 is ok). Prefer local variabes and pass them as parameters to your functions.

The problem of global variable in include files is multiple definition error if you include the header more than once and linker problems.
As coder777 said, it depends on the requirements.

Since you;re writing in C++, I'm presuming you're taking a C++ class.
If you're indeed taking a C++ class, were you supposed to use classes?
If so, where are your classes?

I was not supposed to change the code at all. I was only supposed to separate them into header and cpp files. coder777, do you mean the #include <string> and #include<array>?
Isn't it your teacher's job to explain why they gave you a D? Shouldn't you be asking them first, rather than a bunch of people on the Internet?

coder777 is spot on about the global variables, e.g. in states.h you have:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// How many states participate in the election
int numStates;

//...
// How many delegates in the election (over all states)
int totalDelegates = 0;

// How many candidates in the primary for the state being processed
int numCandidatesInPrimary;

// How many votes were cast in the primary for this state
int totalVotes;

// How many delegates are assigned to the state being processed
int delegatesForThisState;


Also, you have some unnecessary header file inclusions. There's no point at all including iostream or array in states.h, because nothing in that file uses them.

In fact, I don't see anything in any of the code that uses array at all - why is it even there?
Last edited on
Here are the instructions for the assignment:

The challenge in this assignment is to divide the program into separately compiled modules (without breaking the already working code).
A Candidates module, consisting of files candidates.h and candidates.cpp, containing code dealing specifically with information specific to individual candidates.
A States module, consisting of files states.h and states.cpp, containing code dealing specifically with the information about each state and the results of the primaries in that state.
The main driver, in the file primaries.cpp, containing code associated with the launch of the program (main) and the sequencing of call to the module’s functions to provide the overall skeleton of the desired report.
There may be some functions and data that are not specifically related to either of these modules, but that contain code needed by them. You should apportion these to the modules in a way consistent with the goals of high cohesion and low coupling.
Well, if I had a decent teacher I would be able to do that but his only answer was "figure it out"
He told you to figure out why you only got a D? He didn't mark your work or comment on it in any way?
No, he said that programming is self taught.
Your code doesn't compile:

$ make -k states.o candidates.o primaries.o
g++ -Wall -g -D DEBUG -std=c++11 -c states.cpp
states.cpp: In function ‘void readState()’:
states.cpp:23:14: error: ‘votesForCandidate’ was not declared in this scope
       cin >> votesForCandidate[i];
              ^
states.cpp:28:7: error: ‘candidate’ was not declared in this scope
       candidate[i] = word + line;
       ^


Once you fix this, it still won't run because of the problem that coder777 mentioned. I think that's why you got a D. Generally in a programming class, a program has to compile and run to get anything approaching a good grade.
do you mean the #include <string> and #include<array>?
No, I mean the global variables. Removing unnecessary includes are an optimization but has [usually] no effect on the working code.

However, you can keep your global variable with the keyword extern: In the header file prepend the variables with extern and write the same variable without extern in your cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
=================================================
STATES.H
=================================================
#ifndef STATES_H_INCLUDED
#define STATES_H_INCLUDED
#include <iostream>
#include <array>

// How many states participate in the election
extern int numStates;

...


#endif // STATES_H_INCLUDED
========================================================
STATES.CPP
========================================================
#include <iostream>
#include <string>


using namespace std;

#include "states.h"
#include <array>


// How many states participate in the election
int numStates;

...
Note that needs to be done for all global variables.

And as dhayden pointed out, you need to include the header files where they are need. I.e. candidate is declared in what header? -> #include it.
Topic archived. No new replies allowed.