HP-42S mit Original-SkinOK, als ‚Fortgeschrittenen‘ würde ich mich im Bereich Mathematik nicht sehen. Absolut nicht. Ich kann nicht mal mehr schriftlich multiplizieren, geschweige denn dividieren. Aber dafür weiß ich wie man einen Taschenrechner bedient. Dachte ich… :-)

Bislang habe ich auf dem Computer immer gcalctool benutzt. Das ist übersichtlich und kann eigentlich alles was man so dauernd braucht. Zufällig habe ich vor ein paar Tagen einen Emulator für einen real existierenden Taschenrechner gefunden. Emulator? Für einen verdammten Taschenrechner?!? Ja, genau. Free42 heißt das dann.

Bei dem Vorbild handelt es sich um das Modell HP-42S, das wurde 1988 von Hewlett Packard vorgestellt und — ich glaube — bis 1994 gebaut. Das Ding findet man natürlich im Taschenrechner-Museum von HP, aber auch in der Wikipedia. Ein programmierbarer Taschenrechner, Umgekehrte polnische Notation, etwa 600 eingebaute Funktionen und 7200 Bytes Platz für eigene Programme. Ich weiß nicht warum, aber das hat mich irgendwie fasziniert. Und nicht nur mich: bei Online-Versteigerungen wird das Ding offenbar teilweise mit über 200 Euro gehandelt. Das ist deutlich mehr als der originale Verkaufspreis vor 15 Jahren, als man das noch im Laden kriegen konnte. Der lag soweit ich weiß bei 130 Dollar.

HP-42S PlatzsparenderWie sieht jetzt so ein Taschenrechner-Programm aus? Was kann man damit machen? Man kann damit eine ganze Menge tun, wie man schnell sieht wenn man sich ansieht was es an Beispielen im Netz gibt. Ich habe mir mal das Alternative Manual durchgelesen und losgespielt. Ein Beispiel muss her…

Das erste was ich benutzt habe ist die Solver-Funktion. Dabei programmiert man eine Funktion mit mehreren Unbekannten (z. B. das Ohmsche Gesetz: U=R*I) die man umgestellt hat so dass 0 rauskommt (also U-R*i=0). Dann kann man die Variablen der Reihe nach mit Werten belegen und den unbekannten berechnen lassen. Man gibt also Spannung und Strom an die für eine LED benötigt werden und kriegt direkt den Widerstand, ohne selbst zu rechnen. Oder Man gibt den gewünschten Strom und den Widerstand an und bekommt die Spannung an der das betrieben werden muss. Nett, aber trivial. Ein komplizierteres Beispiel muss her…

Die Aufgabenstellung habe ich aus einem Podcast ueber Leonhard Euler, allerdings habe ich als Laie wohl was falsch verstanden. Wahrscheinlich ging es um die Euler-Mascheroni-Konstante oder um das Basel-Problem, mein Programm ist vermutlich total uninteressant. Trotzdem taugt es als Beispiel. Die Aufgabe besteht darin, die Kehrwerte von ganzen Zahlen zu addieren. Also 1/1 + 1/2 + 1/3 + 1/4 und so weiter. Mittlerweile weiß ich, dass man das auch mit Logarithmen berechnen kann, aber wie angedeutet würde ich da von alleine nicht drauf kommen.

LBL "EULER"
STO 01
0
STO 02
RCL 01
LBL A
1/x
STO+ 02
RCL 01
1
-
STO 01
x>0?
GTO A
RCL 02

Das Programm arbeitet wie folgt:

  • aktuellen Wert des X-Registers (also die letzte eingegebene Zahl) in Speicher 01 sichern
  • 0 in Speicher 02 schreiben
  • Speicher 01 wieder herstellen
  • Sprungmarke A setzen
  • von der wiederhergestellten Zahl den Kehrwert bilden und zu Speicher 02 addieren
  • Speicher 01 wieder herstellen
  • 1 subtrahieren und den neuen Wert wieder in 01 speichern
  • wenn der Wert groesser 0 ist, nach A springen
  • ansonsten das Ergebnis aus Speicher 02 anzeigen

Also quasi folgendes, nur halt im Taschenrechner (und nicht nur fuer 100):

perl -e "$j=0;for($i=1;$i<=100;$i++){$j+=1/$i};print$j;

