Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit

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

RunState

CrawlState

ShootState

The states are interconvertible based upon 7 keyboard instructions:

Key.UP

Key.DOWN

Key.RIGHT

Key.LEFT

Key.L

Key.S

Key.RESET

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 memory.

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 memory.

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:

LOAD a;

save 100 to a;

save 10 to&^ variable!@#$%^& ; 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

BST.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:

Add

Subtract

Multiply

Divide

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 Property?

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 ...

3. ...