联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> Java编程Java编程

日期:2020-10-21 10:56

Assignment 1

ippo 2020-2021

coupling java

Object cohesion

class ippo

unit test

hashmap constructor

method

exception

encapsulation

accessor mutator

intelliJ

model

Don’t panic! This document may look long, but it includes the material to help you understand the

underlying concepts, as well as the assignment exercises themselves. It should guide you step-by-step

though a fairly realistic Java application over a period of several weeks. The preparation in section 2

should take no longer than about an hour and we recommend that you do this as soon as possible to

check that everything is working correctly before you start on the following sections. A good solution

should be possible with no more than about one day’s work (eight hours), although you may need to

spend longer if you don’t have much previous programming experience. We strongly recommend that

you work on the assignment steadily over this time, rather than leaving it until the final week - this will

give you an opportunity to get help via the Piazza1

forum if you run into unexpected difficulties.

It is possible to obtain a good mark without attempting all of the tasks (?). Especially if

you don’t have a lot of previous experience, don’t spend an excessive amount of time on the

more difficult tasks. Certain tasks are essential for the various different grades though - so you

should pay careful attention to the marking criteria (appendix A).

1 The Application

For this assignment, you will be working with an application which displays images of the Munros.

These are the 282 highest mountain tops in Scotland and are named after Sir Hugh Munro who first

catalogued them. You can see the full list and hear the pronunciation of the Gaelic names on the Walk

Highlands2 web page (you will not be tested on the pronunciation).

The application itself is quite simple, but it will

give you some realistic experience with:

? Using “professional” development tools.

? Creating applications by “composing”3 objects

of different classes.

? Understanding and using classes created by

others, as well as the standard Java libraries.

? Integrating these with your own code.

? Working with remote services.

? Working with graphical user interfaces.

? Documenting and testing your code.

The images will be downloaded from various web sites, including Wikipedia4

, and some of my own

Photographs on the IPPO site.

1https://piazza.com/ed.ac.uk/fall2020/ippo

2http://www.walkhighlands.co.uk/munros/pronunciation

3

i.e. connecting together existing objects in different ways to create different applications.

4https://en.wikipedia.org/wiki/Munro

Revision: 20.18 06/10/2020

Assignment 1 (2)

2 Preparation

? [1] Before starting on the assignment, make sure that you have a working set of development tools,

and that you understand how to use them, by following the Getting Started tasks.

Real Java applications are constructed from large collections of classes. And most of the code will

usually be provided by other people - either by someone else working on the same (large) project, or as

part of a library or framework imported from elsewhere (such as the JavaFx graphics framework). To

give you a realistic experience for this assignment, we have provided a library containing some useful

classes for downloading and displaying images. You will be extending some of these, and writing new

classes which interact with them to produce an application for viewing photographs of the Munros.

To help you get started, we have also provided some template files for the application . . .

? [2] You should start by creating and linking a git repository containing the starter files. This is a

similar process to the creation of the simple repository in the Git Task:

1. Accept the assignment by selecting your UUN in the GitHub List5

. Remember to check your

UUN carefully and make a note of the repository URL.

2. Download and unzip the Zip file containing the template project.

3. In a terminal window, change in to the resulting ippo-assignment1 directory, initialise the

repository and add the downloaded template files:

? cd ippo-assignment1

? git init

? git add *

? git commit -m "template"

4. You can then push these initial files to your remote repository6

:

? git branch -M main

? git remote add origin url-of-your-repository

? git push -u origin main

The url-of-your-repository should be the full URL, ending in .git.

At the assignment deadline, we will pull your code directly from the repository for marking.

We will also check periodically that you are following good software engineering practice by

making regular updates. So you should remember to commit and push your changes to the

repository as you are working on the assignment - don’t wait until you think it is absolutely

“correct”, or “finished”.

You can now . . .

? [3] Import the template into a new IntelliJ project (in the same way as the Simple Example), and run

the sample application using Tasks ippo run from the Gradle panel.

This should display an interface which allows you to view a selection of images, similar to the one on

