Archiv des Autors: admin

Ein ehrgeiziges Projekt: Stichwortverzeichnis

Meine beiden mit Abstand am häufigsten gebrauchten Kochbücher sind „Das Bayrische Kochbuch“ und „Joy of Cooking“. Und bei beiden ist das am Meisten genutzte Feature das Stichwortverzeichnis, da findet man alles! Es eignet sich auch hervorragend zum kreuz- und querschmökern, man findet dabei Rezepte die man sonst nie gesehen hätte. Langer Rede kurzer Sinn, ein Stichwortverzeichnis (Volltext-Index) wäre ein schickes Feature für mein Inselfisch-Kochbuch. Und dazu möchte ich nicht das Stichwort-Feature von WordPress nutzen, das ist mir viel zu umständlich zu bedienen und zu schlecht auszuwerten.

Dazu waren einige Vorüberlegungen nötig. Zunächst muss ich mal festlegen, woher ich die Stichwörter nehme. Ich habe in meinem Inselfisch-Kochbuch knappe 400 Rezepte, in denen relevanter Text in zwei Feldern steht, einmal in post_title und einmal in post_content. Der Titel ist meist zwischen 5 und 10 Wörter lang, der Content kann wesentlich länger sein, bis zu einer ganzen DIN A 4 Seite und mehr, also auf jeden Fall mehr als 100 Wörter. Ich möchte meine Stichwortbasis natürlich maschinell erzeugen, dazu muss ich irgendwie einzelne Wörter aus meiner Datenbasis extrahieren. Dazu muss ich meinen Quelltext aufsplitten (ob mit PHP oder VBA wird sich noch zeigen) und in eine Tabelle schreiben. Diese Tabelle (ich nenne sie mal Rohdaten) soll am Ende nur alle Stichwörter und eine ID (Autowert) enthalten. Man sieht schon: mit dem Content, das wird uferlos, das können leicht mehrere Zehntausend Wörter werden. Ich beschränke mich also auf die Wörter aus dem post_title, das ist besser zu handeln. Wir machen das mal als erste Annäherung und schauen uns dann an, was wir mit den extrahierten potentiellen Stichworten anfangen können.

Wie ich das in MS Access angehe: ich importiere mir die gesamte Tabelle wp_posts aus dem Original-Inselfischkochbuch über CSV-Export aus phpmyadmin. Dann schreibe ich mir eine Abfrage,, die nur den post_title enthält und als where-Klausel post_Type = post und post_status = publish bekommt, damit ich nur die echt veröffentlichten Rezepte in der Datenbasis habe. Die Abfrage heißt quelle und sieht so aus:

Screenshot quelle

265 Datensätze a drei bis zehn Wörter, damit kann man arbeiten. Ich lege ausserdem fest, dass ich nur Großgeschriebene Wörter im Stichwortverzeichnis haben möchte. Das ist willkürlich, aber doch recht sinnvoll, weil damit die ganzen kleinen Füllwörter rausfallen.

Dann gehts rund: Ich lege mir eine Tabelle namens ziel an, die nur zwei Felder hat: ID(AutoWert) und Wort(Text). Sie bleibt zunächst leer. Dann bastle ich mir ein VBA-Modul. Hier lege ich zwei Recordsets an, rstquelle das ist die Abfrage Quelle, und rstziel, das ist die Tabelle Ziel.

Jetzt gehe ich zum ersten Datensatz in rstquelle und lese mir den Inhalt des Feldes post_title ein. Dann verwende ich die VBA-Funktion split(), die zerlegt das Feld in einzelne Wörter, die in ein Array geschrieben werden.  Ich laufe durch dieses Array und prüfe zunächst, ob das Wort Groß oder klein geschrieben ist:

Asc(Left(liste(i), 1) >= 65) And (Asc(Left(liste(i), 1)) <= 90)

Mit dieser Funktion bin ich nicht so recht glücklich, weil sie unerklärlicherweise manche Wörter mit Kleinbuchstaben doch durchrutschen läßt, aber ich hab noch nichts besseres gefunden.

Dann werden noch evtl vorhandene Sonderzeichen entfernt, dazu gibts eine Funktion die Folgende Zeichenkette durchläuft:

Const strSonderzeichen As String = „.,:;#+’*?=)(/%$§!~\}][{“

Dann schreibe jeweils ein gefundenes, geputztes Wort in die Zieltabelle. Dann gehe ich zum nächsten Datensatz der Quelltabelle und wiederhole den Vorgang. das mache ich, bis EOF der Quelltabelle erreicht ist.

Hurra! 669 Datensätze, beim ersten Drüberschauen sieht es schon mal ganz gut aus. Noch die Dubletten ausblenden, das geht mit einer Abfrage mit Gruppierung ganz easy. Sortieren, man sieht noch ein bisschen Datenschmutz ganz oben, das bereinigt man per Hand.

abfrage quelle

Es bleiben 496 recht manierliche Stichworte übrig. Damit könnte ich jetzt schon nach MySQL und WordPress gehen und die Webseite aufbauen, aber ich halte mich noch ein wenig in Access auf und teste nochmal, mit der „wackeligen“ Asc-Funktion bin ich nicht zufrieden.

Konform zu WCAG: Kontrastfarben automatisch berechnen

