COMP2100 final exam 2022

COMP2100 final exam 2022
Q1 – Design Pattern & Software Testing & Persistent Data
(20 marks)

One day, your supervisor assigns to you a game development task, where a character can be controlled by
external keyboard instructions.

The character has five states, where each state has only one unique instance:

StandState
LieProneState
CrawlState
ShootState

The states are interconvertible based upon 7 keyboard instructions:

You are expected to apply the state and singleton design patterns based on the given state graph
Graph.pdf .

1) You are expected to create all the state classes from scratch to pass the given test cases in
StateTest.java class, where a getInstance() method should be defined to obtain the singleton
instance of each state. Note that any state will be reset to the default StandState on Key.RESET .

Please do not create all the state classes in one file!

2) You are required to develop robust code, which ensures that the passed-in arguments are valid.
You are expected to complete the check() method in the State interface and also create test
cases in the following methods of the ExceptionTest.java class for the exception testing:

testNullKeyException() : If the passed-in key is null, the NullKeyException will be thrown.
testNullCharacterException() : If the passed-in character is null, the NullCharacterException will
be thrown.

Hint: For the marking of part 2, firstly we will check whether your code passes the test cases in the
ExceptionTest.java . Secondly, we will also run the correct test cases to test whether your code in the
check() method meets the requirements.

3) You are expected to complete the read() and write() methods in the XMLProcessor.java .
read() aims to read the keys and events from the xml file. write() aims to write the keys and
events to the xml file in the given order. You are required to comply with the XML format in the
given example.xml file. Ensure that the example XML file is placed in the right directory.

Please try your best to return a value for the required methods, e.g. 0 or null, to make

sure your solutions do compile if you have trouble in providing the solutions. Otherwise,

you may be subject to a mark loss due to compile errors.

You are expected to upload:

State.java

StandState.java

LieProneState.java

RunState.java

CrawlState.java

ShootState.java

ExceptionTest.java

XMLProcessor.java

IMPORTANT NOTES :

Please do not add any packages at the head of any of the above uploaded files. Otherwise, your code
may fail to be compiled by the auto-marker and you may lose marks.
You are allowed to create helper methods in the required java classes. Aside from creating those
helper methods, you are only allowed to implement your code in the designated area between “YOUR
CODE STARTS HERE” and “YOUR CODE ENDS HERE”.
Some test cases are provided to assist your understanding, but passing them does not guarantee you
will get full marks. Remember that we use different test cases to mark your solution. You are free to
add your own test cases to increase your confidence that your solution is correct and robust.

Q2 – Design Patterns & Coding Skills (25 marks)
The given code implements a quote calculator that compares the quotes offered by two express companies
and gives the best quote for delivery. The express companies offer quotes for a parcel delivery based on the
integer weight of the parcel and the integer distance from the express companies to the parcels’
destinations.

Each express company has a delivery radius, within which the companies offer quotes only based on the
weight of the parcel. If the distance is greater than the radius, the companies charge additional fees for the
distance based on the formula: AdditionalDistanceFees = ratePerDistanceUnit * Distance

The distance between two integer points (x1, y1) and (x2, y2) can be calculated using the Euclidean distance
formula: Distance = sqrt((x1-x2)^2 + (y1-y2)^2) where sqrt is square root operation, ^2 is the
power of 2. The express companies charge the distance fees based on the round-up distance values if the
calculated distance is fractional. For example, if the calculated distance is 3.1, then round it up to 4 as the
distance value.

The companies sets several weight intervals and each weight interval has a quote rate. The total quote is the
sum of partial quotes of all the intervals, where the partial quote for each interval is proportional to the part
of weight falling in that interval. For example, for the following quote scheme:

0 < weight <= q1: rate=r1 q1 < weight <= q2: rate=r2 If the weight falls in the interval of (0, q1], the total quote should be Q=weight * r1 . If the weight falls in the interval of (q1, q2], the total quote should be Q=q1 * r1 + (weight - q1) * r2 : Here is the quote scheme of the express company A: 0 < weight <= 20kg: rate=$1.3 20kg < weight <= 40kg: rate=$1.7 40kg < weight <= 60kg: rate=$2.4 weight > 60kg: rate=$3.2

Beyond the radius, the company A charges an extra (ratePerDistanceUnit=$1) for each distance unit.

Here is the quote scheme of the express company B: Different from A, this company has a constant quote
$46 for weights that are no more than 30kg . For weights higher than 30kg , the strategy is the same as that
of A, but with different rates and intervals.