the first page. Ask for help on Piazza if you have problems getting this to work.

5https://ease.groups.inf.ed.ac.uk/cgi/ippo/2020/cgi/git/register/1

6Until October 2020, the default branch on GitHub was master, rather than main.

Paul Anderson 06/10/2020

(3)

If you see the error message “class file has wrong version” it is probably because

you are using the wrong version of the JDK - try going into the project settings and

changing the JDK version to 14.

Adding the project to IntelliJ and executing it with gradle will have created some temporary configuration

and cache files. You can see that these files have not been committed to git:

? git status

You could now add and commit these files, but you almost certainly do not want to include these in

your git repository - they are not “source” files and will be regenerated automatically when they are

needed.

? [4] Instead, you should . . .

1. Tell git to ignore these by creating a plain text file called .gitignore7

containing the following:

/.gradle/

/.idea/

/gradle/

/build/

gradlew

gradlew.bat

Be careful to include the correct punctuation in the file patterns. In the IntelliJ interface, you will

notice that the ignored files are shown in a different colour.

2. Finally, you will need to commit and push the .gitignore file itself:

? git add .gitignore

? git commit -m "ignore temporary files"

? git push -u origin main

When you make changes to your assignment, you should add the changed files and commit/push

them in the same way (with an appropriate comment). You may like to explore the VCS menu which

allows you to perform the git operations from the IntelliJ interface.

You now have a clean template project in your own git repository and you are ready to start work on the

assignment . . .

3 Understanding the Classes

The demonstration application is structured using three main classes:

? A View class which handles the interface (displaying the images, and detecting user input).

? A Service class which retrieves a picture from the remote service.

? A Controller class which manages the other classes and determines the overall behaviour of the

program.

3.1 Using Different Implementations

A well-designed application will allow classes to be easily replaced with different implementations. To

illustrate this, our library provides:

7https://git-scm.com/docs/gitignore

Revision: 20.18 06/10/2020

Assignment 1 (4)

? Two different View implementations - using buttons or menus.

? Two different Service implementations - Wikipedia and the IPPO photographs.

? Two different Controller implementations - one which allows specific images to be viewed, and

another which displays a random image and asks the use to guess the appropriate name (a “quiz”).

You can browse the Javadoc for these classes on the assignment web page. Notice that each of these

(View, Service, Controller) has several implementations and an interface8

specification which defines the

methods that each implementation must provide.

The library provides a mechanism for you to experiment easily with different combinations of these

implementations by changing values in a “property file”:

? [5] Experiment with the different properties:

1. Open the project file src main resources properties app.properties . Lines starting with # are

explanatory comments which are ignored by the system.

2. Change the View from ButtonView to MenuView and re-run the application. Notice how the

interface has changed but the other components remain the same.

3. Change the Controller from SimpleController to QuizController. The application

will show a random Munro. You can guess the name and the application will tell you whether you

are correct or not. Choosing New will display another Munro.

4. Change the Service from IPPOService to WikiService (this example may be clearer if

you change back to the SimpleController) and re-run the application. The application will

fetch the images from Wikipedia, so there will be different images for each mountain (and there

will be a slower response).

5. Reset the property file back to the original values for the following exercises.

This kind of flexibility is an important property of a good object-oriented design, and you

should think carefully about this when you come to create your own class design.

3.2 How Does This Work?

Figure 1

9

is a sequence diagram10 which shows a typical sequence of interactions between the objects:

? A simple Controller creates the View and Service objects.

? It then calls the View to add buttons for the required subjects to the interface. For each subject,

the View returns an identifier which can be used to identify that selection.

? Control then transfers to the View start() method to display the interface and wait for user

input.

? When the user makes a selection in the interface, the View calls the Controller’s select()

method, passing the identifier for the selected item.

? The Controller then calls the Service to fetch a picture for the corresponding subject.

? When the picture is returned, the Controller calls the View to display it.

? [6] Look at the provided code for SimpleController.java11 and follow the code using the

8The term interface here refers to a “Java interface” which has nothing to do with the “user interface”.

