datavisualisation

Generative Art mit Processing und Hype Framework

Wie kann Kunst maschinell mit dem Computer entstehen? Unter dem Schlagwort Generative Art finden sich einige interessante Frameworks. Einen Einstieg in das Thema kann man z.B. unter How to Create Generative Art In Less Than 100 Lines Of Code oder How to hack a painting finden.

Interessant ist das schon länger existierende Framework processing. Processing bietet ein guten Rahmen zum entwickeln generativer Kunst. Dabei ist Kunst hier nicht nur auf reine visuelle GenArt beschränkt. Vielmehr sind auch insbesondere audiovisuelle und interaktive Werke hiermit umsetzbar. Sound kann beispielsweise entweder als Soundfile oder auch direkt generative integriert werden. Die Umsetzung kann dann direkt im Brower mit der Javascript Variante https://p5js.org/ erfolgen.

Interessant ist aber auch die generative Kunst direkt mit den Desktoptools zu erstellen. Hier gibt es einige Plugins, wobei ich das Hype Framework von Joshua Davis ganz besonders hervorheben möchte. Das Framework bringt zahlreiche visuelle Basics und Module mit, die schöne Menschmaschine oder Maschinemaschine Kunst ermöglicht.

Das Beispiel unten zeigt das LIFLIT.io Logo wie es in ein generiertes Bild auf Basis des Farbspektrums integriert wird. Generativ unterstützt die Position der Maus bei der Erstellung mit den sog. Swarms.

Standard
container, socialweb, web

Jitsi Meet integrieren und selbst betreiben

Inzwischen sollte Jitsi Meet neben den diversen Videokonferenzlösungen wie Zoom, Teams ein Begriff sein. Meiner Meinung nach überzeugt Jitsi Meet unter anderem durch eine sehr gute Webintegration. Mit der IFrame API ist das einbetten in eine eigene Websites sehr einfach. Die API hat einen großen Umfang an Command und Events, die eine tiefe Integration ermöglichen.

Obwohl das Einbetten der offiziellen Server von Jitsi Meet durchaus möglich ist sind einige Einstellungen mittels API dann aber doch nicht über die API änderbar. Z.B. ist

  • eine Begrenzung der Videoqualität nicht ohne weiteres möglich
  • das default Branding der Konferenz nicht änderbar
  • manche Funktionen (z.B. Ausblenden von Menüs) nur oberflächlich unterdrückbar

Für eine volle Kontrolle – und das ist meiner Meinung nach derzeit ein Alleinstellungsmerkmal von jitsi – ist die Möglichkeit einen (oder mehrere) eigene Jitsi Meet Server zu betreiben. Es gibt einen Selfhosting Guide der u.a. eine Installation als Docker Container oder näher am Metall auf Ubuntu, Debian, openSuse beschreibt.

Die Variante Docker ist hier unbedingt für einen schnellen Einstieg zu empfehlen. Die komplette Konfiguration erfolgt dann via eines einzelnen Konfigurationsfiles (.env – File). Hier gibt es zwar ggf. ein paar undokumentierte Parameter, die können aber wiederum in der Datei docker-compose.yml  gefunden werden. Mit docker-compose up -d werden die neuen Parameter in den Container übernommen.

Je nach eingesetzter Hardware empfiehlt es sich die Videoqualität anzupassen. Eine Deaktivierung des p2p Modes und die Begrenzung der maximalen Videogröße sind für Server und leistungsschwächere Clienthardware ein echter Performancegewinn. Tobias Scheible hat in seinem Blog hierzu wirklich richtig gute Anleitungen (Danke!) die echt weiterhelfen.

LIFLIT.io

Auch bei www.LIFLIT.io ist nun ein eigener Jitsi Meet Server aktiv und erweitert den schon bekannten Chat (Shopchat) um die Möglichkeit einer Videokonferenz.

Standard
cloud, ops

Opentelemetry – Distributed Monitoring

Github.com beschreibt im Blogartikel das es auch bei Github.com eine Herausforderung ist, die vielen verteilten Systeme gemeinsam zu monitoren und auch traces & metrics über dieses Systeme zu sichten bzw. zu erheben. Schön zu hören 🙂 das auch hier ein offenes Projekt wie Opentelemetry zum Einsatz kommt.

Auf den ersten Blick hat Opentelemetry das potenzial verteilte Systeme die polyglot entwickelt wurden in einen gemeinsamen trace, metrics und log Kontext zu bringen. So gibt es z.B. Agenten für Java und hier insbesondere für Spring. Aber auch andere Frameworks sollen explizit unterstützt werden und sind dem Namen nach zahlreich vertreten. To name of few: Kafka, RabbitMQ, PostgreSQL

