You are on page 1of 16

Semester One Final Examinations, 2012 CSSE2002 Programming in the Large

Page 1 of 16



This exam paper must not be removed from the venue


School of Information Technology and Electrical Engineering
EXAMINATION
Semester One Final Examinations, 2012
CSSE2002 Programming in the Large
This paper is for St Lucia Campus students.
Examination Duration: 120 minutes
Reading Time: 10 minutes
Exam Conditions:
This is a Central Examination
This is an Open Book Examination
During perusal - writing is not permitted at all
This examination paper will be released to the Library
Materials Permitted In The Exam Venue:
(No electronic aids are permitted e.g. laptops, phones)
Calculators - No calculators permitted
Materials To Be Supplied To Students:
2 x 14 Page Answer Booklet
Instructions To Students:
Answer each part of the following 5 questions in the Answer Booklet provided.
Venue ____________________
Seat Number ________
Student Number |__|__|__|__|__|__|__|__|
Family Name _____________________
First Name _____________________
!"# %&'()*+# ,-+ .*/0
!"#$%&'( *+,-





















.'%+/ 00000000
Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 2 of 16
Question 1 [12 marks]
Question 1 (a) [5 marks]
What is printed in the output window by the following Java program?
public static void main(String[] args) {
int [] a = {2,3,7,27,5,8,6,18};
int c = 0;
for(int i = 0; i< a.length; i++) {
if((a[i]%3 == 0 && i/2 > 1) || a[i]%5 ==0)
c += a[i];
}
System.out.println(c);
}

Solution: 29

Question 1 (b) [7 marks]
Consider the class Foo and its subclass Bar:
public class Foo {
protected int y = 0;

public Foo(int y) {
this.y = y;
}

public int getY() {
return y;
}

public void add(int n) {
for(int i = 0 ; i < n ; i++) {
inc();
}
}

public void inc() {
y++;
}
}

public class Bar extends Foo{

private int z = 0;

public Bar(int y) {
super(y);
this.z = 2*y;
}

Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 3 of 16
public int getZ() {
return z;
}

public void add(int n) {
super.add(n);
super.add(n);
}

public void inc() {
z = z + 2;
}
}

What is printed in the output window by the following Java fragment?
Foo foo = new Bar(1);
System.out.print(foo.getY());
foo.add(2);
Bar bar = (Bar) foo;
System.out.print(" " + bar.getZ());
bar.add(1);
System.out.print(" " + bar.getZ());

Solution: 1 10 14


Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 4 of 16
Question 2 [12 marks]
The class AcademicPeriod is an immutable representation of a teaching period,
comprised of a year and a semester.
public class AcademicPeriod implements Comparable<AcademicPeriod>
{
private int semester;
private int year;

public AcademicPeriod(int semester, int year) {
this.semester = semester;
this.year = year;
}

public int getSemester() { return semester; }

public int getYear() { return year; }

public boolean equals(Object o) {
if (!(o instanceof AcademicPeriod))
return false;
AcademicPeriod a = (AcademicPeriod) o;
return (semester == a.semester && year == a.year);
}

public int compareTo(AcademicPeriod a) {
int result = year - a.year;
if (result == 0)
result = semester - a.semester;
return result;
}
}
Class AcademicTranscript is a mutable data type that, for each academic period,
records the courses that were taken by a student in that period and the grade that was
received. Courses may be taken more than once in different academic periods, but only
once in a given academic period. (Both TreeMap and HashMap implement the Map
interface.)
public class AcademicTranscript {

// maps academic periods to courses taken during
// that period and their corresponding grades
private TreeMap<AcademicPeriod,
HashMap<String, Integer>> history;
// maps each course taken to the maximum grade
// ever received for that course
private HashMap<String, Integer> maxGrade;

/** @ensure creates an empty academic transcript */
public AcademicTranscript() {
history = new TreeMap<AcademicPeriod,
HashMap<String, Integer>>();
maxGrade = new HashMap<String, Integer>();
}
Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 5 of 16

/**@require the given academic period p is not null
* and there are currently no courses and
* results recorded for p. Also, results
* is not null and it is non-empty.
* There are no null courses in results
* and each course is associated with
* a non-null grade.
* @ensure records the courses and grades for
* academic period p
*/
public void addSemesterResults(AcademicPeriod p,
HashMap<String, Integer> results) {
history.put(p, results);
Set<String> courses = results.keySet();
for (String course : courses) {
Integer grade = results.get(course);
Integer max = maxGrade.get(course);
if ((max != null && grade > max)
|| max == null) {
maxGrade.put(course, grade);
}
}
}

/**@require course is not null and has been taken
* in at least one academic period
* @assume returns the maximum grade received for course
*/
public int getMaxGrade(String course) {
return maxGrade.get(course);
}

public String toString() {
String s = "";
Set<AcademicPeriod> periods = history.keySet();
for (AcademicPeriod p : periods) {
HashMap<String, Integer> results =
history.get(p);
s += p.toString() + "\n";
Set<String> courses = results.keySet();
for (String course : courses) {
s += course + ": ";
s += results.get(course) + "\n";
}
}
return s;
}
}






Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 6 of 16
Question 2 (a) [4 marks]
Apart from missing or incomplete comments and the lack of an invariant and method to
check the invariant, there are two significant problems with the provided code for
AcademicPeriod. Identify these two problems with the adequacy of AcademicPeriod
and provide the code that would overcome them.
Solution: Inadequate: missing toString() and hashCode() methods