9

Icons from Flaticon licensed under Creative Commons BY 3.0.

10A sequence diagram is used to show the interactions between objects, and the order in which the interactions occur.

11ippo-assignment1/src/main/java/ippo.assignment1/controller/SimpleController.java

Paul Anderson 06/10/2020

(5)

SimpleController

Bu!onView

IPPOService

start()

getPicture

(subject)

picture

addSelection(…)

addSelection(…)

select(id)

showPicture

(picture)

new()

new()

id

id

Loop

start

Figure 1: A sequence diagram for the simple version of the PictureViewer.

above description.

Notice that the getPicture() method allows us to specify an index (as the second argument). In this

case, we always use a value of 1 which returns the first picture for the given subject. Some services

may have more than one image for the same Munro, and we could use different values for the index to

retrieve these other images.

We are now ready to write some actual code!

4 Writing a Controller

The property file makes it easy for us create and experiment with a new controller. Let’s start just by

making a small extension to the SimpleController . . .

4.1 Adding an Extra Option

The supplied class provides just three possible selections.

? [7] Let’s add a fourth one:

1. Copy the SimpleController.java class to BigController.java, and modify the code

to add a fourth option.

2. Change the property file to use BigController instead of SimpleController in the properties

file, and run the application to try out your controller.

3. Keep BigController.java for your submission.

Look at the IPPO page to find Munros which are available on the IPPOService.

Remember to change all occurrences of SimpleController in the new source file to BigController

Revision: 20.18 06/10/2020

Assignment 1 (6)

If you copy and paste the class using IntellIJs’ project menu, it will automatically rename these for you,

but remember to edit the comments so that they are meaningful as well!

4.2 Using a HashMap

You will notice that it is very tedious to add an extra option: you need to add the selection to the view,

and an extra clause to the conditional statement to test for it. In this case, the interface label is the same

as the search string (which may not always be the case), so you have to specify exactly the same name

in two places as well (which is a potential source of errors).

We can improve this by using a HashMap. If you are unsure about these, read the note on HashMaps,

and/or the book section on HashMaps before continuing.

? [8] Create a version of the controller which uses a HashMap to store the Munro names corresponding

to each selection identifier:

? Copy BigController.java to HashMapController.java to create a second new version

of the controller, and change the contents of the new file to match12

.

? Add the following import statement:

import ippo.assignment1.library.utils.HashMap;

? Declare a HashMap to store the correspondence between the selection identifier and the name.

You will need to think carefully about the required type for the HashMap.

? Make sure that you initialise the HashMap to an empty map, otherwise you will get an exception

(NullPointerException) when you attempt to access it.

? Write a method addSubject() which takes the name of a Munro, (a) adds a selection to the

interface, and (b) adds a corresponding entry to the HashMap (the method will be very short).

? You should now be able to rewrite the select() method very simply, and you should only need

to add one line (to the start() method) to add each extra Munro.

? Change the property file to test your HashMapController.

? Keep HashMapController.java for your submission.

You must use the IPPO implementation of the HashMap (above) which includes some code

to be used when testing your submission. Do not import java.Util.HashMap, or

Java.Util.* directly.

4.3 Reading Properties

Having the names of the Munros “hard-wired” into the source code means that they cannot be changed

without recompiling the code. And the user cannot change them without access to the source code either.

We could avoid this by specifying the list of Munros in the property file. For example:

controller.subjects = Beinn a’ Bheithir, Creag Meagaidh, ...

? [9] Create a third version of the controller which reads the list of Munros from the property file:

1. Copy the HashMapController.java to PropertyController.java and modify this

to read the list of Munros from the controller.subjects property in the property file.

12Do not edit the BigController file – you will need to submit both BigController and HashMapController.

Paul Anderson 06/10/2020

(7)

2. Configure the property file to use this controller. The property value above is available by default

from the library, so your application should display these Munros by default.

3. Set a new value for this property in your own property file. This this should override the default

and display your own list of Munros.

4. Keep PropertyController.java for your submission.

