Archiv für den Monat: April 2010

Erste Einsendeaufgabe ist zurück …

… und ich habe 100 von 100 Punkten.

Eine kleine Anmerkung vom Korrektor war dabei, ansonsten hieß ist überall “alles korrekt”.

Das sind dann schon mal die ersten 5 Bonuspunkte für die Klausur. Ich erwarte natürlich nicht, dass das bei allen EA’s so weitergeht, aber es motiviert einen schon mal.

Derzeit sitze ich an EA2 und muss noch die letzten beiden Aufgaben erledigen; dafür habe ich nun noch 4 Abende Zeit – heute eingerechnet.

FROM_UNIXTIME mit negativen Werten berechnen

Benutzt man die mySQL Funktion FROM_UNIXTIME mit negativen Werten, so gibt diese null zurück (zumindest ab einer Version nach 4.0.x).

Der Tip oder besser Workaround lautet: Berechnet das Datum dann doch bitte in der Anwendung, nicht in der Datenbank.

Ich bin generell kein Freund von Workarounds, da diese das Gefühl von “Hilfskrampe” hinterlassen. Also habe ich mal länger geforscht und bin dabei auf diese Sinnvolle Konstruktion gestoßen, die mir das gewünschte Datum korrekt zurückliefert. Das ganze kann man auch schön in mySQL auch mit DATE_FORMAT formatieren.

Im Prinzip ist es recht simpel: Ist das Feld positiv (inklusive 0), dann einfach die funktionierende Variante benutzen, ist es negativ, dann ausgehend vom UNIX_TIMESTAMP(0) via DATE_ADD in Sekundenschritten zurück gehen.

Der UNIX_TIMESTAMP steht in meinem Beispiel im Feld “geburtstag” und gibt entweder direkt den Wert zurück oder den umformatierten:

IF (geburtstag>=0,FROM_UNIXTIME(geburtstag),DATE_ADD(FROM_UNIXTIME(0),INTERVAL geburtstag SECOND) )

Ich hoffe, ich erspare auf diesem Weg dem ein oder anderen langes suchen.

Smarty und der dynamische Zugriff auf Arrays

Innerhalb einer Smarty {section} muss auf ein Array zugegriffen werden, allerdings mit dem Array-Index eines anderen Arrays. Abhängig von der Position der {section} kommt also immer ein anderer index.

Beispiel:

{section name=”num” loop=$data1}
  {$data1[num].ID}
{/section}

In {$data[num].ID} steht der Index des Arrays “data2”, auf den ich zugreifen möchte.

Allerdings, so ein Konstrukt funktioniert dann nicht:

{section name=”num” loop=$data1}
  {$data2.daten[$data1[num].ID]}
{/section}

{$data2.daten} ist wiederrum ein array und dort stehen dann die Daten drin. Leider funktioniert diese Methode nicht.

Nach kurzem und scharfen Nachdenken kam ich dann drauf, man setzt eine temporäre Smarty-Variable, abhängig vom Wert der {section} und das geht mit {assign}:

{section name=”num” loop=$data1}
{assign var=”meineID” value=$data1[num].ID}
  {$data2.daten[$meineID]}
{/section}

Gut zu wissen…

IE8 erkennt den CSS Child Selector nicht

Das Problem: In IE8 funktioniert der CSS Child Selektor > nicht. Warum auch immer. In den “Entwicklertools (F12)” wird im Reiter “Layout” eine “width” von 290px gezeigt, im Reiter “Format” steht ganz klar die “width” auf “500px !important;”.

Was nun?

Nach langer Suche die Lösung und zwar bei Microsoft direkt.

Note   Combinators are enabled only in standards-compliant mode (strict !DOCTYPE).

Quelle: http://msdn.microsoft.com/en-us/library/aa358819.aspx

Und in meinem Fall war es dann so, dass es eine alte “Debugausgabe” gab, die dann den IE8 wohl daran hinterte, den !DOCTYPE richtig zu erkennen. Somit wurden eben viele Funktionen deaktiviert, auch die Child Selektoren.

Debug ausgabe raus, !DOCTYPE rutscht in die erste Zeile, Ausgabe stimmt, alles okay.

POST Parameter in JavaScript benutzen