public int hashCode() {
return semester + year;
}

public String toString() {
return ("Semester " + semester + " " + year);
}


Question 2 (b) [4 marks]
Provide an invariant for the class AcademicTranscript. The invariant can be
expressed in a combination of English and Java notation. You may find it convenient to
use Map methods such as keySet (which returns the set of all keys), values (which
returns the set of all values) and get (which, given a key returns the value associated
with that key) in your invariant.
Solution:

/* invariant:
*
(a): * history!= null && maxGrade != null &&
(b): * ! history.keySet().contains(null) &&
(c): * ! history.values().contains(null) &&
*
(d): * for all results in history.values()
* ! results.keySet().contains(null)
* ! results.values().contains(null) &&
*
(E): * for all results in history.values()
* results.size() > 0 &&
*
(F): * A course is an element of maxGrades.keySet() iff
* there is at least one academic period p for which
* history.get(p).containsKey(course)
*
(G): * For each course in maxGrades.keySet(),
* maxGrades.get(course) is the maximum grade recorded
* in history for course in any academic period.
*/


Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 7 of 16
Question 2 (c) [4 marks]
Apart from missing or incomplete comments, issues with the adequacy of
AcademicPeriod, the lack of an invariant and method to check the invariant, there is
one significant problem with the provided code for AcademicTranscript. Describe
the problem with the implementation from the point of view of using the code in a larger
program, explaining briefly how it may cause a problem, and suggesting a change to the
implementation to avoid it.
Solution:

In addSemesterResults we set part of the value of instance
variable history to an input parameter.

This means that someone external to the class could modify our
instance variable, breaking our invariant.

Overcome it by making a copy of results, and adding that to
history at p.

Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 8 of 16
Question 3 [12 marks]
Consider the method count below. (In the specification, \result is used to refer to the
return value of the method.)

/**@require list != null &&
* for all x in list, 0 <= x < 100 &&
* 0 <= p <= 100
* @ensure \result is the number of elements x in list
* satisfying x < p
*/
public static int count(ArrayList<Integer> list, int p) {
int c = 0;
for (int i = 0; i < list.size(); i++) {
if(list.get(i) < p) {
c++;
}
}
return c;
}


Question 3 (a) [6 marks]
Provide a set of black-box test cases for the method. Each test case should include the
input values, the expected return value or exception thrown, and a brief justification for
the test case.

Solution:

Based on boundary values for list [], [35]
Boundary value for p are 0 and 100

Input Expected output (rationale)

list empty:

[], 0 0 (both boundary values)
[], 100 0 (both boundary values)
[], 50 0 (boundary value, non-boundary value)

list with one element:

[35], 0 0 (both boundary values)
[35], 100 1 (both boundary values)
[35], 34 0 (boundary, non-boundary value, 0-result)
[35], 50 1 (boundary, non-boundary value, 1-result)