The (static) get() method of the Properties class can be used to retrieve the string value of the

property - look at the Javadoc for ippo.assignment1.library.utils.Properties. Having

obtained this string, you will need to (a) split the string at each comma to create a list (array) of names;

(b) remove any leading or trailing spaces from each name; and (c) iterate through the list adding each

item. Look through the Javadoc13 for the standard Java class String to find some helpful methods for

(a) and (b).

Notice that your code should be capable of reading an arbitrary number of Munros from the property

file. Make sure that it is not restricted to a fixed number.

5 Proxies

In this section, we will look at another way of composing objects. Let’s start with a motivating example:

imagine that we are dealing with a very unreliable service, which often returns an error, but usually

succeeds if the call is repeated a few times. We could handle this by simply having a loop which retries

failed calls a number of times. But where should we do this? If we include this code in the controller,

then we would have to duplicate the code in every controller. If we include it in the service, then we

would have to duplicate the code in every (potentially) unreliable service. Of course, in this case, there

isn’t much code involved, so this might not be significant. But in a real application, it may be. We can

solve this in a general way using a proxy class:

Look at the code for the RetryProxy in figure 2. The constructor for this requires that we specify

some base service object. The RetryProxy object saves this, and whenever we attempt to retrieve a

picture from the RetryProxy, it calls the base service repeatedly until it succeeds or it reaches some

maximum number of attempts. The RetryProxy itself conforms to the Service interface, so we can

use a RetryProxy wherever we can use any other service. This means that we can take any service

and “wrap” it with one of these proxy objects to create a version of the service which is more reliable.

The version of the RetryProxy in the library also has a constructor with no parameter (not shown

above). If this is called, the base service is determined from the properties file. This means that the

following properties will configure the application to use IPPOService service with an automatic

retry of any failed calls:

service = RetryProxy

proxy.retry.service = IPPOService

Of course, if you run the application with this configuration, it will be difficult to see any difference

because the service usually behaves reliably. But we can use another proxy class to illustrate that this is

working: The UnreliableProxy adds random errors to an existing service. Try this configuration

and notice the random failures:

service = UnreliableProxy

proxy.unreliable.service = IPPOService

13https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.

html

Revision: 20.18 06/10/2020

Assignment 1 (8)

private Service baseService = null;

public RetryProxy(Service baseService) {

this.baseService = baseService;

}

public Picture getPicture(String subject, int index) {

Picture picture = baseService.getPicture(subject, index);

int attempt = 1;

while (!picture.isValid() && attempt<=maxAttempts) {

picture = baseService.getPicture(subject, index);

++attempt;

}

return picture;

}

Figure 2: The core of the RetryProxy class.

getPicture

(subject)

picture

picture

picture

** fail **

IPPOService UnreliableProxy RetryProxy

getPicture

(subject)

getPicture

getPicture (subject)

(subject)

Figure 3: Recovering from a simulated unreliable service.

Now that we have an unreliable service, we can compose the two proxies to demonstrate that the

RetryProxy is indeed working! You can turn on the debugging messages for the various services

to display the sequence of events in the console:

service = RetryProxy

proxy.retry.service = UnreliableProxy

proxy.unreliable.service = IPPOService

proxy.debug = true

Figure 3 shows the sequence diagram for a typical interaction.

5.1 Writing a Cache Proxy

As well as being unreliable, network services can also be slow. In general, we can’t do anything about

this. But real applications often access the same data repeatedly, and we can improve the observed

performance of a slow service by simply keeping a local copy of any picture that we download and using

Paul Anderson 06/10/2020

(9)

this local copy if the same subject is requested again. This is called caching. Using a cache to reduce

the remote access in this way can also be cheaper for services which charge for access.

? [10] Write a cache proxy for the PictureViewer application:

1. You have seen how the UnreliableProxy can be used to create an unreliable version of a

service for testing. Similarly, the SlowProxy can be used to create a slow version of a service.

Configure the properties to create a slow version of IPPOService and notice the reduced

response time.