Das klingt erstmal vielversprechend, lt. eigener Aussage ist (Stand heute) dieses Agentframework (observability framework) noch als Beta deklariert und soll bald ein offizielles Release erhalten.

Plan meinerseits ist den Testtrail unter https://opentelemetry.io/docs/java/instrumentation_examples/ einmal auszuprobieren.

Standard
mobile, web

Bootstrap 5 in Action

Bootstrap 5 ist seit ein paar Wochen released und bringt viele Neuerungen mit. Neben den überarbeiteten Komponenten wie z.B. Accordion oder das neue Offcanvas ist aus meiner Sicht eine wichtige Neuerung innerhalb des Frameworks der Verzicht auf jQuery. Das macht sich insbesondere bei der Ladegeschwindigkeit bemerkbar.

Gerade released und schon eingebaut. www.LIFLIT.io hat bereits Bootstrap 5 eingebaut und zeigt sich in neuem Glanz. So ist z.B. der Shopchat mit einem Offcanvas ausgestattet und gibt z.B. auch innerhalb eines Fullscreen Modal Dialogs die Möglichkeiten Items oder Bilder ein- und auszublenden.

Grids, Container die schon vorher verbaut wirken nochmal deutlich moderner. Das Accordion, das im LIFLIT Schaufenster zum Einsatz kommt ist ebenfalls grafisch. Ebenfalls verbaut sind die neuen Switches. Die haben mir persönlich schon lange gefehlt.

Danke an https://github.com/orgs/twbs/people, Great Job!

Standard
web

Dark Patterns

Unter Dark Patterns versteht man grafische Mittel um den User entweder zu täuschen bzw. abzulenken oder die eigentliche Intention des Users so zu erschweren das dieser auf einen anderen Pfad geführt wird und am Ende etwas ganz anderes macht oder aufgibt.

Die Seite https://darkpatternstipline.org/ sammelt solche Muster und stellt schon eine schöne Sammlung an Beispielen solcher Muster bereit.

Unter https://darkpatternstipline.org/sightings/busuu/ wie z.B. beschrieben wie ein schlichtes unsubscribe durch ein Captcha unnötig in die Länge gezogen wird.

Standard
Swim the Datalake

Kurztipp: Jupyter logging

Wenn Du mal in Jupyter richtig loggen möchtest, dann nutz doch einfach python logging.

Gute Beschreibung gibt es hier von wassname

"""
In jupyter notebook simple logging to console
"""
import logging
import sys
logging.basicConfig(stream=sys.stdout, level=logging.INFO)
# Test
logger = logging.getLogger('LOGGER_NAME')
logger.debug('This is hidden')
logger.info('So this is shown on the console')
logger.warning('This too')
"""
In jupyter notebook simple logging to console and file:
"""
import logging
import sys
logging.basicConfig(
level=logging.INFO,
format='[{%(filename)s:%(lineno)d} %(levelname)s – %(message)s',
handlers=[
logging.FileHandler(filename='tmp5a.log'),
logging.StreamHandler(sys.stdout)
]
)
# Test
logger = logging.getLogger('LOGGER_NAME')
logger.debug('This message should go to the log file and to the console')
logger.info('So should this')
logger.warning('And this, too')
"""
Setup simple logging in python. This logs info message to stdout and debug messages to file.
Sure it's long but this is as simple as I could make it for this outcome.
Note: We must set the root logger at DEBUG level, since it must be higher than it's children to pass them on.
Then set filehandler at debug and stream handler at info.
"""
import logging
import sys
import datetime
# To use differen't log level for file and console
timestamp = datetime.datetime.utcnow().strftime('%Y%m%d_%H-%M-%S')
filename=f'/tmp/tmp5a_{timestamp}.log'
formatter = logging.Formatter('[%(asctime)s] %(name)s {%(filename)s:%(lineno)d} %(levelname)s – %(message)s')
file_handler = logging.FileHandler(filename=filename)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(formatter)
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setLevel(logging.INFO)
# The handlers have to be at a root level since they are the final output
logging.basicConfig(
level=logging.DEBUG,
format='[{%(filename)s:%(lineno)d} %(levelname)s – %(message)s',
handlers=[
file_handler,
stream_handler
]
)
# Test
logger = logging.getLogger('LOGGER_NAME')
logger.debug('This message should go to the log file')
logger.info('This should go to the stdout and file')
logger.warning('And this, too')
print('filelog', open(filename).read())

