-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathelection.c
287 lines (273 loc) · 7.89 KB
/
election.c
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#define _CRT_SECURE_NO_WARNINGS
#include "mtm_map/map.h"
#include "election.h"
#include "area.h"
#include "assist.h"
#include "tribe.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>
#define SPACE ' '
#define FIRST_LETTER 'a'
#define LAST_LETTER 'z'
struct election_t
{
Area area_list;
};
/**
* Implements an Election type.
* Election has a list of Areas each, Area has name (string) and id (id) and a map of tirbes
*each tribe in the map has tribe id as a key and name+votes as one string
*each area has a copy of all the existing tribes in the election systeme that keeps a record of the votes they got
*from each tribe
**/
Election electionCreate();
void electionDestroy(Election election);
ElectionResult electionAddTribe(Election election, int tribe_id, const char* tribe_name);
ElectionResult electionAddArea(Election election, int area_id, const char* area_name);
char* electionGetTribeName(Election election, int tribe_id);
ElectionResult electionAddVote(Election election, int area_id, int tribe_id, int num_of_votes);
ElectionResult electionRemoveVote(Election election, int area_id, int tribe_id, int num_of_votes);
ElectionResult electionSetTribeName(Election election, int tribe_id, const char* tribe_name);
ElectionResult electionRemoveTribe(Election election, int tribe_id);
ElectionResult electionRemoveAreas(Election election, AreaConditionFunction should_delete_area);
Map electionComputeAreasToTribesMapping(Election election);
static bool isValidVotes(int num_of_votes);
static bool isValidId(int id);
static bool isValidName(const char* name);
static ElectionResult isAddArgumentsValid(Election election, int id, const char* name);
static ElectionResult handleResult(AreaResult result);
Election electionCreate()
{
Election election = malloc(sizeof(*election));
if (election == NULL)
{
return NULL;
}
election->area_list = areaCreate();
if (election->area_list == NULL)
{
free(election);
return NULL;
}
return election;
}
void electionDestroy(Election election)
{
if (election != NULL)
{
areaDestroy(election->area_list);
free(election);
}
}
ElectionResult electionAddTribe(Election election, int tribe_id, const char* tribe_name)
{
ElectionResult result_arguments_valid = isAddArgumentsValid(election, tribe_id, tribe_name);
if (result_arguments_valid == ELECTION_NULL_ARGUMENT || result_arguments_valid == ELECTION_INVALID_ID)
{
return result_arguments_valid;
}
if (areaTribeContains(election->area_list, tribe_id))
{
return ELECTION_TRIBE_ALREADY_EXIST;
}
if (result_arguments_valid != ELECTION_SUCCESS)
{
return result_arguments_valid;
}
AreaResult result = areaAddTribe(election->area_list, tribe_id, tribe_name);
return handleResult(result);
}
ElectionResult electionAddArea(Election election, int area_id, const char* area_name)
{
ElectionResult result_arguments_valid = isAddArgumentsValid(election, area_id, area_name);
if (result_arguments_valid == ELECTION_NULL_ARGUMENT || result_arguments_valid == ELECTION_INVALID_ID)
{
return result_arguments_valid;
}
if (areaContains(election->area_list, area_id))
{
return ELECTION_AREA_ALREADY_EXIST;
}
if (result_arguments_valid != ELECTION_SUCCESS)
{
return result_arguments_valid;
}
AreaResult result = areaAdd(election->area_list, area_id, area_name);
return handleResult(result);
}
char* electionGetTribeName(Election election, int tribe_id)
{
if (election == NULL || !isValidId(tribe_id))
{
return NULL;
}
return areaGetTribeName(election->area_list, tribe_id);
}
ElectionResult electionAddVote(Election election, int area_id, int tribe_id, int num_of_votes)
{
if (election == NULL)
{
return ELECTION_NULL_ARGUMENT;
}
if (!isValidId(area_id) || !isValidId(tribe_id))
{
return ELECTION_INVALID_ID;
}
if (!isValidVotes(num_of_votes))
{
return ELECTION_INVALID_VOTES;
}
AreaResult result = areaUpdateVote(election->area_list, area_id, tribe_id, num_of_votes, addVotes);
return handleResult(result);
}
ElectionResult electionRemoveVote(Election election, int area_id, int tribe_id, int num_of_votes)
{
if (election == NULL)
{
return ELECTION_NULL_ARGUMENT;
}
if (!isValidId(area_id) || !isValidId(tribe_id))
{
return ELECTION_INVALID_ID;
}
if (!isValidVotes(num_of_votes))
{
return ELECTION_INVALID_VOTES;
}
AreaResult result = areaUpdateVote(election->area_list, area_id, tribe_id, num_of_votes, removeVotes);
return handleResult(result);
}
ElectionResult electionSetTribeName(Election election, int tribe_id, const char* tribe_name)
{
ElectionResult result_arguments_valid = isAddArgumentsValid(election, tribe_id, tribe_name);
if (result_arguments_valid == ELECTION_NULL_ARGUMENT || result_arguments_valid == ELECTION_INVALID_ID)
{
return result_arguments_valid;
}
if (!areaTribeContains(election->area_list, tribe_id))
{
return ELECTION_TRIBE_NOT_EXIST;
}
if (result_arguments_valid != ELECTION_SUCCESS)
{
return result_arguments_valid;
}
AreaResult result = areaSetTribeName(election->area_list, tribe_id, tribe_name);
return handleResult(result);
}
ElectionResult electionRemoveTribe(Election election, int tribe_id)
{
if (election == NULL)
{
return ELECTION_NULL_ARGUMENT;
}
if (!isValidId(tribe_id))
{
return ELECTION_INVALID_ID;
}
AreaResult result = areaRemoveTribe(election->area_list, tribe_id);
return handleResult(result);
}
ElectionResult electionRemoveAreas(Election election, AreaConditionFunction should_delete_area)
{
if (election == NULL)
{
return ELECTION_NULL_ARGUMENT;
}
AreaResult result = areaRemove(election->area_list, should_delete_area);
return handleResult(result);
}
Map electionComputeAreasToTribesMapping(Election election)
{
if (election == NULL)
{
return NULL;
}
return areaComputeAreasToTribesMapping(election->area_list);
}
/*
validates the given arguments and return the matched error to to the argument
if all arguments are valid returns ELECTION_SUCCSESS
*/
static ElectionResult isAddArgumentsValid(Election election, int id, const char* name)
{
if (election == NULL || name == NULL)
{
return ELECTION_NULL_ARGUMENT;
}
if (!isValidId(id))
{
return ELECTION_INVALID_ID;
}
if (!isValidName(name))
{
return ELECTION_INVALID_NAME;
}
return ELECTION_SUCCESS;
}
/*
validates the number of votes is a positive number
*/
static bool isValidVotes(int num_of_votes)
{
if (num_of_votes <= 0)
{
return false;
}
return true;
}
/*
validets the id is a positive bumber
*/
static bool isValidId(int id)
{
if (id < 0)
{
return false;
}
return true;
}
/*
validets the name consists only low letter case and spaces
*/
static bool isValidName(const char* name)
{
while (*name)
{
if (*name != SPACE && (*name > LAST_LETTER || *name < FIRST_LETTER))
{
return false;
}
name++;
}
return true;
}
/*
handle the results from tribe
*/
static ElectionResult handleResult(AreaResult result)
{
switch (result)
{
case AREA_SUCCESS:
return ELECTION_SUCCESS;
case AREA_OUT_OF_MEMORY:
return ELECTION_OUT_OF_MEMORY;
case AREA_NULL_ARGUMENT:
return ELECTION_NULL_ARGUMENT;
case AREA_NOT_EXIST:
return ELECTION_AREA_NOT_EXIST;
case AREA_ALREADY_EXIST:
return ELECTION_AREA_ALREADY_EXIST;
case AREA_TRIBE_NOT_EXIST:
return ELECTION_TRIBE_NOT_EXIST;
case AREA_TRIBE_ALREADY_EXIST:
return ELECTION_TRIBE_ALREADY_EXIST;
default:
return ELECTION_SUCCESS;
}
}