2. CacheProxy.java is a skeleton for a proxy which simply forwards all requests to the base

service unchanged. Configure the property file to use this proxy together with the SlowProxy.

You should not notice any difference in performance (i.e. it should still be slow).

3. Edit the CacheProxy.java and declare a HashMap to store the cache14. The values in the

cache will be the downloaded pictures. But you may need to think carefully about the keys – two

requests should only be considered the same if both the subject and the index are both the same.

The question of when two objects should be considered “the same” is not always easy.

You may like to read the note on Equality.

4. Now modify the getPicture() method: if the requested picture is in the cache, return the copy

from the cache; if the picture is not in the cache, download it from the base service and store it

in the cache before returning it. Test your cache with the SlowProxy – the first request for a

particular picture should be slow, but all subsequent requests for the same picture should be very

fast.

5. Keep CacheProxy.java for your submission and the demonstration.

Notice that the cache is only held in memory – if the application is restarted, then the contents of the

cache will be lost. A real application would probably store a copy of the cache on disk.

6 Testing

Beginning programmers sometimes think that “testing” is a chore which happens after the code has all

been written. But when you come to write larger programs, you will find it incredibly useful during

development to have a good test suite - this allows you to “refactor” and modify your code without

worrying whether your changes have broken some other part of the program. When you are designing

and coding a new class, you should think carefully about how it might be tested – otherwise it is easy to

create designs which are unnecessarily difficult to test.

JUnit is a standard framework for writing tests in Java. Both BlueJ and IntelliJ understand JUnit test

files and can run these in a special way which automatically records any failed tests.

6.1 Running JUnit Tests

The assignment template includes a Gradle task to run the JUnit tests, and CacheProxyTest which is

a simple JUnit test for the CacheProxy. This test checks that the proxy returns exactly the same object

whenever it is called with the same name and index – which is what we would expect from a working

cache proxy.

? [11] Experiment with this test:

1. Run the JUnit test with the Gradle task: Tasks ippo test . If your CacheProxy is correct, this

14Remember to import the HashMap from ippo.assignment1.library.utils, and not Java.Util

Revision: 20.18 06/10/2020

Assignment 1 (10)

test should pass.

2. If you (temporarily!) edit your CacheProxy so that it does not keep the copies in the cache,

and re-run the tests, the CacheProxyTest should fail. The test messages printed in the IntelliJ

console can be difficult to read, but you can view a formatted report by copying the URL which

appears in the console, and pasting it into a browser.

3. Remember to re-edit your CacheProxy so that it is working again (test it), and keep the source

file for your submission.

Notice that tests such as these can all be executed automatically. This is much easier than

having to manually run the application and watch the response time (which would simply not

be feasible if you had 100s or 1000s of tests).

6.2 Understanding the Cache Proxy Test

Look at the CacheProxyTest source file. You may find it helpful to sketch a sequence diagram - the

way in which the objects are configured for this test is interesting, and you may have to think carefully

to understand what is happening:

Notice that no view class is necessary, since we are not displaying anything - we are only calling the

service and making sure that it returns the “right” picture. But we do need a base Service object for

CacheProxy to call on. Rather than using a separate service class, the test class itself implements the

Service interface and provides a getPicture() method. When we create the cache proxy, we tell

it to use the test object as the base service by specifying this as the parameter to the constructor.

This means that whenever the cache attempts to call the base service, it will call the getPicture()

method of the test object. This method simply returns a new (empty) picture object every time it is

called. If CacheProxy returns a picture object which is equal to one that has been returned previously,

then it must have been cached. If it returns a new picture object, then it must have come directly from

the base service. Because the test class has control of the base service methods, we could also include

other code in the getPicture() method to control or record other properties of the picture. We say

that the CacheProxyTest object is acting as a mock service object.

The example equalityTest() simply makes two calls to CacheProxy object (with the same subject

and index) and confirms that the same picture object is returned both times. If the pictures were not

being cached, then we would expect two different objects to be returned (even though they may have the

same subject and index), and the test would fail.

