Wordprust

…und das ich’s nicht vergesse: ein Update in Ehren, prost! Diese WordPress-Installation dient neben meiner persönlichen Belustigung und dem Festhalten des einen oder anderen technischen Belanges als Beigabe zu GitHub/Gogs, Jenkins, stackoverflow u.a. auch dem Langzeit-Wordpress-Test.

Was bleibt, ist, dass WordPress gerne mal seine externen Dateien („assets“) im Upgrade verliert – abgesehen von vielen kleinen Code-Schnipselchen, die sich so zur manuellen Nacharbeit ansammeln. Ebenso bleibt, dass eine vorher gesicherte Datenbank nicht ausreicht, um die Bilder dann ohne allzu viel manuelle Nacharbeit wieder mit dem richtigen Namen an die richtige Stelle zu bekommen.

Hier kommt mein Segen: das www darf auf Informationstechnologienetz umgetauft werden.

html5, css grid flex und die Welt dreht sich…

Glückwunsch nach Stuttgart, ein neues Licht will am nächtlichen Säuferhimmel erleuchten: s-brett.com möge seine Türen zeitnah wieder öffnen!

Beileibe nicht nur deswegen wühle ich mich nebst JHipster (konkretisiert mit Spring und Angular) auch in die wohl absichtlich verwirrenden Untiefen von html5, JS, CSS, weiteren zugehörigen frameworks, Präprozessoren und unzähliger Bibliotheken mit jeweiligem Inkompatibilitäts-Wiki und dem Wandel der IT seit 1989 an sich. Dabei kommt nach einiger Recherche und dem Lernen der letzten, neuen Spinnerei irgendwann immer ein recht altes Bild in mir hoch. Vor dem Internet gab es für mich u.a. auch die mütterliche Heimstatt. In jener hingen Bilder an der Wand, auf manchen waren Hühner im Aquarell-Comic-Stil. Eines davon hat – soweit meine Erinnerung mich nicht trügt – einen Hahn auf einsamer Flur angedeutet. Mit einer Gedankenblase über dem kleinen, kammbedeckten Schädel: „Von der Wahrheit haben wir oft nur einen Schimmer. Doch wahr ist: nah ist sie uns immer.“

Und auf der Arbeit durch das CSS grid lande ich bei der Wiederholung mancher CSS flexbox Befremdlichkeit im Vergleich wieder einmal auf dem zugehörigen complete guide: sinnvollerweise ist wenigstens die Tabelle zur Browserkompatibilität einzelner box-dann-hies-es-flexbox-jetzt-heißt-es-flex-properties als schnöde table ausgeführt. Und das hat schon 1997 geklappt, wie mir ein Blick ins Datenarchiv und weinenden Auges in meine seit langem dahingegangene, zehnjährige Selbstständigkeit gezeigt hat. Auch offensichtlich wird da gleich: mit 21 Jahren fast ebenso alte Websites mit csssequenz-Animationspfaden und dergleichen Spielereien lassen sich heute nicht mehr fehlerfrei öffnen.

Mühevolle, vergebliche Berufung.

SQL-Joins bzw. Python pandas Objektvereinigungen

A bzw. B:

  •  in SQL eine Menge an Werten, die aus der Abfrage über eine Spalte einer Tabelle entstehen
  • in pandas ein pandas.Series-Objekt (eindimensionales ndarray mit Achsen-Namen), das ggf. aus der Abfrage eines pandas.DataFrame (zweidimensionale, größenveränderliche, möglicherweise verschieden typisierte Tabellendaten) resultiert
  • für Python pandas gilt: „left“ = 1st Dataframe; „right“ = 2nd Dataframe

Alle Werte der Menge A

SQL:
SELECT * FROM A LEFT JOIN B ON A.Key = B.Key
Python pandas:
A.join(B, on=[‘A.Key‘], rsuffix=‘_B‘)

Alle Werte, die nur in der Menge A sind