Nachdem der letzte Beitrag wohl etwas irreführend war, hier mal ein Bericht mit dem Ziel, POST Parameter in JavaScript zu benutzen.

Nachdem man ja GET-Parameter relativ leicht auslesen kann, will ich hier nur auf die POST-Parameter eingehen.

Zunächst einmal muss man beschreiben, was denn nun bei einem POST-Request passiert und warum man nicht einfach per JavaScript darauf zugreifen kann.

Ganz kurz: Per POST werden Daten vom Browser (Client) an den Webserver (Server) gesendet, wo diese dann ausgewertet werden können. Der Client “wartet” solange auf Antwort, bis der Server diese sendet. In der ganzen Zeit kann man mit “normalem” JavaScript nix anfangen, da der Client-Code ja noch gar nicht im Browser ist. Sendet der Server nun eine Antwort, so erhält der Browser einfach neue Parameter, ähnlich wie beim GET, nur sind die POST-Paramater nicht zugänglich, weil diese in dem Moment nirgendwo mehr gesetzt sind.
Soviel zur Basis.

“Und wie komme ich nun an die Parameter ran?”
Gute Frage und ebenso leicht zu beantworten. Den POST muss Serverseitig ja irgendeine Serverseitige Scriptsprache entgegennehmen (nehmen wir mal rein zufällig … ähm … PHP) und diese kann dann auf die Eingabe reagieren und eine neue Seite bauen.

Damit ich nun Clientseitig wieder die POST-Daten habe, muss ich mir von PHP aus die POST-Daten irgendwohin in die Antwort an den Browser schreiben, wo JavaScript auch was damit anfangen kann.

Beispiel, ein Kontaktformular (ganz simpel):

<form action="formular.php" method="POST">
<input name="meinname" type="text" />
<input name="senden" type="submit" value="absenden!" />
</form>

Wir möchten nun, nachdem das Formular abgesendet wurde, auf der Antwortseite eine alert-Box aufpoppen lassen, die “Danke, xyz” sagt (ist wirklich ein sehr einfaches Beispiel, oder?)

Okay, der Code für formular.php

<?php if (isset($_POST['meinname'])) { ?>
<script>
var derNameLautet = <?=$_POST['meinname']?>;
alert('Danke, ' + derNameLauetet);
</script>
<?php } ?>

So, nun wird, wenn ein POST vorliegt, der POST-Wert in eine JavaScript Variable geschrieben. Diese kann ich dann für vieles Benutzen, ich hoffe, das Prinzip ist klar.

Aber ich habe einen AJAX-POST, wie mache ich das denn da?
Noch einfacher, der AJAX-POST verlässt ja die Seite nicht, d.h. die Werte, die per POST gesendet wurden, liegen ja noch immer vor und können recht einfach weiterbenutzt werden.

So, diesmal sollte das ganze Prinzip klarer sein, warum ein Auslesen der POST-Variablen in JavaScript mittels

<script>
var meinePOSTVariable = POST[‘postVariable’];
</script>

schlicht nicht möglich ist.

Daten verteilt bearbeiten

Ich muss mal eine Lanze brechen für den Cloud-Computing Dienst Dropbox.

Meine Situation derzeit: Ich stehe früh auf (4:30 Uhr), wecke ab 6 die Kinder, bringe die bis halb 8 in den KiGa, versuche bis 8 auf der Arbeit zu sein (was nicht immer hundertprozentig funktioniert), arbeite dann und versuche, bis 16:30 wieder zu Hause zu sein, “Kinderdienst” bis die ins Bett gehen. Bis die dann schlafen und ruhe einkehrt, kann es schonmal 20 Uhr werden, dannach steht dann das Studium an, was dann schon bis Mitternacht gehen kann. Und am nächsten Tag wieder von vorn.

*puh* Da bleibt nicht viel Zeit, um vergessene Dinge zu beschaffen. Warum erzähle ich das?

Okay, jeder, der schonmal studiert hat oder studiert kennt das: Man hat permanent das Gefühl, was nicht gemacht zu haben. Oder man bekommt plötzlich die Erkenntnis, dass an der fertig bearbeiteten Einsendeaufgabe doch noch ein Fehler ist. Nur leider liegt die Datei zuhause auf dem Rechner, die Erkentnis kommt aber auf der Arbeit. Dumm. Oder?