6.3 Introducing Bugs

The BuggyProxy is a version of the cache proxy which contains some bugs. Some of the bugs will be

different for each student, and you must enter your student UUN by editing the build.gradle file:

// the ’uid’ is used when running the BuggyProxy

// you must replace the ’NONE’ with your own user-id (eg. ’s12345678’)

def uid = ’NONE’

Then you can configure the application to use this proxy by setting the following properties:

service = BuggyProxy

proxy.buggy.service = IPPOService

Now you can use the menu Tasks ippo (run buggy proxy) to simulate a proxy with a range of different

Paul Anderson 06/10/2020

(11)

bugs:

? A - No bug.

? B - Does not cache any images.

? C - An obvious bug.

? D - A bug which is different for different students.

? E - A more obscure bug which is different for different students.

? F - Throws an exception after some images have been displayed.

? G - “Hangs” after some images have been displayed.

? [12] Try running the application with these different cases to observe the effect.

Remember that the bugs may not all be obvious from the image - the bug may involve the image subject

(displayed at the top of the window), or even the index, which may not be obvious at all in this particular

application. You will have to interrupt the non-terminating case (G) using the square red button in the

top right of the IntelliJ interface.

Do not spend too long attempting to identify the bugs in cases D and E - these may be quite obscure.

6.4 Testing the Buggy Proxy

? [13] Create a JUNit test file for BuggyProxy:

1. Copy the CacheProxyTest.java class to BuggyProxyTest.java, and change the contents

so that it tests the BuggyProxy instead of the CacheProxy. You will need to add an

appropriate import statement.

2. If you run this test for the various cases with Tasks ippo (test buggy proxy) , it should pass on A

(because this does not introduce any bugs) and it should fail on B (because the BuggyProxy

does not cache any images in this case). But your test code will probably not detect the bugs in

the remaining cases.

6.5 Writing a New Test

? [14] Create an additional test for the BuggyProxy:

1. Extend the BuggyProxyTest to include an extra test for case C.

2. Your tests now should fail for this case, but make sure that they still pass in case A, and fail in

case B.

3. Keep the BuggyProxyTest.java for your submission and the demonstration.

? [15] You might like to try adding tests for some of the remaining cases - but these can be difficult

(especially E, F and G), and are not essential - so you should only do this if you have time after

completing the other tasks.

It is important that your classes can be tested independently from the rest of your application. When

your tests are run for marking, they will not have access to any of your other code. So . . .

Before submitting, check carefully that you do not have any unnecessary imports, or other

dependencies. For example:

? Do not depend on additional properties in the property file.

? Do not import additional files of your own.

Revision: 20.18 06/10/2020

Assignment 1 (12)

7 Readability

In the “real world”, it is not sufficient for code to just “work” - it also has to be easy for other people

to read and understand, easy to extend later, and sufficiently clear that there are no hiding places for

obscure bugs. Clear, readable code is a core requirement of the IPPO course - code which is difficult

to read will not pass, and higher marks require particularly clear and well-structured source code. So,

before you submit . . .

? [16] Look at the notes on code Readability and use this to review the readability of your code.

8 Worksheet

For a higher mark (see appendix A), you will need to demonstrate your understanding of the code, and

your ability to explain it clearly, by submitting a worksheet with answers to a few questions. Some of

these questions are quite challenging, so only attempt them if you are confident that you have completed

the other tasks well:

1. Explain why the controllers are hard to test in the same way that you tested the CacheProxy (i.e.

without relying on external services or views). Suggest how you might make a small modification

to the controller class to make this easier.

2. Explain why it is difficult to “compose” the RandomProxy and CacheProxy. i.e. to use these

class implementations to create a system which both fetches images from a random service and

caches the results. Suggest how you might change the way in which the properties are used to

make this composition possible.

? [17] If you think that you can provide good answers to these questions, create a document containing

your answers:

1. Make sure that your name and student number are clearly visible at the top of the worksheet.

2. Make sure that the answers are clearly numbered.

3. Make sure that your answers are clear and concise, with a good standard of English.