0 < weight <= 30kg: quote is constant at $46 30kg < weight <= 40kg: rate=$1.5 40kg < weight <= 50kg: rate=$2.1 50kg < weight <= 60kg: rate=$2.9 weight > 60kg: rate=$3.6

Beyond the radius, the company B charges an extra (ratePerDistanceUnit=$1.1) for each distance unit.

QuoteCalculator class has a bestQuote() method that compares the quotes of the two express
companies and yields the best quote (the lower quote). The methods calculateQuote() in
CompanyA.java and CompanyB.java are respectively intended to calculate the quotes of the two
companies based on the above quote schemes. Note that if the quotes offered by two companies are equal,
always choose the express companyA .

Moreover, the express companies have specific prohibited item list and need to perform a safety check on
the items in parcels before calculating quotes. You are expected to throw an
IllegalParcelItemException when there are any items prohibited by the companies.

Please refer to the given test cases in ParcelTest.java for more details.

Please try your best to return a value for the required methods, e.g. 0 or null, to make

sure your solutions do compile if you have trouble in providing the solutions. Otherwise,

you may be subject to a mark loss due to compile errors.

You are expected to complete:

calculateQuote() method in the CompanyA.java class
calculateQuote() method in the CompanyB.java class
bestQuote() method in the QuoteCalculator.java class
calculateDistance() and safetyCheckOnItems() in the ExpressCompany.java class

You are expected to Upload:

CompanyA.java

CompanyB.java

QuoteCalculator.java

ExpressCompany.java

You are allowed to create helper methods in the required java classes. Aside from creating those helper
methods, you are only allowed to implement your code in the designated area between “YOUR CODE
STARTS HERE” and “YOUR CODE ENDS HERE”. Some test cases are provided to assist your understanding,
but it does not guarantee you will get full marks. Remember that we use different test cases to mark your
solution. You are free to add your own test cases to increase your confidence that your solution is robust.

Q3 – Tokenisation & Parsing & Tree (30 marks)
The provided code implements a simple compiler that compiles and executes a series of commands. The
compiler interacts with a binary-tree based memory. The memory is initialised as empty. There are three
types of commands with the syntax as below:

LOAD key; : loads the value stored in an address referenced by the string key in memory. If the key
does not exist, return null.
SAVE value TO key; : saves the value to an address referenced by the string key in memory.
SUM pattern TO key; : adds up all the values in addresses referenced by the keys satisfying the
string pattern and saves the sum value to an address referenced by the string key . If no keys satisfy
the given pattern, save 0 to memory.

The string pattern can be:

a wildcard character * indicating 0 or at least 1 letter or digit.
a series of letters and digits along with at most one wildcard character , e.g. abc , abc* , *abc ,
a*c . For example, all of aasdbc , abbbc , abc , a2c , ac satisfy the pattern a*c . bac does not satisfy
the pattern a*c because it does not start with the letter a . The pattern * references all the keys in

Note that you are not allowed to use regex libraries to achieve the pattern search. We will check the usage
of regex-related libraries and assign zero mark for those who use it. Tips: If you have some
difficulties in handling the commands with a wildcard character, it would be better to

adapt your solutions for the commands without a wildcard character. We will prepare

different marking test cases to evaluate your solutions. This will help you get partial

marks but not lose all the marks for this question.

LOAD , SAVE , SUM , TO , TERMINATOR , PARAMETER are the defined keywords of the commands. key ,
value , and pattern are the parameters of the commands. The semi-colon ; is the terminator.

Part 1) Implement the next() method of the Tokeniser class to perform a tokenisation process. The
next() method should be able to identify the keywords and parameters of the commands. The token
types are defined in the Token.java class. The keywords and parameters are separated by at least one
space or special symbol, where a special symbol can be any symbol except a letter, a digit, the wildcard
character * or the terminator ; . For instance, ^%&$@ are considered as special symbols. You are expected
to return valid tokens that do not include any spaces or special symbols.

Please find more details in the given TokeniserTest.java .

Part 2) Implement the parseCmds() method of the Parser class to create three types of commands from
the tokens:

LoadCommand contains one parameter, a string key .
SaveCommand contains two parameters, a string key and a non-negative integer value .
SumCommand contains two parameters, a string pattern and a string key .

Please find more details in the given ParserTest.java .

Part 3) Implement the find() and invertedPreOrder() methods of the BST class to realise the
underlying operations of binary search tree. find() aims to find a particular node based on a given key.
invertedPreOrder() aims to perform an inverted pre-order traversal of the tree. Note that the traversal of
an inverted pre-order should be: root, right child, left child.