In einer Tabellenkalkulation habe ich das auch mal gemacht um die Werte zu kontrollieren, aber da kann man das (ohne wirklich zu programmieren) nur bis knapp ueber 60.000 machen, weil dann die Tabelle am Ende ist. Das Ergebnis fuer 999.999.999 ist 21,3004815013 (da hat der Taschenrechner aber auch eine Weile drauf rumgekaut).

Ich bin einfach mal weiter fasziniert, vielleicht konnte ich ja irgendwen anstecken… ;-)

Das erinnert mich daran warum ich die Sprache C nach Möglichkeit nur auf Mikrocontrollern benutze:

rschaten% cat array.c
#include <stdio .h>
int main(int argc, char **args) {
  char *string = "abc";
  printf("%c %c %cn", string[0], string[1], string[2]);
  printf("%c %c %cn", 0[string], 1[string], 2[string]);
  return 0;
}

rschaten% gcc -o array array.c

rschaten% ./array
a b c
a b c

rschaten%

Das habe ich aus dem Unix Haters Handbook, ich hätte nicht gedacht dass das wirklich funktioniert…

DOS und %ERRORLEVEL%, Teil 1Wie schon erwähnt muss ich mich bei der Arbeit mit Windows rumschlagen. Um Sehnenscheidenentzündungen vorzubeugen verschlägt es mich da bisweilen auch in die Kommandozeile. OK, das ist nicht der einzige Grund. Manchmal will man ja aus einem Skript (leider in diesem Fall kein Perl) heraus einfach mal ein system() aufrufen, und da muss man dann halt DOS-Kommandos absetzen.

Jetzt wollte ich etwas kluges basteln, das testet ob ich eine Datei (schreiben|lesen|löschen) kann. Auf anderen Systemen hätte ich dazu auf etwas in der Form

kommando; echo $?

gesetzt, die Ausgabe könnte ich parsen. Ein Kollege hat für DOS

kommando && echo ok || echo nein

vorgeschlagen, das sollte funktionieren. Prima, Exitcodes kann ich dann offenbar auswerten. Oder?

Um Vielleicht mehr Infos zu kriegen als (tut’s|tut’s nicht) versuche ich folgendes:

kommando & echo %ERRORLEVEL%

Und jetzt bin ich verwirrt (siehe Screenshot):

Das mit && funktioniert scheinbar, die Ausgabe von %ERRORLEVEL% bringt aber nicht sinnvolles? Was wird denn dann von && bzw. || ausgewertet? Und wie zur Hölle kriege ich den wirklichen Exit-Code?!?

DOS und %ERRORLEVEL%, Teil 2Nach etwas mehr Spielerei stelle ich fest, dass in einigen Konstellationen der %ERRORLEVEL% tatsächlich gesetzt wird. Leider immer ein Kommando zu spät, wie man am zweiten Screenshot erkennen kann. Komischerweise funktioniert das aber — wenn man da von ‚funktionieren‘ sprechen kann — auch nur bei Programmaufrufen.

echo > . & echo %ERRORLEVEL%

führt zwar jedes Mal zu einer Fehlermeldung, gibt aber trotzdem nur 0 aus…