list with many elements:

[45, 28, 89], 0 0 (non-boundary, boundary value)
[45, 28, 89], 100 3 (non-boundary, boundary value)
[45, 28, 89], 20 0 (non-boundary values, 0-result)
Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 9 of 16
[45, 28, 89], 29 1 (non-boundary values, 1-result)
[45, 28, 89], 51 2 (non-boundary values, 2-result)
[45, 28, 89], 90 3 (non-boundary values, 3-result)


The first 3 cases correpsond to the list boundary value []. This
includes testing for boundary values and non-boundary value of p.
The next 4 of cases corresponds to the random boundary value
[35]. This includes two tests for boundary values of p, and one
case with a non-boundary p-value and a 0 result, and another non-
boundary p value with a 1 result.
The next 6 cases corresponds to the non-boundary case for list.
Both boundary cases for p are considered. For non-boundary cases
for p we consider three possible return values: 0, 1, 2 and 3.

Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 10 of 16
Question 3 (b) [6 marks]
Provide a set of white-box test cases for the method. Again each test case should
include the input values, the expected return value or exception thrown, and a brief
justification for the test case. It is OK to include test cases that are also listed in the
answer to Question 3(a).

Solution:

Input Expected rationale
[], 50 0 (0 times through the loop)
[35], 50 1 (1 time through the loop, if true)
[35], 20 0 (1 time through the loop, if false)
[35, 45],50 2 (2 times loop, if true, if true)
[35, 45],40 1 (2 times loop, if true, if false)
[45, 35],40 1 (2 times loop, if false, if true)
[35, 45],20 1 (2 times loop, if false, if false)



Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 11 of 16
Question 4 [12 marks]
Consider the following specification of a method. (Expression \old is used to refer to the
value of a variable before the method occurs; \result refers to the return value of the
method.)

/**
* Without modifying list, returns an array \result of
* integers of the same size as list such that for each
* index i of \result, \result.get(i) is the product of the
* first i+1 elements of list.
*
* @require list != null
* @ensure list == \old(list) &&
* \result.size() == list.size() &&
* for each index i satisfying 0 <= i < \result.size(),
* \result.get(i) is the product of
* the first i+1 elements of list
*/



Question 4 (a) [6 marks]
State the loop invariant of the following implementation of the above specification and
use it to argue that the method is partially correct. Provide a further argument that the
method is totally correct.
public static ArrayList<Integer> multiply(
ArrayList<Integer> list) {
ArrayList<Integer> products = new ArrayList<Integer>();
for (int i = 0; i < list.size(); i++) {
int product;
if (i == 0) {
product = list.get(i);
} else {
product = products.get(i - 1) * list.get(i);
}
products.add(product);
}
return products;
}

Solution:

Invariant:

list == \old(list) &&
products.size() == i &&
for each index j satisfying 0 <= j < i
products.get(j) is the product of the first j+1 elements of
list

Partial correctness:
Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 12 of 16

If the loop terminates then the loop invariant holds and the exit
condition for the loop, i == list.size(), holds.

From this we have that:

list == \old(list) &&
products.size() == list.size() &&
for each index j satisfying 0 <= j < products.size()
products.get(j) is the product of the first j+1 elements of
list

and so the method specification is satisfied.

Total correctness:

The loop is partially correct (above) and it terminates.
Termination is guaranteed because i starts at 0 and increments,
hence it will eventually be equal to list.size() and terminate


Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 13 of 16
Question 4 (b) [6 marks]
Provide a recursive implementation of the specification. You may use one or more
additional (auxiliary) methods to do this. Comments, including specification of methods,
are not required. Your solution should avoid unnecessary re-calculation where possible.
Solution:
Possible solution (1):

public static ArrayList<Integer> multiply(
ArrayList<Integer> list) {
return multiply (list, list.size() - 1);
}

public static ArrayList<Integer> multiply(
ArrayList<Integer> list, int i) {
ArrayList<Integer> products;
if (i < 0) {
products = new ArrayList<Integer>();
return products;
}
products = multiply(list, i-1);
int product;
if( i == 0) {
product = list.get(i);
}
else {
product = products.get(i - 1) * list.get(i);
}
products.add(product);
return products;
}