SQL:
SELECT * FROM A LEFT JOIN B ON A.Key = B.Key WHERE B.Key IS NULL
Python pandas:
A[~A[‘A.Key‘].isin(B[‘B.Key‘])

Alle Werte, die in Menge A und gleichzeitig in Menge B sind

SQL:
SELECT * FROM A INNER JOIN B ON A.Key = B.Key
Python pandas:
A.join(B, on=[‘A.Key‘], how=‘inner‘)

Alle Werte, die entweder in Menge A oder in Menge B sind

SQL:
SELECT * FROM A FULL OUTER JOIN B ON A.Key = B.Key WHERE A.Key IS NULL OR B.Key IS NULL
Python pandas:
pd.concat([A, B].loc[lambda df: ~df.index.duplicated()]

Alle Werte aus Menge A und B

SQL:
SELECT * FROM A FULL OUTER JOIN B ON A.Key = B.Key
Python pandas:
pd.merge(A, B, how=‘outer‘, on=[‘A.Key‘,‘B.Key‘], validate=“one_to_one“, indicator=True)

Weitere Varianten und komplexere Vereinigungen in der pandas-Dokumentation.

Download SQL-pandas-Cheatsheet

Deep Thought

Dem Deutschen Volke - Schriftzug

Die Antwort „42“ auf die Frage nach dem Sinn des Lebens, dem Universum und dem ganzen Rest ist bekannt. Zaphod Beeblebrox und seine Begleiter, darunter ein depressiver, suizidaler Roboter versuchen, gejagt von einem der unausstehlichsten Völker des Universums, den Vogonen, mithilfe des Unendlichen-Unwahrscheinlichkeitsantrieb und gemeinsam mit uns die eigentliche Frage auf diese Antwort zu entdecken.

Einen unserer Empfindung nach nicht unerheblichen Beitrag, Dem Deutschen Volke zu helfen, aus dem Bann der Überregulierung, falscher Methodik, überkommener Hetz-Proklamationen à la AFD, dem Untergang der Erde sowie den Vogonen zu entkommen, leistet folgender Beitrag:

Ein Vortrag keinesfalls nur für Programmierer, von  „Pragmatic“ Dave Thomas, einem „alten Hasen“, der uns empfiehlt, nicht jedem Quacksalber – auch ihm nicht – auf den Leim zu gehen, aus dem Quark zu kommen, die Cojones auszupacken, Courage zu zeigen. KEINE PANIK!

„It takes guts“ – gute, deutsche Handwerkskunst, Eigeninitiative und ein seit Jahrmillionen in der Evolution genau so wie in modernen Steuerungen praktiziertes Vorgehen anhand eines „proportional-integral-derivative controllers“. Leider ist sogar die Deutung im deutschen Teil des Wikipedia-Universums mit der einzigen Definition des PID-Reglers nur eine ziemlich beschränkte Sicht auf die umfassendere, englische Definition und auch die Suche nach „Kontrollschleife“ fördert nichts zu Tage.

Mehr Klarheit zur praktischen Anwendung nicht nur in großen Schiffen und kleinen, selbstausbalancierenden Robotern, sondern im Rahmen alltäglicher Progresskontrolle im Privat- und Berufsleben bringt die Definition zum „agile life“ im hier verlinkten Video:

Agility – what to do

  • Find out where you are
  • Take a small step towards your goal
  • Adjust your understanding based on what you learned
  • Repeat

und falls sich auf diesem einfachen Weg Alternativen ergeben:

Agility – how to do it

  • When faced with two of more alternatives that deliver roughly the same value, take the path that makes future change easier

Das Preussische, Vogonische hat uns auf Platz 17 der leistungsfähigsten Digitalökonomien (IMD World Competitiveness Ranking 2019) verbannt. Irgendwann mag jeder, vom kleinen Angestellten bis hin zu den Gelähmten der jeweiligen Regierung, sich denken, dass auch die Deutschen dazu lernen sollten und schon lange nicht mehr mit dem Finger auf andere zeigen brauchen.

Hier die ersten zehn Länder des Rankings, an denen wir uns ein Beispiel nehmen könnten:

  1. USA
  2. Singapur
  3. Schweden
  4. Dänemark
  5. Schweiz
  6. Niederlande
  7. Finnland
  8. Hongkong
  9. Norwegen
  10. Südkorea

Diese Rankings können laut einem Artikel im Wirtschaftsteil der „Welt“ „durchaus als Weckruf verstanden werden“. Natürlich nimmt ein agiler Deutscher wie ich solche Schweizer Rankingtabellen nicht ernst – zumal die schönsten Länder auf unserer Erde meiner Ansicht nach viel zu weit hinten vertreten sind: die Möglichkeit, Schönheit im eigenen Leben verwirklichen zu können, stellt doch wohl die größte „competitiveness“ [Wettbewerbsstärke, Konkurrenzfähigkeit] dar.

Und schon sind wir wieder bei der Agilität: das bedeutet dem Vortrag von Pragmatic Dave zufolge vor allem auch, sich nicht von Experten einschüchtern zu lassen – sie kennen weder Deinen oder meinen individuellen Platz, noch den vorherrschenden Kontext, noch die individuelle Erfahrung, noch den nächsten richtigen Schritt auf Deinem oder meinem Weg. Wir haben nicht nur in unserem Leben auf dem Lande bereits einige Menschen kennen lernen dürfen, die weder den Begriff Agilität kennen, noch mit Software-Programmierung zu tun haben und uns mit der Weisheit ihres „höheren Alters“ ganz ähnlich klingende Tipps gegeben haben. Mitunter ist auch die deutsche Geschichte mitsamt Altersvorsorge und Leistungsprinzip kein Kontinuum, wie wir es gerne eingeredet bekommen. Wie stets kommt der deutsche Kant und seine Imperative zum Tragen!

Some people think they are important. Don’t let them tell you what to do.

Thank you Pragmatic Dave – you made my day twice!

Hier noch die zugehörige Vortrags-Präsentation von der GOTO 2015.

Observable Anxiety

Ein passender Titel für den Vortrag auf der NG-CONF 2018 von Ward Bell & Sander Ellis zum Thema „Angular APIs with RxJS“:

.pipe your Observables!

Angular APIs using RxJS: HttpClient, AsyncPipe, Forms, Router:

  • .get() with .subscribe() in your service, .pipe() the Observable and map() it there to the object you want to consume in your components, then use the service in your components
  • .post() with .subscribe(), including error-handling
  • or get the data with using async in your template and error handling (catchError()) in the component
  • with Angular reactive forms APIs valueChanges-Observable, .pipe() with tap() for error message, and three functions to reduce http-requests: debounceTime(), disctinctUntilChanged() and switchMap() for discarding an inflight-search, .pipe()‚d again to sandbox the errors inside the switchMap() so that examining the Observable does not complete, e.g. for auto-completion (use reactive style instead of Angular template-driven forms)
  • error isolation (explicit example) for sandboxing errors in an isolation level with the help of another .pipe() to map() and catchError() inside the .pipe() to switchMap(). RxJS rule: if an error occurs, the upstream is dead.
  • ActivatedRoute used with Observable paramMap.pipe(), Router events and url address path change while navigating on the same component with changing routerParams, map() and then switchMap(), again to cancel previous queries. Including watching the routing for debugging (altenrnative .subscribe()-style!)
  • Recommended way if subscribing to an Observable: .unsubscribe() from the source, a Subject, with Observable.onDestroy.next() in life cycle event hook ngOnDestroy() with the aid of Observable.pipe() to takeUntil() emitting the Subject in the Observable.pipe() to complete the Observable which prevents memory leaks. .unsubscribe() when in doubt with takeUntil(notifier) pattern. It never hurts to .unsubscribe()!
  •  .subscribe() takes: 1.) the happy (or: the next channel), 2.) the sad (or: the error channel) and 3.) alert things when the Observable completes (which means the Observable terminates and let go of any subscribers)
  • async autosubscribes when the Component is destroyed, but emits no „completed“: savely use AsyncPipe in the components template!
  • combine multistreams: bring multiple streams from Observers and Subjects together with combineLatest() .pipe()‘d to map() for mapping them into an immutable array of immutable objects
  • role your own Observables which have .next(), .error() and .complete(), from properties („rolling http of local storage“) in the component
  • create a new result array when any source emits an Observable array with .pipe()‚ing the Observable to scan(), which accumulates all incoming Observables into an array starting empty with startWith( [] ). combineLatest() takes the latest value of every Observable it gets
  • sort values in an additional map()
  • (not in movie) filter() the .pipe()‚d Observable to filter out unwanted values

