University of Liverpool
Department of Computer Science
COMP282 – Advanced Object-Oriented C
Languages
Coursework 1 – C++
Deadline: Wednesday 27th of April at 17:00
Last possible hand-in: Wednesday 11th of May at 17:00
Feedback will be released shortly after the last possible hand-in.
Weighting: 50%
What to submit: You are meant to submit 4 files: country.h, country.cpp,
menupart2.cpp and menupart3.cpp to get the highest grade (three files are also
included, both in the template and intuitively1 when your solution is compiled:
menupart2.h, menupart3.h and mainmethod.cpp. mainmethod.cpp contains a main
method that can test each task – you simply write X to test task X, but if doing it by
hand you need to explicitly do the inputs for tasks 4-8 afterwards. CodeGrade will do
that for you if you upload though). Penalties for late work will be applied in accordance
with the Code of Practice on Assessment. Your grade and penalty are based on your
last submission.
Work alone: You must work alone on the assignment. Plagiarism checks will be run.
You will be asked to acknowledge that you have seen this, in the quiz:
MUST COMPLETE TO BE MARKED: Acknowledge Plagiarism checks for C++
assignment. If you choose not to acknowledge it, you will not be marked… Note, I will
contact you in this case, to be sure you choose not to be marked and not just overlook
that you were meant to do this.
Tests and grading: Each task will have associated some public tests and some
private tests. For part 1, the tests are based on methods that return Booleans, true if
the test is successful, false if not.
For part 2 and 3, the tests are pairs of input (to cin) and expected output (in cout) when
the corresponding method is run. In this file, the output and input will be shown
together, as it will look like if you tested it manually. The input (being rather sparse) is
shown in red though to distinguish. If the output match (ignoring whitespace and case),
the test is successful otherwise not.
You will be told (by CodeGrade) which of the public tests you passed whenever you
submit – it will take a few minutes to run, depending on the number of people trying to
submit at the same time. You are therefore heavily suggested to submit a number
1 The intuitive part is just to cover that CodeGrade has different main files to test the different tasks so
that you can solve some tasks, but not others while still being able to compile on CodeGrade –
otherwise, e.g. if you had done Task 1 but not Task 2 the test for Task 2 would make it impossible to
compile. The main methods are just the subset of mainmethod.cpp relevant for the current task –
besides the private tests.
of times – before the deadline - and change your submission based on how it
went! Your grade will be based on the outcome of the tests on your last submission.
The private tests for a task are similar, but not identical to the corresponding public
tests. This is to ensure that you can not get the best grade by hardcoding the output
for a given input.
The compilation of your code will be done using clang++ with the options:
-Wall -std=c++11
The former gives more warnings, and the latter ensures you can only do C++11 as is
the case by the baseline setup of Visual Studio 2019 you were meant to install.
Tests cannot be done without some assumed behaviour. Some of the tests for
different tasks (both public and private) assume that you have done the earlier tasks.
If you have not, it is unlikely that you can succeed on that test/task.
The data used for the public tests are from:
https://en.wikipedia.org/wiki/List_of_countries_and_dependencies_by_population
The countries picked are the 5 largest in Europe, the 3 largest in the world as well as
Denmark, where I am from. In the private tests, the data will be randomly generated
instead.
Project Overview
You will create a small interactive program to input data about countries, manipulate
the data, and display the data. The project consists of 3 parts: one on creating the
country files (both .cpp and .h), one on creating the method menu() in the MenuPart2
class, which should be implemented in a menupart2.cpp file you should create and
one on creating the method menu() in the MenuPart3, which should be implemented
in a menupart3.cpp file you should create. It is likely easier to do the tasks in order
(and besides that, as mentioned, some of the tests for some of the tasks assume this
has been done). Each task builds on the previous ones. Do as much as you can and
then package your project for submission. Begin by downloading the Visual Studio
project template for this assessment.
Read through this entire document before you start coding, so you’re aware of all parts
and the overall structure of the program. Your solution should demonstrate your
knowledge of C++. Important: Each task requires you to add extra code. You shouldn’t
need to remove any code. Keep the code from previous tasks in your program so we
can see it and mark it. In particular, menu() in a menupart2.cpp should work correctly
even when you are done with menu() in a menupart3.cpp!
Part 1 (Worth 15% in total)
Task 1 – Country Class Definition – 5%
Create a Country class (incl. both a .h file and a .cpp file) that stores a name and a
population size. The name should be stored as a string, and the population size as a
long. Declare and define a public constructor Country(std::string name, long pop) that
stores the parameters in the object. Also declare and define a default constructor that
sets the name to an empty string and the population size to zero.
Create also two public methods: getName() and getPop(), that should return name
and population size respectively.
The public tests for this are in the template, in mainmethod.cpp as methods
Task1Test1(), Task1Test2(), Task1Test3().
The tests are simply testing if the objects are constructed correctly (or at least the get
methods output the correct thing after construction)
Task1Test1() has the following implementation:
Country c("UK", 67081234);
return c.getName() == "UK" && c.getPop() == 67081234;
Task1Test2() has the following implementation:
Country c("Germany", 83222442);
return c.getName() == "Germany" && c.getPop() == 83222442;
Task1Test3() has the following implementation:
Country c;
return c.getName() == "" && c.getPop() == 0;
Task 2 – Country I/O - 5%
Implement the << and >> operators so you can output and input a Country object with
the following string format.
UK 67081234
In other words, the name of the country is output followed by the population. When the
user types a similar string as input, the first token (up to the space) should be stored
as the name, and the second (after the space) as the population. For this task you do
not need to do any input validation or error handling. Assume the user will always type
the correct format. In particular, the name of the country (for the purpose of this
assignment) is always 1 word.
The public tests for this are in the template, in mainmethod.cpp as methods
Task2Test1(), Task2Test2(), Task2Test3() and Task2Test4().
Note, the tests uses stringstream. Think of it as cout in the first two (and the tests are
then testing if the output in cout is correct when outputting the countries) and cin in the
last two (and the tests are then testing if the countries are constructed correctly when
the “user” inputs them)
Task2Test1() has the following implementation:
Country c("UK", 67081234);
stringstream ss;
ss << c;
return ss.str() == "UK 67081234";
Task2Test2() has the following implementation:
Task2Test3() has the following implementation:
Task2Test4() has the following implementation:
Task 3 – Comparison Operators – 5%
Implement comparison operators (<, >, and ==) for the Country class. These should
work numerically, based on the populations of the countries involved.
The public test methods for this task, Task3Test1 and Task3Test2 are somewhat
convoluted, because they are running many tests.
Specifically, Task3Test1 runs all the 4*4*3=48 tests (i.e. each pair of countries and
each of the three operators) for the countries:
And Task3Test2 does the same for the countries
Part 2 (Worth 45% in total)
menu() in the class MenuPart2, as defined in menupart2.h and which you should
implement in menupart2.cpp (later on, part 3 will require similar setup but with 3
instead of 2) is meant to be the main function of a simple command-line app (ala the
calculator in the second lab session) based on a loop that displays a menu and takes
user choices as text input.
The menu should have these options at the end of Part 2:
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
Country c("Germany", 83222442);
stringstream ss;
ss << c;
return ss.str() == "Germany 83222442";
stringstream ss("UK 67081234");
Country c;
ss >> c;
return c.getName() == "UK" && c.getPop() == 67081234;
stringstream ss("Germany 83222442");
Country c;
ss >> c;
return c.getName() == "Germany" && c.getPop() == 83222442;
Country("Germany", 83222442)
Country("UK", 67081234)
Country("France", 67813000)
Country("United_Kingdom", 67081234)
Country("c", 83222442)
Country("c", 67081234)
Country("c", 67813000)
Country("c", 67081234)
The user is then asked to enter an option as follows:
And the corresponding option is then picked. If Q is entered, the method should return.
Otherwise, the tasks in this part will explain what you need to implement for each
option. Whenever an option finishes execution, loop back to the menu.
Task 4 – Adding & Listing Countries (Fixed Storage) – 20%
In this task, you should implement menu option 1. Add country and option 2. List
countries. We need both to be able to test anything really…
Whenever option 1 is chosen by the user, they should be asked to input a country
(unless there are currently 9 countries, see below), like the following:
After the user enters a country, it should then be stored in some suitable way.
If there are currently 9 countries when option 1 is chosen an error message should be
displayed instead of more countries being added. The error message should be:
Whenever option 2 is picked by the user, the current list (i.e. the ones entered, but not
yet removed – see task 6) should be outputted – in the order inputted. E.g. if the
countries in the current list are UK 67081234 and Germany 83222442 (entered in that
order), then output
NOTE: The indices start at 1!
The public tests will be shown over the next few pages – there was not quite enough
space on this one
Enter Option:
Enter details:
Can not add country: There are already 9 countries
[1] UK 67081234
[2] Germany 83222442
The public test will test the following runs (there are more on the next page):
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
Enter Option: 1
Enter Details: UK 67081234
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
Enter Option: 1
Enter Details: Germany 83222442
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
Enter Option: 2
[1] UK 67081234
[2] Germany 83222442
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
Enter Option: Q
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
Enter Option: 2
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
Enter Option: Q
To improve readability, the menu, i.e.
will be shortened to [MENU] in the remaining run. The output from your code is still
supposed to be full menu as output in the example above. Boldface will otherwise not
be used in the run. Hence, the second run would be as above.
[MENU]
Enter Option: 1
Enter Details: UK 67081234
[MENU]
Enter Option: 1
Enter Details: Germany 83222442
[MENU]
Enter Option: 2
[1] UK 67081234
[2] Germany 83222442
[MENU]
Enter Option: 1
Enter Details: France 67813000
[MENU]
Enter Option: 1
Enter Details: Italy 58983122
[MENU]
Enter Option: 1
Enter Details: Spain 47326687
[MENU]
Enter Option: 1
Enter Details: China 1412600000
[MENU]
Enter Option: 1
Enter Details: India 1374441500
[MENU]
Enter Option: 1
Enter Details: USA 332574351
[MENU]
Enter Option: 1
Enter Details: Denmark 5873420
Run in left column continues in right
1. Add country
2. List countries
3. Find largest country
4. Remove country
Q. Quit
[MENU]
Enter Option: 2
[MENU]
Enter Option: Q
Example 2 from above after being
shorten
[MENU]
Enter Option: 2
[1] UK 67081234
[2] Germany 83222442
[3] France 67813000
[4] Italy 58983122
[5] Spain 47326687
[6] China 1412600000
[7] India 1374441500
[8] USA 332574351
[9] Denmark 5873420
[MENU]
Enter Option: 1
Can not add country: There are
already 9 countries
[MENU]
Enter Option: Q
Run in left column continues in right
Note, whitespace (and
case) are not taken into
account, so you can write
that error message over
as many lines as you
want
Task 5 – Finding the Most Populous Country - 10%
This task is about implementing option 3. Find largest country. You should find the
country with the largest population size and then display
Where [LARGEST COUNTRY] is the output to cout of the largest country. If there are
no countries in the list, the error message
should be shown instead. The algorithm for this task should be straightforward using
e.g. the already defined < operator on countries. You may assume for the purpose of
this task that the sizes of the populations of the different countries are distinct (i.e. this
option will only be run in the tests when the different countries each have a distinct
population size).
There is just one public test, shown below. Like the last public test in Task 4, the menu
will be displayed as [MENU], but you are still expected to output the real menu!
There are no countries in the index currently
Largest: [LARGEST COUNTRY]
[MENU]
Enter Option: 3
There are no countries in the index
currently
[MENU]
Enter Option: 1
Enter Details: UK 67081234
[MENU]
Enter Option: 3
Largest: UK 67081234
[MENU]
Enter Option: 1
Enter Details: Germany 83222442
[MENU]
Enter Option: 3
Largest: Germany 83222442
[MENU]
Enter Option: 1
Enter Details: France 67813000
[MENU]
Enter Option: 3
Largest: Germany 83222442
[MENU]
Enter Option: Q
Task 6 – Removing Countries - 15%
We will here implement 4. Remove country. After the option has been picked, the user
is asked for an index:
If there is no country with that index (i.e. the index is too high or too low) the error
message
should be displayed and then we should go back to the menu. On the other hand, if
there is such an index, the country with that index should be removed from the list and
the countries with higher index should have their index decremented (to remove gaps).
Note, this means that you can e.g. keep on removing the same index – each time it
will apply to the one that had 1 higher index before. Also, if you had 9 and removed 1,
then you can add a country again (i.e. without getting the warning from having too
many countries)
The public tests for this task is as follows (like in the last run in Task 4, [MENU] is used
to improve readability – it should still be the original menu!):
Enter Index:
No country has that index
[MENU]
Enter Option: 4
Enter Index: 1
No country has that index
[MENU]
Enter Option: 1
Enter Details: UK 67081234
[MENU]
Enter Option: 1
Enter Details: Germany 83222442
[MENU]
Enter Option: 1
Enter Details: France 67813000
[MENU]
Enter Option: 1
Enter Details: Italy 58983122
[MENU]
Enter Option: 2
[1] UK 67081234
[2] Germany 83222442
[3] France 67813000
[4] Italy 58983122
[MENU]
Enter Option: 3
Largest: Germany 83222442
Run in left column continues in right
[MENU]
Enter Option: 4
Enter Index: 2
[MENU]
Enter Option: 2
[1] UK 67081234
[2] France 67813000
[3] Italy 58983122
[MENU]
Enter Option: 3
Largest: France 67813000
[MENU]
Enter Option: 4
Enter Index: 1
[MENU]
Enter Option: 2
[1] France 67813000
[2] Italy 58983122
[MENU]
Enter Option: 3
Largest: France 67813000
[MENU]
Enter Option: Q
Run in left column continues in right
The second public test run is a continuation of the last one from task 4, replacing the
last line: “Enter Option Q” with the following:
Part 3 (Worth 40% in total)
In this part, you are meant to implement menu() for the class MenuPart3 as defined in
menupart3.h. You are meant to do the implementation in menupart3.cpp, which you
should create. It should look a lot like menu() for MenuPart2, but there is one more
menu option:
Task 7 – Refactored Program (Dynamic Data) – 25%
Refactor the program so it uses a dynamic data structure. In other words, there is no
limit on the number of countries the program could store (assuming unlimited
memory). The actual behaviour of the program won’t change from the user’s
perspective, but internally it will be very different.
You should use a dynamic data structure from the Standard Template Library, such
as a vector or a list (you should NOT use set or map – they sort automatically, and
things will then be out of order – i.e. not ordered by the order they were entered -
unless you do things in an ugly way). You should also use iterators and algorithms.
E.g. containers have an erase() function to remove items (which, as you saw in the