4. Convert the document to PDF format15 with the name worksheet.pdf.

5. Place the PDF document in the top-level directory of your project.

It is important that the name (worksheet.pdf), format (PDF), and location (top level directory)

of the worksheet are all correct - otherwise we will assume that you have not submitted

this task.

9 Finally . . .

The assignment files will be automatically extracted from your Git repository precisely on the

assignment deadline. Changes made after the deadline will not be included.

? [18] Remember to add/commit/push all of your files (to the main git branch), so that they appear

in your remote repository. In particular, the following files will be required for the marking:

(a) BigController.java

(b) HashMapController.java

15It is good practice not to depend unnecessarily on proprietary formats (such as Microsoft Word). Ask on the Piazza forum

if you are unsure how to create a PDF document from your source format.

Paul Anderson 06/10/2020

(13)

(c) PropertyController.java

(d) CacheProxy.java

(e) BuggyProxyTest.java

(f) worksheet.pdf

? [19] Make sure that you understand about good scholarly practice – see the Course Information for

further details. We have automated tools for checking both worksheets and code for similarity

with other submissions (including previous years). If you are in any doubt about any part of your

submission, please discuss this with the course lecturer.

If we have difficulties running your code, or any queries, we may ask you to meet with a tutor online to

explain and demonstrate your solution.

We hope that you found this a useful and realistic exercise. Please do let us know what you think. use

Piazza to ask the tutors if you would like any further feedback, or to discuss any issues relating to this

exercise.

Revision: 20.18 06/10/2020

Assignment 1 (14)

Appendix A Marking Criteria

When assessing the submitted code, we will consider the following criteria:

Completion: Those with less previous experience may have difficulty completing all of the assignment

tasks. It is possible to pass without attempting the more advanced tasks - and a good solution to some of

the tasks is much better than a poor solution to all of them.

Readability & Code Structure: Code is a language for expressing your ideas - both to the computer,

and to other humans. Code which is not clear to read is not useful, so this is an essential requirement.

Correctness & Robustness: Good code will produce “correct” results, for all meaningful input.

But it will also behave reasonably when it receives unexpected input.

Use of the Java Language: Appropriate use of specific features of the Java language will make the

code more readable and robust. This includes, for example: iterators, container classes, enum types, etc.

But the structure of the code, including the control flow, and the choice of methods, is equally important.

Marks will be assigned according to the University Common Marking Scheme16. The following table

shows the requirements for each grade. All of the requirements specified for each grade must normally

be satisfied in order to obtain that grade.

Pass (Diploma only): 40-49%:

? Submit some plausible code for a significant part of the assignment, even if it does not work

correctly.

Good: 50-59%:

? Submit the Getting Started form before the deadline shown in the Schedule.

? Check some initial code into your git repository by the deadline shown in the Schedule.

? Submit working code for most parts of the assignment, even if there are small bugs or omissions.

This must include some plausible code for each of the sections 4, 5, and 6.

? Submit code which is sufficiently well-structured and documented to be comprehensible. This

includes an appropriate use of Java features and choice of methods, as well as layout, comments

and naming.

Very Good: 60-69%:

? Submit working code for all parts of the assignment, even if this contains small bugs.

? Submit code which is well-structured and documented.

? Provide answers to some of the worksheet questions which demonstrate some understanding of

the issues involved.

Excellent: 70-79%:

? Submit working code for all parts of the assignment, with no significant bugs.

? Provide answers to the worksheet questions which demonstrate a good understanding of the issues

involved, and propose plausible solutions.

Excellent: 80-89%:

? Marks in this range are uncommon. This requires faultless, professional-quality design and implementation,

in addition to well-reasoned and presented answers to the worksheet questions.

16https://web.inf.ed.ac.uk/infweb/student-services/ito/students/common-markingscheme

Paul Anderson 06/10/2020

(15)

Outstanding: 90-100%:

? Marks in this range are exceptionally rare. This requires work “well beyond that expected”.

Revision: 20.18 06/10/2020


版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp