Verfasst von: bletra | 28. Juni 2012

Algorithmen: Visualisierung und mehr

Ich bin auf eine schöne Seite aufmerksam gemacht worden, die Studierenden und anderen Interessierten das Verstehen von Standardlösungen zu Standardproblemen, also das Verstehen bekannter Algorithmen erleichtern möchte: discenopus.com. Es handelt sich um ein Projekt, das noch Mitstreiter sucht 🙂 — wer also in den Semesterferien Langeweile haben sollte …

 

 

Verfasst von: bletra | 23. April 2012

Teamarbeit im Praktikum

In unseren Praktika arbeiten die Studierenden in Zweierteams. Später im Studium werden die Teams auch größer. Teamarbeit ist im Allgemeinen mit Arbeitsteilung und Teammeetings verbunden. Gerade die Arbeitsteilung trifft auf die Praktikumsaufgaben nur bedingt zu. Viele Praktika lassen sich nicht so aufteilen, dass beide alles lernen und durchdenken. Daher halte ich den Ansatz „Think, Pair, Share“ für besser: Think: Sie arbeiten zunächst alleine an der Lösung. Pair: Sie tauschen sich mit Ihrem Praktikumspartner aus und optimieren. Share: Sie diskutieren Ihre Lösung mit anderen Praktikumsteilnehmern, z.B. während des eigentlichen Praktikums.
Nach meiner Erfahrung sind Teams von möglichst gleich starken Partnern erfolgreich. Bei einem zu starken Ungleichgewicht, schleppt einer den anderen durch, der Profi lässt gedankliche Zwischenschritte aus oder wählt nicht den intuitiven oder leicht verständlichen Lösungsweg, Der „Anfänger“ kommt sich dumm vor, findet die Lösung nicht alleine und hat damit wenig Erfolgserlebnisse.  Teamwork heißt nicht „ein anderer machts“, jeder sollte sich über Erwartungen und Ziele klar sein und diese deutlich kommunizieren.
Welche Erfahrungen haben sie mit Ihren Teams, was läuft gut, was läuft schlecht, welche Schlüsse ziehen Sie daraus?

Verfasst von: bletra | 17. April 2012

Informatik und Gesellschaft

Im Praktikum meiner Erstsemesterveranstaltung werde ich von einem sehr engagierten und vielseitig interessierten Tutor unterstützt. Er kam auf die Idee, die Studierenden zu einer Diskussion über verschiedene gesellschaftlich relevante Forschungsbereiche der Informatik anzuregen. Die Studierenden ließen sich darauf ein, haben ihr abzulegendes Testat hintenan gestellt, beteiligten sich rege an der Diskussion und gaben rundweg gutes Feedback zu dem gemachten Angebot.

Ein Ausgangspunkt der Diskussion war das Singularitätsinstitut mit Fragen wie, was ist Intelligenz? Was ist künstliche Intelligenz? Welche Rechte sollen/können eine künstliche Intelligenz haben? Was ist, wenn Programme/Roboter „intelligenter“ werden als wir Menschen? Können Programme Gefühle haben, wenn ja, muss man diese respektieren? Kann/darf man sie dann einfach abschalten? Sollten sie eher wie Menschen aussehen oder besser nicht? Die Diskussionen wurden bisher in zwei Praktikumsgruppen durchgeführt und verliefen sehr unterschiedlich. Dadurch angeregt bin ich auf die Seite des Singularitätsinstituts. Ich wollte wissen, wer dahinter steckt – bei gesamtgesellschaftlichen Fragen bin ich immer kritisch, ob Einfluss durch politische oder religiöse Gruppierungen genommen wird. Eine treibende Kraft des Instituts scheint Eliezer Yudkowsky zu sein, dessen Darstellung bei Wikipedia mich nicht überzeugte. Beratend wirken jedoch ausgewiesene Wissenschaftler, wie z.B. Professor Nick Bostrom (Wikipedia, Homepage, Direktor von Future of Humanity Institute, Mitgründer von Institute for Emerging Ethics & Technologies) am Institut mit, so dass meine Zweifel keine weitere Nahrung bekamen. Das Institut wird auch bei der New York Times in „The Coming Superbrain“ erwähnt. Dort fand ich auch einen weiteren interessanten Artikel „Merely Human? That’s So Yesterday“, in dem auf die Singularity University verwiesen wird – diese wurde von Google mitgegründet … In diesem Zusammenhang möchte ich Sie auch noch auf das Video Dr. Michio Kaku: „The World in 2030“ aufmerksam machen.

Im ersten Semester sind die Englischkenntnisse häufig noch sehr ausbaufähig, so dass ich mich auf die Suche nach deutschsprachigen Quellen machte. Fündig wurde ich zunächst beim SFB 588: Humanoid Robots, die aktuelle Seite ist leider in Englisch. Ethische Fragen dieses Projekts werden in „Towards tightly-coupled robot-human interaction”  diskutiert — wieder in Englisch …

Nun aber zu den wirklich deutschsprachigen Seiten:

So, das war’s erst einmal für heute für mich. Ich freue mich auf weitere anregende Diskussionen und Themen.

Verfasst von: bletra | 29. März 2012

C++-Renaissance

Bei uns am Fachbereich wird seit vielen Jahren C++ als erste Programmiersprache gelehrt. Als C#-Fan hätte ich anfangs gerne C# oder Java gehabt. Seitdem ich Programmieren, Algorithmen und Datenstrukturen (PAD)  selbst halte, sehe ich viele Argumente für C++. C++ ist wirklich ein gutes Fundament. In C# und Java werden viele Dinge wegabstrahiert oder „versteckt“. In C++ nicht, hier müssen wir uns beispielsweise selbst mit der Speicherverwaltung auseinandersetzen. C++ ist in vielen Bereichen strenger und damit oft klarer, z.B. werden Referenztypen und Zeiger klar unterschieden. Zugegeben, die Lernkurve ist flacher, mühsamer, die Console leider weniger ansprechend als eine hübsche GUI. Mit dem neuen C++-Standard, erhält die Sprache viele wichtige Sprachkonstrukte, die die Entwicklung vereinfachen. Mit der wachsenden Nachfrage an Echtzeitanwendungen wird Performance wieder wichtig und C++ erhält neuen Aufwind. Dies wird im Web auch vielfältig unter dem Begriff „C++-Renaissance“ diskutiert, z.B. von Herb Sutter. Es ist deutliche einfacher, von dem Fundament C++ ausgehend, Java oder C# zu lernen, als umgekehrt. Lassen Sie uns also, ein ordentliches Fundament in der Veranstaltung PAD aufbauen. Sie lernen eine brandaktuelle Sprache, eine Sprache der Zukunft.

Verfasst von: bletra | 21. März 2012

NetBeans, Umlaute, C++, cygwin

NetBeans ist für mich eine relativ neue Entwicklungsumgebung. Obwohl ich VS sehr schätze, habe ich mich bzgl. C++ für NetBeans entschieden. Leider hatte ich Schwierigkeiten, deutsche Umlaute im Output-Fenster von NetBeans darzustellen — natürlich hatte ich in meiner main-Funktion die Anweisung setlocale( LC_ALL, „“ ); und dies auch mit verschiedenen Lokalisierungen wie de oder de_DE, Umlaute wurden aber einfach nicht richtig dargestellt. Nach längerem Suchen fand ich folgenden Tipp, der bei mir mit NetBeans (Englisch), cygwin, Win7 (Englisch) funktionierte: Im Verzeichnis NetBeans7.1.1\etc die Datei netbeans.conf editieren und innerhalb der Anführungszeichen von netbeans_default_options -J-Dfile.encoding=UTF-8 einfügen.

Verfasst von: bletra | 19. März 2012

ENA-Appetizer: What is HCI

Anlässlich der morgen startenden Vorlesung „Entwicklung nutzerorientierter Anwendungen“ habe ich ein schönes Video gefunden, das sehr anschaulich und kurzweilig wesentliche Elemente von HCI darstellt:

Stimmen Sie sich auf ENA ein mit What is HCI von der University of Washington.

Verfasst von: bletra | 27. Februar 2012

Agile Entwicklung

Agile Entwicklung ist in aller Munde. Wer jedoch nicht das Glück hat, in einem modernen Entwicklungsteam dessen Prinzipien umzusetzen, kann sich den Alltag nur schwer vorstellen. In zwei Artikeln beschreiben Alex Bepple und Henning Wolf eine fiktive und damit durchaus eher ideale Woche eines agilen Entwicklers. Beim Lesen dieser Artikel wird schnell klar, dass Kommunikationskompetenz, kritisches Mitdenken und Teamgeist wichtige Kompetenzen heutiger Entwickler sind. Lesen Sie selbst:

Verfasst von: bletra | 16. Januar 2012

happy new year

Hallo zusammen,

eigentlich viel zu spät möchte ich allen Leserinnen und Lesern noch ein schönes neues Jahr 2012 wünschen und mich für das Interesse im vergangenen Jahr bedanken. 19.000 Besuche in 2011 sind eine beeindruckende Zahl. Die Artikelserie „von Spaghetticode zu MVVM“ war mit Abstand am häufigsten nachgefragt. Ich werde mich bemühen, bald wieder mehr von dieser Art zu bringen oder auch ganz neue Themen beleuchten. Aktuell ist es in diesem Blog leider etwas ruhiger geworden, da eine volle Stelle und Familie doch insgesamt sehr fordernd sind. Ich lese noch viel und arbeite mich in interessante Themen ein, jetzt müssen daraus „nur“ noch Artikel werden … Ich hoffe, in den Semesterferien werde ich hier wieder produktiv.

Ich würde mich freuen, wenn Sie Themen, die Sie interessieren, per Mail oder als Kommentar schicken, oder wenn Sie gar einen Post selbst schreiben würden. Im letzten SS gab es einige interessante Posts von Studierenden. In Rücksprache mit dem Autor/der Autorin editiere ich gerne und veröffentliche unter dem angegebenen Namen/Pseudonym.

Viele Grüße und bis bald,

ubt

Verfasst von: bletra | 24. November 2011

JavaScript: Globale Variablen bei Event-Handlern

Gestern im Praktikum habe ich ein seltsames Verhalten beim Zusammenspiel von JavaScript und HTML kennen gelernt:Innerhalb eines click-Events sind je nach Browser Elemente mit einer id unter dieser id als globale Variable verwendbar. Der aktuelle IE macht dabei alle Ids verfügbar, während Firefox nur die Ids innerhalb des gleichen Formulars kennt. Betrachten Sie hierzu folgendes Beispiel:

<h1>Demo Auto-Globals</h1>
<input type="text" name="name2" id="name2" />
<form accept-charset="utf-8" method="get" action="demo.html">
<div>
<label for="firstName">Vorname:</label><input type="text" name="name" id="firstName" /><span id="x"></span>
<button onclick="alert(firstName);">test von firstName</button>
<button onclick="alert(name2);alert(x);">test von span-Element und input außerhalb</button>
</div>
</form>

Der erste Button zeigt sowohl im IE als auch im Firefox die Variable firstName als Input-Element an. Beim zweiten Button wird im Firefox nichts ausgegeben, während der IE sowohl das außerhalb des Form-Tags gelegene Input-Element als solches kennt, als auch das span-Tag.
Möchte man diese Variablen dagegen per JavaScript innerhalb des Script-Tags oder innerhalb einer eingebundenen JavaScript-Datei verwenden, so stehen sie nicht zur Verfügung.
Folgender Code zeigt somit nichts an:

function globals()
{
  alert(firstName);
}

mit HTML-Code:

<button onclick="demo();">input-global in JS unbekannt</button>

Falls Sie mit Objektschablonen und globalen „Instanzen“ arbeiten, dann achten Sie darauf, diese globalen Variablen anders alle alle Ids Ihrer HTML-Tags zu nennen. Wie gesagt, diese nur den Click-Handlern bekannten Globals haben mich sehr überrascht.

Verfasst von: bletra | 7. November 2011

Barrierefreie Formularvalidierung mit JavaScript

Die Validierung von Formularen auf dem Client ist eine Standardaufgabe bei Webapplikationen. Mit Html5 wird es hierfür hilfreiche Attribute geben. Momentan stehen diese jedoch noch nicht in allen Browsern benutzbar zur Verfügung. Daher erfolgt üblicherweise die clientseitige Validierung mit JavaScript, genauer gesagt ECMAScript. Die clientseitige Validierung von Formularen reduziert den Datentransfer und dient somit ausschließlich der Benutzerfreundlichkeit – serverseitige Validierung ist dennoch aufgrund von Sicherheitsanforderungen notwendig. In den Genuss der clientseitigen Validierung sollen auch Benutzer kommen, die Hilfsmittel zur Bedienung benötigen, z.B. blinde Menschen, die einen Screenreader benutzen.
Damit stellt sich die Frage, welche Strategie zu verfolgen ist. Zunächst die Anforderungen:

  1. Bereits bei der Eingabe soll klar sein, was in dem jeweiligen Feld erwartet wird.
  2. Ist JavaScript deaktiviert, erfolgt die Validierung ausschließlich auf dem Server. Das Formular wird dennoch abgeschickt.
  3. Das Formular lässt sich auch mit der Tastatur allein korrekt ausfüllen und abschicken.
  4. Unvollständig, falsch oder nicht ausgefüllte Formularfelder führen dazu, dass das Formular nicht abgeschickt wird (bei aktiviertem JavaScript).
  5. Fehlermeldungen müssen für alle Benutzer wahrnehmbar und leicht verständlich sein und sind leicht zu korrigieren.
  6. Die clientseitige Validierung ist eine gute Unterstützung für die Benutzer, das Formular effizient auszufüllen. Sie wird nicht als nervig wahrgenommen.
  7. Fehlermeldungen sind leicht an die gewählte Sprache anpassbar (Internationalisierung).

Die ersten Forderungen lassen sich einfach umsetzen:

Zu 1.: Pflichtfelder werden typischerweise mit * markiert, ggf. gibt es zusätzliche Angaben in welchem Format die Eingabe (z.B. Telefon oder Datum) zu erfolgen hat. Damit bei der Eingabe in ein Formularelement auch vorgelesen werden kann, welche Information gewünscht ist, gehört zu jedem Eingabeelement (select, textarea, input type text oder password oder radio oder checkbox) ein Label-Element. Dabei wird das for-Attribut des Labels mit dem id-Attribut des Eingabeelements verknüpft, wie folgendes Beispiel zeigt:

<label for="lastName">Nachname:</label><input type="text" name="name" id="lastName" value="" size="10" />

Zu 2.: Die Validierung wird im onsubmit-Attribut des Form-Tags aufgerufen und nicht an ein change-Ereignis o.ä. gebunden. Wird von der Methode ein „false“ zurückgegeben, so wird durch die gezeigte Aufrufmethodik die Default-Action, also das Abschicken des Formulars, nicht ausgeführt.

<form action="script.php" method="post" accept-charset="UTF-8" onsubmit="return formOk();">

Alternativ kann hier auch das Event übergeben werden und seit DOM2 mit preventDefault die Ausführung der Default-Action verhindert werden.

Zu 3: Eingaben und Aktionen der Benutzer sind an entsprechende Formularfelder oder Links gebunden. Diese lassen sich generell mit Tabs fokussieren und durch ein Return wird auch ein click-Ereignis ausgelöst.

Zu 4: Die in zu 2. verwendete JavaScript-Funktion formOk gibt im Fehlerfall „false“ zurück. Damit wird die Default-Action des Formulars nicht ausgeführt, d.h. das Formular wird nicht abgeschickt. Bei deaktiviertem JavaScript wird das Formular an den Server geschickt.

Zu 5-7: Schwieriger ist die Frage, wie die Fehlermeldungen zu kommunizieren sind. Früher wurde hierfür ausschließlich eine alert-Meldung verwendet. Diese fällt dem Benutzer direkt auf und wird auch vom Screenreader direkt vorgelesen. Mehrere alert-Fehlermeldungen werden als nervig empfunden und nachdem die Box weggeklickt wurde, hat man oft auch vergessen, was zu korrigieren ist. Zusätzlich ist also auch eine Markierung (roter Hintergrund, …) der fehlerhaften Eingabeelemente hilfreich. Alert-Boxen werden als „nicht schön“ empfunden und von Designern ungern eingesetzt. Daher werden häufig nur noch entsprechende Fehlertexte und Styleänderungen im HTML direkt vorgenommen. Diese Änderungen werden jedoch von Screenreadern nicht notwendigerweise bemerkt und somit nicht vorgelesen. Folgender Ansatz stellt Designer und Screenreader (getestet mit JAWS und Windows7-System-Reader) gleichermaßen zufrieden und ist daher uneingeschränkt zu empfehlen:
Sie können in Ihrem HTML-Code Fehlermeldungen vorbereiten: Fügen Sie ein a-Tag mit href-Attribut als Fehlermeldung ein und setzen den Focus darauf. Idealerweise fügen Sie für alle fehlerhaften Felder ein a-Tag in eine Liste ein, diese Liste kann ggf. für sehende Menschen versteckt werden. Zusätzlich werden fehlerhafte Felder sichtbar markiert. Folgender Code veranschaulicht die dargestellte Strategie:

HTML-Seite:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<title>test</title>
<script type="text/javascript" src="demo.js"></script>
<link rel="stylesheet" type="text/css" href="demo.css" />
</head>
<body>
<h1>Demo Formularvalidierung</h1>
<p id="formwarnings">
<a href="#">Fehler in der Eingabe:</a>
<ul>
<li  id="link_name"><a href="#name">Name ist ein Pflichtfeld</a></li>
<li id="link_zip"><a href="#zip">Postleitzahl ist ein Pflichtfeld, fünfstellige Zahl</a></li>
</ul>
</p>
<form action="script.php" accept-charset="utf-8" method="post" onsubmit="return isValid();">
<div>
<label for="name">Name *</label><input id="name" name="name" type="text" />
<label for="zip">Postleitzahl *</label><input id="zip" name="name" type="text" />
<input type="submit" value="abschicken" />
</div>
</form>
</body>
</html>

CSS:

.hideWarning {display:none;}
.showWarning{display:block;}
.warning{border: 1px solid red;}

JavaScript:

"use strict";
function isValid()
{
  var ok = true;
  var pattern = /^[0-9]{5}$/;
  var inputField = document.getElementById("zip");
  if (!pattern.test(inputField.value))
  {
    ok = false;
    showWarning("zip");
    inputField.focus();
  }
  inputField = document.getElementById("name");
  if (inputField.value.length == 0)
  {
    ok = false;
    showWarning("name");
    inputField.focus();
  }
  return ok;
}

function showWarning(id)
{
  document.getElementById(id).className = "warning";
  document.getElementById("link_" + id).className = "showWarning";
  document.getElementById("formwarnings").className = "showWarning";
}

Wie Sie sehen, enthält der JavaScript-Code keine Strings zur Erzeugung von Fehlermeldungen, diese sind im HTML-Code bereits vorbereitet. Damit kann das Script auch in übersetzten HTML-Seiten eingesetzt werden, Internationalisierung ist somit vorbereitet.

Links zum Thema:

Verfasst von: bletra | 1. November 2011

HowTo WPF

Unter WindowsClient.Net von Microsoft gibt es zu fast allen Fragen rund um WPF kurze Videos. Sie möchten von WinForm auf WPF umsteigen, mit WPF anfangen, haben 10 Minuten nichts zu tun und möchten kurz etwas dazu lernen oder Sie müssen ein konkretes WPF-Problem lösen? Schauen Sie sich die Themen an, es ist sicher etwas dabei, das Ihnen weiter hilft.

Verfasst von: bletra | 31. Oktober 2011

Entwickler/innen gefragt

Nach einer aktuellen Umfrage von Computerworld werden im nächsten Jahr vorwiegend folgende Fähigkeiten nachgefragt:

  1. Softwareentwicklung (insb. Anwendungsentwicklung für mobile Endgeräte): 61 %
  2. Projektmanagement: 44%
  3. Support: 35%
  4. Netzwerktechnik (insb. Cloud-Computing und Virtualisierung): 35 %
  5. Business Intelligence (BI): 23%
  6. Datenmanagement und Systemintegration: 18%
  7. Web 2.0: 18%
  8. Sicherheit: 17%
  9. Telekommunikation: 9%

Grundkenntnisse in den genannten Bereichen sollte jeder Informatik-Absolvent mitbringen. Wer sich gute Kenntnisse und Methoden in Softwareentwicklung angeeignet hat, kann sich auch in eine andere Entwicklungsumgebung und Programmiersprache einarbeiten. Viele Absolventen fangen als Entwickler an. Diese Studie verdeutlicht wieder einmal, wie wichtig es ist, als Informatiker wirklich programmieren zu können. Denn auch für alle anderen aufgelisteten Fähigkeiten sind Programmierkenntnisse zum Anpassen vorhandener Werkzeuge hilfreich. Für das Projektmanagement wird typischerweise eine entsprechende Berufserfahrung vorausgesetzt.

Verfasst von: bletra | 27. Oktober 2011

Singleton vs. static

In der Vorlesung sprach ein Student den Unterschied zwischen Singletons und statischen Klassen an. Diese Frage möchte ich hier gerne aufgreifen.

Methoden und Eigenschaften, die zu einer Klasse gehören, also nicht zu einer einzelnen Instanz, nennt man statisch. Hierfür dient das Schlüsselwort static. Unabhängig von der Anzahl der Instanzen einer Klasse, sind sie einmal vorhanden. Statische Klassen — genauer gesagt statische Methoden oder Eigenschaften einer Klasse — können weder als Parameter übergeben noch von einer Methode zurückgegeben werden. Sie lassen sich auch nicht in eine Liste einfügen (z.B. bei Observer/Ereignissen). Daher können sie auch nicht Bestandteil eines Interfaces oder Eigenschaften anderer Klassen sein. Sie können somit nicht im Sinne von Aggregation oder Komposition verwendet werden. Ein Casten ist ebenfalls nicht möglich, da es keine Instanz zum Casten gibt.

Singleton ist ein Entwurfsmuster, dessen Implementation dafür sorgt, dass es nur eine Instanz dieser Klasse geben kann. Nach außen hin verhält sich ein Singleton wie eine normale Instanz einer Klasse, kann also als Parameter etc. verwendet werden. Ein Singleton kann auch einfach serialisiert werden und so z.B. remote oder in Webdiensten verwendet werden. Im Prinzip ist es ein Geheimnis der Klasse, dass diese einmalig ist, den Nutzern kann es egal sein. Das Singleton-Dasein gehört zur inneren Logik der Klasse. Das Testen von Singletons kann insbesondere bei asynchronen Prozessen schwierig sein. Die Implementation eines Singletons verwendet typischerweise eine statische Eigenschaft. Singletons lassen sich einfach durch polymorphe Klassen austauschen und somit gut bei automatischen Tests durch „Scheinobjekte“ (mocking) simulieren.

Funktionsbibliotheken (z.B. mathematische Funktionen wie sin etc.) werden oft und sinnvollerweise als statische Methoden implementiert, da ihr Rückgabewert nur von den übergebenen Parametern abhängt. Singletons kommen im Kontext von Logging, Authorisierung, Monitoring, Druckaufträge und anderen Diensten zum Einsatz. Hier ist es wichtig, dass es ein hauptverantwortliches Objekt, eben das Singleton gibt. Beide Technologien werden manchmal verwendet, um globale Variablen „einzuschmuggeln“, hier ist natürlich Vorsicht geboten.

Bzgl. der Performance gibt es unterschiedliche Aussagen und je nach Implementation wird ein Singleton erst dann erzeugt, wenn es tatsächlich benötigt wird, während statische Eigenschaften direkt im Speicher angelegt werden. Im Allgemeinen, werden diese Performancedetails jedoch nicht als Argument für die eine odere andere Variante angeführt. Die Verwendung von Singleton bzw. statischen Methoden sollte sich an der Semantik und der geplanten Verwendung orientieren und damit aus dem Zusammenhang ergeben.

Links zum Thema:

Verfasst von: bletra | 19. Oktober 2011

Weboberflächen mit Selenium automatisiert testen

Im Praktikum der Veranstaltung „Entwicklung webbasierter Anwendungen“  ist eine integrierte webbasierte Anwendung zur Unterstützung eines Pizzaservices zu entwickeln. Bei der Bestellung kann der Kunde seine Pizzen aus der Speisekarte auswählen und in einen Warenkorb übernehmen.

Die Applikation ist bewusst einfach gehalten, um anhand dieses Beispiels exemplarisch alle wesentlichen Technologien zu erarbeiten und die Aufgabe strukturiert und wiederverwendbar zu entwickeln. Als Warenkorb wird daher eine einfache List-Box (HTML-Tag: Select) gewählt, in die die Pizzen als Option-Elemente eigefügt werden. Ein beispielhaft gefüllter Warenkorb (ohne Design) zeigt die Abbildung links.

Wesentlicher Ausschnitt des zugehörigen Markups:

<form ...>
<p>
<select id="ShoppingCart" ...>
<option ...>Palermo</option>
<option ...>Hawaii</option>
<option ...>Vegetaria</option>
<option ...>Salami</option>
</select>
</p>
<p><span id="TotalPrice">23,50</span> &euro;</p>
...
</form>

Mit dem Firefox-Addin Selenium lassen sich sehr einfach Web-Oberflächetests entwickeln. Was Sie hierfür tun müssen beschreiben ich anhand eines einfachen Anwendungsfall der gegebenen Pizzaanwendung.
Gegeben sei folgender Anwendungsfall:
Löschen im Warenkorb: Im Warenkorb kann man alle Pizzen oder auch mehrere ausgewählte Pizzen löschen. Der Preis wird aktualisiert.
Test: Warenkorb füllen mit jeweils einer Palermo, Hawaii, Vegetaria und Salami. Dann die Salami und die Hawaii markieren und diese Auswahl löschen. Im Warenkorb verbleiben Palermo und Vegetaria. Neuer Preis: 13,50 €

Im Folgenden beschreibe ich die Umsetzung des dargestellten Test mit Selenium. Starten Sie hierzu Firefox->Webentwickler->Selenium IDE

Rechts-Klicken Sie auf den angelegten Testfall und wählen Sie Properties aus. Vergeben Sie einen sinnvollen Namen. Gehen sie nun in das Tab „Table“ und drücken Sie den Aufnahmeknopf.
Laden Sie Ihre Bestellseite, legen Sie die Pizzen Palermo, Hawaii, Vegetaria und Salami in den Warenkorb. Markieren Sie Salami und Hawaii im Warenkorb und wählen Sie „Auswahl löschen“. Beenden Sie die Testaufzeichnung.
Nun müssen Sie noch überprüfen, ob die richtigen Pizzen im Warenkorb stehen und der Preis stimmt.
Klicken Sie hierzu ans Ende der bisher erzeugten und in der Tabelle angezeigten Befehle und definieren Sie folgenden neuen Befehl:
Command: assertText
Target: TotalPrice
Value: 13,50
Die verbleibenden Pizzen im Select-Feld kann man mit folgendem Befehl überprüfen:
Command: assertSelectOptions
Target: ShoppingCart
Value: Palermo,Vegetaria

Auf diese Weise kann man weitere Testfälle erstellen und in einer Suite speichern. Selenium verwendet hierzu eine leicht verständliche HTML-Struktur. Gut gefällt mir auch die Auto-Vervollständigung, so dass man bei den Asserts recht gut die passenden Befehle findet. Die Referenz der einzelnen Commands ist kompakt und dennoch verständlich gehalten.
Die Tests können einzeln ausgeführt werden oder alle Tests einer „Suite“ können ausgeführt werden. Es gibt Breakpoints und bei Asserts gibt es im Fehlerfall die übliche Meldung mit dem erwarteten und dem tatsächlichen Wert.

Verfasst von: bletra | 10. Oktober 2011

Zeitmanagement

Im Zuge der Vorlesungsvorbereitung für dieses Semester habe ich einige Links gesammelt, die sich mit dem Thema Zeitmanagement beschäftigen. Ich denke, insbesondere mit dem Bologna-Prozess, also Bachelor und Master und den damit verbundenen hohen zeitlichen Anforderungen, ist es wichtig, effektiv zu arbeiten. Schauen Sie sich die Links an, reflektieren Sie, wie Sie momentan an die Aufgaben gehen und wählen Sie eine für Sie passende Technik aus. Vielleicht probieren Sie auch unterschiedliche Techniken oder mischen die Ansätze. Ich bin auf Ihre Erfahrungen gespannt!

Ich persönlich habe immer einen Zettel greifbar, auf dem ich alle ToDos notieren kann, eine einfache Txt-Datei auf dem Desktop, in der ich mir Links, Stichworte etc. notiere und in der Vorbereitungszeit natürlich einen Zeitplan. Zu Wochenbeginn räume ich immer meine Ablage und meine Mails auf. Aber, meine Anforderungen sind anders als Ihre.

Ein Student berichtete mir von positiven Erfahrungen mit der Pomodoro-Technik. Wie gehen Sie mit Ihren Aufgaben und Ihrer Zeit um?

Hier nun die Links:

Wenn Sie im Blick haben möchten, wofür Sie wie viel Zeit verwenden, dann schauen Sie sich Klok (auch als Freeware) an.

Verfasst von: bletra | 6. Oktober 2011

Das Zusammenfuddeln einer Skybox mittels XNA – C#

Autoren: 2 Studierende der Veranstaltung .Net Framework und C#

In diesem Artikel werden wir uns an eine Implementierung einer Skybox in XNA herantasten und hilfreiche Tipps geben, wie man diese schnell und unkompliziert in sein eigenes Projekt einbauen kann.

Zunächst einmal: Was ist eigentlich eine Skybox?
Eine Skybox besteht aus sechs Bildern, die man bildlich gesprochen auf einen Würfel, auf jede Seite natürlich ein Bild, aufpresst. Hinzu kommt, wie man unten sieht, dass die Skybox, wie auch andere 3D-Objekte aus Meshes besteht. Meshes sind nichts anderes als Ansammlungen von Polygonen, die man nach dem Laden nur noch zeichnen muss:

Codefragment 1:

foreach (ModelMesh mesh in skyboxModel.Meshes)
{
  foreach (Effect currentEffect in mesh.Effects)
  {
    Matrix worldMatrix = skyboxTransforms[mesh.ParentBone.Index] *
    Matrix.CreateTranslation(cameraPosition);
    currentEffect.CurrentTechnique =
    currentEffect.Techniques["Textured"];
    currentEffect.Parameters["xWorld"].SetValue(worldMatrix);
    currentEffect.Parameters["xView"].SetValue(viewMatrix);

    currentEffect.Parameters["xProjection"].SetValue(projectionMatrix);

    currentEffect.Parameters["xTexture"].SetValue(skyboxTextures[i++]);
  }
  mesh.Draw();
}

Zu den Effekte die in diesem Codefragment benutzt werden kommen wir später noch.

Hier entstand allerdings bereits ein Problem, mit dem wir klarkommen mussten: Unsere sechs Grafiken für die Skybox, die wir mit Hilfe von GIMP hergerichtet hatten, sahen in den Überschneidungsgebieten, also Ecken und Kanten zu den anliegenden Grafiken, nicht gut aus. Man sah jede Kante und spitzzulaufende Ecke.

Somit mussten wir unser Konzept, dass wir wirklich das Schiff in der Skybox bewegen, nochmal umkrempeln. Anstatt die Skybox „festzuhalten“ und das Schiff in ihr zu bewegen, haben wir es genau andersherum gemacht. Das Schiff ist immer an derselben Position, auch wenn man meint, man fliegt in eine Richtung. Wir bewegen alles um das Schiff herum. Somit sind wir der Problematik, eine dynamisch erweiternde Skybox zu bauen, direkt aus dem Weg gegangen. Man muss gestehen, wirklich schön ist diese Lösung nicht, aber praktikabel bei unserem kleinen Projekt.

Allerdings war das leider noch nicht alles. Eine weitere Implementierung muss man noch vornehmen, um diese schöne Weltraumansicht genießen zu können. Die Grafiken müssen natürlich noch irgendwie an die Skybox geklebt werden. Das Ganze machen wir über unsere „Skybox.x“ (Auszug im Anhang). Hier muss man seine 6 Skyboxgrafiken noch in die MeshMaterialList reinbasteln.

Eigentlich war es das dann auch schon. Eigentlich: Wir hatten herausgefunden, dass XNA einen Shader benötigt um Dreiecke zu zeichnen. Sprich: Ohne einen Effekt, kein Bild. Wir haben uns dazu einen BasicShader besorgt und somit nicht nur unsere Dreiecke gezeichnet, sondern auch ein DefaultLightening gewonnen.

Codefragment 2: Implementierung des Shaders

effect = Content.Load<Effect>("effects");

Dieser Einzeiler reicht schon, um den Effekt zur Verfügung zu stellen.
Je nach Anforderung muss man nun noch die entsprechenden Funktionen aufrufen, um die Effekte anzuwenden. Für das DefaultLightening muss man nur die gleichnamige Funktion aufrufen:

Codefragment 3:

effect.EnableDefaultLighting();

Im Codefragment 1 werden vier Effektparameter und eine Effekttechnik verwendet. Diese sind soweit selbsterklärend, sodass die Technik, mit der wir unsere Welt darstellen, auf Texturen basieren. Es gibt auch noch weitere Techniken, die der Shader bereitstellt, zum Beispiel pretransformed, colored, Pointsprites und andere, mit denen wir uns aber nicht weiter auseinandergesetzt haben. Die Parameter, die wir dem Effekt zuweisen sind auch soweit logisch. Wir müssen unserem Effekt natürlich mitteilen, auf welche projektionsMatrix, viewMatrix, worldMatrix und welche Textur er sich bezieht. Somit wird der Effekt auf jedes Bild/Textur, dass durch die foreach-Schleife im Codefragment 1 gezogen wird, angewendet.

Quellen:

Verfasst von: bletra | 5. Juli 2011

WPF: DataSet und DataGrid

Nachdem ich mit mit WPF und MVVM beschäftigt habe, stellte sich mir die Frage, wie ein ViewModel mit einem DataGrid kommuniziert. Zunächst experimentierte ich mit INotifyPropertyChanged. Doch hat folgende Überlegung gewonnen, die auch noch leichter zu implementieren ist: Es sollen nicht alle Änderungen sofort in die Datenbank weggeschrieben werden, denn das ist doch gerade der Clou eines verbindungslosen Datenobjekts (DataSet), die Benutzer sollen alle Änderungen in Ruhe durchführen und auf Knopfdruck werden diese auf einen Schlag in die Datenbank geschrieben.

Jetzt musste ich nur noch rausfinden, dass als zu bindendes Objekt DataView deutlich besser geeignet ist, als das DataSet selbst und folgender Code läuft wunderbar:

//MainWindow.cs
InitializeComponent();
DataContext = new DBViewModel();

//DBViewModel.cs
class DBViewModel
{
  private const string CONN_STRING = @"Server=localhost;Database=SQLLectureDemo;Uid=demo;Pwd=geheim;";
  private const string SELECT_SQL = "SELECT Id, Name, Birthday, Matrikel FROM Student";
  private ICommand _saveCmd;
  private DataSet _students;

  public DBViewModel()
  {
    _students = ReadDataIntoDataSet();
    _saveCmd = new DelegateCommand((param) => SaveDataSetChangesToDb());
  }

  public DataView Students
  {
    get { return _students.Tables[0].DefaultView; }
  }

  public ICommand SaveCmd
  {
    get { return _saveCmd; }
  }

  private static DataSet ReadDataIntoDataSet()
  {
    DataSet myDataSet;
    using (MySqlConnection conn = new MySqlConnection(CONN_STRING))
    {
      conn.Open();
      MySqlCommand cmd = new MySqlCommand(SELECT_SQL, conn); //fetches primary key, as needed by commandbuilder
      MySqlDataAdapter myMySqlDataAdapter = new MySqlDataAdapter(cmd);
      myDataSet = new DataSet(); //disconnected storage
      myMySqlDataAdapter.Fill(myDataSet, "Student");
      myMySqlDataAdapter.Dispose(); //not needed any longer!
      conn.Close();
    }
    return myDataSet;
  }

  private void SaveDataSetChangesToDb()
  {
    using (MySqlConnection conn = new MySqlConnection(CONN_STRING))
    {
      conn.Open();
      MySqlCommand cmd = new MySqlCommand(SELECT_SQL, conn);
      MySqlDataAdapter da = new MySqlDataAdapter(cmd); //select cmd as used to fill the dataset!
      MySqlCommandBuilder builder = new MySqlCommandBuilder(da); //needed to build the commands
      da.Update(_students, "Student");
      conn.Close();
    }
  }
}

Mit MainWindow.xaml:

<DataGrid  Height ="250" HorizontalAlignment="Stretch" Margin="0"  AutoGenerateColumns="True"  ItemsSource="{Binding Path=Students}"  Name="dataGrid"  AlternatingRowBackground="#FF1ACE1A" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" />
<Button Name="btnSave" Content="write changes to database" Command="{Binding Path=SaveCmd}" />

Dabei verwende ich die in Artikel „WPF: Von Spaghetticode zu MVVM – Teil 5 von 9“ eingeführte Klasse DelegateCommand.

Das Beispiel greift auf eine MySql-Datenbank zu. Wenn Sie den ConnectionString anpassen und bei den DB-Klassen anstelle des Prefixes MySql nur das Prefix Sql verwenden, so funktioniert das Beispiel auch für den Sql-Server von Microsoft.