Ich bin darauf hingewiesen worden, dass mein Color Tool für barrierefreie Kontrastfarben im WEB nicht der aktuellsten Version der WCAG entspricht. OK, hab ich ein bisschen recherchiert und umgestrickt. Was früher als Brightness gehandelt wurde, heißt jetzt Luminescence und wird etwas anders berechnet. Zum Vergleich der Schrift- und Hintergrundfarbe wird eine Ratio herangezogen, 4.5:1 entspricht AA, 7:1 enspricht AAA. Die Berechnung ist im Ganzen etwas komplexer geworden, aber doch kein Hexenwerk. Nachlesen kann man die nötigen Formeln hier:
https://www.w3.org/WAI/GL/wiki/Relative_luminance

Das Kernstück ist die Formel zur Umrechnung des RGB-Wertes aus dem Colorpicker in WCAG-konforme Lumineszenz, die sieht so aus:

function Luminescence($r, $g, $b) //neuere Definition nach wcag s. a. https://www.w3.org/WAI/GL/wiki/Relative_luminance

 {
 $rs = $r/255;
 $gs = $g/255;
 $bs = $b/255;
 
 if ($rs <= 0.03928)
 {
 $R = $rs/12.92;
 }
 else {
 $R = (($rs+0.055)/1.055) ** 2.4;}
 
 if ($gs <= 0.03928)
 { $G = $gs/12.92;
 }
 else {
 $G = (($gs+0.055)/1.055) ** 2.4;
 }
 
 if ($bs <= 0.03928){
 $B = $bs/12.92 ;}
 else 
 {$B = (($bs+0.055)/1.055) ** 2.4;}

 $Lumi = 0.2126 * $R + 0.7152 * $G + 0.0722 * $B;
 
 return $Lumi;
 
 
 }

Dann braucht man noch die Formel für die Contrast Ratio, die findet sich hier im WCAG-Wiki. Damit kann man sich einstellen, ob man AA oder AAA kompatibel sein möchte, und das wars dann auch im Grossen und Ganzen.