Observable Decision Graph:
https://xgrommx.github.io/rx-book/content/which_operator_do_i_use

Source fork (Angular 7 / Node 10 commit):
https://github.com/Mesqualito/rxjs-in-ng-angular_berlin

Python3 pandas-Bibliothek

Wirklich fein.

DIE WELT HÄNGT AN EINEM KOMMA.

Und nicht vergessen: „Truth value of a Series is ambiguous.
„The or and and python statements require truth-values. For pandas these are considered ambiguous so you should use „bitwise“ | (or) or & (and) operations:
These are overloaded for these kind of datastructures to yield the element-wise or (or and).“

Da braucht es Ruhe. Schöne Ruhe. Hacking music Ruhe.

Angular 9 switchMap

Observable bedeutet zu deutsch: „Beobachtbares“

Die Funktion: mit switchMap kann zum Observable geschalten werden, welches sich zuletzt geändert hat („switch to a new observable“).

Der switchMap-Operator aus der RxJS-Bibliothek bildet jedes Element auf ein Observable ab. Er ordnet alle empfangenen Observables auf einer Ebene ein. Der switchMap-Operator projiziert jeden Wert aus der Quelle in ein Observable und führt dieses in einem Ziel-Observable zusammen, welches vom switchMap-Operator schließlich ausgegeben wird. Im Ziel-Observable finden sich immer nur die Werte, die vom zuletzt von der Quelle abgegebenen Observable empfangen wurden.

