Donnerstag, 30. April 2009

 

Musterlösung zu Unit-Tests

Folgende Grenzfälle werden getestet:
Sonderfälle:
"Normalfälle":
Weitere Annahmen, die aus der Angabe nicht unbedingt hervorgehen:
Die Artikel (Elemente/Items) werden in der Reihenfolge und der gegebenen Anzahl gespeichert, als addItems() aufgerufen wurde. Wird ein Element mit der Anzahl 5 in den Warenkorb aufgenommen, so wird das Element 5 mal gespeichert.

Testklasse:
import java.util.Iterator;
import junit.framework.TestCase;

/**
* unittests/.ShoppingCartTest.java
*
* @author (c) 2009, Harald R. Haberstroh 23.04.2009
*/
public class ShoppingCartTest extends TestCase {

private ShoppingCart cart;

private Item[] items = { new Item(1), new Item(2), new Item(3) };

/**
* @throws java.lang.Exception
*/
protected void setUp() throws Exception {
cart = new MyCart();
}

/**
* @throws java.lang.Exception
*/
protected void tearDown() throws Exception {
}

/*
* addItem mit Menge 0, itemCount() muss gleich bleiben.
*/
public void testAddItems0() {
try {
cart.addItems(items[0], 0);
assertEquals("testDeleteItems0: 0 Elemente", 0, cart.itemCount());
} catch (NegativeCountException e) {
fail("testAddItem0: es dürfte keine NegativeCountException geworfen werden");
}
}

/*
* eine negative Anzahl von Elementen aufnehmen -> NegativeCountException
*/
public void testAddItemNegativ() {
try {
cart.addItems(items[0], -23);
fail("testAddItemNegativ: es müsste eine NegativeCountException geworfen werden");
} catch (NegativeCountException e) {
}
}

/*
* deleteItem mit Menge 0, itemCount() muss gleich bleiben.
*/
public void testDeleteItems0() {
try {
cart.addItems(items[0], 1);
cart.deleteItems(items[0], 0);
assertEquals("testDeleteItems0: 1 Element", 1, cart.itemCount());
} catch (NegativeCountException e) {
fail("testDeleteItems0: es dürfte keine NegativeCountException geworfen werden");
} catch (NoSuchItemException e) {
fail("testDeleteItems0: es dürfte keine NoSuchItemException geworfen werden");
}
}

/*
* deleteItem nicht gültiges Item -> NoSuchItemException, itemCount() == 0
*/
public void testDeleteItemsNoSuchItem() {
try {
cart.addItems(items[0], 1);
cart.deleteItems(items[1], 1);
fail("testDeleteItemsNoSuchItem: es müsste NoSuchItemException geworfen werden");
} catch (NegativeCountException e) {
fail("testDeleteItemsNoSuchItem: es dürfte keine NegativeCountException geworfen werden");
} catch (NoSuchItemException e) {
assertEquals("testDeleteItemsNoSuchItem: 1 Element", 1, cart.itemCount());
}
}

/*
* eine negative Anzahl von Elementen aufnehmen -> NegativeCountException
*/
public void testDeleteItemNegativ() {
try {
cart.addItems(items[0], -23);
fail("testAddItemNegativ: es müsste eine NegativeCountException geworfen werden");
} catch (NegativeCountException e) {
}
}

/*
* addItems für 10 Items, keine Exception, itemCount() == 10
*/
public void testAddItems10() {
try {
cart.addItems(items[0], 3);
cart.addItems(items[1], 3);
cart.addItems(items[2], 4);
assertEquals("testAddItems10: 10 Elemente", 10, cart.itemCount());
} catch (NegativeCountException e) {
fail("testAddItems10: es dürfte keine NegativeCountException geworfen werden");
}
}

/*
* addItems für 10 Items, deleteItems für 5 Items, keine Exception,
* itemCount() == 5
*/
public void testAddDeleteItems5() {
try {
cart.addItems(items[0], 3);
cart.addItems(items[1], 3);
cart.addItems(items[2], 4);
cart.deleteItems(items[0], 2);
cart.deleteItems(items[2], 2);
cart.deleteItems(items[1], 1);
assertEquals("testAddDeleteItems5: 5 Elemente", 5, cart.itemCount());
} catch (NegativeCountException e) {
fail("testAddDeleteItems5: es dürfte keine NegativeCountException geworfen werden");
} catch (NoSuchItemException e) {
fail("testAddDeleteItems5: es dürfte keine NoSuchItemException geworfen werden");
}
}

/*
* addItems für 10 Items, Iterator muss Zugriff auf die 10 Elemente gestatten
*/
public void testIterator() {
try {
cart.addItems(items[0], 3);
cart.addItems(items[1], 3);
cart.addItems(items[2], 4);
Iterator<Item> iterator = cart.iterator();
int cntItems = 0;
Item[] stroredItems = new Item[10];
while (iterator.hasNext()) {
stroredItems[cntItems] = iterator.next();
cntItems++;
}
assertEquals("testIterator: 10 Elemente", 10, cntItems);
for (int i = 0; i < 3; i++) {
assertEquals("testIterator: Element sollte gleich sein", items[0],
stroredItems[i]);
System.out.println(stroredItems[i]);
}
for (int i = 3; i < 6; i++) {
assertEquals("testIterator: Element sollte gleich sein", items[1],
stroredItems[i]);
System.out.println(stroredItems[i]);
}
for (int i = 6; i < 10; i++) {
assertEquals("testIterator: Element sollte gleich sein", items[2],
stroredItems[i]);
System.out.println(stroredItems[i]);
}
} catch (NegativeCountException e) {
fail("testIterator: es dürfte keine NegativeCountException geworfen werden");
}
}
}