Ich beschließe einfach erstmal, das nicht zu verstehen. Mein eigentliches Problem kann ich offenbar unter Windows nicht elegant lösen, also muss ich mir da was anderes ausdenken… :-(

Im Moment bin ich wie schon erwähnt dazu gezwungen, beruflich viel auf Windows zu machen. Leider knirscht es dabei an allen Ecken und Enden, wenn man wie gewohnt produktiv sein will. Eine Menge Werkzeuge fehlen einfach, mal eben schnell eine elegante Shell- oder Perl-Zeile abschicken geht nicht. Von ganzen Skripten ganz zu schweigen.

Klar gibt es mit Cygwin oder ActiveState auch die Möglichkeit, einen Werkzeugkasten auf Windows nachzuinstallieren. Aber das ist lästig, und das würde ich auch nicht auf hunderten produktiver Server bei meinem aktuellen Kunden machen wollen. Geschweige denn: dürfen.

Ich habe jetzt eine Lösung gefunden die zwar kein hundertprozentiger Ersatz für eine anständige Umgebung ist, aber die an einigen Stellen schon echt hilfreich war: PAR::Packer.

Auf meinem Arbeitsplatz habe ich ein ActiveState-Perl installiert, darin das genannte Modul. Jetzt kann ich beispielsweise folgendes eingeben:

pp -e "print time();"

Die Maschine kaut eine Weile auf dem Kommando rum und spuckt dann eine a.exe aus, die ab sofort den aktuellen Unix-Timestamp ausspuckt wenn man sie aufruft. Und das auch auf Systemen auf denen keine Perl-Umgebung installiert ist, man braucht also keine zusätzlichen DLLs oder so, nur die jeweilige EXE.

Leider ist es nicht so, dass pp das Kommando wirklich compiliert. Es ist vielmehr so, dass pp ein Archiv zusammenpackt in dem alles drin steckt was zur Ausführung des Befehls nötig ist. Die Ausgabe des entstehenden Executables ist zwar die gleiche, aber oben genanntes a.exe ist 1.844.011 Bytes groß und braucht auf meiner Kiste über eine Sekunde bevor sie wirklich ausgeführt wird. Klar, muss ja erst entpackt werden.

Die gute Nachricht ist, dass lediglich der Start so lange dauert. Das enthaltene Programm läuft — nach dem Entpacken — praktisch genauso schnell wie in einer ‚richtigen‘ Perl-Umgebung.

Wer es etwas schicker haben will kann übrigens auch direkt folgendes machen:

pp --output=timestamp.exe -e "print time();"

Und komplexe Skripte werden wie folgt gepackt:

pp --output=weltherrschaft.exe weltherrschaft.pl

Die Größe der entstehenden Datei steigt übrigens nicht derartig an dass für jede Zeile wieder 1,8MB dazu kommen. Ich habe hier ein Skript von 5.308 Bytes übersetzt, das EXE ist 2.493.292 Bytes groß. Immer noch eine Menge, aber für einen schnellen Hack ist das durchaus tauglich.

Ich bin im Moment dazu verdammt, mit Windows zu arbeiten. XP am Arbeitsplatz, und unter anderem Windows 2003 Server irgendwo im RZ. Das heißt: ich versuche, damit zu arbeiten. Geht aber viel zu oft nicht, weil das ein großer Haufen Scheiße ist. Stinkend. Irgendwie.

Ich habe mir Heute Nachmittag vorgenommen, das zu schreiben. Während ein Kollege (der im Gegensatz zu mir auch sonst freiwillig mit Windows hantiert) versucht, einen Windows-Server zu rebooten. Weil der Speicher voll gelaufen ist. Oder so. Geht nicht. Muss wohl jemand den Server samt Reset-Knopf suchen gehen…

Naja, mein Problem findet aber auf einem anderen Server statt, und auch lokal auf dem XP kann ich das reproduzieren:

Ich bin mit dem Explorer in einem Verzeichnis mit etwa 20 Textdateien (plain ASCII, Quelltexte). Ich öffne eine der Dateien, suche da nach einem String, finde den auch. Ich will wissen in welchen anderen Dateien der String noch vorkommt. Also Rechtsklick auf den Ordner, ‚Suchen…‘. Auf XP öffnet sich ein neues Fenster mit einem aufwändig animierten Hund. Auf dem Server sieht das anders aus, macht aber das gleiche. Über dem Hund habe ich mehrere Eingabefelder. Über einem steht ‚Ein Wort oder ein Begriff innerhalb der Datei‘. Klingt sympathisch, nehme ich. Bringt aber nix. Der Hund wird aktiv, findet aber keine Dateien mit dem Begriff. Obwohl ich die vorher im Editor offen hatte. Noch mal rein gesehen, steht immer noch drin.

Ich versuche, zwei Kollegen zu fragen was ich falsch mache. Die haben sich aber beide nicht angesehen was ich wirklich getan habe, sondern schon bei der groben Schilderung des Problems wissend gegrinst, und Kommentare wie ‚Hab ich auch schon versucht, klappt nicht.‘ abgegeben.

Ich habe dann in einer DOS-Box mit ‚findstr‘ gesucht. Das ging. Ist dann allerdings auch ohne Hund. Und nicht rekursiv.

Liegt das an mir? An meiner Aura? Habe ich was falsch gemacht?

Ach ja, der Kollege hat den Server dann auch noch rebooten lassen können. Da musste nicht mal jemand einen Reset-Button suchen. Die Kiste ist keine Kiste sondern nur eine virtuelle Kiste. Und VMware hat quasi einen Fernsteuerungsresetbutton. Schöne neue Welt, der Serverbetrieb ist auf die Weise selbst mit Windows ganz angenehm. Zumindest die Abnutzung von Turnschuhen war hat deutlich nachgelassen…

Um die Mikrocontroller-Einöde der letzten Tage mal etwas aufzulockern: ich habe mich fast gewundert als ich gelesen habe wofür ‚grep‚ steht. Also nicht was man damit macht, sondern dass das Wort tatsächlich eine Bedeutung hat, beziehungsweise eine Abkürzung ist.

Das steht für Global Regular Expression Printer. Auch wenn man es fast täglich nutzt, ich behaupte mal dass das kaum jemand weiß. :-)

