https://martinfowler.com/articles/modularizing-react-apps.html
Voice.AI: GPL Violations with a Side of DRM
The technology behind GitHub’s new code search
Leibniz, Llull, and the Computational Imagination
Abstraction is Expensive
“At companies with huge engineering forces, abstraction management is what a lot of them spend their time on. Often, these engineers are actually the most “productive” in terms of money saved – infrastructure projects tend to result in 8-9 figure savings or unique capabilities, and performance engineering (another form of abstraction alignment) frequently has 8 figure returns per engineer. Another large group of engineers is in charge of making sure that the old abstractions don’t break and crash the entire system.
Conversely, this is where startups can develop technical advantages on big tech despite having much smaller engineering teams, and where bootstrapped companies can out-engineer series-D companies. Given the freedom to align your abstractions to your goals, amazing things are possible.”
Refactoring Python
Man and machine: GPT for second brains
Dataset Retrieval: Informationsverhalten von Datensuchenden und das Ökosystem von Data-Retrieval-Systemen
Allgemeines Metadatenprofil für Bildungsressourcen (AMB)
Data on the web
37signals (Basecamp, Hey) – cloud spend in 2022
“So that’s how we spent millions on the cloud in 2022!
In 2023, we hope to dramatically cut that bill by moving a lot of services and dependencies out of the cloud and onto our own hardware. We don’t operate our own data centers, but work with our friends at Deft to lease rackspace, bandwidth, power, and white glove service. That isn’t cheap either at our scale, but it’s far, far less than what we spend on the cloud.”
Your tech stack is not the product
javascript console.log et al
Kommentar zu: Harmonisiertes Metadatenschema für die DSpace-Repositorien der Berliner Universitäten
Im folgenden teile ich hier einige Gedanken zu dem Papier:
“Harmonisiertes Metadatenschema für die DSpace-Repositorien der Berliner Universitäten – Ergebnis der Arbeitsgruppe DSpace Metadaten bestehend aus Mitgliedern der Charité – Universitätsmedizin Berlin, der Freien Universität Berlin, der Humboldt-Universität zu Berlin und der Technischen Universität Berlin”
Zu finden hier: https://refubium.fu-berlin.de/handle/fub188/37260
Direktlink zum Datensatz hier: https://refubium.fu-berlin.de/bitstream/handle/fub188/37260/Berlin_DSpace_MDS.xlsx?sequence=1&isAllowed=y&save=y
Als Entwickler finde ich die im Abstract formulierten Zielsetzungen besonders wichtig und erfreulich:
“Ziel ist, innerhalb der Berliner Universitäten einen einheitlichen
Gebrauch der Metadaten zu gewährleisten. Gleichzeitig wird es bei
Einführung des neuen Modells möglich sein, Mappingtabellen, Schnittstellen
und Programmierarbeiten zwischen den beteiligten Einrichtungen leichter
auszutauschen.”
Trigger
Das Arbeitsergebnis wurde als Excel-Datei veröffentlicht. Dies reicht als Grundlage für einen gelungenen Datenaustausch natürlich noch nicht aus. Typische Folgefragen von Softwareentwicklern sind:
– Wo finde ich die konkreten Schemadateien?
– Gibt es Testsysteme?
– Welche Protokolle/APIs sollen zum Austausch der Daten angeboten und genutzt werden?
– Wie sieht es mit Mehrsprachigkeit in den Metadaten aus?
Aber zurück zum vorliegenden Datensatz:
Beobachtung
An vielen Stellen in der Excel-Datei steht als Datentyp Freitext. Es gibt kaum MetaMetadaten. An einigen Stellen erscheint das Modell zu flach und zu spezifisch. Dies ist in gewisser Weise Schade, da hier die zitierte. Zielsetzung möglicherweise durch “ein paar Handgriffe” optimaler unterstützt werden könnte.
Beispiel aus Zeile 22-24:
Feld | Beispielwert |
dc.subject | open access |
dc.subject.ddc | 300 Sozialwissenschaften |
dc.subject.rvk | AK 54355 |
Ein paar Dinge fallen hier auf:
1. In den Freitextfeldern werden Notationen und Label gemischt
2. Für einzelne Notationssyteme existieren spezielle Unterfelder (ddc,rvk). Dies ist nicht gut erweiterbar. Besser wäre es zu jedem Subject das Notationssystem zu vermerken und für diesen Vermerk seinerseits ein kontrolliertes Vokabular (z.B. basierend auf Wikidata, s.u.) zu definieren.
3. Es wird nicht ganz klar, wie Mehrsprachigkeit realisiert werden soll.
4. Es gibt kein (Sub)Feld indem z.B. URIs auf SKOS-Vokabulare mitgeführt werden könnten.
These
Um den Bereich “subject” besser maschinell nachnutzbar zu machen, sollten kontrollierte SKOS-Vokabulare die Regel sein. Wenn möglich sollten URIs zur Identifikation von verwendeten Termen mit im Datensatz gespeichert werden.
In jedem Fall sollten Notationen, Label und IDs im Datenmodell in getrennte Unterfelder laufen. Labels sollten mehrsprachig im Datensatz mitgeführt werden können bzw. über eine URI leicht nachgeladen werden können.
Beispiel und Vorschlag
Das Beispiel zeigt ein Schlagwort im Feld subject mit zusätzlichen Informationen.
"subject":[{ "id":"http://dewey.info/class/300", "notation":"300", "prefLabel": "Sozialwissenschaften", "label":{ "de":"Sozialwissenschaften" "en": "Social Sciences" "fr":"...." }, "source":{ "id":"https://www.wikidata.org/wiki/Q15222117", "label":{ "en": "Dewey Decimal Classification" } "similarTo": "https://www.wikidata.org/wiki/Q34749" } }]
Zusätzlich zu dem Schlagwort werden Informationen zur Quelle und zum Notationssystem gegeben. Notation und Schlagwort werden getrennt. Es wird über einen Link auf Wikidata eine Verlinkung in andere Schlagwortsysteme realisiert.
Und was bringt das?
Dies hat vor allem Vorteile auf der maschinellen Konsumentenseite.
- Alle subjects, egal aus welchem Vokabular, können zunächst mal leicht verarbeitet werden. Folgendes geht z.B. immer: subject.0.prefLabel, subject.0.label.de . Hierbei ist es egal, aus welchem Notationssystem ein Schlagwort kommt. Dies stellt eine erhebliche Vereinfachung für Aggregatoren dar, die für einfache Anwendungsfälle keine weiteren Informationen über die angebotenen Subfelder eines Quellsystems haben müssen. Siehe Punkt 4.
- Über die “source” und die “notation” können einerseits in einer grafischen Oberfläche zusätzliche Hinweise gegegeben werden, andererseits können die nachnutzenden Systeme Verknüpfungen zu anderen Datensätzen herstellen und so sehr effektive Browsingoberflächen oder sonstige Bezugssysteme aufbauen.
- Wikidata als ein mögliches Werkzeug um Verknüpfungen herzustellen. Über den Link unter “similarTo” können weitere Vokabulare verknüpft werden. Sehr praktisch wenn man z.B. die Inhalte unterschiedlicher Quellen mit unterschiedlicher Verschlagwortung/Erschließung aggregieren möchte.
- Durch den Verzicht auf Unterfelder für spezifische Vokabulare, z.B. .ddc oder .rvk , wird ein einheitlicher Zugriff auf Schlagworte aus unterschiedlichen Vokabularien unterstützt. Dadurch können konsumierende Systeme auch Schlagwortsysteme, die sie nicht vollständig unterstützen einfach zur Anzeige bringen und indexieren, etc..
- Anzeige und intellektuelle Erschließung werden separiert. Die Anzeige eines Schlagworts (das Label) wird von der verwendeten Notation getrennt. Dies eröffnet nachnutzenden Systemen die Möglichkeit kontextspezifische Anzeigestrategien zu etablieren ohne die zugrundeliegende intellektuelle Erschließung (in Form der Notation) anpassen zu müssen. Ersteres ist oft gewünscht, letzteres ist oft nicht ohne weiteres möglich.
Accessing container environment at startup time with typescript / react / docker
Blogpost for this stackoverflow answer: https://stackoverflow.com/a/74701083/1485527
Get code here
Create example app
npx create-react-app read-env-example --template typescript
Navigate to fresh app
cd read-env-example
Create Dockerfile
mkdir -p docker/build
docker/build/Dockerfile
# build environment
FROM node:19-alpine3.15 as builder
WORKDIR /app
ENV PATH /app/node_modules/.bin:$PATH
COPY package.json ./
COPY package-lock.json ./
RUN npm ci
RUN npm install react-scripts@5.0.1 -g
COPY . ./
RUN PUBLIC_URL="." npm run build
# production environment
FROM nginx:stable-alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
COPY docker/build/docker-entrypoint.sh /
RUN chmod +x docker-entrypoint.sh
ENTRYPOINT ["/docker-entrypoint.sh"]
Create docker-entrypoint.sh
This script will be executed at container start.
It generates the config.js
file containing all environment variables starting with ‘MYAPP’ under window.extended
.
docker/build/docker-entrypoint.sh
#!/bin/sh -eu
function generateConfigJs(){
echo "/*<![CDATA[*/";
echo "window.extended = window.extended || {};";
for i in `env | grep '^MYAPP'`
do
key=$(echo "$i" | cut -d"=" -f1);
val=$(echo "$i" | cut -d"=" -f2);
echo "window.extended.${key}='${val}' ;";
done
echo "/*]]>*/";
}
generateConfigJs > /usr/share/nginx/html/config.js
nginx -g "daemon off;"
Create docker-compose.yml
mkdir docker/run
docker/run/docker-compose.yml
version: "3.2"
services:
read-env-example:
image: read-env-example:0.1.0
ports:
- 80:80
env_file:
- myapp.env
Create runtime config for your app
docker/run/myapp.env
MYAPP_API_ENDPOINT='http://elasticsearch:9200'
Create config.js <– this is where .env will be injected.
public/config.js
/*<![CDATA[*/
window.extended = window.extended || {};
window.extended.MYAPP_API_ENDPOINT='http://localhost:9200';
/*]]>*/
Note: This file will be completely overwritten by the docker-entrypoint.sh
. For development purposes you can set it to any value that is appropriate, e.g. when used together with npm start
.
Include config.js in index.html
public/index.html
<head>
...
<script type="text/javascript" src="%PUBLIC_URL%/config.js" ></script>
...
</head>
<body>
Make use of your environment variable
src/App.tsx
declare global {
interface Window { extended: any; }
}
function App() {
return (
<div className="App">
<header className="App-header">
You have configured {window.extended.MYAPP_API_ENDPOINT}
</header>
</div>
);
}
Build
npm install
Create docker image
docker build -f docker/build/Dockerfile -t read-env-example:0.1.0 .
Run container
docker-compose -f ./docker/run/docker-compose.yml up
Navigate to your app
Open http://localhost in your browser.
You will see the content of MYAPP_API_ENDPOINT
like provided in your docker/run/myapp.env
.
Further usage
You can provide additional variables starting with MYAPP
. The docker-entrypoint.sh
script will search for all variables starting with MYAPP
and make them available through the windows
object.
Erweiterung des “RheinEnergieSportparks” in Köln ist unwirksam
“Der 7. Senat des Oberverwaltungsgerichts hat heute über zwei Normenkontrollanträge einer Bürgerinitiative und des Landesverbands NRW des Naturschutzbunds Nabu mündlich verhandelt, die sich gegen den Bebauungsplan der Stadt Köln für die Erweiterung des “RheinEnergieSportparks” in Köln-Sülz richten. Er hat entschieden, dass der Plan unwirksam ist, weil er an einem Abwägungsmangel leidet; der Senat hat zugleich darauf hingewiesen, dass dieser Mangel in einem ergänzenden Planungsverfahren geheilt werden kann und weitere Mängel nicht ersichtlich sind.”
https://www.justiz.nrw/JM/Presse/presse_weitere/PresseOVG/24_11_2022_/index.php
Weitere Einordnungen finden sich u.a. hier: https://unsergruenguertel.de/2022/11/24/ausbauplaene/