Category: Programmierung

OpenCL und OpenGL

author | 6. August 2011

Für diejenigen, die es interessiert: Ich habe einen Artikel über Interaktionsmöglichkeiten zwischen OpenCL und OpenGL geschrieben.

In jungen Jahren programmieren…

author | 6. Februar 2009

Ich plädiere ja eh’ dafür, dass schon in jüngsten Jahren neben den menschlichen Fremdsprachen auch Programmiersprachen beigebracht werden. Dass es machbar ist, beweist ein 9-jähriger singaporischer Schüler, der in der vierten Klasse bereits sechs Programmiersprachen versteht und bereits 20 Programmierprojekte hinter sich hat. Vornehmlich scheint er für den IPhone zu programmieren:

Lim, who is in fourth grade, writes applications for Apple’s popular iPhone. His latest, a painting program called Doodle Kids, has been downloaded over 4,000 times from Apple’s iTunes store in two weeks, the New Paper reported on Thursday.

The program lets iPhone users draw with their fingers by touching the iPhone’s touch screen and then clear the screen by shaking the phone.

“I wrote the program for my younger sisters, who like to draw,” Lim said. His sisters are aged 3 and 5.

wp-stattraq in wordpress 2.6 – kompatibler Version

author | 11. August 2008

Bislang stand unter der wordpress Kompatibitätsliste bei Stattraq:

Stattraq 1.1.1 – Has problems with the changed cookie/login system.

Stattraq ist eines der aussagekräftigsten und detailliertesten Statistik-Plugins für WordPress. Leider ist es schon in die Tage gekommen, seitdem Randy es zuerst herausgab. Langer Rede kurzer Sinn: ich habe das Plugin nun übernommen und als erstes in einen Zustand versetzt, in dem es mit wordpress 2.6 lauffähig ist und zwar unter der normalen Administrationsoberfläche von wordpress1.

Mehr erfahrt ihr hier, hier und hier.

Das ist damit mein erstes öffentliches wordpress-plugin.

  1. bislang hat es eine vollkommene Oberfläche genutzt[]

Beitragsversionen ab WordPress 2.6

author | 23. Mai 2008

Wer hätte das gedacht? WordPress 2.6 soll Beitragsversionen verwalten, so dass man Änderungen (bei Gruppenschreiben ganz wichtig) nachverfolgen und gegebenenfalls diese rückgängig machen kann. Die Besprechung dazu fand vor allem im Ticket 6775 statt. Cool, demnächst kann man mit wordpress nicht nur full-fledged cms Applikationen ersetzen, sondern auch gängige wikis! [via]

Dragonfly: Opera’s Antwort auf Firebug

author | 7. Mai 2008

Opera hat die erste Alpha der Debug-Werkstatt Dragonfly herausgebracht. Obwohl der Browser Opera noch immer ein closed-source Projekt ist, wird Dragonfly unter der BSD-Lizenz veröffentlicht.

Opera pitches Dragonfly as a tool for debugging web pages and web applications. Its feature set includes a JavaScript error console and command line, a debugger, and CSS and DOM inspectors. The current release (out today, and requiring Opera 9.5 beta 2) is an alpha, but they’ve announced planned improvements for the future. Notably, write access to CSS and DOM properties is still to come, as well as support for non-desktop versions of Opera.

Noch reicht die Funktionalität nicht an die von Firebug, aber das soll noch kommen..

The initial alpha release is just the beginning. Opera Dragonfly has a fully featured road map, including support for editing of CSS, JavaScript and the DOM, a single window mode, improved JavaScript thread handling, XHR and HTTP monitoring, improved keyboard navigation, and translation into a number of languages.

WordPress 2.5.1 Test

author | 1. Mai 2008

Dies ist nur ein Post, um zu testen, ob die neue 2.5.1-Version von WordPress auch wirklich funktioniert. Ich hatte zu 2.5 einen patch eingereicht, das nicht bearbeitet wurde und nun will ich wissen, ob der Fehler beim Fix anderweitig behoben wurde..

void gosleep(date time, bool havework)

author | 25. Februar 2008

[cpp]
{
if (havework && time->hour > 25) {
if (self->cantsleep){
// TODO: implement algorithm for forcesleep()
}else {
shutdown();
}
}
}
[/cpp]

script-fu: exporting the same region for different layers

author | 31. Januar 2008

Intro

Gimp offers the ability to run scripts and by that create, manipulate and save images automatically. The language used normally is script-fu, though one could also use perl or (more commonly) python.

In my current project, I have to take pictures of different samples which are partly manipulated (using surface processing). In those pictures I’m mostly interested in three regions:

  • the reflection of light on an untreated surface,
  • the reflection of light on a treated surface,
  • the histogram of the image.

A sample image that i took looks like this:

Sample image for script-fu

The regions I’m interested in are as follows:

rund_1_16_markiert.jpg

I took about 30 pictures (with more to come) and i needed an automated method to copy those regions and save them as new images with an appropriate filename.

Read more »

Successfull at building Blender3d

author | 21. Dezember 2007

Phew! At last i was able to build and even modify the blender sources. I need to do that for my current project:

I’m trying to Simulate different BRDF-models for my research using the render engine of blender. It was easy to find the source code locations, where i had to change it, but the hard part was to get the blender source code compiled..

I tried following the guides that are given at blender.org, i downloaded all needed software, libraries and documentations, even tried changing the code on my own, when an error was shown. Mainly i tried compiling the code with cygwin and visual studio and although there are project files specially for visual studio, i couldn’t succeed at building the project.

