Donnerstag, 28. Januar 2010
Entwicklung von iPhone Apps unter Linux - VMware Image
root
und Passwort toolchain
anmelden.cd /PROJECTS/HelloWorldmachen um ein fertiges "Hello, World"-Projekt zu übersetzen und zum iPhone zu übertragen. Vorher muss man aber im Makefile noch die IP-Adresse des iPhones eintragen. Außerdem benötigt mein ein "jailbreaked" iPhone (also ein entsperrtes Gerät).
make clean
make
Labels: iPhone, Linux, Objective C, PR5
Entwicklung von Android Apps unter Linux - Hello World
und lädt sich die Packages für den/die Emulatoren/Handys herunter:
Für "Hello World" muss man noch ein Textfeld (
TextView tv
) anlegen:package at.haberstroh.android.hello;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Hello, Android");
setContentView(tv);
}
}
Zum Starten muss man noch eine eigene "Run Configuration" anlegen:
Labels: android, eclipse, Java, Linux, PR5
Entwicklung von iPhone Apps unter Linux
Ich habe Inoffizielles iPhone-SDK unter Linux einrichten versucht.
Leider bin ich zu Hause hängen geblieben, weil ich ein 64bit-Debian habe. Da funktioniert das Linken nicht. Ich werde es da auf einer 32bit-Debian-VM noch einmal probieren. Erfolgsmeldungen wird es hier geben.
In der Schule (Ubuntu 9.04) bin ich nach etlichen Versuchen auch hängen geblieben. Hier fehlen die "includes".
Es gibt aber ein - nicht aktuelles - VM-Image am edvoftp, das ich aber noch nicht testen konnte.
Hätt' ich doch nur einen Mac!
Labels: iPhone, Linux, Objective C, PR5
Entwicklung von Android Apps unter Linux
Labels: android, eclipse, Java, Linux, PR5
Mittwoch, 20. Januar 2010
Aufgabe Gruppenwechsel Ski
Schreiben Sie eine Java-Klasse Grw.java
, welches aus dem Datenbestand ski.csv die beigelegte Statistik erzeugt.
Lesen Sie die csv
-Datei zeilenweise und erstellen Sie aus jeder Zeile ein Objekt einer Klasse SkiDaten
, die alle notwendigen Attribute (Klasse, Name, Geb.Datum,....) enthält.
Nennen Sie das Projekt grwski
(also insgesamt z.B. 2ad-haberstroh-grwski
).
Sollte eine neue Sortierung des Sätze notwendig sein, bitte mit OpenOffice Calc oder Excel sortieren. 1-er Kandidaten sortieren bitte mit eigenem Sortprogramm.
INFO: es handelt sich um einen zweistufigen Gruppenwechsel mit den Gruppen
KLASSE und GESCHL
und einer Gesamtdarstellung des Durchschnitts!
Eine Einführung in den Gruppenwechsel finden Sie in der Datei gruppenwechsel.pdf
Aufruf des Programms:
java Grw [-h | -o ausgabedat] [-d] eingabedatei
Die Option -d
bewirkt die Ausgabe der Detailzeilen, ohne -d
nur Summenzeilen ausgeben!
Beispiel Statistik:
--------------------------------- --------------------------------
STATISTIK zum Schuelerrennen der HTL am SKIKURS 2006 in OBERTAUERN
------------------------------------------------------------------
AMINGER Georg 0.02
ELIAS Thomas 0.97
GALAVICS Marcus 0.15
GALLAUNER Alexander 0.26
HECHER Markus 0.58
HERMANN Gregor 0.65
KAMPER Raphael 0.55
KRIVOKUCA Milan 7.73
MOSER Christoph 2.34
NEPOLA René 0.14
PRIELER Stefan 0.63
RECHBERGER Christian 3.11
RIEGLER Mario 0.87
SCHNEEBERGER Joerg 1.22
SENN Bernhard 0.65
WIESSNER Maximilian 1.61
ZENZ Markus 2.04
die durchschnittliche Zeitdifferenz bei den MAENNERN betraegt: 1.38
die KLASSE 2AHDV erreichte eine Durchschnittsdifferenz von 1.38 Sekunden
CMUND Katharina 2.81
HARATHER Alice 1.87
KONLECHNER Viktoria 0.39
RIEGER Jennifer 0.63
RINNHOFER Elisabeth 1.65
...........................................................
...........................................................
REICHHART Thomas 0.30
RIEDER Dominik 1.07
SCHERMANN Georg 0.85
STANGL Stefan 1.48
STAUFER Andreas 0.47
die durchschnittliche Zeitdifferenz bei den MAENNERN betraegt: 2.38
die KLASSE 3CHDV erreichte eine Durchschnittsdifferenz von 2.36 Sekunden
************************************************GESAMT-Differenz : 1.93
Achtung: Die obige Ausgabe stellt nur einen Ausschnitt dar (Aufruf mit Option -d
) und es wurde die vorletzte Zeile (Hüpfner) gelöscht, da dort extrem abweichende Zeiten vorkommen (die Schülerin ist scheinbar gestürzt). Die Gesamt-Different würde mit dieser Zeile 11,37
Sekunden betragen.
Abgabetermin: Donnerstag, 28. Jänner 2010
Mittwoch, 13. Januar 2010
Ringbuffer Simulation
Aufrufen mit
java -jar ringbuffer.jar
Hier noch ein paar Worte zur Implementierung. Die Klasse
Queue
ist ganz herkömmlich implementiert. Bei einem Über- bzw. Unterlauf wird eine IndexOutOfBoundsException
geworfen. Die Felder der Klasse wurden ohne private
definiert, damit die Klasse GraphView
im selben Paket direkt darauf zugreifen kann (erspart Schreibarbeit...).package queuegraph;
/**
* Ringbuffer.
*
* @author Harald R. Haberstroh (hp)
*
*/
public class Ringbuffer {
String[] ring;
int usedSize = 0;
int size = 0;
int getIndex = 0;
int putIndex = 0;
final static int DEFAULTSIZE = 12;
public Ringbuffer(int size) {
this.size = size;
ring = new String[this.size];
}
public Ringbuffer() {
this(DEFAULTSIZE);
}
public void put(String c) throws IndexOutOfBoundsException {
usedSize++;
if (usedSize > size) {
throw new IndexOutOfBoundsException("Ringbufferüberlauf");
}
ring[putIndex] = c;
putIndex = (putIndex + 1) % size;
}
public String get() throws IndexOutOfBoundsException {
usedSize--;
if (usedSize < 0) {
throw new IndexOutOfBoundsException("Ringbuffer schon leer");
}
String ret = ring[getIndex];
getIndex = (getIndex + 1) % size;
return ret;
}
public int getSize() {
return size;
}
public boolean isEmpty() {
return usedSize == 0;
}
}
Die Klasse
GraphView
erweitert ein JPanel
und "zeichnet" das Array mit Inhalt. Zusätzlich werden die "Zeiger" getIndex
und putIndex
durch die Position dargestellt.Bei einem Über- bzw. Unterlauf wird der Fehler angezeigt und die Funktion "deaktiviert", indem
put()
und get()
immer prüfen, ob error == null
(also kein Fehler gesetzt ist).Das Fenster wird in
main()
aufgebaut.package queuegraph;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Rectangle2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
/**
* graphische Darstellung eines Ringbuffers.
*
* @author Harald R. Haberstroh (hp)
*
*/
public class GraphView extends JPanel {
private static final long serialVersionUID = -5311802173756493369L;
private Ringbuffer ringbuffer;
private String error;
/**
* Hier wird das Array mit Inhalt, die Indices und und die Ampel gezeichnet.
*
* @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
*/
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int maxx = 0; // für Panelgröße
int maxy = 0;
int x = 10;
int y = 10;
// das Array
for (int i = 0, j = ringbuffer.getIndex; i < ringbuffer.usedSize; i++) {
String s = ringbuffer.ring[j];
Rectangle2D box = g.getFontMetrics().getStringBounds(s, 0, s.length(), g);
int hpos = (int) (15.0 - box.getCenterX());
int vpos = (int) (15.0 - box.getCenterY());
g.drawString(s, j * 30 + hpos + 10, y + vpos);
j = (j + 1) % ringbuffer.getSize();
x = j * 30 + 10;
if (x > maxx)
maxx = x;
if (y > maxy)
maxy = y;
}
// die Indices
x = 10;
y = 10;
for (int i = 0; i < ringbuffer.getSize(); i++) {
g.drawRect(x, y, 30, 30);
if (i == ringbuffer.getIndex) {
pfeil(g, x + 15, y + 30, "getIndex");
}
if (i == ringbuffer.putIndex) {
pfeil(g, x + 15, y + 30, "putIndex");
}
x += 30;
if (x > maxx)
maxx = x;
if (y > maxy)
maxy = y;
}
// Panelgröße
maxx += 10;
maxy += 100;
setPreferredSize(new Dimension(maxx, maxy));
// die Ampel
if (!ringbuffer.isEmpty() && ringbuffer.getIndex == ringbuffer.putIndex) {
g.setColor(Color.RED);
g.fillOval(20, maxy - 5, 10, 10);
} else if (!ringbuffer.isEmpty()) {
g.setColor(Color.YELLOW);
g.fillOval(35, maxy - 5, 10, 10);
} else {
g.setColor(Color.GREEN);
g.fillOval(50, maxy - 5, 10, 10);
}
g.setColor(getForeground());
g.drawOval(20, maxy - 5, 10, 10);
g.drawOval(35, maxy - 5, 10, 10);
g.drawOval(50, maxy - 5, 10, 10);
g.drawString("Füllstand", 80, maxy - 5 + g.getFontMetrics().getAscent());
// Fehlermeldung
if (error != null) {
g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 35));
g.setColor(Color.YELLOW);
Rectangle2D box = g.getFontMetrics().getStringBounds(error, 0,
error.length(), g);
g.drawString(error, (int) (getWidth() / 2.0 - box.getCenterX()) + 2,
(int) (getHeight() / 2.0 - box.getCenterY()) - 2);
g.setColor(Color.RED);
g.drawString(error, (int) (getWidth() / 2.0 - box.getCenterX()),
(int) (getHeight() / 2.0 - box.getCenterY()));
}
}
private void pfeil(Graphics g, int x, int y, String bez) {
// FIXME: ist noch kein Pfeil, nur Linie
g.drawLine(x, y, x, y + 30);
Rectangle2D box = g.getFontMetrics().getStringBounds(bez, 0, bez.length(),
g);
int hpos = (int) (x - box.getCenterX());
int vpos = (int) (y + 30 + box.getHeight());
g.drawString(bez, hpos, vpos);
}
public GraphView() {
ringbuffer = new Ringbuffer();
}
public void put(String c) {
if (error != null)
return;
try {
ringbuffer.put(c);
} catch (IndexOutOfBoundsException e) {
error = "Ringbufferüberlauf";
}
repaint();
}
public String get() {
String ret = null;
if (error != null)
return ret;
try {
ret = ringbuffer.get();
} catch (IndexOutOfBoundsException e) {
error = "Ringbuffer schon leer";
}
repaint();
return ret;
}
static int element = 0;
/**
* Gesamtes Fenster zeichnen mit Buttons etc.
*
* @param args
*/
public static void main(String[] args) {
final GraphView view = new GraphView();
JFrame f = new JFrame("Ringbuffer");
f.setSize(500, 200);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane pane = new JScrollPane(view);
JPanel panel = new JPanel(new BorderLayout());
panel.add(pane, BorderLayout.CENTER);
JPanel buttons = new JPanel(new FlowLayout());
JButton putButton = new JButton("put");
putButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
element++;
view.put("" + element);
}
});
JButton getButton = new JButton("get");
getButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
view.get();
}
});
buttons.add(putButton);
buttons.add(getButton);
panel.add(buttons, BorderLayout.SOUTH);
f.setContentPane(panel);
f.setVisible(true);
}
}
Der Code ist kein gutes Beispiel für Programmierstil, weil ziemlich viele Konstante für die grafische Aufbereitung einfach im Code stehen.
Simulation einer Warteschlange an der Kasse
Schreiben Sie ein Programm, welches die Warteschlange an einer Kasse simuliert.
Es sollen in beliebigen Abständen Namen der Kunden eingegeben werden können, die sich an der Kasse anstellen.
Die Kasse bedient nun einen Kunden nach dem anderen. Die Bearbeitungsdauer soll zufällig aus einem Intervall von 5 bis 10 Sekunden gewählt werden. In regelmäßigen Abständen soll die Warteschlange bzw. die Anzahl der Kunden ausgegeben werden:
hp@L309:~/queue/bin> java kassa/Warteschlange
Marina Kathi Klaus Susi
es warten: Marina Kathi Klaus Susi
Tom es warten: Marina Kathi Klaus Susi
bediene Marina
Manues warten: Kathi Klaus Susi
Marina fertig
elaes warten: Kathi Klaus Susi
bediene Kathi
es warten: Klaus Susi Tom Manuela
es warten: Klaus Susi Tom Manuela
es warten: Klaus Susi Tom Manuela
es warten: Klaus Susi Tom Manuela
Kathi fertig
es warten: Klaus Susi Tom Manuela
bediene Klaus
es warten: Susi Tom Manuela
es warten: Susi Tom Manuela
es warten: Susi Tom Manuela
es warten: Susi Tom Manuela
Klaus fertig
es warten: Susi Tom Manuela
bediene Susi
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
es warten: Tom Manuela
Susi fertig
es warten: Tom Manuela
bediene Tom
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
es warten: Manuela
Tom fertig
es warten: Manuela
bediene Manuela
Manuela fertig
Normalerweise würde man so etwas mit Threads programmieren. Es gibt aber auch eine andere Möglichkeit durch die Verwendung eines InputStreamReader
. Ein InputStreamReader
besitzt eine nicht blockierende Methode um abzufragen, ob Eingabe vorhanden ist: ready()
. Zum Lesen kann dann trotzdem ein BufferedReader
verwendet werden, der den InputStreamReader
verwendet:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
...
InputStreamReader instream = new InputStreamReader(System.in);
BufferedReader in = new BufferedReader(instream);
Damit kann man den Eingabestrom pollen
:
boolean eof = false;
while (!eof) {
// poll
if (instream.ready()) { // is there something to read?
String zeile = in.readLine(); // yes, read it
System.out.println("------- " + zeile);
if (zeile.equalsIgnoreCase("quit")) {
eof = true;
}
} else {
// no, do the other work...
Thread.sleep(500); // wait 500 ms
}
}
in.close();
Warteschlange als Ringpuffer
Eine Warteschlange besitzt drei Operationen:
put(element)
ein Element in die Warteschlange aufnehmen.get()
das erste Element entfernen.isEmpty()
prüft, ob die Schlange leer ist.
Werden Daten in dieses Array aufgenommen und wieder entnommen, so kommt man bald ans Ende des Arrays. Man muss also wieder von vorne beginnen. Daher kann man sich das Array als Ring vorstellen:
Man benötigt zwei Zeiger
(Indices), einen putIndex
für die Schreiboperation put()
und einen getIndex
für die Leseoperation get()
.
Der Leseindex (getIndex
) muss immer hinter
dem Schreibindex (putIndex
) sein. Sind beide Indices gleich, so ist der Puffer entweder leer oder ganz voll. Um dies zu unterscheiden, könnte man einen Füllstand einführen (usedSize
).
public class Queue {
public static final int DEFAULTSIZE = 10;
private int size; // size of ringbuffer/queue
private int usedSize; // so many elements are in the ringbuffer
private char[] ring; // the ringbuffer
private int getIndex = 0;
private int putIndex = 0;
public void put(char elem) {
usedSize++;
ring[putIndex] = elem;
putIndex = (putIndex + 1) % size;
}
public char get() {
usedSize--;
char ret = ring[getIndex];
getIndex = (getIndex + 1) % size;
return ret;
}
public Queue(int size) {
this.size = size;
ring = new char[size];
}
public Queue() {
size = DEFAULTSIZE;
ring = new char[size];
}
public boolean isEmpty() {
return usedSize == 0;
}
public int getSize() {
return size;
}
}
Queue.java enthält dokumentierten Sourcecode (Achtung Package queue
) inklusive Fehlerbehandlung (die man normalerweise mit Exceptions machen würde) für eine Schlange von char
.
Montag, 11. Januar 2010
Googles Go ist TIOBEs Programmiersprache des Jahres 2009
Googles Go wurde von TIOBE deshalb als "Programmiersprache des Jahres 2009" gewählt, weil die Verbreitung dieser Sprache im Jahr 2009 am meisten gestiegen ist, von 0% auf 1,25%. Die am häufigsten verwendete Sprache nach diesem Index ist nach wie vor Java.
Position Jan 2010 | Position Jan 2009 | Delta in Position | Programming Language | Ratings Jan 2010 | Delta Jan 2009 | Status |
---|---|---|---|---|---|---|
1 | 1 | Java | 17.482% | -1.54% | A | |
2 | 2 | C | 16.215% | +0.28% | A | |
3 | 5 | PHP | 10.071% | +1.19% | A | |
4 | 3 | C++ | 9.709% | -0.41% | A | |
5 | 4 | (Visual) Basic | 7.354% | -1.81% | A | |
6 | 6 | C# | 5.767% | +0.16% | A | |
7 | 7 | Python | 4.453% | -0.28% | A | |
8 | 8 | Perl | 3.562% | -0.74% | A | |
9 | 9 | JavaScript | 2.707% | -0.65% | A | |
10 | 11 | Ruby | 2.474% | -0.67% | A | |
11 | 10 | Delphi | 2.392% | -0.91% | A | |
12 | 37 | Objective-C | 1.379% | +1.24% | A | |
13 | - | Go | 1.247% | +1.25% | A-- | |
14 | 14 | SAS | 0.809% | +0.01% | A | |
15 | 13 | PL/SQL | 0.718% | -0.29% | A | |
16 | 18 | ABAP | 0.641% | +0.10% | A-- | |
17 | 15 | Pascal | 0.624% | -0.04% | B | |
18 | 23 | Lisp/Scheme | 0.576% | +0.14% | B | |
19 | 20 | ActionScript | 0.566% | +0.11% | B | |
20 | 24 | MATLAB | 0.540% | +0.11% | B |
Labels: C, C#, C++, Go, Java, Programmiersprachen, Python
Abonnieren Posts [Atom]