Gerade wollte ich wissen wie lang 250 Fuß in einem gebräuchlichen Längenmaß sind. Dass Google mir das umrechnen kann wusste ich. Dass es aber schon reicht, im Suchfeld des Firefox (bei mir immer noch ein zweier) ‚250 feet in meters‚ einzugeben war mir neu. In den Suchvorschlägen erscheint dann direkt ‚=76.2 meters‚, ohne dass ich die Seite laden muss. Sehr praktisch.

Leider scheint das nur mit Masseinheiten zu funktionieren. Google kann eigentlich auch Waehrungen umrechnen, aber das geht wohl an dieser Stelle nicht.

Eine Mail von Bill Gates, der vergeblich versucht ein Microsoft-Produkt auf einem Microsoft-Betriebssystem zu installieren:

Someone decided to trash the one part of Windows that was usable? The file system is no longer usable. The registry is not usable. This program listing was one sane place but now it is all crapped up.

Herrlich. Oder dieser Absatz:

Then it told me to reboot my machine. Why should I do that? I reboot every night — why should I reboot at that time?

Täglicher Reboot? Sicher nur weil er umweltbewusst Abends den Rechner abschaltet, oder? Der Mann hat auf jeden Fall Humor:

So they told me that using the download page to download something was not something they anticipated.

Die Mail ist fünf Jahre alt und bezieht sich auf XP. Keine Ahnung ob das heutzutage besser ist. Warum hat er nicht einfach etwas in der Form ‚apt-get install moviemaker‚, oder noch besser ‚pacman -S moviemaker‚ ausprobiert? :-D

Ich bin auf ein merkwürdiges Phänomen in C gestoßen, vielleicht kann mir das jemand erklären. Extrem eingedampft sieht das Problem so aus:

int main(int argc, char* arg[]) {
    int i = 0;
    switch (i) {
        case 0:
            int j = 7;
            break;
    }
}

Der Compiler (aufgerufen mit ‚gcc test.c‘) sagt dazu „t.c:5: error: expected expression before ‚int‘„. Mit geschweiften Klammern funktioniert der case-Block dagegen prima:

case 0: {
    int j = 7;
    break;
}

Zu meinem grössten Erstaunen klappt auch folgender Block:

case 0:
    i = 3;
    int j = 7;
    break;

Es geht halt nur nicht wenn direkt nach dem case eine Variablendeklaration kommt.

Wenn man schon innerhalb eines case eine Variable deklarieren kann… warum dann nicht ganz am Anfang? Ich meine: ich habe ja Lösungen für das Problem. Mir fehlt halt nur das ‚Problembewusstsein‘. Kann mir das jemand vermitteln?

Ich habe ein wenig in einem Vorbereitungsbuch für die LPI-Zertifizierung geblättert. Dokumentation und insbesondere das Lesen selbiger wird da ziemlich ernst genommen:

Achtung:Als Linux-Einsteiger neigt man leicht dazu, diesen Abschnitt auf die leichte Schulter zu nehmen. Für die Praxis ist die Verwendung der Online-Dokumentation aber absolut unentbehrlich, wenn man sich nicht ganz verloren vorkommen will. Der geübte Umgang mit der Dokumentation ist sehr, sehr wichtig! (Wirklich!)

Recht hat das Buch, und ich finde die Schreibweise sehr gelungen (das ist ein 1:1-Zitat). :-)