Then – just before giving up completely – i decided to try to contact the ‘elders’ and describe my problem. The easiest way was to get into the irc-channel. I thought #blendercompilers would be the right place to ask this sort of question, but unfortunately nobody was really active at that channel. Then At #blendercoders someone pointed me to this guide. The guide uses mingw and – to my surprise – it works .. flawlessly!

So, at last i’m getting to the fun part: writing my own shader!

Online Bibliography

author | 12. Dezember 2007

Ever been looking for a system to manage your list of literature? Well, only think about the time needed to write a thesis, a paper or any other publication. Most of the time, you’re searching for “that paper”, you’ve just read some months or even years ago.. Then, you’d like to have the documents that your predecessor used when he wrote his thesis. Or sometimes you could simply profit from the collection of papers your colleagues have prepared.

Well, since I began working at a university institute, I’ve had to collect quiet some papers and was looking for the best solution to archive them. One way would certainly be to print them out and put them into a folder. This has some disadvantages:

  1. The documents can’t be searched through easily.
  2. Ever tried to extract bibliography information from a paper? Well i have (for a friend) and think, it’s the most underpaid job one could do and one that could be substituted, when one collects that information right from the beginning..
  3. Ever heard of the coffee-cup-syndrome? Printed documents get dirty with time.

Just recently did I find out about Aigaion.

Both for individual researchers as for research groups or projects, it is of major importance to organize the literature one has read. A well organized bibliography is a powerful instrument. It speeds up the search for publications one has already read and supports the user in structuring information. Aigaion provides a bibliography management environment that supports a user in just this: Organizing and managing a complete bibliography, from small bibliographies to bibliographies for a complete research department.

The system makes it easy to collect and categorize published articles. The easiest way to import a document into the aigaion-system is to import the bibtex-code associated with the document. Then one can attach as many files as necessary and assign one of those files to be the main document.

Aigaion supports the export of bibtex-code for all documents, a specific category or a set of bookmarked documents. It also allows for basic user management and the linking of external references. It’s written in php and needs a mysql-database to run. So nearly any webhosting account or private computer can host the package.

The latest alpha-version (2.0) is not published yet (but i can confirm, that it works just fine). It can be obtained by writing an email to the project-maintainer: reidsma <overat> users <subdomainof> sourceforge.net. For a quick test of the system, you may either try the demo-application or you may download the latest stable version: Aigaion 1.3.4.

SharpDevelop 2.1

author | 2. April 2007

The latest version of SharpDevelop was released nearly a month ago bringing with it some nice features i’ve been waiting for. My main interest is the support of the Compact Framework.

Anyone trying to develop .net-applications will normally start off by using Microsoft’s free (but stripped down) IDE MS Visual Studio Express. Initially I was astonished to hear that Microsoft released the Express edition even for commercial use (!!) without many strings attached.

Later, once i found out about SharpDevelop I was looking for a method to develop applications for my pda-like xda. Unfortunately Microsoft has reserved Compact Framework support for professional users of Visual Studio. Now with the release of SharpDevelop 2.1 it’s possible to create applications for use in Microsoft’s Windows Mobile platform.

Structures in vb.net and c#

author | 22. März 2007

Ever since i ‘discovered’ how to use structures in vb.net, I’ve been fascinated by the abilities they give to developers. Structures are sort of mini-classes, that can have properties and methods. Take for example the following structure:

[vbnet]
Structure measurement
Dim startdate As DateTime
Dim enddate As DateTime
Dim heattemp As Double
Dim heattime As Double
Dim overalltime As Double
Dim title As String
End Structure
[/vbnet]

It describes a complete measurement-cycle of a heating device. The syntax for using structures is as simple as it gets:

[vbnet]
Dim meas As new measurement
meas.title = “hallo”
[/vbnet]

Next, it’ll need some measurement points. I’ll just create a new structure

[vbnet]
Structure measpoint
Dim time as DateTime
Dim tempt1 As Double
Dim tempt2 As Double
Dim tempb1 As Double
Dim tempb2 As Double
Dim volt As Double
Dim currt As Double
End Structure
[/vbnet]

This structure describes exactly one measurement point. In it we find the current time stamp, four temperature values, a current and a voltage value. Every measurements has an undefined number of measurement-points. To include them into the main measurement-structure, we use an array:

[vbnet]
Structure measurement
Dim startdate As DateTime
Dim enddate As DateTime
Dim heattemp As Double
Dim heattime As Double
Dim overalltime As Double
Dim title As String
Dim mpoints() As measpoint
End Structure
[/vbnet]

Next, we’ll need some evaluation of measurement-values. To do that, we’ll include a method into the measurement-structure:

[vbnet]
Structure measurement
Dim startdate As DateTime
Dim enddate As DateTime
Dim heattemp As Double
Dim heattime As Double
Dim overalltime As Double
Dim title As String
Dim mpoints() As measpoint
Public Function lowestvolt() as double
Dim lv As Double
Dim i As Integer
lv=mpoints(0).volt
For i = 1 To mpoints.Length – 1
If lv>mpoints(i).volt Then
lv=mpoints(i).volt
End If
Next
lowestvolt=lv
End Function
End Structure
[/vbnet]

The method ‘lowestvolt’ iterates through mpoints and finds the lowest voltage. That’s it!

Using the free IDE sharpdevelop we can now translate the code into c#:

[csharp]
public struct measpoint
{
public DateTime time;
public double tempt1;
public double tempt2;
public double tempb1;
public double tempb2;
public double volt;
public double currt;
}
public struct measurement
{
public DateTime startdate;
public DateTime enddate;
public double heattemp;
public double heattime;
public double overalltime;
public measpoint[] mpoints;
public double lowestvolt()
{
double lv;
int i;
lv = mpoints(0).volt;
for (i = 1; i <= mpoints.Length - 1; i++) {
if (lv > mpoints(i).volt)
{
lv = mpoints(i).volt;
}
}
return lv;
}
}
[/csharp]

So, why still use classes, when there is something as nice as structures? Well, structures can have properties, methods and even constructors but the main difference to classes is that structures are sterile, they can’t inherit from other structures. Also, there are no private properties/methods in structures as there are in classes. Other than that, there is no major difference other that that structures are much easier to use.. Since I don’t really use inheritance much, structures are my first choice for organizing data.

Webmontag in Hannover

author | 4. März 2007

Morgen ist Webmontag im hannoverschen Viva. Da es das erst zum ersten Mal in Hannover gibt, bin ich recht gespannt, wie sich das entwickelt. Folgende Vorschläge für Vorträge wurden gemacht:

  • Vorstellung des WeblogCamp@CeBIT, Bjoern Negelmann
  • Microformats: eine kurze Einführung, Tobias Glawe
  • Vorstellung des Projekts feedbeat, Sascha Kluger
  • Vorstellung des T3N Magazins für Open Source, Webentwicklung und TYPO3, Andreas Lenz

Ich hoffe, es kommen auch so viele, wie sich angekündigt haben. Das ganze “steigt” ab 19:00 Uhr. Ich hoffe außerdem, dass ich dazu komme, später etwas darüber zu berichten isa.

Better “Related Posts” Plugin for Lightpress

author | 26. Februar 2007

The standard “Related Posts” plugin for lightpress tries to find posts that are posted under the same or nearly the same categories as the one currently viewed. The results are highly unsatisfactory.

I got the new sql-query from the “Related Posts” plugin for wordpress.

Download

Lightpress ‘Related Posts’ plugin

Installation

From the Lightpress root directory

  • Copy PostRelatedExt.php to plugins
  • Copy post_relatedext.xml to /themes/XXXX/YYYY/plugins/ (XXXX and YYYY correspond to current theme and lang-codification respectively
  • Activate the plugin from WP-Admin
  • Add {PLUGIN_POSTRELATED} at the appropiate place in your theme (either sidebar or directly beneath the post-content)
  • (optional but recommended) install the “Related Posts” wp-plugin from here (this plugin activates full-text index to columns post_name and post_content)

Have fun!

WordPress 2.1 “Ella”

author | 23. Januar 2007

Endlich und nach langer Probezeit ist WordPress 2.1 mit dem Namen “Ella” raus. Einige der meines Erachtens wichtigsten Neuerungen ist das automatische Speichern offener Beiträge, der vollständige Im- und Export via xml, ein asynchrones Laden der Dashboard-Seite und bessere Unterstützung internationaler Beiträge (vor allem rechts-nach-links Schriften).

Vor dem download sollte man unbedingt prüfen, ob alle verwendeten Plugins kompatibel sind, da sich so einiges an der Datenstruktur von wordpress geändert hat.

Ich selbst benutze seit einigen Tagen den RC2 der neusten WordPress-Version zusammen mit Lightpress. Dafür musst ich aber so einiges am plugin ändern. Wie ich bereits auf lightpress.org angekündigt habe, arbeite ich gerade an einem patch für Lightpress, um es auch unter wp2.1 zum Laufen zu kriegen.

Footnotes for lightpress

author | 22. Januar 2007

About

Since i changed to lightpress i’ve missed the old footnotes-plugin by Simon Elvery that i was using with the standard wordpress. So, here i present the (partly finished)1 port to a lightpress-plugin.

Installation

From LightPress root directory

  • Copy footnotes.php in /plugins
  • Copy footnotes.xml in /themes/XXXX/YYYY/plugins/ (XXXX and YYYY correspond to current theme and lang-codification respectively)
  • Activate the plugin from WP-Admin
  • To write a footnote, just add ‘ (_(This is the footnote)_)’ without the quotation marks or the underscores. That’s it! It will look like this: 2

Features

  • You can change both the hook and the appearance of a footnote in the plugin-management.
  • To change the look of the footnotes block you’d have to change the template ‘footnote.xml’
  • You can even change the position of the footnotes block. For example to put the footnotes in the sidebar:
    1. add { PLUGIN_FOOTNOTES } (without the spaces) to the sidebar at the desired position
    2. in the plugin management page, set ‘templateready’ to ’1′

Download

Footnotes plugin for lightpress 2.0.x

  1. this means that the support for paginated posts isn’t included and legacy/markup support neither[]
  2. This is the footnote[]

Konsum und Magie – Warum Rechner nie sicher sein werden!

author | 16. Januar 2007

Ich habe eben gerade etwa 3 Tonnen Wäsche gewaschen. Naja, ich hab die Wäsche machen lassen.. eigentlich habe ich sie nur in zwei Haufen geteilt, und nacheinander in die Waschmaschine und dann in den Trockner gestopft, ein paar Bedieneinheiten bedient und sie später wieder rausgeholt. Aber genau das ist doch das Beängstigende: Könnte ich auch die Wäsche waschen ohne automatische Waschmaschine und Trockner??

Nun gut, die Wäsche waschen, wird wahrscheinlich gerade noch gehen. Schließlich gehört dazu lediglich ein wenig Seife, warmes Wasser und sehr viel Arbeit. Es kann also nur an der eigenen Faulheit scheitern. Aber was ist mit anderen technischen Einrichtungen, die wir täglich benutzen?

Im Vorwort zum genialen Buch “Die Gelehrten der Scheibenwelt” führt Terry Pratchett folgende Zitate zusammen:

Jede hinreichend entwickelte Technik unterscheidet sich nicht mehr von Magie. Arthur C. Clarke

Jede Technik, die sich von Magie unterscheidet, ist nicht hinreichend entwickelt. Gregory Benford

Die Wahrheit ist deshalb soviel seltsamer als Fiktion, weil sie nicht konsistent sein muß. Mark Twain

Es gibt nirgends Schildkröten. Ponder Stibbons

Ich möchte mich nur auf die ersten zwei Zitate beziehen1.

Wieviel von dieser Welt für den Einzelnen von uns wie Magie erscheint, hängt sehr stark von der Bildung und zu einem nicht zu unterschätzenden Teil von persönlichem Engagement ab. Zweck der Bildung müsste also sein, die Magie hinter den Dingen, die uns begegnen und mit denen wir tagtäglich arbeiten müssen (weil sie eben zum modernen Leben dazugehören) zu entschleiern und damit die Mittel an die Hand zu geben, weitere Magie zu erfinden.

Schaut man sich aber die Allgemeinheit an, wird schnell klar: Wir kommen nicht mehr hinterher! Aus der Schule ins Leben entlassene Schüler wissen heute im Allgemeinen immer noch nicht viel über Computer – die sie bereits mit 8 ausgiebig benutzen. Sie wissen, wie sie Applikationen installieren, wie sie sie ausführen und natürlich fällt die Bedienung von Maus und Tastatur fast schon intuituv – fast, wenn man sich die Einfinger-Tipper anschaut. Aber was ist mit dem tieferen Einblick?? Kümmert sich heute noch jemand darum, Treiber auszuprobieren und möglicherweise herauszufinden, warum ein bestimmter Treiber nicht funktioniert, während der andere funktioniert? Schaut sich jemand die Prozessliste an und weiß, was ihn da aus dem Monitor angrinst? Wie viele kennen sich mit dem Innenleben ihres Rechners aus oder wissen zumindest zwischen Grafikkarte und Netzwerkkarte zu unterscheiden oder können die Batterie des Mainboards identifizieren?

Unwissen

Bei den meisten Rechnern, die ich zur Wartung2 von Bekannten bekomme, schaue ich mir spaßeshalber zuerst die Prozessliste an, nur um festzustellen, dass sie bei Neustart des Rechners aus mehr als 50(!) Prozessen besteht. Wenn ich den Besitzer frage, ob er wisse, was da eigentlich alles läuft, wird fast immer verneint. Unter den ausgeführten Prozessen mischen sich immer wieder mal – wie könnte es anders sein – Malware (und nicht zuletzt auch Viren), die irgendwo im Internet aufgegriffen wurde.

Zwar laufen inzwischen auf fast allen Computern irgendwelche Anti-Virus- und Firewall-Applikationen, aber es hat sich in meinen Augen gezeigt, dass sie die Einschleusung von Malware nicht verhindern können, da der Fehler durch willentliches Ausführen von Applikationen entsteht. Viren können meist – wenn sie denn entdeckt werden – trotzdem gestoppt werden, aber das hindert keine Applikation daran, ein “format c” oder ein “del *.*” auszuführen – oder eben Daten zu verändern und damit kaputtzumachen.

In einer technisierten Welt ist jedes Individuum Magier und trotzdem gibt es für jeden eine Menge Magie, die er nicht versteht!

Omar Abo-Namous

Solange der Benutzer keine Ahnung von den Konsequenzen seiner Bedienung hat, wird die beste Antivirensoftware und das beste Betriebssystem eine Fehlbedienung nicht ausschliessen oder einen derartig verursachten Fehler abfangen können.

Auf diese Ebene beschränkt sich aber das Unwissen keineswegs. Schaut man sich Programmierer an, so merkt man auch schnell, dass der Trend zum “Weniger-Wissen(C)” immer mehr Einzug hält. Letztens habe ich mit einem (studierten) Java-Programmierer diskutiert und ich hatte bemängelt, dass Java-Applikationen durch die große Interpretations- und Ausführungsschicht sehr langsam liefen. Er gab das zwar zu, sagte aber, er finde Java trotzdem ideal, da er sich als Programmierer nicht mehr um die Unterschiede zwischen den verschiedenen Betriebssystemen kümmern müsste. Das ist zwar richtig und im Einzelfall muss man immer abwägen, was für einen wichtiger ist, aber allein eine solche Einstellung eines Programmierers fand ich komisch!

Inzwischen ist nämlich eine Programmierung mit C++ auch plattformunabhängig möglich, nur dass man dann darauf achten muss, spezielle Bibliotheken zu benutzen, die für die verschiedenen Plattformen existieren. Damit gibt man sich aber die Freiheit, im Zweifelsfall eine Bibliothek neu zu schreiben, um sie an die eigenen Bedürfnisse (eben weniger allgemein, dafür aber etwas schneller) anzupassen. Und was sollte so schlimm daran sein, das eigene Programm in verschiedenen Programmiersprachen für verschiedene Plattformen zu schreiben? Auch wenn das länger dauert, es ist in den meisten Fällen leistungsfähiger.

Training

Wir werden tatsächlich darauf trainiert, das Einfachste zu verwenden und uns so wenig wie möglich dafür zu interessieren, wie das Regelwerk dahinter funktioniert. Das ist nicht zuletzt dem populärsten Betriebssystem derzeit Windows, aber auch solchen Gadgets wie iPod oder Handy zu verdanken. Einfachheit ist – verständlicherweise – besser; das fordert schließlich der Kunde. Der Kunde, der sich die Finger nicht dreckig machen möchte und der sich auch zunehmend keinen Kopf darum machen möchte, wie er eigentlich von einem Tag zum nächsten, geschweige denn von einem Ort zum nächsten. Einsteigen und Abfahren!

“Einfache Bedienung” ist das große Stichwort bei der Erstellung von Applikationen und ein Entscheidungsmerkmal ohne gleichen. Dass wir uns damit aber als Konsumenten selbst in den Fuß schießen, wird uns nur bewusst, wenn wir mal frustriert vor einer Applikation sitzen, die nicht “machen will, was wir wollen”. Das ist das traurige Ergebnis der Wissensgesellschaft – und der Grund, weshalb die technischen Fortschritte nicht nützliche Tools sind, sondern zu Lebenserhaltungssystemen mutieren.

Wissensgesellschaft?

Wir können den Fortschritt nicht aufhalten und wir können auch nicht jeder alles Wissen sammeln – soviel ist klar. Aber ich frage mich langsam, ob wir uns überhaupt noch als “Wissensgesellschaft” bezeichnen können? Denn darin müsste das Streben nach Wissen höchste Priorität sein. Tatsache ist aber, dass es zwar sehr viel Wissen gibt, dieses aber zum größten Teil brach liegt, da es nicht genügend Menschen gibt, die es anwenden können oder wollen. Und das Streben nach Wissen wird bereits in der Schule – die zu einem Sozialisierungsinstrument verwest – auf eine sehr niedrige Prioritätsstufe gesetzt.

Unser Unwissen beschränkt sich natürlich nicht allein auf den Umgang mit Rechnern. Auf Anhieb wüsste ich persönlich nicht, wie ich Kakao-Pulver herstellen könnte!

Übrigens: Bei mir selbst läuft seit etwa fünf Jahren weder ein Antivirus-, noch eine Firewall-Software3. Wenn ich den Rechner frisch gestartet habe, laufen etwas mehr als 20 Prozesse, die meisten davon Systemprozesse. Der Rechner ist die meiste Zeit direkt (also nicht über einen Router) mit dem Internet verbunden – und zwar 24 Stunden am Tag und sieben Tage die Woche. In diesen fünf Jahren hat sich mein Rechner nur zwei Mal an einem Virus infiziert. Großartige Hackvorkommen kann ich nicht verzeichnen. Versuche kann es durchaus gegeben haben, aber von Erfolg gekrönt waren sie nicht. Soviel zur Theorie, dass jeder Rechner innerhalb von Minuten nach direktem Zugang zum Internet gehackt wird..

Es gibt nirgends Schildkröten. Ponder Stibbons

  1. vor allem, da das letzte Zitat nur Leuten verständlich wird, die die Scheibenwelt kennen[]
  2. “ich hab’ nichts gemacht, plötzlich hat er nicht mehr funktioniert!”[]
  3. die mit windowsxp mitgelieferte Firewall läuft auch nur zeitweise[]

Umwandeln von Real Media (rm) zu avi

author | 1. Oktober 2006

Weil ich fast endlos gesucht habe und keine schnelle Antwort auf meine Frage gefunden habe, wie man ein Real-Video in ein avi umwandelt, fasse ich eine schnelle und flexible Methode hier zusammen.

Man muss beachten, dass ich diverse Conversion-Programme bereits ausprobiert habe. Die meisten haben Ewigkeiten gebraucht und kein Programm hat das komplette Video (1:30 h lang) transformiert. Zu den Programmen, die ich ausprobiert habe, gehören:

  • Zweifull
  • Video Converter 3.0.0.1 (Unterstützung durch zango
  • Advanced Video Editor 3.0.0.0 (wollte erst gar nicht starten!)
  • SUPER 2006 (von eRightSoft)
  • Tinra und TinraGUI

Um es kurz und schmerzlos zu machen: Um das Video letztendlich zu konvertieren, habe ich avisynth installiert und eine avs-Datei erstellt mit folgendem Inhalt:

DirectShowSource(“C:\video.rm”, fps=29.97, convertfps=true)

Schon vorher hatte ich RealAlternative installiert. Dieses erlaubt es, Real Media Dateien abzuspielen, ohne Real-Software installieren zu müssen. Jedenfalls werden dabei directshow-Filter installiert, die AviSynth benutzen kann (mit der kurzen Zeile im Script).

Die avs-Datei kann man nun in VirtualDub öffnen und hat die Videodatei vorliegen, die man wie eine avi-Datei behandeln kann! Das wichtigste hierbei ist, dass etwaige Fehler in der rm-Datei im Normalfall dazu führen, dass normale Konvertierprogramme aussteigen und nicht die komplette Datei konvertieren. Bei VirtualDub kann man direkt an die Stelle springen, die man konvertiert haben möchte!

AviSynth

AviSynth-Scripts kann man im normalen Editor erstellen. Dazu sollte man allerdings entweder die Dokumentation aufgeschlagen haben oder oder ein Tutorial nachvollziehen. Für Avisynth stehen aber inzwischen einige Tools zur Verfügung, die bei der Erstellung der Scripts behilflich sind. Offizieller Editor ist AVSEdit. Er hilft mit der Syntaxmarkierung und einer nicht ganz so guten Autocomplete-Funktion (Strg-Leerzeichen drücken!).

Die Applikation AVE Visual Editor versucht eine grafische Oberfläche zum Scripting von AviSynth-Scripten zu liefern. Ich finde si zwar höchst interessant, allerdings habe ich nicht herausfinden können, wie man einzelne Filter wieder löscht..

Dynamic Sorting of HTML-tables via XSLT

author | 27. August 2006

[lplang lang="english"]

More than eight months ago – actually on newyear’s eve – i was sitting at my PC trying to find a solution to a question Ursula asked in wer-weiss-was1 about sorting data in HTML-tables without having to reconnect to the server. At the end of the night, i was able to make a suggestion in form of a XSL Transformation that was changed dynamically with a javascript function whenever the user selected a table header.

Looking back..

The suggested solution does work fine, but it has some flaws that make it rather hard to implement in a normal webdesign-case.

The most fatal problem about the solution was, that the data that had to be sorted would be loaded after the document was loaded. That way, someone running without javascript enabled, wouldn’t be able to see the document correctly. Also, search engines such as googlebot won’t be able to see any of the data presented.

Of course one could attach the table and delete it via javascript. This would mean that javascript-disabled clients would still be able to see the data and javascript-enabled clients would be able to dynamically sort the table. But this way one would load the data in the table twice. This could be a problem when one has to display a big table or if creating the table costs too much CPU-time on the server.

Another problem of the implementation is the inflexibility of the script. It is made exactly for the specific data and has to be changed for any other data resulting in a huge amount of coding required.

Alternative suggestion

In the latest iX-magazine there is an article about sorting HTML-tables via Javascript (Sept. 2006 | “Auf der Stelle: HTML-Tabellen mit Javascript sortieren”, p. 142). The author Christian Kirsch suggests saving all the data of a given table into an array and sorting it via array.sort(col) using the standard sorting algorithms of javascript.

In fact, he solves every problem i had with my implementation, but i still think, that it is more elegant to use XSL-Transformations, since they can be expanded to include filtering-capabilities which still can be implemented using normal javascript, but at the cost of huge code. Plus if one wants to sort by more than one column, the pure javascript-solution would be even bigger whereas the XSL-solution will only expand by one statement per sortcolumn or filter-criteria!

New Suggestion

Here’s my new suggestion: XSL-Sort for HTML-Tables

The basis of the implementation was a normal HTML-table. It has to be XHTML-compatible, as shown in the example below:

<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>Hans Jürgen</td>
</tr>
<tr>
<td>1</td>
<td>Otto Quatsch</td>
</tr>
</tbody>
</table>

Note that i’m using thead and tbody – elements! They are important or else i’d have to rewrite the table header every time i resort the table. Now to sort this markup-fragment i will use this xslt-file:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="tbody">
<html>
<body>
<table>
<tbody>
<xsl:for-each select="tr">
<xsl:sort select="td[1]" />
<tr>
<xsl:for-each select="td">
<td class="{@class}"><xsl:value-of select="current()" /></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

The select-statement in the sort-element is the one that has to be changed programatically depending on which column-header the user selects. For more explanation on the select-statement refer to this wonderful reference.

Coding

The code is pretty much straight forward, though it could be irritating because it’s not very well structured. To begin with, the engine searches for any table inside the document and then installs eventlisteners in every column head and marks the column heads with a non-standard attribute colnumber. This is the easiest way i found to know which column to sort on. This is done in install_sorters() and install_sorter(mytable) respectively.

The onclick-Event of every column header calls the function sortfor(). Here, the colnumber-attribute of the event target (some column header) is read and used to change the xsl-DOM. It needs to only change the element xsl:sort:

// sort for column #
var mysort = xslt.getElementsByTagNameNS(XSLNS, "sort").item(0);
mysort.setAttributeNS(null,"select","td["+colnumber+"]");
// Perhaps sort as number??
colclass=col.getAttributeNS(null,"class");
if (colclass.lastIndexOf('sorttypenumber')>-1)
mysort.setAttributeNS(null,"data-type","number");
else mysort.removeAttributeNS(null,"data-type");
// Alternating Sort order
sortorder="ascending";
if (table.getAttributeNS(null,"sortedfor")==colnumber) {
if (table.getAttributeNS(null,"sortorder")=="ascending")
sortorder="descending";
}
mysort.setAttributeNS(null,"order",sortorder);
// Now save the sort-parameters as attributes of table
table.setAttributeNS(null,"sortedfor",colnumber);
table.setAttributeNS(null,"sortorder",sortorder);

As can be seen in the last two lines, the script saves the sort-information as attributes in the table-element. This information is then used to determine which way to sort the next time the user selects a column header. Furthermore, it has to be able to differentiate between numeric and string columns, since sorting numbers as though they were strings would result in a weird row order. To determine the data-type of a specific column, the script reads the class-attribute of the column header. It expects that numeric columns are marked with the class “sorttypenumber”.

After that, there isn’t much to do: running the xsl-processor and replacing the old tbody-element with the sorted data.

// run the xslt-processor
processor.importStylesheet(xslt);
result = processor.transformToDocument(data.getElementsByTagName("tbody").item(0));
result=result.getElementsByTagName("tbody").item(0);
// and replace old data with sorted data.
var temp=table.getElementsByTagName("tbody").item(0);
table.replaceChild(result,temp);

Problems with Internet Explorer

As usual Microsoft has it’s own implementing theory that says:

Thou shall not be compatible!

I don’t want to get into details concerning the changes i had to make for the sake of Internet Explorer, but two points i’d like to mention:

  1. The eventlistener of the object window wasn’t willing to work. I tried the method attachEvent as well as simply assigning the event-function to the attribute onload. Both didn’t get me, where i wanted to be. But the attachEvent method can be set at the end of the main HTML-document. Strangely, not at the end of the javascript-file, which – logic would suggest – would be parsed after the main file..
  2. Replacing existing nodes with a string of xml-elements did seem to be rather easy, but it wasn’t, especially since i only need a fragment of the markup the xsl-processor outputs! I ended up running a regular expression search for the tbody-fragment inside the outerHTML-attribute of the online-table and replacing it with the xml-fragment from the processor. Just have a look at the code (around line 80) and you’ll see how much trouble i had inserting that small portion of markup.. If anyone has a better solution, please don’t hesitate to post a comment!

Conclusion

It is possible to have data, that is already loaded and parsed into the HTML-document resorted and – hopefully in the near future – filtered or otherwise manipulated without having to put too much into coding special-case functions. The script can easily be implemented into any existing page and make every table on that page sortable. At this time it requires the table to be xhtml-compatible and to have column headers. If some columns have to be sorted numerically, the script requires a special class to be given to the column header.

Of course, this script isn’t meant for badly designed sites where the element-placement is done via fake tables. It’s also not meant for tables with spanning cells (colspan or rowspan), since they will throw the xsl-transformation off-balance. Either way, it shouldn’t destroy any of the two cases, as long as they don’t employ table headers (and most don’t)..

Have fun and please do comment!

[/lplang]
[lplang lang="deutsch" default="default"]

Schon vor mehr als 8 Monaten habe ich mich mit der dynamischen Sortierung von HTML-Tabellen beschäftigt und einen Lösungsvorschlag gemacht, mit dem sich erreichen lässt, dass in einer Tabelle nach einem beliebigen Feld sortiert werden kann.

Die Grundidee besteht darin, die Tabellendaten als XML-Daten nachzuladen und durch eine XSL-Transformation laufen zu lassen, die letztere sortiert. Bei Anwahl einer Spaltenüberschrift wird ein Script ausgeführt, das die XSL-Anweisungen verändert und die Transformation erneut laufen lässt und die “alten” Daten mit den sortierten ersetzt.

Nachteile

Der grösste Nachteil der bisherigen Lösung ist die Abhängigkeit des Nutzers von Javascript. Bei abgeschaltetem Javascript ist die Tabelle – und damit die Daten – nicht zu sehen. Während das für den normalen Benutzer relativ erträglich ist, da die meisten Nutzer Javascript eingeschaltet haben, ist das für eine Suchmaschinenoptimierung kontraproduktiv, da Such-Bots wie googlebot keine Scripte ausführen und somit nicht die Daten in der Tabelle indexieren können.

Natürlich kann man die Daten als statische Tabelle im HTML einfügen und bei eingeschaltetem Javascript die xml-Daten nachladen, allerdings bedeutet das die doppelte Übertragungsmenge und kann bei grösseren Tabellen eine starke Verlangsamung der Seite zur Folge haben.

Weiterhin ist das Script nicht sehr flexibel, da es für eine spezielle Tabelle geschrieben ist und für andere neu geschrieben werden müsste. Das bedeutet widerum viel mehr code als vertretbar wäre..

Array-Alternative

In der neusten iX findet sich ein Artikel mit dem Titel “Auf der Stelle – HTML-Tabellen mit Javascript sortieren”, der dasselbe Problem bespricht und einen Vorschlag zur Lösung macht (Sept. 2006, S. 142). Der Author Christian Kirsch schlägt vor, die Daten einer beliebigen Tabelle komplett in ein Array einzulesen, darin mittels der Methode .sort(col) zu sortieren und danach wieder in die Tabelle zu schreiben.

Während dieser Vorschlag alle von mir angesprochenen Nachteile meines scripts löst – es ist nicht auf eine Tabelle bezogen und die Daten sind bei abgeschaltetem Javascript sichtbar – glaube ich, dass die Lösung im Vergleich nicht sehr elegant ist und möglicherweise langsamer als die xsl-gestützte Sortierung. Weiterhin ist es mittels xsl möglich das Script weiter aufzuwerten, um etwa nach bestimmten Suchkriterien zu filtern oder nach mehr als einer Spalte zu sortieren, während das mittels javascript zwar auch möglich, aber mit sehr komplexem code verbunden ist.

Neuer Ansatz

Hier ist mein neuer Vorschlag: XSL-Sort for HTML-Tables

Die Grundlage für die Umsetzung bildet eine standardmässige HTML-Tabelle, die über Spaltenüberschriften und xhtml-kompatibles tbody-Element verfügt.

<table>
<thead>
<tr>
<th>ID</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>4</td>
<td>Hans Jürgen</td>
</tr>
<tr>
<td>1</td>
<td>Otto Quatsch</td>
</tr>
</tbody>
</table>

Es bietet sich an, auch das thead-Element zu benutzen, um den Überschriften-Teil der Tabelle vom Datenteil syntaktisch zu trennen.

Um diesen Teil der Seite zu sortieren, kann man sich eines xsl-Fragments bedienen, wie er weiter unten aufgelistet ist:

<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="tbody">
<html>
<body>
<table>
<tbody>
<xsl:for-each select="tr">
<xsl:sort select="td[1]" />
<tr>
<xsl:for-each select="td">
<td class="{@class}"><xsl:value-of select="current()" /></td>
</xsl:for-each>
</tr>
</xsl:for-each>
</tbody>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Interessant ist hier die Benutzung der select-Anweisung im sort-Element. Das sort-Element bezweckt, dass die Daten nach dem Inhalt der ersten Spalte sortiert werden. Die Zahl in den eckigen Klammern gibt somit direkt die zu sortierende Spalte an. Für mehr Informationen zur sort-Anweisung, empfehle ich die folgende Seite: XPath Expression Syntax.

Javascript

Zu allererst muss dafür gesorgt werden, dass alle Spaltenüberschriften einen Eventlistener verpasst bekommt, der erst bei Selektierung dieser Überschrift die Sortierung einleitet. In den Funktionen install_sorters() und install_sorter() werden in allen Spaltenüberschriften in allen Tabellen diese Eventlisteners installiert und weiterhin über ein nicht-standard-Attribut colnumber die Spaltennummer übergeben, die für die Sortierung gebraucht wird.

Die onclick-Events der Spaltenüberschriften rufen die Funktion sortfor() auf. Darin wird das Attribut colnumber ermittelt und für die Manipulation der xsl-Transformation xsl:sort verwendet.

// Nach Spalte # sortieren
var mysort = xslt.getElementsByTagNameNS(XSLNS, "sort").item(0);
mysort.setAttributeNS(null,"select","td["+colnumber+"]");
// Als Zeichenfolge oder als Zahl sortieren?
colclass=col.getAttributeNS(null,"class");
if (colclass.lastIndexOf('sorttypenumber')>-1)
mysort.setAttributeNS(null,"data-type","number");
else mysort.removeAttributeNS(null,"data-type");
// Aufsteigend oder absteigend sortieren?
sortorder="ascending";
if (table.getAttributeNS(null,"sortedfor")==colnumber) {
if (table.getAttributeNS(null,"sortorder")=="ascending")
sortorder="descending";
}
mysort.setAttributeNS(null,"order",sortorder);
// Nun noch einige Sortier-Parameter in die zugehörige Tabelle speichern..
table.setAttributeNS(null,"sortedfor",colnumber);
table.setAttributeNS(null,"sortorder",sortorder);

Wie man den letzten zwei Zeilen ansehen kann, werden weitere zwei weitere Parameter in die DOM gespeichert. Beide dienen der Ermittlung bei der nächsten Selektion einer Spaltenüberschrift, in welche Richtung sortiert werden soll (absteigend oder ansteigend). Die Speicherung in Element-Attribut sichert eine gänzliche Abkoppelung des Scripts vom tatsächlichen HTML.

Weiterhin verwendet das Script das Klasse-Attribut der Spaltenüberschriften für die Ermittlung des Datentyps der Spalte. Wenn sich ein Eintrag “sorttypenumber” in der Klassenangabe wiederfindet, dann ist die Spalte numerisch zu sortieren!

Der Schluss bildet die Verarbeitung der xsl-Anweisungen und das Austauschen der “alten” Daten gegen die neu sortierten Daten. Beides findet sich ähnlich schon im letzten Vorschlag wieder.

// run the xslt-processor
processor.importStylesheet(xslt);
result = processor.transformToDocument(data.getElementsByTagName("tbody").item(0));
result=result.getElementsByTagName("tbody").item(0);
// and replace old data with sorted data.
var temp=table.getElementsByTagName("tbody").item(0);
table.replaceChild(result,temp);

Probleme mit dem Internet Explorer

Wie sooft braut sich Microsoft mit ihrer Nicht-Umsetzung von w3c-Vorgaben ihre eigene Suppe. Ich möchte nicht in die Details einsteigen, sondern nur zwei Punkte ansprechen:

  1. Der Eventlistener des Objekts window wollte partout sich nicht ordentlich setzen lassen. Ich habe es über attachEvent, sowie über die statische Vergabe des Attributs onload versucht – ohne Erfolg. Die attachEvent-Methode hat aber funktioniert, als ich sie ans Ende der HTML-Datei brachte. Der gesunde Menschenverstand sagt doch aber, dass die Javascript-Datei (die ja erst noch eingebunden werden müsste) später ausgeführt wird als Skripte in der HTML-Datei..
  2. Die Ersetzung der alten Nodes mit den sortierten Daten war im IE nicht so einfach wie ich annahm, besonders da ich nur einen Teil der von der xsl-Engine zurückgegebenen Zeichenfolge einbinden möchte. Für Lacher wird also meine eher eigenartige Lösung sorgen. Einfach mal um Zeile 80 herum schauen..

Schlussfolgerung

Es lassen sich bereits geladene und eingebundene Tabellen im nachinein ohne weitere Verbindung zum Server und ohne besonders angefertigte Funktionen neu sortieren und – hoffentlich in naher Zukunft- filtern oder anderweitig manipulieren. Das Skript lässt sich relativ leicht für andere Seiten verwenden und kann idealerweise durch einfache Einbindung und Beachten der Grundstrukturen dafür sorgen, dass alle Tabellen auf einer beliebigen Seite sortierbar werden.

Natürlich wird das Skript versagen, wenn es auf Seiten angewandt wird, die aus weit verschachtelten Tabellen als Designersatz bestehen. Auch wird die Sortierung von Tabellen mit zusammengefassten Zellen (über die Attribute colspan oder rowspan) nicht ohne weiteres funktionieren. Auf der anderen Seite sollten beide Sorten von Tabellen nicht weiter vom Skript zerstört werden, solange sie nicht über Spaltenüberschriften verfügen.

Viel Spass und bitte kommentieren..

[/lplang]

  1. roughly who-knows-what, a very nicely structured german internet forum[]

Warum ich nicht mit Flash arbeite

author | 9. Juni 2006

via Narfbase: Animator vs Animation

Animator vs. Animation (Flash)