Genau dafür habe ich Dropbox. Dieser Dienst bietet einem im Free-Account Modus 2 GB Platz im Netz, auf die man zugreifen kann. Besonderes “Schmankerl” ist das Desktop-Tool von Dropbox. Installiert man dieses, bekommt man ein “Dropzone” genanntes Verzeichnis und ein Tray-Icon (man merkt, ich arbeite auf Windows, das Tool gibt es aber auch für Mac und Linux). Legt man nun Dateien oder Ordner in diesem VZ ab, so synchronisiert das Programm diese automatisch mit meinem Account. Die neueste Fassung wird automatisch geladen.

Das ist toll, denn nun kann ich meine Einsendeaufgaben zuhause bearbeiten und speichern. Diese liegen in der Dropzone. Von der Arbeit aus kann ich diese abrufen, ändern und hochladen (am einfachsten natürlich auch via Dropzone) und bin immer auf dem aktuellsten Stand. Gleiches gilt für Quelltexte, die mensch im Info-Studium ja auch schreiben muss. Alles liegt auf vielen Rechnern, vor allem zentral “in der Cloud”.

Und auch, wenn mein INet mal nicht läuft, die Dateien selbst liegen ja auf meiner Festplatte, ich kann weitermachen. Es gibt durchaus auch Dienste, die stellen das ganze als Netzlaufwerk zur Verfügung, dieses wäre ohne INet nicht erreichbar – und das wäre in meinem Fall “tödlich”.

Also, auch wenn manch einer nun “Werbung” schreit: Ich finde Dropbox gut. Und wer möchte, bekommt bei der Anmeldung über meinen Link nochmal 250 MB mehr.

Dropbox Homepage: https://www.dropbox.com/referrals/NTE2MzgyNDk

Führungsnull in Excel aus CSV anzeigen

Viele kennen das Problem. Man hat eine CSV Datei, in dieser steht eine Postleitzahl oder eine Telefonnummer, die als erste Stelle eine 0 (Null) hat.

Öffnet man das nun in Excel, ist die Null weg.

Beispiel: Ein Kunde kommt aus Dresden, gibt als PLZ “01307” ein. Exportiert man das ganze dann als “kunden.csv” und doppelklickt es in Excel auf, so erscheint “1307”, was ja nicht ganz richtig ist. Excel ist einfach zu schlau…

Da wir aber klein, trotzig und unwürdig sind, möchten wir trotzdem die führende Null sehen; der Kunde übrigens auch. Da der Kunde König und Excel eh nur eingekauft ist, ist der Weg klar: Die Null muss her!

Wer lange sucht, der findet auch die tollsten Lösungswege. Nicht Excel muss sich an uns, vielmehr müssen wir uns an Excel anpassen; sprich: Nicht einfach per doppelklick öffnen, o nein, gefälligst per Import die Daten einholen und dann als Text formatieren.

Das kann es nicht sein, hier also der Weg des Programmierers!

Unser Vorteil ist, das Excel die Daten pro Spalte nicht nur importiert, sondern auch interpretiert, d.h. wir benutzen eine Funktion aus Excel, die dafür sorgt, dass die Daten korrekt dargestellt werden.

Diese heißt für unseren Zweck: VERKETTEN

Will man also diese Zeile richtig importieren:

“Max”;”01307”;”Dresden”

Dann muss man sowas schreiben:

“Max”;”=VERKETTEN(0;1;3;0;7)”;”Dresden”

Und da Programmierer erwiesenermaßen faul sind, werfe ich gleich mal eine PHP-Funktion dafür in die Runde. Die kann sicherlich noch optimiert werden, aber für’s erste genügt diese den Anforderungen:

function formatForExcel($text) 
{
   $excelText = '=VERKETTEN(';
   for($i=0; $i<strlen($text);$i++)
   {
     if ($i>0) {
       $excelText .= ';';
     }
     $excelText .= $text[$i];
   }   
   $excelText .= ')';
   return $excelText; 
}

Wird nun formatForExcel aufgerufen, dann werden die Daten entsprechend per “Verketten” abgelegt und dann in Excel richtig aufgerufen.