Verfasst von: bletra | 29. Juni 2011

C#, XNA: Kostenloses eBook

Wer eine ausführliche und gut aufgebaute Einführung in XNA sucht, der sollte sich folgendes kostenloses eBook von Rob Miles anschauen: Introduction to Programming Through Game Development Using Microsoft XNA Game Studio

Dieses Buch ist ebenfalls dazu geeignet, sich über Spiele in C# und Visual Studio 2010 einzuarbeiten. Jedes Kapitel schließt mit w/f-Fragen ab, deren Lösungen (mit Begründungen) am Buchende zu finden sind. Das Buch ist in drei Abschnitte gegliedert:

  1. Getting started
  2. Images, Sound and Text
  3. Writing proper games (including multiplayer network games!)

Der Autor schreibt, dass das Buch zum Lernen von C# und objektorientierter Programmierung geeignet sei. Nach meiner Einschätzung wird dieses Ziel nicht erreicht.

Verfasst von: bletra | 24. Juni 2011

GameComponents in XNA

Autoren: Daniel Träder und Sebastian Koralewski

Bei der Entwicklung eines XNA-Spiels  sind von Entwicklungsstufe zu Entwicklungsstufe immer mehr Objekte zu zeichnen. Diese alle in einer Klasse zu verwirklichen führt  dazu, dass diese schnell unübersichtlich wird. Um dieses Problem modular zu lösen stellt XNA die sogenannten „GameComponent“s zu Verfügung.  Damit lässt sich beispielsweise die Hintergrundkarte unseres Autorennspiels verwirklichen.

public class MapComponent : Microsoft.Xna.Framework.GameComponent
{
  public MapComponent(Game game) : base(game)
  {
  }

  public override void Initialize()
  {
    base.Initialize();
  }

  public override void Update(GameTime gameTime)
  {
    base.Update(gameTime);
  }
}

Die Funktionen von GameComponents werden automatisch zur passenden Zeit vom XNA Framework aufgerufen, sobald man sie zu einer Collection von Components hinzugefügt hat.

GameComponents realisieren das Initialisieren und das Updaten einer Komponente. Um eine Komponente periodisch mitzeichnen zu lassen, ist das Interface DrawableGameComponent zu verwenden. Dieses erweitert die Klasse um die Funktionen

– Draw(),
– LoadContent(),
– UnloadContent().

Um nun verschiedene Karten benutzen zu können, wird der Konstruktor um einen Identifier erweitert, welcher in der Funktion „LoadContent“ genutzt wird, um die Textur der Karte zu laden. In der Funktion „Draw“ wir die Karte anschließend gezeichnet.

public class MapComponent : Microsoft.Xna.Framework.DrawableGameComponent
{
  public MapComponent(Game game, string mapIdentifier)
    : base(game)
  {
  }

  public override void Initialize()
  {
    base.Initialize();
  }

  protected override void LoadContent()
  {
    _spriteBatch = new SpriteBatch(base.Game.GraphicsDevice);
    _map = base.Game.Content.Load<Texture2D>(_mapId);
  }

  protected override void UnloadContent()
  {
  }

  public override void Update(GameTime gameTime)
  {
  }

  public override void Draw(GameTime gameTime)
  {
    _spriteBatch.Begin();
    _spriteBatch.Draw(_map, new Vector2(0, 0), _map.Bounds, Color.White, 0f, new Vector2(0, 0), 1f, SpriteEffects.None, 1f);
    _spriteBatch.End();
  }
}

Um diese GameComponent nun in der Hauptklasse des Spieles einzufügen muss folgendes getan werden:

MapComponent map;
public Game1()
{
  map = new MapComponent(this, „PFAD/ZUR/BILD_RESSOURCE “);
  Components.Add(map);
}

Das war alles, den Rest erledigt XNA automatisch.

Ein gutes Tutorial zu XNA-GameComponet findet man unter: http://www.xnamag.de/article.php?aid=16

Verfasst von: bletra | 23. Juni 2011

Schnelleinstieg: Crystal Reports

Autoren: 2 Studierende der Veranstaltung .Net Framework und C#

Ein nützliches Mittel, um Berichte aus verschiedenen Datenquellen zu erstellen, ist Crystal Reports. Als Datenquelle kann man hier verschiedene Datenquellen angeben.  Es ist dann ebenfalls möglich, aus dieser Datenquelle nur eine bestimmte Menge beziehungsweise bestimmte Daten anzeigen zu lassen. In unserem Fall ist die Datenquelle eine SQL-Datenbank. Eine Möglichkeit, diese Daten darzustellen, besteht darin, zuerst die Daten mittels SqlDataAdapter in ein DataSet zu schreiben und dieses anschließend als XML-Datei abzuspeichern. Danach fügt man zu dem Projekt einen Crystal-Report hinzu und wählt als Quelle diese XML-Datei aus, welche diesem Bericht als Struktur dient. Um nun einen Bericht im CrystalReportViewer anzeigen zu können, erstellt man erst einmal ein ReportDocument und ein DataSet:

ReportDocument report = new ReportDocument();
DataSet myDataSet = new DataSet();

Dieses DataSet befüllt man wieder mit einem SqlDataAdapter und lädt dann den CrystalReport und setzt die Datenquelle:

report.Load(@"CCrystalReport1.rpt");
report.SetDataSource(myDataSet);
crystalReportViewer1.ReportSource = report;

« Newer Posts - Older Posts »

Kategorien