if ($input_luminescence >= $row_luminescence){
  $ratio = ($input_luminescence+0.05)/($row_luminescence+0.05);
  }
 else
 {
 $ratio = ($row_luminescence+0.05)/($input_luminescence+0.05);
 }

 if ($ratio>4.5){ //Nur die Farben nehmen bei denen die Ratio grösser als 4.5 ist
...


Viel Spaß beim Ausprogrammieren!

Erster Versuch mit HTML5 Canvas: ein kleines Feuerwerk

Ich habe bei den Musik-Animationen die ersten Erfahrungen mit dem Canvas-Element gesammelt, und ich muss sagen, ich bin sehr angetan. Das eröffnet wirklich ungeahnte Möglichkeiten, und ich finde es wesentlich eingänginger und intuitiver zu bedienen als CSS-Animationen, wo man sich ja ewig mit der Cross-Browser-Kompatibilität herumschlagen muss. Canvas wird von den meisten gängigen modernen Browsern unterstützt, genauere Info hier auf der Seite der Canvas Community.

Statt langer Vorreden legen wir gleich los: passend zum Jahreswechsel habe ich eine kleine Feuerwerksanimation geschrieben. Sowas gibt es schon, auch als downloadbare Freeware, aber mir kam der Sourcecode der Beispiele immer unnötig aufgeblasen vor, ich dachte mir, das muss doch auch einfacher gehen…. und es geht einfacher, deutlich.

Die Vorgabe

Meine Vorgabe ist folgende: auf einem dunklen Sternenhimmel sollen farbige Feuerwerksraketen sternförmig explodieren, an zufälligen Stellen auf dem Canvas. Die Animation soll per Klick startbar sein und dann in einer Endlosschleife laufen. Aussehen soll das ganze etwa so:

screenshot_feuerwerk

screenshot_feuerwerk

Dafür brauche ich zwei Zeitschleifen. Die äussere Schleife wird endlos wiederholt (setInterval…) und erzeugt immer einen neuen zufälligen Mittelpunkt der nächsten Explosion. An einem gegebenen Mittelpunkt startet dann die zweite Zeitschleife, hier soll die Sternenexplosion in mehreren Iterationsschritten von der Mitte aus zeitverzögert ablaufem, dafür nehme ich einen setTimeout. Für die Skriptsteuerung brauche ich Jquery, das binde ich mal lokal ein.

Los gehts: wir basteln uns erst einmal die Leinwand, den canvas, das ist straightes HTML:

<canvas id="leinwand" width="400" height="400" 
style="display: block; background: url('sternenhimmel.jpg')" ></canvas>

Ich lege hier gleich mal einen netten Sternenhimmel in den Hintergrund.

Dann brauchen wir noch einen Startknopf:

<input type="button" value = "Abspielen" onclick = "kontrolle()" >

Die Funktion kontrolle() tut nichts weiter als die Funktion zeichnen() aufzurufen, hier könnte man noch Parameter übergeben, z.B. eine Wiederholungsrate oder die Dauer einer Schleife, aber ich hab das mal gelassen und setze die entsprechenden Werte direkt im Code. Als allererste Massnahme definiert die Funtkion zeichnen() einen Canvas-2d-Context, mit dem arbeiten wir dann weiter:

function zeichnen(param) {
    
    // get the context from the canvas to draw on
    var lwd = $("#leinwand").get()[0].getContext("2d");
...

lwd ist jetzt unser Zeichenbrett.

Wie man einen Stern zeichnet

Wir zäumen das Pferd jetzt mal von hinten auf. Wie zeichnet man überhaupt einen Stern auf den Canvas? Man braucht einen festen Mittelpunkt in Form einer x- und einer y-Koordinate, und einen festen Radius. Dann braucht man noch eine mathematische Formel, die einem ausrechnet bis zu welchem Endpunkt ein Strahl zu einem bestimmten Winkel gesetzt werden soll. Die Formel packt man in eine for…Schleife, und zählt den Winkel einfach hoch, bis man einmal rum ist.

//Begin funktion strahlen zeichnen        
function strahlen(fx,fy,radius){
                    
           var rad = radius;
                    //Beginn strahlen graduell
                    for (grad = -1; grad <=1; grad = grad + 0.2){
                        
                        theta = grad*Math.PI;
                        lwd.moveTo(fx, fy);
                        lwd.lineTo(fx + rad * Math.cos(theta), fy + rad * Math.sin(theta));
                                            
                        //jeder Strahl eine andere Farbe
                        lwd.strokeStyle = "hsl("+Math.floor((Math.random()*359))+", 100%, 50%)";
                        lwd.stroke();
                        
                        //Nach der letzten Schleife Leinwand leer machen
                        if (radius == 100){lwd.clearRect(0, 0, 400, 400);}
                        
                        //**Pfad neu zeichnen (ohne "Geisterbilder")
                        lwd.beginPath();
                                                                
                    }//end strahlen graduell
        
} // Ende von fucntion strahlen    zeichnen

Man setzt den Cursor mit .moveTo auf den Mittelpunkt, und zeichnet mit dem .lineTo den Strahl bis zur berechneten Koordinate. .stroke() führt die Zeichnung aus. Dann wird der Winkel hochgesetzt, man zeichnet den nächsten Strahl, bis man einmal um den Kreis von -1 bis +1 herum ist. Ich hab hier auch noch die Farbdefinition mit hineingepackt und bestimme für jeden Strahl eine zufällige hsl-Farbe, das macht sich ganz hübsch.

Nach dem letzten Aufruf (gegebener maximaler Radius von 100 ist erreicht) macht man die Leinwand leer, damit der Stern auch wieder verschwindet. .beginPath() macht dann noch klar Schiff auf dem internen Pfad-Objekt, wenn das fehlt hat man dann später „Geisterbilder“ von den vorher bereits gezeichneten Sternen.

Die erste Animation: Sterne mit steigenden Radien

Damit der Stern nicht in einem Flash auftaucht, sondern sich wie bei einer Explosion von innen heraus vergrößert, rufe ich die soeben definierte Funktion strahlen() mehrfach auf, immer mit dem selben Mittelpunkt, aber mit stetig wachsenden Radien. Dafür benutze ich einen setTimeout:

//*********begin function sternchen mit timeout    
function sternchen(koord1,koord2){

var i = 10;      //  zähler für den Radius auf 10 (px)
                
//Zufälliger Mittelpunkt des sterns kommt als Parameter rein koord zwischen 1 und 400
var x1 = koord1;
var y1 = koord2;
                
        function myLoop () {           //  Loop function definieren
           setTimeout(function () {    //  setTimeout Wenn die Loop-Funktion aufgerufen wird
                        
              strahlen(x1,y1,i);        //  Strahlen zeichnen an festem Mittelpunkt und Radius
              i=i+10;;                  //  Radius um 10 (px) hochsetzen
              if (i <=100) {            //  Radius <= 100?           
                 myLoop();              //  Loop function erneut aufrufen, Strahlen mit neuem Radius zeichnen
              }                           
              
           }, 50)                        //  ..  setTimeout() auf 50 ms
           
        } //*******Ende von function myloop

myLoop();        //Startet den Loop

} //******ende von function sternchen

Mein i geht in 10er-Schritten hoch, das benutze ich als Radius für den explodierenden Stern in px. Die x- und y-Koordinate des Mittelpunkts bleiben immer gleich, die hab ich als Parameter reingegeben. Der Timeout läuft auf 50 Millisekunden, das ergibt eine hübsch gleichmässige Bewegung. Die Schleife bricht erst ab, wenn der maximale Radius von 100 px erreicht ist.

Die zweite Animation: alle halbe Sekunde ein neuer zufälliger Mittelpunkt

Meine Funktion sternchen() wird jetzt alle 500 my aufgerufen, und bei jedem Aufruf wird eine zufällige x- und y-Koordinate für den Mittelpunkt der Explosion generiert. Das ganze wird mit einem setInterval in einer Endlosschleife gesteuert:

//Beginn Feuerwerk Endlosschleife
        //passiert alle x millisekunden
        var drawLinesInterval = setInterval(function() {
                
                //Leinwand putzen
                lwd.clearRect(0, 0, 400, 400);
                
                //Zufälligen Mittelpunkt des Sterns bestimmen Koordinaten zwischen 1 und 400
                var koord1 = Math.floor(Math.random() * 20 + 1)*20;
                var koord2 = Math.floor(Math.random() * 20 + 1)*20;
                
                //Funktion zum Sternzeichnen aufrufen            
                sternchen(koord1,koord2);
                
        }, 500); // end drawLinesInterval

Das wars auch schon! Morgen packe ich noch eine Demo mit dazu. da könnt ihr euch dann den Source direkt anschauen. Canvas macht Laune!

 

 

Musik sichtbar machen 2: ein animiertes Volume Meter

Ich hab noch ein bisschen nach Audiospielereien gegooglet, und bin bei dzone fündig geworden. Hier wird ganz genau erklärt, wie man mit der Web Audio API von HTML5 einen Audioplayer und ein einfaches Zweikanal-Volumemeter konstruiert:

https://dzone.com/articles/exploring-html5-web-audio

Mit den vorgefertigten Beispielen ist es einfach, sich ein kleines Animationsbeispiel selber zu basteln. Kleiner Wermutstropfen: es funktioniert nicht mit dem Internet Explorer. Aber hübsch ist es trotzdem!

Statt langer Rede stelle ich hier einfach eine kleine Demo rein:

https://evileu.de/demos/peters_roll/peters_roll.html

Das Script läuft mit einer lokalen Kopie von jquery-1.8.0.min.js, wer mag kann das ja noch anpassen. Viel Vergnügen beim Nachbasteln!

Musik sichtbar machen: der Wavesurfer

Ich habe an den Feiertagen ein bisschen mit Audio/Multimedia rumgespielt, und bin da auf ein sehr hübsches Skript gestossen, den wavesurfer.js. Er ermöglicht die Darstellung einer wav-Datei als Frequenzkurve, die beim Abspielen der Musik animiert durchlaufen wird. Das sieht dann zum Beispiel so aus:

peters_roll_screenshot

peters_roll_screenshot

Die Animation läuft synchron zur Musik, das Layout ist fully responsive – eine sehr hübsche Angelegenheit!

Die Implementierung ist denkbar einfach, man bindet das Skript ein:

<script src="https://unpkg.com/wavesurfer.js"></script>

Dann kann man schon loslegen. Man braucht nur eine Div, in die der wavesurfer-Output geschrieben werden kann, und einen Button zum Starten:

<input type="button" value = "Abspielen" onclick = "play()" >
<div id="waveform"></div>

Die Function play sieht dann Beispielsweise so aus:

function play(){
    
    var wavesurfer = WaveSurfer.create({
    container: '#waveform',
    waveColor: 'yellow',
    progressColor: 'blue',
    });

Man legt eine neue Instanz von WaveSurfer auf eine Variable, und stellt die Ausgabe-div und die Farbe ein. Mit der Variablen kann man dann weiterarbeiten:

wavesurfer.load('musik.wav');

wavesurfer.on('ready', function () {
    
    wavesurfer.play();
    var dauer = wavesurfer.getDuration();
    console.log("Dauer:"+dauer);
    
}); //Ende von play()

Die Wav-Datei muss erst vollständig geladen sein, ehe die Animation loslegen kann, deswegen erst den load, dann die Statusabfrage  wavesurfer.on(‚ready’…, die Musik wird erst gestartet wenn der ready-Event zündet. Ich hab hier gleich mal noch ein bisschen gespielt und gebe mir die Dauer des Musikstücks in der Konsole aus, das funktioniert mit dem .getDuration().

Hier habe ich eine kleine Demoversion gebastelt, der Trommelwirbel stammt von meinem Lieblingscousin:

https://evileu.de/demos/wavesurfer_min.html

Mehr zu den Wavesurfer-Methoden gibts hier:

https://wavesurfer-js.org/docs/methods.html

Die Doku ist zwar sehr knapp gehalten, aber das Nötigste findet man schnell heraus, und es gibt auch einige hübsche Plugins. Ein gelungene Sache, finde ich – und ausbaufähig!

WordPress 5.0 und Gutenberg – der erste Eindruck

Was soll ich sagen? Gerade WordPress 5.0 installiert, und gleich beim ersten Versuch mit dem neuen Editor Gutenberg einen Bug produziert. Ich hab einfach mal rumgeklickt und einen „Drop Cap“ angewählt, also ein Initial, und dazu eine Hintergrundfarbe. Das sah dann erstmal so aus:

dropcap_bug

dropcap_bug

Ist jetzt irgendwie nicht so ideal, oder?

Das neue Theme Twenty Nineteen ist ausserdem so ziemlich das häßlichste Theme, das mir je untergekommen ist. Das Design ist absolut grottig, die Schriften sind für meinen Geschmack lieblos zusammengeklatscht, und statt eines schönen Titelbilds ist nur ein minikleines rundes Logo vorgesehen. Die Startseite sieht dann z.B. so aus:

schriften

schriften

Weiter unten ist es auch nicht schöner, der Widget-Bereich ist vom Layout her so schön wie eine billige Einwurfzeitung:

widgetarea

widgetarea

Dann wollte ich ein Bild einfügen – hab erstmal nur die Option „Beitragsbild“ gefunden, das stellt sich dann so dar, blaugetönt und über die ganze Seite ausgebreitet:

beitragsbild

beitragsbild

Finde ich jetzt auch nicht wirklich prickelnd…

Aber ein Theme kann man wechseln, ich hör da mal auf zu meckern und nehm das Twenty Sixteen, damit bin ich eigentlich immer gut gefahren. Wollen doch mal sehen, wie sich der neue Editor benimmt.

Ich möchte gerne eine Liste mit Bullets, erster Ansatz: ich schreib mal meine Listenpunkte untereinander hin, mach jeweils ein Return am Ende. Und jetzt? Noch nichts weiter in Sicht. Ich markiere mal meine drei Listenpunkte, dann ändert sich das Bild. Anscheinend wird für jeden Listenpunkt ein Block angelegt.

drei_blocks

drei_blocks

Ah, guxtu! Wenn man auf das Paragraph-Zeichen drauffährt, kommt auch ein Tooltip, der sagt „Change Block Type“, und hier kriege ich schließlich die Auswahl Liste oder Zitat:

transform_to_list

transform_to_list

Ah, geschafft! Anscheinend brauche ich für jeden Listenpunkt einen eigenen Block, so läuft der Hase.

liste

liste

Dann werde ich wohl für ein Bild auch einen eigenen Block brauchen, schätze ich mal. Ich mach da mal unterhalb der Liste weiter. Wenn man da ganz genau hinguckt, aber wirklich ganz genau, sieht man drei ausgegraute Icons, das mittlere davon könnte evtl. für ein Bild sein:

graue_icons

graue_icons

Sehen sie die Icons in der rechten unteren Ecke? Also, ohne Brille hätte ich da keine Chance. Na gut, klicken wir mal auf das Bild-Icon. Hurra, da kommt der Media-Uploader!

media_uploader

media_uploader

Wenn ich das Bild eingefügt habe, erscheinen rechts im Editorfenster die Bildeigenschaften, das ist OK:

bildeigenschaften

bildeigenschaften

Wenn ich jetzt rechts neben dem Bild Text weiterlaufen lassen will, geht das wieder nur mit einem neuen Block. Hier vermisse ich die Oprion „Als Text einfügen“, die hab ich einfach nicht gefunden. Wenn ich jetzt z.B. aus Word einen Text mit einer Überschrift reinkopiere, baut er mir gleich wieder zwei Blocks, einen für die Überschrift und einen für den Textkörper. Langsam wirds hier unübersichtlich. Ausserdem fehlen im Text etliche Leerzeichen, das ist nicht schön:

leerzeichen_fehlen

leerzeichen_fehlen

Jetzt möchte ich gern noch ein Video einfügen, also frisch auf, ein neuer Block. Klick auf das Icon „Add file“, dann gehts wieder in die Mediathek oder zum Upload und wird defaultmässig zum Download angeboten, das ist ganz OK.

file_download

file_download

Man kann aber auch mit „Change Block Type“ das ganze in ein eingebettetes Video konvertieren, wer das möchte ist auch gut bedient.

Ich lasse es hier mal gut sein, für einen ersten Eindruck reicht das. Das man für jeden Pfiffkaas einen eigenen Block braucht, finde ich dann doch etwas gewöhnungsbedürftig. Man hat dann quasi den Bildschirm voll mit lauter kleinen spezialisierten Editorfenstern, die einem immer nur die Optionen anbieten, die für den jeweiligen Blocktype gültig sind. Na ja. Das kann man mögen oder nicht, ich finde es ziemlich gewöhnungsbedürftig. Was mich definitiv stört: ich bin mehrfach in eine „Keyboard Trap“ gefallen, wo die Tab- und Pfeiltasten nicht mehr so durch den Artikel navigieren, wie man es erwarten würde. Das ist natürlich total grottenschlecht für Benutzer, die Gutenberg nicht mit der Maus, sondern über die Tastatur bedienen möchten. Aber das geht schon stark ans Thema Barrierefreiheit, und sprengt den Rahmen dieses ersten subjektiven Eindrucks.  Mein Fazit: geht so. Ich sehe keinen großen Vorteil im Block-Konzept, aber man kanns wahrscheinlich doch recht schnell lernen. Man kann mit Gutenberg arbeiten, aber wo der grosse bahnbrechende Innovationsvorsprung liegt, hat sich mir nic.ht erschlossen.

Barrierefreie Farbkontraste revisited: die ganze HTML-Palette

140 Farben war mir zuwenig

Ich habe in dem Artikel über Barrierefreie Farbkontraste 2 den Source zur Bestimmung von idealen Kontrastfarben nach WCAG-Richtlinien aus den benannten Farben der HTML-Palette vorgestellt. Jetzt habe ich das Thema nochmal aufgegriffen, weil mir die Beschränkung auf die benannten Farben doch ein zu enges Korsett war, das sind ja nur ca. 140, und der HTML-Farbraum umfasst  bekanntermassen 24 Bit Farbtiefe, das sind 16.777.216 Farben. Ich hatte damals eine MySQL Tabelle der benannten Farben mit ihren RGB-Werten verwendet, das Konzept habe ich jetzt gekippt, bei über 16 Mio Farben war mir das dann doch zu unhandlich.

Der ganze HTML-Farbraum

Statt dessen benutze ich jetzt den ganzen Farbraum zur Bestimmung der idealen Kontrastfarben und berechne mir die RGB-Komponenten durch drei geschachtelte While-Schleifen. Na ja, nicht den ganzen Farbraum, ich steppe mit einer definierten Schrittweite durch die RGB-Werte, damit die Ergebnisse nicht so unübersichtlich werden. In der Testphase hat sich eine Schrittweite von 20 als praktikabel erwiesen, da hat man noch eine wirklich grosse Auswahl möglicher Farben, und es bleibt trotzdem recht übersichtlich.

Was das Programm macht

Zur Eingabe der vom Benutzer gewünschten Farbe benutze ich wieder einen Colorpicker, man könnte aber auch gleichgut ein Textfeld zur Eingabe des Hex- oder RGB-Wertes vorsehen. Die gewählte Farbe wird in ihre RGB-Komponenten zerlegt, mithilfe der Formel für die relative wahrgenommene Helligkeit wird die Brightness bestimmt. Ein barrierefreier Farbkontrast wird bei einer Differenz der Brightness zweier Farben von einem Wert von ca. 120 bis 130 erzielt, diesen kann man im Code festlegen.

Ich steppe jetzt in drei geschachtelten Schleifen durch den gesamten 24-Bit-Farbraum. Damit das nicht uferlos wird, gebe ich wie gesagt für jede Iteration eine Schrittweite von 20 an, bei Bedarf könnte man das auch noch feiner oder gröber einstellen.

Ich berechne die Brightness der jeweils aktuellen Farbe, berechne die Differenz zur vom Benutzer gewählten Farbe und gebe die aktuelle Farbe nur dann aus, wenn diese Differenz über dem eingestellten Schwellwert liegt. Bei der Ausgabe liefere ich dann gleich den rgb(x,y,z) der aktuellen Farbe mit. That’s it – wenn ich dazukomme, mache ich die Tage noch ein paar Screenshots der Ausgabe. Den Sourcecode liefere ich diesmal nicht mit, der kommt in mein Portfolio 🙂

Nachtrag: die Screenshots

Der Startbildschirm ist unspektakulär, hat aber auch nur eine Funktionailtät: den Colorpicker.

el_allcolors_start

el_allcolors_start

Hier ein Ausschnitt des Ergebnisses, man sieht dass die gewählte Farbe wirklich gut zu den vorgeschlagenen Farben kontrastiert:

el_allcolors_ergebnis

el_allcolors_ergebnis

Ganz am Ende gebe ich noch aus, wieviele mögliche Kontrastfarben es gibt:

el_allcolors_anzahlfarben

el_allcolors_anzahlfarben

Das wars –  viel Spaß beim Austüfteln!

PHP ist tot? Mein Bankkonto hat nichts davon gemerkt…

So lautet, frei übersetzt, ein Zitat von Brandon Savage, PHP Developer und grosser Spaßvogel auf Twitter.

In der Tat, mit dem ganzen Brimborium um den neuen WordPress-Editor Gutenberg, der ja komplett in React.js programmiert wurde, ist es gerade wieder einmal angesagt PHP für tot zu erklären. Da hat mich ein Passus aus diesem Artikel bei Kinsta köstlichst amüsiert:

„For a humorous take on it, there’s this Reddit post where a job description wanted a React developer with 5 years of experience back in 2017, at which point React had only been around for ~4 years.“

Da wurde 2017 ein React Developer mit 5 Jahren Erfahrung gesucht, aber React war zu diesem Zeitpunkt erst ~4 Jahre auf dem Markt. Sowas nennt man Hype, und leider fallen viele Entscheider, die selbst selten Developer sind, auf so etwas herein und fällen Entscheidungen für oder gegen zu verwendende Programmiersprachen je nach dem was gerade angesagt ist. Und angesagt scheint zur Zeit nur Javascript und sämtliche angeschlossenen Derivate und Bibliotheken.

Das hindert aber PHP nicht daran, nach wie vor die erfolgreichste Programmiersprache im Internet zu sein. Ich zitiere mal noch ein paar Zahlen aus dem Kinsta-Artikel:

  • Im November 2017 berechneten W3Techs PHP auf 80,1 % der Webseiten als serverseitige Programmiersprache.
  • Im Juni 2018 waren es noch 79,6 %.
  • PHP wird heute (November 2018) von 78% aller Webseiten benutzt, die eine serverseitige Programmiersprache verwenden.
  • Wenn die Verwendung von PHP weiter in diesem Masse abnimmt, wird es noch ca. 25 Jahre dauern bis PHP unter die 50 % Marke kommt.

Das sieht jetzt aber wirklich nicht nach Zahlen vom Sterbebett aus, oder? Wenn man noch in Betracht zieht, dass sowohl WordPress (ca. 32% aller Webseiten laufen heute auf WordPress), als auch Wikipedia, als auch alle Drupal- und Joomla-Webseiten PHP-basiert sind, siehts auch nicht wirklich toter aus.

Und wenn in erhitzten Diskussionen heutzutage immer wieder gegen PHP argumentiert wird, aus welchen Gründen auch immer, da gefällt mir ein Zitat von Bjarne Stroustrup, dem Schöpfer von C++ ganz hervorragend:

„Es gibt nur zwei Arten von Programmiersprachen. Diejenigen, über die die Leute meckern, und diejenigen, die niemand benutzt.“

Das ist ein schönes Schlußwort, finde ich – und mache im nächsten Artikel wieder ein Tänzchen mit PHP, weil es einfach Spaß macht.

Was ich an meinem Beruf so liebe: Freiheit und Kreativität

Es ist ein verbreiteter Irrglaube, dass Programmierung nur ein Job für verbiesterte Tüftler, stubenhockerische Mathegenies und trockene Zahlenschubser ist. Nach fast 30 Jahren Berufserfahrung weiß ich, dass genau das Gegenteil der Fall ist. Programmierung hat viel mit Kreativität und einem schöpferischen Prozess zu tun – und auch da bin ich Expertin, ich bin ja schließlich auch Künstlerin und male und gestalte seit meiner Kindheit schon mein ganzes Leben lang.

Programmierung an einem guten Projekt startet mit einer leeren Seite im Code-Editor, das ist genauso gut wie eine leere, weisse Leinwand. Programmierung erfordert einen erheblichen Planungsaufwand, genau wie zum Beispiel ein Bildmotiv erstmal komponiert werden muss, wie man den Bildausschnitt festlegt, die notwendigen Details ermittelt und die Farb- und Lichtstimmung erarbeitet.

Aber wenn man den Blueprint einmal hat, gehts los – und da kommt aber ganz groß die Kreativität und die Erfahrung zum Einsatz. Kunst muss man auch lernen, die unterschiedlichen malerischen und gestalterischen Techniken erfordern erhebliches Knowhow über unterschiedliche Materialien und Verarbeitungsweisen. Schnelltrocknende Acrylfarben erfordern eine ganz andere Vorangehensweise als Ölfarben, die tagelang zum Trocknen brauchen. Ein Visual Basic Programmerl in Excel oder Word löst schnell mal ein Office-Problem, eine grosse Datenbankanwendung erfordert exakte Planung und passgenaue Detailarbeit.

Wir waren bei der leeren, weissen Leinwand: das ist der Casus Knacktus, ein guter Programmierer erschafft ein funktionierendes Produkt aus dem Nichts. Ich rede hier nicht vom zusammenkleistern fertiger Codeschnipsel aus Programmbibliotheken (schöne Grüße an alle *.js Programmierer), ich rede von Software Engineering, nicht von der Zusammenklitterung endlosen Codeeintopfs aus aus vorgefertigten Schnipseln, die buntgemischt in der Brühe schwimmen wie die Zutaten einer Hochzeitssuppe. Ich spreche von Software-Architektur, und die hat viel gemeinsam mit der kreativen Leistung des Architekten bei einem frei geplanten Gebäude.

Man legt ein Fundament aus den Unternehmensdaten, oft ist dies eine schon vorhandene Datenbank, ein bestehendes ERP/CRM-System. Darauf baut man die unterschiedlichen Module auf. Durch die Tür oder den Lieferanteneingang kommen neue Daten (Kundenstamm, Bestellungen, Aufträge…) herein, durch die Auftragsabwicklung werden Antwortschreiben generiert und Geschäftsprozesse angestossen, die das ganze Unternehmen über die Auftragserfassung- und Abwicklung bis hin zur Produktion abbilden. Schliesslich gehts zur Warenausgabe an den Kunden, hier werden die fertigen Produkte oder Dienstleistungen ihrem Empfänger zugeteilt. Am Ende baut man noch einen Qualitätssicherungsmechanismus, eine Reklamationsbearbeitung und die evtl. nötige Nachbesserung nach Kundenwünschen mit ein, und so hat man am Ende eine ganze Fabrik dastehen, die die Geschäftsprozesse eines Unternehmens nicht nur abbildet, sondern verantwortlich trägt.

Das, liebe Leser, ist Softwarearchitektur, und nicht nur Code-Erzeugung. Es ist auch komplett unabhängig von den verwendeten Programmiersprachen und sonstigen Hilfsmitteln wie Frameworks und Programmbibliotheken. Und was heutzutage sehr oft übersehen wird: es läßt sich nicht alles auf einer Internetseite abbilden.

Der eigene Webauftritt mutiert heutzutage oft zum Selbstzweck und soll eine eierlegende Wollmilchsau werden, in die Planung einer neuen Webseite wird oft viel zuviel von den lebensnotwendigen Unternehmensabläufen mit hineingepfropft. Es mag zwar in vielen Fällen akzeptabel sein, für die Mitarbeiter Intranetlösungen für die tägliche Arbeit bereitzustellen, aber wesentlich öfter wird es angebracht sein, Standalone-Lösungen auf der Datenbank und mit den eingesetzten Office-Produkten zu realisieren.

Das wird heutzutage gern belächelt, Visual Basic zum Beispiel wird gerne als „Programmiersprache für arme Bastler“ abgetan, und ein Excel- oder Wordmakro als handgestrickter Popelkram belächelt. Da ist wieder Umdenken angesagt, gerade die „kleinen“ Office-Lösungen sind es, die den Mitarbeitern wirklich das Leben leichter machen. Sei es die Serienbrieffunktion für die Sekretärin, der ODBC-Zugriff auf die Datenbank mit Excel für den Controller, der damit seine Berichte erstellt, oder die Unternehmenskennzahlen, Umsätze, Rückläufe uvm. für die Geschäftsführung, die danach ihre Business-Entscheidungen trifft. Ein Software-Architekt berücksichtigt alle diese unterschiedlichen Bedürfnisse, und baut das Haus und seine Module entsprechend der tatsächlichen Anforderungen.

Hier ist Raum für große Pläne und freie schöpferische Tätigkeit sowie für echte Kreativität, und hier ist auch Raum für die Akzeptanz der Mitarbeiter des Unternehmens, deren Feedback für den Softwarearchitekten dasselbe ist wie Applaus und gute Kritiken für einen Künstler. Ein erfolgreicher Usability Test ist wie eine gelungene Konzertpremiere, und ein gelungenes User Interface gleicht sehr einem durchdacht komponierten Gemälde, das beim Publikum gut ankommt.

Ich werde oft darauf angesprochen, wie ich meine zwei Berufe als Programmiererin und als Künstlerin unter einen Hut bringe. Das ist ganz einfach: es gibt so viele Parallelen, der kreative Schaffensprozess ist in beiden Fachgebieten vorhanden, und meine Liebe zum Detail und die geradlinig logische Denke kommt bei mir in beiden Berufen gleich gut zum Zug. Programming is like Poetry, heißt es oft, und obwohl ich jetzt nicht gerade gereimte Codezeilen verfasse, finde ich doch Gefallen an wohlstrukturierten Programmen und einer sauber durchkomponierten Software.

Deswegen: gute Programmierung oder besser gesagt gutes Software Engineering ist für mich eine Kunstform, und nicht zuletzt: sie kann auch unheimlich Spaß machen. Deswegen liebe ich meinen Beruf, und bin auch nach 30 Jahren im Geschäft immer noch fasziniert und positiv angesprochen von den vielfältigen Herausforderungen, die einem anspruchsvolle Softwareprojekte bieten. Ich bin eine alte Programmiererin, und soweit ich es absehe, werde ich mit den Jahren auch noch eine uralte Programmiererin werden, weil ich nicht daran denke mit der nahenden Rente auch meinen Beruf aufzugeben. Ich werde noch bis ins hohe Alter an Softwareprojekten mitmischen, und meinen Spaß daran haben!

Wie lange braucht man, um eine neue Programmiersprache zu lernen?

Das selbsternannte Javascript-Genie

Ich hatte mal einen Teamkollegen in einem sehr explosiven Projekt, der hielt sehr grosse Stücke auf sich. Er codierte ellenlange Module, war ein furchtbarer Geheimniskrämer und ließ sich nicht in die Karten schauen. Er war auch kein Teamplayer, und seine Codeschnipsel arbeiteten nie so mit den Codeschnipsel der anderen Teamkollegen zusammen, dass man sie verwenden konnte. Ich musste eines Tages an einem Algorithmus mit ihm zusammenarbeiten, und das war eine mittlere Katastrophe. Er verkündete: „Ich habe mir Javascript selbst beigebracht, deswegen bin ich so erfolgreich und kann von meinem Know-How in diesem Job gut leben! Ich teile mein Wissen nicht mit dir, schau wie du zurechtkommst!“ und schnappte zu wie eine beleidigte Auster.

Ich schrieb mir dann die notwendigen Routinen selber, statt mich mit seinem Spaghetti-Code herumzuschlagen, und brachte mir dafür ebenfalls Javascript selber bei – in ein paar Tagen, das hat keine Woche gedauert. Warum ich das erzähle? Weil es mich immer wieder erstaunt, dass es Leute gibt die tatsächlich nur eine einzige Programmiersprache beherrschen und sich doch als Developer auf dem Markt behaupten können. Und weil es mich auch immer wieder noch mehr erstaunt, welches Brimborium verantaltet wird, wenn es darum geht, eine neue Programmiersprache zu erlernen.

Gutenberg und React.js

Nehmen wir nur mal als Besipiel den Zinnober, der um den neuen WordPress Editor Gutenberg gemacht wird. Der ist komplett neu programmiert worden, in React.js. Ich habe (noch) keine Ahnung von React.js, vielleicht handelt es sich ja wirklich um eine sehr schwierig zu erlernende und komplizierte Sprache… aber ich schweife ab.

Was ich eigentlich erzählen wollte: als WordPress Accessibility Team Lead Rian Rietveld kürzlich ihren Rücktritt wegen der Querelen um Gutenbergs schlechtes Abschneiden in den Accessiility Audits erklärte, nannte sie als eine der Hauptschwierigkeiten, dass es im Accessibility Team niemanden gab, der sich mit React.js auskannte, und es in der knappen Zeit auch nicht möglich war, einen externen React-Programmierer anzuheuern.

Was kann denn da so schwierig sein?

Ja Donnerlittchen, dachte ich mir, dieses React muss aber ein harter Brocken sein. Ich meine, wenn ich ein Projekt in einer neuen Programmiersprache vor die Nase gesetzt bekomme, hocke ich mich ein paar Tage auf den Hosenboden und arbeite mich da ein, und gut ists.

Ich lerne jetzt seit bald 30 Jahren regelmäßig neue Programmiersprachen, und die Hauptschwierigkeit dabei ist, dass die Syntax von Sprache zu Sprache ein bisschen unterschiedlich ist und man hier ein einfaches oder ein doppeltes Hochkomma, da ein Komma oder ein Semikolon, und dort eine eckige oder geschweifte Klammer braucht.

Aber die Sprachelemente sind fast überall gleich oder zumindest sehr ähnlich. Datentypen sind Datentypen, ein Array ist ein Array, ein Objekt ist ein Objekt, und all die FORs, WHILEs, SWITCHes und wie sie alle heissen, folgen in allen Programmiersprachen der selben Logik. Wenn man die Grundlagen einmal draufhat, ist es auch nicht weiter schwer, sich die Semantik einer neuen Programmiersprache einzuverleiben, die Konstrukte gleichen sich ja doch.

Wieso zum Dunnerkeil hat sich also nicht jemand aus dem Accessibility Team hingesetzt und sich dieses verflixte React.js schnell mal reingezogen? Ich kann es mir nur so erklären: das sind wohl alles keine Programmierer, sondern „nur“ Barrierefreiheits-Experten, die mit Codierung nichts am Hut haben. Denn für einen alter Programmierer ist es eine der leichteren Übungen noch eine Programmiersprache zu lernen, egal wie modern und hyper die auch immer sein mag.

Wenn mich der Teufel reitet, ziehe ich mir mal auf FreeCodeCamp die React-Challenges rein, und ich wette dass ich damit in wenigen Tagen durch bin und dann sehr wohl weiß, was React macht und tut und wie man es anwendet. Echte Programmierer sind nämlich keine One-Trick-Ponys, sondern immer auch ein bisschen Universalgenies. Aber das ist unser Betriebsgeheimnis …