Donnerstag, 28. Januar 2010

 

Entwicklung von iPhone Apps unter Linux - VMware Image

Meine Versuche, die iPhone Entwicklungsumgebung unter Linux zum Laufen zu bringen sind ja bisher gescheitert. Ich habe ein fertiges VM-Image mit einer iPhone-Toolchain heruntergeladen.
Ist nicht ganz das, was ich mir vorgestellt habe:

Ist nur ein Debian (Ubuntu) mit Kommandozeile. "Toolchain" stimmt, es sind passende Compiler, make und ssh installiert. Übrigens muss man sich mit root und Passwort toolchain anmelden.
Man kann dann z.B.
cd /PROJECTS/HelloWorld
make clean
make
machen 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).
Mangels iPhone kann ich das natürlich nicht ausprobieren. Ich hatte mir schon einen Emulator wie beim Android erwartet.
Also nur einmal probieren, wie das Feeling ist, für ein iPhone zu entwickeln, ist offensichtlich nicht drinnen.

Labels: , , ,


 

Entwicklung von Android Apps unter Linux - Hello World

Ich möchte kurz skizzieren, wie man zur ersten Android "Hello World"-Applikation kommt. Für eclipse (3.4, 3.5) gibt es ein Plugin, das man wie folgt installieren kann:
Bei "work with" muss man https://dl-ssl.google.com/android/eclipse/ eingeben:
Mit Auswählen von "Developer Tools" und "Finish" installiert man das Plugin.
Man muss das Android SDK herunterladen und auspacken. Das Installationsverzeichnis muss man noch bei den Settings angeben:
Als nächstes ruft man den "Android SDK and AVD Manager" auf:
und lädt sich die Packages für den/die Emulatoren/Handys herunter:


Dann muss man noch ein konkretes Gerät anlegen:
Dann kann man schon ein Android-Projekt anlegen:




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:
Mit "Run" kann man dann den Emulator mitsamt seiner Applikation starten:


Im Prinzip habe ich hier nur nachvollzogen, was im Hello World Tutorial auf http://developer.android.com/ beschrieben wurde.

Labels: , , , ,


 

Entwicklung von iPhone Apps unter Linux

iPhone Entwicklung gibt es eigentlich nur für Mac-User (iPhone ist mir noch nicht unter Linux gelungen). Inoffiziell gibt es die Möglichkeit, das iPhone Software Development Kit auch unter Linux (32bit!) zum Laufen zu bringen.

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: , , ,


 

Entwicklung von Android Apps unter Linux

Android Entwicklung ist nicht nur für Mac-User (iPhone ist mir noch nicht unter Linux gelungen). Das Android SDK gibt es für Linux, Mac und Windows! Man benötigt das SDK und ein eclipse-Plugin, das ADT - Installing and Updating ADT. Dann kann man schon los legen. Man braucht auch keine neue Sprache lernen, wenn man Java schon kann.
Leider braucht man eine aktuellere eclipse-Version, 3.4 oder 3.5. Die Version 3.2 in der Schule funktioniert nicht richtig mit dem ADT.
Auf dem edvoftp gibt es auch ein ISO-Image für eine "Android Live-CD".
Der Emulator funktioniert schon:

Labels: , , , ,


Mittwoch, 20. Januar 2010

 

Aufgabe Gruppenwechsel Ski

Schreiben Sie eine Java-Klasse Grw.java, welches aus dem Datenbestand ski.csv die beigelegte Statistik erzeugt.


Ausschnitt csv-Datei ski.csv als Bild

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,37Sekunden betragen.

Abgabetermin: Donnerstag, 28. Jänner 2010

Labels: , ,


Mittwoch, 13. Januar 2010

 

Ringbuffer Simulation

Sie finden unter ringbuffer.jar eine Simulation eines Ringbuffers (bzw. Queue).


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.

Labels: , ,


 

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.

Array

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:

Ringbuffer

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.

Labels: , ,


Montag, 11. Januar 2010

 

Googles Go ist TIOBEs Programmiersprache des Jahres 2009

TIOBE erstellt monatlich einen TIOBE Programming Community Index, in dem die populärsten Programmiersprachen ermittelt werden. Die Reihung erfolgt aufgrund der Anzahl der qualifizierten Ingenieure weltweit, Kursen und Drittanbietern. Die Suchmaschinen Google, MSN, Yahoo und YouTube werden zur Berechnung der Reihung herangezogen. In dieser Reihung geht es nicht um die beste Programmiersprache und auch nicht und jene Sprache in der diemeisten Zeilen geschrieben wurden.

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.

Hier die TOP 20 (Jänner 2010):
Position
Jan 2010
Position
Jan 2009
Delta in PositionProgramming LanguageRatings
Jan 2010
Delta
Jan 2009
Status
11Java17.482%-1.54% A
22C16.215%+0.28% A
35PHP10.071%+1.19% A
43C++9.709%-0.41% A
54(Visual)
Basic
7.354%-1.81%
A
66C#5.767%+0.16% A
77Python4.453%-0.28%
A
88Perl3.562%-0.74% A
99JavaScript2.707%-0.65%
A
1011Ruby2.474%-0.67% A
1110Delphi2.392%-0.91%
A
1237Objective-C1.379%+1.24%
A
13-Go1.247%+1.25% A--
1414SAS0.809%+0.01% A
1513PL/SQL0.718%-0.29%
A
1618ABAP0.641%+0.10% A--
1715Pascal0.624%-0.04%
B
1823Lisp/Scheme0.576%+0.14%
B
1920ActionScript0.566%+0.11%
B
2024MATLAB0.540%+0.11% B


(Status A...Mainstream, siehe Erklärungen von TIOBE).

Ich habe die Tabelle aus TIOBE Programming Community Index kopiert, da über diesen Link nur die aktuellen Daten verfügbar sind.

Ranking über die Jahre:


Labels: , , , , , ,


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

Abonnieren Posts [Atom]