or possible solution(2):

public static ArrayList<Integer> multiply(ArrayList<Integer>
list) {
return multiply(list, 0);
}

public static ArrayList<Integer> multiply(ArrayList<Integer>
list, int i) {
ArrayList<Integer> products;
if (i == list.size()) {
products = new ArrayList<Integer>();
return products;
}
products = multiply(list, i+1);
int product;
if (i == list.size() - 1){
product = 1;
for(int j = 0; j < list.size(); j++) {
product = product * list.get(j);
}
Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 14 of 16
} else {
product = products.get(0) / list.get(i);
}
products.add(0, product);
return products;
}

or nave possible solution (3):

public static ArrayList<Integer> multiply(ArrayList<Integer>
list) {
return multiply (list, 0);
}

public static ArrayList<Integer> multiply(ArrayList<Integer>
list, int i) {
ArrayList<Integer> products;
if (i == list.size()) {
products = new ArrayList<Integer>();
return products;
} else {
products = multiply(list, i+1);
int product = 1;
for(int j = 0; j <= i; j++) {
product = product * list.get(j);
}
products.add(0, product);
return products;
}
}



Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 15 of 16
Question 5 [12 marks]
Assuming the existence of a class Task with specification,
public class Task {
/** @ensure returns true if the task depends on t,
* and false otherwise
*/
public boolean dependsOn(Task t) { }
}

consider the following class specifications. (In the ensures clause, expression \old is
used to refer to the value of a variable before the method occurs.)

public class Scheduler {
/**@require tasks != null &&
* no Task can occur more than once in tasks
* @ensure tasks is a permutation of \old{tasks}
*/
public void schedule(ArrayList<Task> tasks) {}
}

public class IndependentScheduler extends Scheduler{
/**@require tasks != null &&
* no Task can occur more than once in tasks &&
* for all t1, t2 in tasks,
* ! t2.dependsOn(t1) && ! t1.dependsOn(t2)
* @ensure tasks is a permutation of \old{tasks}
*/
public void schedule(ArrayList<Task> tasks) {}
}

public class OrderedScheduler extends IndependentScheduler{
/** @require tasks != null &&
* no Task can occur more than once in tasks &&
* there exists a permutation "schedule" of tasks
* such that for all t1, t2 in tasks
* if t2.dependsOn(t1) then
* schedule.indexOf(t1) < schedule.indexOf(t2)
* @ensure tasks is a permutation of \old{tasks} such that
* for all t1, t2 in tasks,
* if t2.dependsOn(t1) then
* tasks.indexOf(t1) < tasks.indexOf(t2)
*/
public void schedule(ArrayList<Task> tasks) {}
}

For each of the next 2 questions, indicate whether the code fragment would compile
successfully. If it does not compile, explain the reason. If it does compile, indicate
whether the code would run successfully or if not, indicate what Exception would be
thrown.
Semester One Final Examinations, 2012 CSSE2002 Programming in the Large
Page 16 of 16
Question 5 (a) [2 marks]
IndependentScheduler a = new OrderedScheduler();
OrderedScheduler b = new OrderedScheduler();
b = a ;

Solution: does not compile, cannot assign a to b because of a
type mismatch


Question 5 (b) [2 marks]
IndependentScheduler a = new IndependentScheduler();
if (a instanceof Scheduler) {
OrderedScheduler b = (OrderedScheduler) a;
}

Solution: compiles fine, ClassCastException cannnot convert a to
b (IndependentScheduler cannot be cast to OrderedScheduler)



Question 5 (c) [4 marks]
Does IndependentScheduler satisfy the substitution principle with respect to
Scheduler? Explain why or why not.
Solution:
No, the precondition of schedule is strengthened in
IndependentScheduler. The postcondition is unchanged.

Question 5 (d) [4 marks]
Does OrderedScheduler satisfy the substitution principle with respect to
IndependentScheduler? Explain why or why not.
Solution:
Yes, the precondition of schedule is weakened in
OrderedScheduler. Effectively (taking preconditions into
consideration) the postcondition is unchanged


END OF EXAMINATION

You might also like