Implementierung des Interfaces ShoppingCart:
import java.util.ArrayList;
import java.util.Iterator;

/**
* unittests/.MyCart.java
* @author (c) 2009, Harald R. Haberstroh
* 23.04.2009
*/
public class MyCart implements ShoppingCart {

private ArrayList<Item> items = new ArrayList<Item>();

/*
* (non-Javadoc)
*
* @see ShoppingCart#addItems(Item, int)
*/
public void addItems(Item anItem, int quantity) throws NegativeCountException {
if (quantity < i =" 0;" i =" 0;"> iterator() {
return items.iterator();
}

}

Zusätzlich müssen natürlich die geforderten Exceptions implementiert werden (Kommentare wurden hier weggelassen):
public class NegativeCountException extends Exception {

}

public class NoSuchItemException extends Exception {

}

Die Klasse für die Artikel (Item) wurde einfach durch eine Nummer ergänzt, die beim Konstruktor angegeben werden muss. Für eine realistische Anwendung müsste diese Klasse noch erweitert werden:
/**
* unittests/.Item.java
* @author (c) 2009, Harald R. Haberstroh
* 23.04.2009
*/

/**
* @author Harald R. Haberstroh (user)
*
*/
public class Item {
private int itemNr = 0;

/**
* @param itemNr
*/
public Item(int itemNr) {
this.itemNr = itemNr;
}

/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Item " + itemNr;
}

}

Labels: , ,


 

cvs up & running

cvs.htlwrn.ac.at wurde wiederhergestellt. Stand der Daten: Montag 27.4.

Labels: , , ,


Mittwoch, 29. April 2009

 

cvs zerstört

Der cvs-Server cvs.htlwrn.ac.at wurde leider zerstört. Wahrscheinlich sind einige Daten verlorengegangen. Möglichweise sogar alle!

Ausständige Abgaben bitte per Mail als ZIP oder JAR.

Ihr Workspace ist wahrscheinlich die einzige Sicherung.

Labels: , , ,


Mittwoch, 22. April 2009

 

Beispiel zu Unit-Tests

In einem Online-Shop wird unter anderem ein Warenkorb benötigt. Schreiben Sie Unit-Tests zu folgendem Interface (welches Sie natürlich auch implementieren müssen):

import java.util.Iterator;

/**
* @author (c) 2009, Harald R. Haberstroh 23.04.2009
*/
public interface ShoppingCart {

/**
* legt die übergebene Anzahl von Elementen in den Warenkorb
*
* @param anItem
* Element
* @param quantity
* Anzahl
* @throws NegativeCountException
* negative Anzahl gibt's nicht
*/
public void addItems(Item anItem, int quantity) throws NegativeCountException;

/**
* entfernt die Anzahl von Elementen vom Warenkorb.
*
* @param anItem
* welches Element
* @param quantity
* Anzahl
* @throws NegativeCountException
* negative Anzahl gibt's nicht
* @throws NoSuchItemException
* das Element existiert nicht im Warenkorb
*/
public void deleteItems(Item anItem, int quantity)
throws NegativeCountException, NoSuchItemException;

/**
* wieviele Element gibt's überhaupt
*
* @return Anzahl Elemente
*/
public int itemCount();

/**
* Iterator für alle Elemente (siehe Collection-API).
*
* @return Iterator über alle Elemente
*/
public Iterator<Item> iterator();
}
Denken Sie bei der Erstellung der Tests an Grenzfälle, Sonderfälle und erst dann an den "Normalfall".

Nennen Sie das Projekt klasse-unittests-name (z.B. 3ad-unittests-haberstroh) und checken Sie es am CVS ein (Achtung 3BD: packen Sie das Projekt in ein jar 3bd-unittests-name.jar und schicken Sie es per Mail an mich).

Abgabetermin 29.04.2009

Labels: , ,


Mittwoch, 15. April 2009

 

Verkettete Listen mit Java - Verschiedenes

Diese Aufgabe enthält mehrere Übungsbeispiele zu Listen. Es sollen verschiedenste Aufgabenstellungen mit verketteten Listen gelöst werden, um das Verständnis mit Beispielen zu vertiefen.

Welche Daten in den Listen gespeichert werden ist meist nicht so wichtig. Verwenden Sie Strings oder ganze Zahlen, wenn nichts anderes angegeben wird.

Erstellen Sie jeweils eine Klasse public class Liste, wie in Verkettete Listen beschrieben mit den in der jeweiligen Aufgabenstellung gefprderten Methoden. Für die Datenelemente erzeugen Sie eine Klasse public class Data, welche einen ganzzahligen Wert (int key) und einen String (String value) aufnehmen kann.

1. Am Ende einer (einfach verketteten) Liste einfügen und löschen.

Schreiben Sie die Funktionen

void append(Data data);   /* anhängen */
void delEnd(); /* entfernen des letzten Elements */

Skizzieren Sie mehrere Listenbeispiele und entwickeln sie passende Testfälle (leere Liste, ein Element, 2 Elemente, 3 oder mehr Elemente).

2. Sortiertes Einfügen in eine doppelt verkettete Liste

Schreiben Sie eine Funktion

void insert_sort(Data data);

welche ein Element sortiert nach key in die doppelt verkettete Liste einfügt (Vorwärts- und Rückwärtsverkettung).

3. Löschen eines bestimmten Elements

Schreiben Sie eine Funktion

boolean del(Data data);

welche ein Element mit dem gesuchten Inhalt löscht (meist wird nur ein key verwendet, hier können Sie aber einfach die Daten verwenden). del() soll true liefern, wenn das Element gefunden und gelöscht wurde.

4. Ändern eines Elements in einer einfach verketteten Liste

Schreiben Sie eine Funktion

void change(Data old, Data newdata);

welche ein Element old aus der Liste nimmt, es durch die Werte von newdata ersetzt und dieses Element dann wieder an geeigneter Stelle einfügt, sodass die Liste nach diesem Aufruf wieder sortiert ist (normalerweise betrifft das Enfernen und Wiedereinfügen nur den key).

Erstellen Sie für alle Funktionen passende Testfälle und fertigen Sie ggf. Skizzen an.

Labels: , ,


 

Queue mit Verketteter Liste in Java

Ändern Sie das Beispiel Simulation einer Warteschlange an der Kasse derart, dass statt des Ringbuffers (der ja eine Implementierung einer Queue ist) eine Verkettete Liste verwendet wird. Damit ist es (zumindest theoretisch) möglich, die Warteschlange beliebig lange werden zu lassen.

Labels: , ,


 

Stack mit Verketteter Liste

Ändern Sie das Beispiel Einfacher Rechner mittels Stack - UPN-Rechner derart, dass der Stack beliebig groß werden kann. Implementieren Sie den Stack mit einer Verketteten Liste.

Labels: , ,


 

Verkettete Listen mit Java

Erstellen Sie ein Java-Programm, welches Namen von der Standardeingabe liest und sortiert in eine einfach verkettete Liste einträgt. Bei EOF wird dann die Liste auf der Standardausgabe ausgegeben.

Machen Sie zwei Varianten:

