We are looking over your submissions for exercise sheet A. On the whole they were good. Luckily, you get the chance to make them even better.
We are writing some comments onto them now and will hand them back to you in the next couple of weeks. I will then notify you by email of the date for resubmission of your improved versions.
Some problems cropped up time and time again. I summarise a few of them here:
s, s1, s2, str2
, etc., where, e.g.,
host
or hostName
would have been better.
host
, not Host
.
new String(...)
).
for
-loops were often very messy. They
showed that you were using trial-and-error to work out whether the
counter should start/end at
0, 1, str.length()
or str.length() - 1
and whether the test should use < or <= or =. Use
reasoning, not trial-and-error!In particular, those of you who are using this:
for (int i = 0; i <= str.length() - 1; i++)
should abandon it in favour of the following
for (int i = 0; i < str.length(); i++)
which is (a) equivalent in terms of how many times we go round the loop, (b) easier on the eye, and (c) more efficient.
public static boolean checkProtocol(String theProtocol) { if (theProtocol.equals("http://")) { return true; } else { return false; } }
But the following is equivalent and much more concise:
public static boolean checkProtocol(String theProtocol) { return theProtocol.equals("http://"); }
Your work for this exercise sheet will be automatically collected in (if you put it in the right place) at 5 p.m. on Friday 8th November.
Create a subdirectory of your cs2000
directory.
Call this new directory
sheetB
. Place your answers to this exercise in your
cs2000/sheetB
directory.
This exercise gives you practice in writing
a fairly straightforward class definition (`blueprint').
In particular, you will be writing a class definition called ATM
,
which represents simplified ATMs (automated teller machines, i.e.
hole-in-the-wall cash dispensers) for an international bank.
Machines in different countries will be loaded with banknotes
of different denominations depending on the currency of the country.
Read the whole exercise before writing any code.
Create a file ATM.java
in which you will
write a class definition (`blueprint')
for ATMs. (Do this by copying and editing the template
mentioned in the lecture.)
Here's some client code, which will become clearer as you read the rest of the exercise:
int[] euroDenoms = {5, 10, 20, 50}; // denominations ATM atm = new ATM("euro", euroDenoms); // create the ATM atm.load(5, 1); // load it with 1 x 5 euro notes atm.load(20, 3); // load it with 3 x 20 euro notes atm.load(50, 2); // load it with 2 x 50 euro notes System.out.println(atm.getQty(20)); // print how many 20 euro notes atm.display(); // display the contents atm.dispense(50, 1); // dispense 1 x 50 euro note to a customer System.out.println(atm.getTotal() + " " + atm.getCurrency()); // print total
Each ATM must know
String
,
e.g. "euro", "dollar", "peso".int
s. For example,
if this currency's banknotes come in denominations of 5, 10, 20 and 50,
then these are the values that will be stored in the array.
Throughout this exercise, you may assume that the values in this array
are sorted in ascending order.int
s, of the same length
as the previous array. If this array contains {1, 0, 3, 2} and the
denominations array contains {5, 10, 20, 50} and the currency variable
contains "euro", then this shows that
this machine contains 1 note worth 5 euro, 0 notes
worth 10 euro, 3 notes worth 20 euro and 2 notes worth 50 euro.(So, define three instance variables!)
The interface of your ATM
class should
consist of the following:
public ATM(String theCurrency, int[] theDenominations)
When client code invokes the constructor, the client code supplies the currency and the banknote denominations. Use these to initialise the first two instance variables. The third instance variable should contains all zeros at this stage because the machine is presently empty.
public String getCurrency()
which returns the name of the currency that this machine contains.
public int getTotal()
which returns the total amount of money in the machine at the moment.
public void display()
which displays on the standard output (i.e. on the screen, using
System.out
) how many of each banknote the machine
contains, e.g.:
euro5 x 1 euro10 x 0 euro20 x 3 euro50 x 2
public int getQty(int theDenomination)
which returns how many notes of the specified denomination the machine contains. For example, if the parameter is 20, we're asking how many 20 euro notes the machine contains; in our running example, the return value is 3.
If the parameter is an illegal denomination, then the return value is zero.
public void load(int theDenomination, int theQty)
This method allows someone to load the machine with money. The parameters specify the banknote denomination and the number of banknotes. This method updates the third instance variable. For example if the parameters are 20 and 3, then the contents of the cell of the array that represents 20 euro notes are increased by 3.
You may assume that the second parameter is a positive integer. But, if the first parameter is illegal, then no update should occur.
public void dispense(int theDenomination, int theQty)
This method allows someone to take money out of the machine. Somewhat unrealistically (but in the interests of making your exercise easier!), they must specify the banknote denomination and how many banknotes of that denomination they wish to withdraw. This updates the third instance variable. For example, if the parameters are 50 and 1, then the contents of the cell of the array that represents 50 euro notes is reduced by 1.
You may assume that the second parameter is a positive integer. But, if the first parameter is illegal, then no update should occur.
(A more realistic version of dispense
is the subject of
the Challenge Exercise.)
If you haven't already done so, you need to test your ATM
class definition. I've written some
extensive client code to help you do this.
Get your copy here: CashFlow.java.
First make sure that you can compile CashFlow.java
and ATM.java
. (Compiling the former will automatically
compile the latter because the latter is client code of the former.)
If there are compile-time errors, fix ATM.java
.
(All such errors are caused by your file; do not change
CashFlow.java
.)
Then, when there are no more compile-time errors,
try to execute CashFlow
. If your program is perfect,
the
following will be displayed on the screen:
a b c d e f g h i j k l m n o p q r s t u v w x y z atm1.display() ============== euro5 x 1 euro10 x 1 euro20 x 0 euro50 x 1 atm2.display() ============== peso500 x 0 peso1000 x 5 peso2000 x 10 peso5000 x 0 peso10000 x 0
Check your output carefully against the above. If there are differences, then you have a bug.
Why does it print the alphabet? CashFlow.java
carries
out a sequence of tests on your program. After each test it prints
a letter of the alphabet. This is so you can see how far through the
tests your program gets. If it prints a-z, then it got through
all the tests. But if it stops printing before it gets to z,
then there is a problem, e.g.:
a b c d e f There's an error in your ATM definition.
or
a b c Exception in thread "main" java.lang.NullPointerException at ATM.getTotal(ATM.java:48) at CashFlow.main(CashFlow.java:20)
Look at the last letter it prints. Find the line in
CashFlow.java
that prints that letter.
The problem
arose when trying to execute whatever statement comes after that line.
Check all your files. Are they in the right directory?
Are they correctly named?
Does your name appear in an @author
comment
at the start of each file? Did you lay them out using the template?
Are your instance variables private
?
Are your variable names meaningful?
Are curly braces aligned? Etc. etc.
Elegance, conciseness, clarity, consistency of layout, good commenting, and meaningful variable names are all as important in the marking criteria as whether the program works or not.
Sheet A's Challenge Exercise was reasonably demanding, so here's a short and much much easier challenge for Sheet B. Remember, challenge exercises are optional. They never count toward your final mark.
Create a subdirectory of your
sheetB
directory, calling this new directory
challenge
. Put a copy of your ATM.java
class into this new directory.
The task is to add a second but
more realistic version of dispense
to
ATM.java
, as follows:
public int[] dispense(int theAmount)
This method is used to dispense a specified amount of money from this ATM, if possible. It should use the minimum number of notes by making use of as many higher denomination notes as possible before using lower denomination notes.
If it can dispense the requested amount of money exactly, it updates the third instance variable and returns an array: each value in this array is the number of notes of the corresponding denomination that is being dispensed.
If the given amount cannot be exactly dispensed using the notes that are currently in this ATM, the contents of the ATM are not changed, and the array that is returned contains all zeros.
E.g. if the machine contains 2 x 5 euro note, 3 x 10 euro notes, 3 x 20 euro notes and 2 x 50 euro notes, then after executing the following
int[] cashInHand = atm.dispense(75);
the array cashInHand
would contain {1, 0, 1, 1}, which
shows that to dispense 75 euro with the fewest notes, it used
1 x 5, 0 x 10, 1 x 20 and 1 x 50. (The contents of the machine will be
decremented also.)
But after executing the following
int[] anotherWad = atm.dispense(76);
the array anotherWad
would contain {0, 0, 0, 0},
which shows that this amount cannot be dispensed with the available
notes. (The contents of the machine remain unchanged.)