Please find more details in the given BSTTest.java .

Part 4) Implement the load() , save() and sum() methods of the Executor class to execute the parsed
commands. You are required to use find() and invertedPreOrder() as helper methods. For instance,
invertedPreOrder() method needs to be used to loop through all the keys stored in the tree-based

Please find more details in the given ExecutorTest.java .

IMPORTANT NOTES:

The string key parameters are composed of letters and digits, whereas the value parameters are
non-negative integers.
The key or value parameters DO NOT include a wildcard character.
The keywords are all case INSENSITIVE , whereas the key parameters are case SENSITIVE . HINT:
you can use toLowerCase() or toUpperCase() , etc. defined in the String.class to compare strings
without care for case sensitivity.
The keywords will not appear in the parameters .
At least one space or special symbol between the keyword and parameter is allowed.
Each single command is terminated by a semi-colon ; .
A series of single commands can be concatenated together in any order.
All the commands in the given and marking test cases are valid. You don’t need to consider the
invalidity of the commands.

We give some examples of valid commands below:

save 100 to a;

save 10 to&^ ; Load variable ; Sum vari* To ret ;

We may not give all the valid test cases. Feel free to add more test cases to test the robustness of your
solutions.

Please try your best to return a value for the required methods, e.g. 0 or null, to make

sure your solutions do compile if you have trouble in providing the solutions. Otherwise,

you may be subject to a mark loss due to compile errors.

You are expected to complete:

next() method in the Tokeniser.java class
parseCmds() method in the Parser.java class
find() , invertedPreOrder() methods in the BST.java class
load() , save() , sum() methods in the Executor.java class

You are expected to upload:

Tokeniser.java

Parser.java

Executor.java

You are allowed to create helper methods in the required java classes. You are only allowed to implement
your code in the designated area between “YOUR CODE STARTS HERE” and “YOUR CODE ENDS HERE”. Some
test cases are provided to assist your understanding, but it does not guarantee you will get full marks.
Remember that we use different test cases to mark your solution. You are free to add your own test cases
to increase your confidence that your solution is robust.

Q4 – Open Question (25 marks)
A junior software engineer designs and implements a simple calculator that is required to perform the
following basic arithmetic operations:

Exponentiate

Each operation takes 2 integers as inputs and outputs the result. The calculator users are allowed to specify
the operations and the inputs via a Client class.

Part 1) However, there are a number of deficiencies and loopholes in the current code. Could you point
them out and improve them?

Part 2) What are your suggestions for the design of the code for the purpose of a better extensibility if new
arithmetic operations are needed to be incorporated into the code in future? You can provide concrete
examples. What kinds of new features can be incorporated? How your current code needs to be adapted for
the new features?

Part 3) Is there any room for improvement on the code from the perspective of Licensing and Intellectual

Exploit all the knowledge you have learned from this course to give answers to the above questions. You are
encouraged to answer the questions from any perspectives that you think are appropriate, e.g. efficiency,
testability, extensibility, maintainability, correctness, intellectual property, etc. You are encouraged to point
out as many deficiencies as possible.

Please be concise (objective and specific). Try to provide a list of bullet points summarising your thoughts
with concise explanations for each bullet point. Long paragraphs may not help you get more marks.

Here is some examples of your answers:

1. There is a deficiency in the design of the calculator … because it is not efficient to ….

I will apply a design pattern to the classes …

2. There is a calculation error in the XXX() method of the class XXX.

I will …

COMP2100 final exam 2022
Q1 – Design Pattern & Software Testing & Persistent Data (20 marks)
1) You are expected to create all the state classes from scratch to pass the given test cases in StateTest.java class, where a getInstance() method should be defined to obtain the singleton instance of each state. Note that any state will be reset to the default StandState on Key.RESET.
2) You are required to develop robust code, which ensures that the passed-in arguments are valid. You are expected to complete the check() method in the State interface and also create test cases in the following methods of the ExceptionTest.java class for the exception testing:
3) You are expected to complete the read() and write() methods in the XMLProcessor.java. read() aims to read the keys and events from the xml file. write() aims to write the keys and events to the xml file in the given order. You are required to comply with the XML format in the given example.xml file. Ensure that the example XML file is placed in the right directory.

You are expected to upload:

Q2 – Design Patterns & Coding Skills (25 marks)
You are expected to complete:
You are expected to Upload:

Q3 – Tokenisation & Parsing & Tree (30 marks)
You are expected to complete:
You are expected to upload:

Q4 – Open Question (25 marks)