Mittwoch, 23. Dezember 2009
Syntaxprüfung für Brainf***
<
>
+
-
.
,
[
]
[
und ]
. Jede öffnende [
muss eine passende schließende ]
haben.[ [ ] [ [ ] [ ] ] ]
ist richtig geklammert, [ [ [ ] ] [ ]
jedoch nicht.BFCheck
und die Klasse für den Stack Stack
.System.in
bzw. stdin
) prüfen.klasse-familienname-bfcheck
(z.B. 2ad-haberstroh-bfcheck
).Donnerstag, 17. Dezember 2009
Ergebnisse Fragen Java
Bereich | Note | FALSCH |
Declarations, Initialization, Scoping | 1 | 3/11 |
Flow Control | 2 | 1/18, 2/17, 3/18, 1/21, 2/21, 3/23 |
API Contents | 3 | 1/26, 1/30, 2/28, 2/29, 3/20, 3/30 |
Concurrency | 3 | 1/34, 1/35, 2/34, 2/37, 2/40, 3/39 |
OOP | 2 | 1/41, 1/42, 2/41, 2/42, 3/41, 1/48, 1/50 |
Collections, Generics | 3 | 1/51, 2/52, 2/54, 3/52, 1/55, 2/54, 1/59, 3/57 |
Language Fundamentals | 4/5 | 1/62, 2/62, 3/62, 1/65, 2/64, 3/63, 1/66, 1/67, 2/65, 2/66, 3/65, 3/66, 1/69, 2/67, (3/67, 3/68, 1/70, 2/69, 2/70, 3/69, 3/70) |
Bei "Language Fundamentals" haben alle bis auf einen ein Genügend, der eine hat ein Nicht genügend.
Labels: PR5
Aufrufstack Lösung
Setzt man das Programm fort (
return
in Zeile 28) und kommt zurück zur Zeile 26, dann ergibt sich das folgende Bild. ret
ergibt sich aus dem vom letzten Aufruf zurückgegebenen Wert 1
mal dem n
(=2):Setzt man das Programm weiter fort (wieder
return
in Zeile 28) und kommt zurück zur Zeile 26, dann ergibt sich das folgende Bild. ret
ergibt sich aus dem vom letzten Aufruf zurückgegebenen Wert 2
mal dem n
(=3):Setzt man weiter fort, so ergibt sich...
und...
Zum Schluss erreicht man wieder die Zeile 39 in
main
und der Wert für f
wird gesetzt:Man sieht in dem Feld "Zeile" immer die Zeilennummer, zu der beim
return
zurückgekehrt wird.Labels: allgemeines, Java, Lösung, PR2
Mittwoch, 16. Dezember 2009
Aufrufstack - Fibonacci
Betrachten Sie folgendes Beispiel:
1:/** 2: * java-stoff: speicher.Fib.java 3: * 4: * 16.12.2009, Harald R. Haberstroh 5: */ 6:package speicher; 7: 8:import java.util.Scanner; 9: 10:/** 11: * Fibonacci-Zahlen zur demo des Aufrufstacks. 12: * 13: * @author Harald R. Haberstroh (hp) 14: * 15: */ 16:public class Fib { 17: 18: public static int fib(int n) { 19: int ret = 1; 20: if (n < 0) { 21: throw new IllegalArgumentException("n muss größer oder gleich Null sein"); 22: } 23: if (n > 1) { 24: ret = fib(n-1) + fib(n-2); 25: } 26: return ret; 27: } 28: /** 29: * @param args 30: */ 31: public static void main(String[] args) { 32: Scanner in = new Scanner(System.in); 33: int n = 0; 34: int f = 0; 35: while (in.hasNextInt()) { 36: n = in.nextInt(); 37: f = fib(n); 38: System.out.printf("fib(%d) = %d\n", n, f); 39: } 40: } 41:}
Uns interessiert die Funktionsweise der Aufrufs der rekursiven Funktion fib(). Arbeiten Sie das Programm am Papier ab. Beginnen Sie mit Zeile 37 und dem Wert n = 5. Skizzieren Sie den Aufrufstack, wenn Sie in Zeile 26 angelangt sind.
Bedenken Sie, dass bei den meisten Aufrufen von fib()
zwei rekursive Aufrufe stattfinden, die ihrerseits wieder zwei rekursive Aufrufe tätigen usw. Das Bild zeigt die Aufrufe für n = 5
:
Labels: allgemeines, Aufgabe, Java, PR2
Aufrufstack
Betrachten Sie folgendes Beispiel:
1:/**
2: * java-stoff: speicher.Fact.java
3: *
4: * 16.12.2009, Harald R. Haberstroh
5: */
6:package speicher;
7:
8:import java.util.Scanner;
9:
10:/**
11: * Faktorielle rekursiv als Demo für den Aufruf-Stack.
12: *
13: * @author Harald R. Haberstroh (hp)
14: *
15: */
16:public class Fact {
17:
18: public static int fac(int n) {
19: int ret = 0;
20: if (n < 0) {
21: throw new IllegalArgumentException("n muss größer oder gleich Null sein");
22: }
23: if (n <= 1) {
24: ret = 1;
25: } else {
26: ret = n * fac(n - 1);
27: }
28: return ret;
29: }
30: /**
31: * @param args
32: */
33: public static void main(String[] args) {
34: Scanner in = new Scanner(System.in);
35: int n = 0;
36: int f = 0;
37: while (in.hasNextInt()) {
38: n = in.nextInt();
39: f = fac(n);
40: System.out.printf("%d! = %d\n", n, f);
41: }
42: }
43:}
Uns interessiert die Funktionsweise der Aufrufs der rekursiven Funktion fac()
. Arbeiten Sie das Programm am Papier ab. Beginnen Sie mit Zeile 39 und dem Wert n = 5
. Skizzieren Sie den Aufrufstack, wenn Sie in Zeile 24 angelangt sind.
Labels: allgemeines, Aufgabe, Java, PR2
Donnerstag, 10. Dezember 2009
ASmu - Arrays, Klassen in Java
Die Lösung könnte etwa so aussehen:
/**
* java-array-smu: .ASmu.java
*
* 10.12.2009, Harald R. Haberstroh
*/
/**
* SMÜ zu Arrays.
*
* Erzeuge ein Feld mit den Werten:
* 1
* 1 1
* 1 2 1
* 1 3 3 1
* 1 4 6 4 1
* 1 5 10 10 5 1
* Methoden:
* public void create(int anzahlZeilen, int anzahlSpalten)
* public int[][] getArray()
* public int[] summen()
* public boolean set(int zeile, int spalte, int wert)
* @author Harald R. Haberstroh (hp)
*
*/
public class ASmu {
private int[][] feld = {
{1},
{1,1},
{1,2,1},
{1,3,3,1},
{1,4,6,4,1},
{1,5,10,10,5,1}
};
public void create(int anzahlZeilen, int anzahlSpalten) {
feld = new int[anzahlZeilen][anzahlSpalten];
}
public int[][] getArray() {
return feld;
}
public int[] summen() {
int[] sum = new int[feld.length];
for (int i = 0; i < sum.length; i++) {
sum[i] = 0;
for (int j = 0; j < feld[i].length; j++) {
sum[i] += feld[i][j];
}
}
return sum;
}
public boolean set(int zeile, int spalte, int wert) {
if (zeile >= 0 && zeile < feld.length &&
spalte >= 0 && spalte < feld[zeile].length) {
feld[zeile][spalte] = wert;
return true;
} else {
return false;
}
}
}
Alternativ könnte man set()
auch so implementieren:
public boolean set(int zeile, int spalte, int wert) {
try {
feld[zeile][spalte] = wert;
return true;
} catch (IndexOutOfBoundsException e) {
return false;
}
}
Donnerstag, 3. Dezember 2009
Objektorientiertes Programmieren
Es folgt ein Beispiel:
Aufgabe: Finden Sie Klassen bzw. Objekte zu folgenden Begriffen: Leo, Tiger, Samurai, Elefant, Taigon, Benjamin Blümchen, Tier, Löwe
Lösung: Beim Programmieren muss man aus einer Aufgabenstellung immer wieder Objekte und Klassen identfizieren, die man zur Implementierung benötigt. Man kann z.B. alle Subjekte der Aufgabenstellung suchen und sich dazu fragen "ist das ein Objekt oder sind das viele Objekte?". In letzterem Fall hat man einen Kandidaten für eine Klasse. Sonst ist es ein Objekt. Nicht alle Objekte werden für das Programm benötigt.
Bei diesem Beispiel ist nur eine Liste von Tieren und Namen gegeben. Namen sind normalerweise Objekte, die verschiedenen Tiere sind natürlich Klassen.
Wir werden also die Klassen Tier, Tiger, Löwe und Elefant haben. Die anderen Begriffe sind konkrete Namen. Weiters können wir die "is-a" ("ist-ein") Beziehung Tiger is-a Tier, Löwe is-a Tier und Elefant is-a Tier ausmachen.
Damit ergibt sich folgendes Bild:
Kästchen mit unterstrichenen Namen stellen konkrete Objekte dar.
Die strichlierten Pfeile stellen die Instanzierung dar. Sie sind in Pfeilrichtung zu lesen: Leo ist-ein-konkreter Löwe (Leo is-instance-of Löwe) oder Samurai ist-ein-konkreter Tiger.
Die Pfeile mit Dreiecksspitzen und durchgehenden Linien stehen für die Vererbung (is-a, ist-ein), Beispielsweise Löwe ist-ein Tier (Löwe is-a Tier).
Die Klassen könnte man so implementieren (z.B. Scrapbook):
class Tier {
String name;
public String toString() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Löwe extends Tier {
}
class Elefant extends Tier {
}
class Tiger extends Tier {
}
Löwe leo = new Löwe();
leo.setName("Leo");
Elefant benjamin = new Elefant();
benjamin.setName("Benjamin Blümchen");
Tiger samurai = new Tiger();
samurai.setName("Samurai");
Tiger taigon = new Tiger();
taigon.setName("Taigon");
System.out.println(leo);
System.out.println(benjamin);
System.out.println(samurai);
System.out.println(taigon);
Die Ausgabe könnte so aussehen:
Leo
Benjamin Blümchen
Samurai
Taigon
In Python könnte man das Beispiel so implementieren:
class Tier:
def __init__(self):
self.name = ""
def setName(self, name):
self.name = name
def __str__(self): # toString() in Java
return self.name
class Loewe(Tier):
pass
class Elefant(Tier):
pass
class Tiger(Tier):
pass
leo = Loewe()
leo.setName("Leo")
benjamin = Elefant()
benjamin.setName("Benjamin Blümchen")
samurai = Tiger()
samurai.setName("Samurai")
taigon = Tiger()
taigon.setName("Taigon");
print leo
print benjamin
print samurai
print taigon
Labels: allgemeines, Links, PR2
Mittwoch, 2. Dezember 2009
Währungsumrechner
Schreiben Sie ein Programm, welches eine Währungsumrechnungstabelle ausgibt. Dazu sind eine Währung (z.B. USD), der Kurs (z.B. 1.4), eine Untergrenze (z.B. 0), eine obergrenze (z.B. 10) und eine Schrittweite (z.B. 0.5) einzugeben. Weiters muss noch angegeben werden, ob die Tabelle von EUR -> Währung oder Währung -> EUR ausgegeben werden soll.
Beispiel:
Währung> USD
Kurs> 1,4
Untergrenze> 1
Obergrenze> 10
Schrittweite> 0,5
USD -> EUR (1) oder EUR -> USD (2)> 1
USD EUR
1,00 0,71
1,50 1,07
2,00 1,43
2,50 1,79
3,00 2,14
3,50 2,50
4,00 2,86
4,50 3,21
5,00 3,57
5,50 3,93
6,00 4,29
6,50 4,64
7,00 5,00
7,50 5,36
8,00 5,71
8,50 6,07
9,00 6,43
9,50 6,79
10,00 7,14
Mit diesem Beispiel soll auch ObjektOrientiertes Programmieren (OOP) geübt werden. Daher verwenden Sie bitte folgende Klassen:
Die Klasse Euro
kennt den Umrechnungsfaktor und die Währung und kann Umrechnen (toEuro()
bzw. toForeign()
).
Die Klasse Tabelle
erzeugt mit Hilfe von Euro
die entsprechende Tabelle. In der main()
Methode von Tabelle
sollen dann die Eingaben gemacht werden, die Objekte erzeugt werden sowie die entsprechenden Aufufe der Methoden durchgeführt werden.
Etwa so:
// Eingaben bereits vorhanden...
Euro waehrung = new Euro(kurs, symbol);
Tabelle tabelle = new Tabelle(waehrung, untergrenze, obergrenze, schrittweite);
if (toEuro) {
tabelle.printEuro();
} else {
tabelle.printForeign();
}
Beachten Sie, dass sich diese Euro
-Klasse von jener in den letzten Beispielen unterscheidet.
Mögliche Lösung in Python
#!/usr/bin/python
# -"- coding: utf-8 -*-
# waehrungstabelle.py
def frange(start, stop=None, step=None):
if stop is None:
stop = float(start)
start = 0.0
if step is None:
step = 1.0
cur = float(start)
while cur < stop:
yield cur
cur += step
class Euro:
def __init__(self, faktor, symbol):
self.faktor = float(faktor)
self.symbol = symbol
def toEuro(self, betrag):
return betrag / self.faktor
def toForeign(self, betrag):
return betrag * self.faktor
class Tabelle:
def __init__(self, waehrung, start, end, schrittweite):
self.waehrung = waehrung
self.start = start
self.end = end
self.schrittweite = schrittweite
def printEuro(self):
print "%10s %10s" % (self.waehrung.symbol, "EUR")
for wert in frange(self.start, self.end, self.schrittweite):
print "%10.2f %10.2f" % (wert, self.waehrung.toEuro(wert))
def printForeign(self):
print "%10s %10s" % ("EUR", self.waehrung.symbol)
for wert in frange(self.start, self.end, self.schrittweite):
print "%10.2f %10.2f" % (wert, self.waehrung.toForeign(wert))
if __name__ == '__main__':
symbol = raw_input("Währung> ")
kurs = float(raw_input("Kurs> "))
waehrung = Euro(kurs, symbol)
start = float(raw_input("Untergrenze> "))
end = float(raw_input("Obergrenze> "))
step = float(raw_input("Schrittweite> "))
tabelle = Tabelle(waehrung, start, end, step)
if "1" == raw_input("%s -> EUR (1) oder EUR -> %s (2)> " % (symbol,symbol)):
tabelle.printEuro()
else:
tabelle.printForeign()
Übung Geld (Klasse, Methoden)
- Erweitern Sie die Währungen um die Kurse von XOF, AUD, CAD und ARS.
- Erweitern Sie die Klasse
Geld
um eine Methodesub(geld)
, welche analog zuadd(geld)
geld
vom aktuellen Geld subtrahiert. - Erweitern Sie die Klasse
Geld
um eine Methodeconvert(waehrung)
, welche dasGeld
in die angegebene Währungwaehrung
umwandelt. Geld
soll über eine MethodegetBetrag()
den Betrag in der entsprechenden Währung liefern.- Die Methode
getWaehrung()
soll die Währung zurückliefert (z.B. "USD"). - Zeichnen Sie das neue Klassendiagramm
Labels: Aufgabe, Java, PR2, Python
Dienstag, 1. Dezember 2009
Einführungsbeispiel Klassen/Objekte
Die Währungstabelle
wechselkurs
könnte natürlich auch wieder in eigenen Klassen/Objekten realisiert werden (im Java-Code ist das auch tatsächlich der Fall).Die Attribute (Eigenschaften) sind alle öffentlich (
public
), da damit das Beispiel kürzer wird. Tatsächlich werden normalerweise die Attribute nach außen unsichtbar gemacht (private
) und nur Methoden öffentlich gemacht, um den Zugriff auf das Innere der Objekte zu verhinden (Information Hiding oder Datenkapselung).Die Methode
getEuro()
liefert den auf Euro umgerechneten Geldbetrag.Die Methode
add(geld)
addiert den Wert des Parameters geld
zum Wert des aktuellen Objekts und erzeugt ein neues Objekt mit der Summe und liefert es als Returnwert zurück.Der Konstruktor wird in diesem Klassendiagramm nicht angegeben. Durch ihn wird aber die Währung der Betrag festgelegt. Der Konstruktor wird ausgeführt, wenn ein Objekt erzeugt wird.
Die Umsetzung in Python
Der Wechselkurs wird einfach in Form eines Dictionaries gespeichert.
Der Konstruktor heißt in Python immer
__init__(self)
.In Python muss bei Methoden immer
self
angegeben werden. Damit wird die Methode mit einem bestimmten Objekt (zu einer bestimmten Klasse zugehörig) verbunden. Man kann sich den Aufruf mietwagen.add(hotelrechnung)
so vorstellen: add(mietwagen, hotelrechnung)
. Die Objektreferenz mietwagen
wird also als Parameter an die Methode add(self)
übergeben. In der Methode add(self)
kann dann auf das Objekt über self
zugegriffen werden.# Python Klasse Geld
class Geld:
wechselkurs = { 'USD': 1.505, # US-$ (1EUR sind 1.505 USD)
'GBP': 0.908, # Britische Pfund
'EUR': 1.0,
'CHF': 1.509, # Schweizer Franken
'JPY': 130.582, # Japanische Yen
}
def __init__(self, waehrung, betrag):
self.waehrung = waehrung
self.betrag = float(betrag)
def getEuro(self):
"""liefert den Betrag in EUR"""
return self.betrag / self.wechselkurs[self.waehrung]
def add(self, geld):
"""addiert Geld und liefert summe als Geld"""
summeInEuro = self.getEuro() + geld.getEuro()
summe = Geld(self.waehrung, summeInEuro * self.wechselkurs[self.waehrung])
return summe
if __name__ == '__main__':
hotelrechnung = Geld('EUR', 560)
mietwagen = Geld('USD', 760)
summe = mietwagen.add(hotelrechnung) # summe = add(mietwagen, hotelrechnung)
print "Summe: %s%.2f, %s%.2f\n" % (summe.waehrung, summe.betrag, "EUR", summe.getEuro())
Die Umsetzung in Java
Anders als in Python heißt hier die Referenz auf das aktuelle Objekt
this
und nicht self
. this
wird nicht als Parameter deklariert. Den Methoden fehlt ein this
-Parameter (bzw. self
). Dieser Parameter existiert nur intern.Dennoch kann man
this
beim Zugriff auf Attribute (und Methoden) angeben. Im folgenden Beispiel wird das auch gemacht.Man muss
this
nur dann angeben, wenn es sonst zu Mehrdeutigkeiten käme (in unserem Beispiel beim Konstruktor, wo die Parameter genauso benannt sind wie die Attribute).Der Kunstruktor heißt in Java immer so wie die Klasse, in unserem Fall
Geld()
.Die Währungstabelle
wechselkurs
wird als Array einer eigenen Klasse Wechselkurs
realisiert. Zusätzlich benötigt man mangels Dictionary eine Methode, die zu einer gegebenen Währung den Kurs liefert: getKurs()
class Geld {
final class Wechselkurs { // final nur für's scrapbook
String waehrung;
double kurs;
public Wechselkurs(String waehrung, double kurs) {
this.waehrung = waehrung;
this.kurs = kurs;
}
}
private Wechselkurs[] wechselkurs = {
new Wechselkurs("USD", 1.505), // US-$ (1EUR sind 1.505 USD)
new Wechselkurs("GBP", 0.908), // Britische Pfund
new Wechselkurs("EUR", 1.0),
new Wechselkurs("CHF", 1.509), // Schweizer Franken
new Wechselkurs("JPY", 130.582),// Japanische Yen
};
String waehrung;
double betrag;
public Geld(String waehrung, double betrag) {
this.waehrung = waehrung;
this.betrag = betrag;
}
public double getEuro() {
return this.betrag / this.getKurs();
}
private double getKurs() {
for (Wechselkurs kurs : this.wechselkurs) {
if (kurs.waehrung.equals(this.waehrung)) {
return kurs.kurs;
}
}
return 0.0;
}
public Geld add(Geld geld) {
double summeInEuro = this.getEuro() + geld.getEuro();
Geld summe = new Geld(this.waehrung, summeInEuro * this.getKurs());
return summe;
}
}
/*** Testaufrufe ***/
Geld hotelrechnung = new Geld("EUR", 560);
Geld mietwagen = new Geld("USD", 760);
Geld summe = mietwagen.add(hotelrechnung);
System.out.printf("Summe: %s%.2f, %s%.2f\n", summe.waehrung, summe.betrag,
"EUR", summe.getEuro());
Testausgabe:
Summe: USD1602,80, EUR1064,98
Scrapbook oop.jpage zum Download (Python Code kann nicht im Scrapbook ausgeführt werden).
Abonnieren Posts [Atom]