Allerdings funktionieren die Einstellungen in logging.basicConfig erst wenn man die existierenden handler entfernt:

for handler in logging.root.handlers[:]:
    logging.root.removeHandler(handler)

Siehe auch https://stackoverflow.com/questions/54246623/how-to-toggle-jupyter-notebook-display-logging

Standard
Development, mobile

Mobilplatform: Tabris

Überblick

Auf der Suche nach crossplattform Ansätzen zur Mobilentwicklung  soll hier kurz das Framework Tabris vorgestellt werden. Tabris bietet eine Abstraktion zu den derzeit vorherrschende mobilen Platformen Android und IOS. Der Ansatz von Tabris ist dabei eine hybride Variante mit der Besonderheit das nicht H5JSCS (HTML5+JS+CSS) zum Einsatz kommt sondern die UI-Elemente dynamisch von einem Appframe in native Elemente umgesetzt werden.

Auf Basis von Eclipse-RAP wird das UI und Applogik in Plain Java (SWT & Jface für UI, JEE für Applogik) mittels einer Webapplikation komplett bereitgestellt. Die Kommunikation findet via REST+JSON statt und lässt somit Raum für diverse zukünftige Clients.

Auf dem Prüfstand

Eine erste Testanwendung ist schnell umgesetzt: Im wesentlichen muss dafür in der Webapplikation das Interface org.eclipse.rap.rwt.lifecycle.IEntryPoint implementiert werden und in der web.xml das Servlet org.eclipse.rap.rwt.engine.RWTServlet zum zum Einsatz kommen. Zur Konfiguration kommt eine Implementierung von org.eclipse.rap.rwt.application.ApplicationConfiguration die ebenfalls in der web.xml als context-param eingesetzt wird. (Siehe auch Getting Started von Tabris.)

Für Android und IOS muss nur der Appframe gebaut werden und auf die URL der Webapplikation gezielt werden. Nach Start des Appframes im Simulator oder Device lässt sich direkt die Anwendung mit nativen UI-Elementen ausführen.

Schokoladenseite

Dieser hybride Ansatz kann insbesondere durch folgende Eigenschaften punkten:

  1. Komplette Entwicklung des UI und der Applogik in Plain Java als Webapplikation.
  2. Das UI entspricht der jeweiligen Platform. Dies zahlt auf das UX (Userexperience) und die Performance/Responsivität der Applikation ein
  3. Erprobte Techniken mit SWT und Jface, sowie JEE kommen zum Einsatz
  4. Anbindung weiterer Clients z.B. Windows8 möglich.

Problemzonen

Es greift auch hier das generelle Problem einer Crossplattform-Lösung: Aufgrund der Abstraktion unterschiedlicher Zielplatfformen kann immer nur eine Untermenge der verfügbaren nativen Funktionen angesprochen werden. Derzeit unterstützt Tabris nur eine Abstraktion für die Geolokalisierung. Hier sind aber für das Release 1.0 mehr Funktionen geplant. (siehe http://developer.eclipsesource.com/tabris/docs/faq/ ) Trotzdem: Spezielle Funktionen wie NFC sind schlicht auf IOS nicht verfügbar und können nur auf einzelnen Plattformen bereitgestellt werden. Wie dies architektonisch sauber umzusetzen ist für die Appentwicklung einerseits und die Entwicklung von Tabris andererseits muss sich erst noch zeigen.

Zu bedenken ist aber auch noch eine weitere Facette: Wie eine H5JSCS App benötigt Tabris ebenfalls eine ständige Verbindung zur Webapplikation. UI und Applogik sind nur via Serververbindung verfügbar. Auf den ersten Blick ist man hier geneigt zu sagen, das Verhalten entspricht halt einer Webanwendung: Ohne Netz keine Funktion. Nur: Vom Thema Userexperience her gesehen ist dieses „Webapp-Verhalten“ schädlich, da der Nutzer dieses Verhalten von einer (scheinbaren) nativen App so nicht kennt und vermutlich überrascht sein wird, warum z.B: die ganze App ausfällt.

Fazit

Der innovative Ansatz  als eigenständige Form einer hybriden Appentwicklung positioniert sich in der Mitte zwischen reinen H5JSCS und nativen Anwendungen als weitere wichtige Stufe: Natives UI mit zentraler Applogik. Sollte es gelingen die Problemzonen insb. der Offlinefähigkeit ggf. über Caching abzufangen ist dieses Framework für eine Vielzahl von Anwendungsfällen sicherlich der Schlüssel in die mobile Entwicklung aus der Javawelt.

Standard