  1. Iteratives sortiertes Einfügen und iteratves Ausgeben
  2. Rekursives sortieres Einfügen und rekursives Ausgeben

Labels: , ,


Freitag, 3. April 2009

 

Addieren von Binärzahlen mittels Automat

Schreiben Sie ein Programm, welches zwei Binärzahlen mit Hilfe eines Automaten addiert. Das Programm soll korrekt addieren, wenn die Eingabe in richtiger Weise aufbereitet ist, d.h. es kommen jeweils eine Ziffer der ersten Zahl und eine Ziffer der zweiten Zahl. Die Ziffern kommen richtig von rechts nach links. Ist eine Zahl kürzer, so wird sie mit Nullen aufgefüllt.

Sind die Zahlen z.B. 101101 und 1001, so muss die Eingabe 110010110010 sein.

101101
001001
Von rechts nach links bzw. von oben nach unten gelesen ergibt das die richtige Eingabe von 110010110010.

Der Automat erkennt und addiert dann jeweils zwei Ziffern, also

1 + 1     = 0 Ü 1
0 + 0 + 1 = 1 Ü 0
1 + 0 + 0 = 1 Ü 0
1 + 1 + 0 = 0 Ü 1
0 + 0 + 1 = 1 Ü 0
1 + 0 + 0 = 1 Ü 0
Die Ausgabe ist daher 011011. Umgedreht ergibt dies das Ergebnis von 110110.
Probe
101101
001001
------
110110
U U

Nennen Sie das Programm (die Klasse) Addierwerk.java und schreiben Sie zwei weitere Programme (Klassen) Input.java und Output.java, welche die Ein- und Ausgabe aufbereiten.

Input.java nimmt zwei (Kommandozeilen-)Argumente und gibt von rechts nach links gelesen jeweils ein Zeichen des ersten und ein Zeichen des zweiten Arguments aus. Ist ein Argument kürzer als das andere, so sind Nullen an dieser Stelle auszugeben.
Zum Beispiel:

java Input 1234 12
42312010
oder (richtige Zahlen)
java Input 101101 1001
110010110010
Input.java kümmert sich nicht um richtige Eingaben.

Output.java liest von stdin und gibt die Zeichen in umgekehrter Reihenfolge wieder aus.
Zum Beispiel:

java Output
1234
4321

Alle drei Programme kombiniert, ermöglichen es Binärzahlen zu addieren.
Zum Beispiel:

java Input 101101 1001 | java Addierwerk | java Output
110110

Bild Addierwerk 2 Ziffern + Übertrag
Automat, der 2 Ziffern addiert und bei Übertrag weitere 2 Ziffern berücksichtigt (Ende der Eingabe mit '\n').

Labels: , ,


This page is powered by Blogger. Isn't yours?

Abonnieren Posts [Atom]