Die Syntax des switchMap-Operators

switchMap<T, R, O extends ObservableInput>(project: (value: T, index: number) => O, resultSelector?: (outerValue: T, innerValue: ObservedValueOf, outerIndex: number, innerIndex: number) => R): OperatorFunction<T, ObservedValueOf | R>

Der Parameter project in der Syntax ist eine Funktion, die ein Observable zurück gibt, sobald sie auf ein Element angewandt wird, das von einem Quell-Observable ausgegeben wurde.
Der Parameter resultSelector ist optionell und der Standardwert dieses Parameters ist nicht definiert. Der Rückgabewert, „OperatorFunction<T, ObservedValueOf | R>“, ist ein Observable, welches das Ergebnis liefert, das aus der Anwendung der projection-Funktion (und dem optionalen, veralteten [„deprecated“] resultSelector) auf jedes Element, welches aus dem Quell-Observable übergeben wird, resultiert, wobei nur die Werte des zuletzt proijezierten, inneren Observables verwendet werden.

Den switchMap-Operator in Angular anwenden

Der switchMap-Operator liefert ein Observable zurück, das Elemente ausgibt, auf welche eine Funktion, die dem Operator als Parameter mitgeliefert wird, angewandt wird. Dabei wird die Funktion auf jedes Element, das vom Quell-Observable kommt, angewandt. Diese Funktion gibt bei jeder Anwendung intern im switchMap-Operator ein inneres Observable zurück. Jedes Mal wenn eines dieser inneren Observable in Betracht gezogen wird, beginnt das von der switchMap zurückgelieferte Observable, die Elemente dieses inneren Observables  auszugeben.

Wenn ein neues, inneres Observable verarbeitet wird, beendet switchMap die Ausgabe der Elemente des vorher ausgelieferten, inneren Observable und beginnt, die Elemente des neuen, inneren Observable zurück zu liefern. Dieser switchMap-Prozess setzt sich kontinuierlich für jedes folgende, innere Observable fort.

switchMap-Einsatz beim Angular Routing

Der switchMap-Operator kann mit Angulars Activated Route verwendet werden.

Als erstes müssen Router, ActivatedRoute und ParamMap Wertmarken [„token“] aus dem router-Paket importiert werden. Anschließend muss der switchMap-Operator importiert werden, der dazu verwendet wird, die beobachtbaren [„observable“] route-Parameter abzuarbeiten. Wie gewöhnlich schreiben wir einen constructor, der Angular anfragt, services einzuspeisen, welche die Komponente benötigt, und diese mithilfe privater Variablen zu referenzieren.

In der ngOnInit-Methode verwenden wir den ActivatedRoute service, um die Parameter für das route-Objekt abzurufen, den employee ID aus den Parametern heraus zu ziehen und den employee zu extrahieren, den wir anzeigen wollen. Die Abarbeitung der paramMap ist etwas knifflig. Wenn die map sich ändert, bekommen [„get()“] wir die ID Parameter von den geänderten Parametern. Man könnte denken, jetzt wäre die Gelegenheit die RxJS map zu verwenden, der EmployeeService Operator liefert jedoch ein Observable zurück. Deswegen ebnen wir stattdessen das Observable mit dem switchMap-Operator ein. Zusätzlich verwirft der switchMap-Operator vorhergehende, „fliegende“ Anfragen. Wenn der Benutzer mit einer neuen ID zur gleichen Route zurück kehrt während der EmployeeService noch eine alte ID verarbeitet, verwirft switchMap die alte Anfrage und liefert den employee für die neue ID zurück.

Teilweise Übersetzung des Artikels von Yallaling Goudar. Code-Beispiele und weitere Ausführungen dort.

Ebenso ein nützlicher Link: switchMap auf Learn RxJS.