Wenn ich nach längerem meine Excel Blätter mal wieder öffne, muss ich erstmal suchen, wo die Excel Eingaben hingehören.
In welchen Zellen stehen Formeln? Wo durfte ich reinschreiben?
Oder gib mal eins deiner Kalkulations-Tools an einen Kollegen weiter!
Der ist direkt verloren …
Das muss es aber nicht sein.
Mit nur wenigen Schritten kannst du die perfekte Eingabemaske für deine Excel Dateien erstellen.
Und das ganz ohne VBA!
Und noch besser! Die Eingabemaske, die wir hier bauen, kannst du als Grundlage für alle anderen Excel Dateien verwenden!
Dafür brauchst du nur ein paar kleine Änderungen vorzunehmen.
Wie simpel das ist, zeige ich dir am Ende. Also bleib unbedingt dran!
Deine Kollegen können kein Python? Sehr schade …
Aber natürlich lassen wir sie deshalb nicht im Regen stehen!
Wir erstellen einfach noch eine ausführbare Datei aus der Eingabemaske.
Ein Doppelklick und ab geht’s.
Das wird ja wohl noch jeder Kollege schaffen, oder? 😉
Wie kann ich eine Eingabemaske für Excel erstellen?
Mit PySimpleGUI erstellst du schnell und einfach Eingabemasken für deine Excel Dateien.
Du bekommst verschiedene Komponenten direkt mitgeliefert, die dir bei den verschiedenen Eingaben helfen.
Mit PyInstaller kannst du am Ende noch eine ausführbare Datei erstellen und deine Eingabemaske ohne Probleme an Kollegen verteilen.
Anforderungen
Was ist PySimpleGUI?
PySimpleGUI ist praktisch eine Hülle um GUI Frameworks wie den Python Standard Tkinter.
Du verlierst zwar etwas Flexibilität, kannst dafür aber viel schneller grafische Oberflächen zusammen stecken.
Falls dich Tkinter interessiert, hier habe ich ein Video dazu.
Das erste Fenster
Ohne ein Fenster, keine Eingabemaske.
Irgendwo müssen die ganzen Felder, Texte und Buttons ja festgehalten werden.
Um ein Fenster zu erzeugen, brauchst du die Klasse Window aus PySimpleGUI.
Viel braucht dein Fenster gar nicht. Einen Titel, ein Layout und in der Größe veränderbar sollte es auch sein.
import PySimpleGUI as sg
layout = [
[],
]
window = sg.Window(title='Excel Dateneingabe', layout=layout, resizable=True)
Das Layout ist eine Liste, wobei jeder Eintrag der Liste eine ganze Zeile darstellt. Und da in jeder Zeile mehrere Elemente liegen können, muss auch eine Zeile wiederum eine Liste sein.
Du hast also eine Liste aus Listen als Layout.
So leer wie hier ergibt das natürlich nicht viel Sinn. Aber darum kümmern wir uns gleich.
Erstmal geht es darum, überhaupt ein Fenster zu sehen.
Wenn du dein Programm jetzt startest, funktioniert es zwar schon, das Fenster schließt sich allerdings sofort wieder.
Um es offenzuhalten, brauchst du eine Schleife. Und zwar eine Endlosschleife:
while True:
event, values = window.read()
if event == sg.WIN_CLOSED:
break
window.close()
Und schon hast du eine Endlosschleife. Solange du sie nicht bewusst abbrichst, wird sie ewig laufen.
Oder bis dir der Strom ausgeht … Oder der Computer verreckt … je nachdem was schneller passiert 😉
Bei jedem Durchlauf der Schleife wird mit window.read() etwas vom Fenster abgefragt.
PySimpleGUI funktioniert mit einem Event System. Sobald in der GUI etwas passiert, wird also ein Ereignis (Event) ausgelöst.
Dabei hat jedes Event einen Namen und einen Wert, die du in den Variablen event und values entgegennimmst.
Jetzt kannst du prüfen, was es für ein Event war.
Als Erstes ist auf jeden Fall interessant, ob der Benutzer das Programm beenden wollte.
Dafür bringt PySimpleGUI ein eingebautes Event mit: WIN_CLOSED.
Das wird ausgelöst, wenn der Benutzer den Schließen-Button am Fenster betätigt.
Das rote X in der rechten oberen Ecke bei Windows, der rote Punkt links oben bei MacOS.
Bei Linux … je nach Oberfläche, die du benutzt, aber eine der beiden Ecken.
Kommt dieses Event bleibt dir nichts weiter zu tun, als die Schleife mit einem break zu verlassen und das Fenster sauber über window.close() zu schließen.
Sehr schön!
Damit hast du ein erstes Fenster.
Es ist klein und leer und unbrauchbar, aber es ist sichtbar!
Und wenn du es in der Größe änderst, siehst du sogar ein echtes, leeres Fenster mit einem Titel.
Die ersten Inhalte
Leere Fenster sind langweilig. Änder das!
Wie schon gesagt, ist jeder Eintrag im Layout eine Liste, die wiederum eine ganze Zeile darstellt.
Und die Listen kannst du mit einzelnen Komponenten befüllen.
Fang mal einfach an. Ein Text, ein Eingabefeld mit einem Label und einen Button zum Abschicken, sowie einen zum Abbrechen.
import PySimpleGUI as sg
layout = [
[sg.Text('Bitte fülle die folgenden Felder aus:', font='14')],
# size: 15 chars wide, 1 char tall
# key: used to get values
[sg.Text('Name', size=(15, 1), font='14'), sg.InputText(key='Name', font='14')],
# two buttons
[sg.Submit(font='14'), sg.Exit(font='14')]
]
Die erste Zeile bekommt einen Text, der erklärt, was hier gemacht werden soll.
Dabei setzt du die Schriftgröße (font) noch auf 14.
Der Text in der zweiten Zeile dient als Label für das Eingabefeld in der zweiten Zeile.
Die Reihenfolge in der Liste gibt also auch gleich die Darstellungsreihenfolge an.
Auch hier setzt du die font wieder auf 14.
Allerdings kommen jetzt noch die Attribute key und size mit dazu.
key gibt einen eindeutigen Namen für ein Element an. Diese Namen dürfen nicht doppelt verwendet werden. Hast du einem Element einen Namen gegeben, darf kein zweites Element denselben Namen tragen!
Bei size handelt es sich um eine Größenangabe für das Textfeld. Mit dem ersten Wert gibst du die Breite des Textfelds an, also wie viele Zeichen Breite das Feld haben soll. Die Angabe ist unabhängig vom tatsächlichen Inhalt!
Die zweite Zahl gibt die Zeilenhöhe an. Auch wieder in Zeichen bemessen. Die 1 ist also Inhalt mit einer Zeile.
Die erste Funktion
Abschließend fügst du noch zwei Buttons hinzu. Einen zum Abschicken der eingegebenen Daten und einen zum Beenden der Anwendung.
Für den Exit Button reicht es, wenn du die schon vorhandene Bedingung erweiterst:
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
window.close()
Der Exit Button schickt ein “Exit” Event. Darauf kannst du prüfen und genauso wie bei einem WIN_CLOSED die Schleife stoppen und damit die Anwendung beenden.
Fehlt noch der Submit Button zum Abschicken der Inhalte.
Erstmal reicht es, wenn du prüfst, dass der Button auch tatsächlich funktioniert.
Dafür kannst du nach der Prüfung auf ein Beenden der Anwendung einfach eine weitere Bedingung einführen und auf “Submit” prüfen.
So wie der Exit Button ein “Exit” sendet, erhältst du vom Submit Button ein “Submit”.
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit':
break
if event == 'Submit':
print(event, values)
window.close()
Starte dein Programm und schreibe “Test” in das Eingabefeld. Wenn du im Anschluss den Submit Button betätigst, erhältst du so eine Ausgabe auf der Konsole:
Submit {'Name': 'Test'}
Die Excel Datei einbinden
Nachdem du jetzt gesehen hast, wie einfach du eine GUI mit Label und Textfeldern aufbauen und die Daten abschicken kannst, wollen wir uns an den nächsten Schritt machen.
Am Ende willst du eine GUI für Excel Daten haben, also müssen die Daten natürlich auch in eine Excel Datei eingegeben werden.
Zuerst legst du mal den Pfad zu deiner Excel Datei fest. Ohne den läuft nämlich einfach mal gar nichts.
from pathlib import Path
EXCEL_FILE = Path(__file__).parent.joinpath('Dateneingabe.xlsx')
Mit Path(__file__) bekommst du den aktuellen Pfad, in dem dein Skript ausgeführt wird. EINSCHLIESSLICH des Namens des Skripts.
.parent wechselt in der Ebene eins nach oben und hängt dann mit .joinpath() den Dateinamen an den Pfad an.
Somit liegt deine Excel Datei dann an der Stelle, an der später deine ausführbare Datei liegt. Also deine .exe unter Windows zum Beispiel.
HINWEIS:
Wenn du auf MacOS unterwegs bist, muss die Zeile so aussehen:
from pathlib import Path
EXCEL_FILE = Path(__file__).parent.parent.parent.parent.joinpath('Dateneingabe.xlsx')
Das liegt daran, dass der Finder die Pfade etwas anders behandelt, bzw. bei einer ausführbaren Datei unter MacOS der Pfad tiefer beginnt.
Wenn du mehr zu Python und Dateien lesen möchtest, habe ich hier einen wunderbaren Artikel für den Einstieg für dich.
Falls du noch mehr zu Dateien und auch Verzeichnissen und Verzeichnisstrukturen lesen möchtest, dann habe ich hier noch mehr Artikel für dich.
Gibt es die Datei schon?
Wenn dein Skript startet, gibt es direkt zwei mögliche Szenarien:
- Eine Excel Datei existiert bereits und soll erweitert werden
- Eine Excel Datei existiert noch nicht und soll angelegt werden
Also erstmal prüfen, ob die Datei schon existiert.
Da du den Pfad schon mithilfe der Klasse Path erzeugt hast, kümmert sich Python im Hintergrund schon darum den Pfad auch wirklich als Pfad zu behandeln.
Du kannst somit direkt verschiedene Operationen daran ausführen.
So auch prüfen, ob der Pfad – also die Datei – denn existiert:
if EXCEL_FILE.exists():
pass
else:
pass
Damit weisst du, wann du was unternehmen musst. Weiter geht’s.
Im ersten Fall, die Excel Datei existiert bereits, musst du die Datei einlesen, damit du später Daten hinzufügen kannst.
Mit Pandas geht das schnell und unkompliziert.
df = pandas.read_excel(EXCEL_FILE)
Im zweiten Fall existiert die Datei noch nicht. Wir haben also nichts, was wir einlesen könnten.
Das heißt, wir müssen uns selbst ein Dataframe erstellen, zu dem wir dann Daten hinzufügen können.
Dafür legen wir einfach alle Spalten an, die wir in der Excel Datei haben wollen und fügen sie zu einem neuen Dataframe hinzu:
columns = ['Name']
df = pandas.DataFrame(columns=columns)
Daten anhängen
Egal wie – jetzt hast du ein Dataframe, an das du Daten anhängen kannst.
Und woher bekommen wir jetzt die Daten? Aus dem Submit Event.
Bisher haben wir die Daten einfach nur auf die Konsole ausgegeben.
if event == 'Submit':
print(event, values)
Jetzt wollen wir sie auch anhängen und speichern.
Dafür legen wir uns zuerst eine neue Zeile an. Eine Zeile ist im Endeffekt auch nur ein weiteres Dataframe mit einem Eintrag:
entry = pandas.DataFrame(values, index=[0])
Wir nehmen also die Werte, die uns das Submit Event geschickt hat und erzeugen damit ein neues Dataframe.
Der Eintrag bekommt dabei den Index 0.
Als Nächstes muss der Eintrag an die bestehenden Daten angehängt werden.
Zu Beginn unseres Skripts laden wir die Daten oder erzeugen ein neues, leeres Dataframe.
Das heißt, egal wie, wir haben ein Dataframe, dass beliebig viele Daten beinhalten kann.
Um unsere neue Zeile jetzt anzuhängen, müssen wir nur das neue Dataframe an das bestehende Dataframe anhängen.
Dafür liefert uns Pandas die Funktion .concat:
df = pandas.concat([df, entry], ignore_index=True)
An .concat() wird einfach eine Liste mit allen Dataframes übergeben, die der Reihe nach aneinander gehängt werden sollen.
Wir nehmen also das “alte” Dataframe (df) und hängen die neue Zeile (entry) mittels .concat an.
Dazu müssen wir Pandas noch mitteilen, dass der Index bei der Aktion ignoriert werden soll.
Andernfalls würde es zu Fehlern, bzw. Inkonsistenzen kommen, da der originale Index nicht mit unserer neuen Zeile übereinstimmt.
Daten speichern
Damit haben wir jetzt EIN Dataframe in der Hand, dass ALLE Daten beinhaltet, die wir haben möchten.
Jetzt müssen wir nur noch eine Excel Datei daraus erstellen, damit die Daten auch gespeichert sind und wir sie weiter geben können.
Wie so oft ist auch das wieder einfach nur ein Einzeiler:
df.to_excel(EXCEL_FILE, index=False)
An unserem Ergebnis-Dataframe können wir direkt die Funktion .to_excel() aufrufen und einfach unser Path Objekt übergeben.
Damit weiß Pandas, wohin die Daten geschrieben werden sollen und unsere vorhandene Excel Tabelle wird direkt ersetzt.
Pandas erstellt immer einen Index. Im Standard ist das einfach eine fortlaufende Nummer, die die Zeilen durchzählt.
Wenn wir jetzt einfach nur die Daten in einer Excel Datei speichern, wird die erste Spalte automatisch der Index sein.
Um das zu verhindern, fügen wir einfach nur das Attribut index=False hinzu. Schon wird der Index beim Speichern ignoriert und es tauchen nur die Spalten auf, die wir in der Datei sehen wollen.
Rückmeldung an den Benutzer
Das alles passiert jetzt weitgehend im Hintergrund.
Natürlich sieht und weiß der Benutzer, dass er den Button Submit gedrückt hat und erwartet auch, dass etwas passiert.
Ob das aber wirklich passiert, sieht er aktuell nicht. Als Bestätigung sollten wir ihm also irgendeine Art Meldung ausgeben.
Auch das ist mit PySimpleGui kein Problem!
Dafür erzeugen wir einfach ein neues Popup und füllen es mit Text:
sg.popup('Daten erfolgreich gespeichert!', font='14')
Fügen wir das nach dem Speichern der Excel Datei ein, bekommt der Benutzer eine Ausgabe, sobald die Datei gespeichert wurde.
Daten leeren
Nachdem die neuen Daten jetzt erfolgreich gespeichert wurden, wollen wir die Eingabefelder leeren.
Andernfalls müsste der Benutzer nach jeder Eingabe durchgehen, die alten Daten löschen und neue hinzufügen.
Das ist nicht nur viel zu aufwändig, sondern auch viel zu fehleranfällig.
Zu leicht kann dabei was übersehen werden und schon sind falsche Daten eingetragen.
Also nehmen wir dem Benutzer die Arbeit ab und löschen die Daten für ihn, sobald sie erfolgreich in der Datei hinterlegt wurden.
Mit window.read() haben wir vorher schon alle Werte aus dem Fenster ausgelesen.
Jeder Wert wiederum besteht aus einem Schlüssel und dem eigentlichen Inhalt.
Das InputText Feld Name hat den Schlüssel (key) Name, den wir gesetzt haben und dazu den zugehörigen Wert, der in das InputText Feld eingetragen wurde.
Um jetzt die Daten zu löschen müssen wir also nur durch alle Werte, bzw. Felder laufen, die wir in dem Fenster haben und ihre Werte entfernen:
for key in values:
window[key]('')
Das könnten wir jetzt einfach nach dem Popup setzen.
Werden die Daten gespeichert, erscheint das Popup als Rückmeldung für den Benutzer und die Felder werden geleert, damit alles für die nächste Eingabe vorbereitet ist.
Aktuell haben wir ein Feld. Das ist nicht besonders viel und noch überschaubar.
Aber überleg mal wie die Sache aussieht, wenn es auf einmal 10, 20 oder 50 Felder sind, die gefüllt werden müssen?
Und was, wenn der Benutzer mitten in der Eingabe merkt, dass er im falschen Datensatz ist?
Da wäre es doch klasse, wenn er einen Button bekommt, der ihm alle Felder zurücksetzt, oder?
Da wir Code ungern doppelt schreiben, lagern wir das Löschen der Felder einfach in eine eigene Funktion aus.
Damit können wir sie überall wiederverwenden:
def clear_input(values, window):
for key in values:
window[key]('')
Und statt den Code jetzt nach dem Popup einzufügen, fügen wir nur noch den Funktionsaufruf ein:
sg.popup('Daten erfolgreich gespeichert!', font='14')
clear_input(values, window)
Jetzt fehlt nur noch der Button, mit dem die Daten auch noch geleert werden können.
Dafür gehen wir nach oben, in unser Layout.
Die Liste, bzw. Zeile, die für unsere Submit und Exit Buttons zuständig ist, werden wir jetzt einfach um einen weiteren Button erweitern:
[sg.Submit(font='14'), sg.Button('Clear', font='14'), sg.Exit(font='14')]
Da es für Clear keinen vorgefertigten Button gibt, fügen wir einfach nur ein Element vom Typ Button.
Jeder Button feuert ein Event. Bei Submit und Exit ist das bereits mit eingebaut und wir mussten uns um nichts kümmern.
Jetzt haben wir einfach nur einen Standard Button. Der feuert auch ein Event. Aber wie das Event heißt, dürfen wir jetzt selbst bestimmen.
Dafür trägst du einfach einen beliebigen Namen als ersten Parameter ein.
Ich habe hier Clear gewählt, weil, nun ja, es ein Clear Button ist.
Du kannst es auch Löschen, Entfernen oder sonst wie nennen. Das liegt komplett bei dir.
Damit wir jetzt auf das Event reagieren können, gehen wir wieder nach unten im Code.
An die Stelle, an der wir die Events auslesen und schon auf Submit und Exit reagieren.
Hier kommt einfach nur eine neue Bedingung mit dem Event Namen rein, den du oben vergeben hast:
if event == 'Clear':
clear_input(values, window)
Wie schon bei Submit prüfen wir hier bei Clear auch einfach auf den Event Namen.
Ist es das Event, dass wir suchen, führen wir die clear_input() Funktion aus.
Und schon werden alle Daten aus den Eingabefeldern gelöscht, sobald der Button gedrückt wird.
Eingabemaske erweitern
Wie eingangs angekündigt, möchte ich dir jetzt noch zeigen, wie schnell du die Eigabemaske auf deine Bedürfnisse anpassen und erweitern kannst.
Nehmen wir an, wir möchten eine Liste mit Mitarbeitern in der IT-Abteilung erstellen und einen Überblick über deren Fertigkeiten erhalten.
Dafür wollen wir zusätzlich zum Namen noch die folgenden Daten sammeln
- Bereich (Frontend oder Backend)
- Alter (Als Zahlenwert)
- Erfahrung (in Jahren 1 – 3)
- Programmiersprachen (Mehrfachauswahl: Python, JavaScript, Java)
- Info (Ein Textfeld für optionale, weitere Informationen)
Wie du siehst, habe ich zu den Feldern schon immer mit angegeben, in welchem Format ich die Eingaben gerne hätte.
Das habe ich getan, weil PySimpleGui mehrere verschiedene Elemente angibt, die verwendet werden können.
Natürlich kann ich dir hier schlecht einen Überblick über alle verschaffen, aber wenigstens ein paar solltest du gesehen haben.
Den Rest kannst du jederzeit auf der Webseite von PySimpleGui unter Features nachlesen.
Zuerst fügen wir alle neuen Felder in unsere column Definition ein.
Das ist ganz oben, wo die Excel Datei erstellt wird. Ohne den Eintrag existieren die Spalten nicht und du hast nachher keine schöne Beschriftung oder sogar Fehler.
columns = ['Name', 'Bereich', 'Alter', 'Erfahrung', 'Python', 'JavaScript', 'Java', 'Info']
Dann geht’s auch schon ins Layout.
Hier fügen wir eins nach dem Anderen ein.
Dropdown
Zuerst der Bereich:
[sg.Text('Bereich', size=(15, 1), font='14'), sg.Combo(['Frontend', 'Backend'], key='Bereich', font='14')],
Der soll ein Dropdown sein, in dem zwischen Frontend und Backend ausgewählt werden kann.
Zuerst brauchen wir also wieder einen Text als Bezeichner, gefolgt von einer Combo Komponente.
Eine Combo Komponente macht nichts weiter, als ein Dropdown darzustellen. Um festzulegen, welche Werte in dem Dropdown erscheinen, übergeben wir einfach eine Liste mit den Werten, die darin erscheinen sollen.
Zahlenfeld
Dann können wir das Alter, als Zahlenfeld einfügen.
Das wird über einen Spinner dargestellt.
Wir brauchen also erst wieder einen Text als Bezeichner und dann einen Spinner:
[sg.Text('Alter', size=(15, 1), font='14'), sg.Spin([num for num in range(1, 100)], initial_value=18, key='Alter', font='14')],
Ein Spinner bekommt eine Liste mit Zahlen. Das schränkt die Auswahl ein, die dargestellt werden kann.
Zusätzlich kann über das Attribut initial_value angegeben werden, welcher Wert initial angezeigt werden soll.
Slider / Schieberegler
Für die Darstellung der Erfahrung wollen wir einen Slider verwenden.
Slider sind einfache Schieberegler mit einem festen WertebWertebereich,ereich in dem hin und her geschoben werden kann.
[sg.Text('Erfahrung', size=(15, 1), font='14'), sg.Slider(orientation='horizontal', key='Erfahrung', range=(1, 3), font='14')],
Nichts Neues: Wir brauchen einen Text als Bezeichner.
Danach kommt der angesprochene Slider.
Zuerst kannst du über das Attribut orientation angeben, ob der Slider ‘horizontal’ oder ‘vertical’ angezeigt werden soll.
Anschließend gibst du über das Attribut range an, welcher Bereich abgedeckt sein soll.
Checkbox
Zuletzt wollen wir uns noch um die Auswahl der Programmiersprache kümmern.
Hier gibt es auch erstmal wieder einen Bezeichner mit der Text Komponente.
Anschließend können wir die benötigten Checkboxen hinzufügen.
Dafür reihst du einfach alle Checkboxen auf und gibst ihnen den Wert, den sie darstellen sollen.
[sg.Text('Programmiersprachen', size=(15, 1), font='14'),
sg.Checkbox('Python', key='Python', font='14'),
sg.Checkbox('JavaScript', key='JavaScript', font='14'),
sg.Checkbox('Java', key='Java', font='14')],
Eine Checkbox hat am Ende immer einen Wahr oder Falsch Wert und wird als solches in deine Excel Daten übernommen.
Ein Theme für deine GUI
Bisher ist deine GUI einfach in den Standardfarben gehalten. Daran ist auch nichts falsch, aber vielleicht gefallen dir andere Farben besser?
PySimpleGUI kommt direkt mit einer Palette an Themes im Gepäch. Damit ist es ein Leichtes, zwischen verschiedenen Farben zu wecheln.
Natürlich könntest du die Themes auch dem Benutzer zur Auswahl geben und einfach zur Laufzeit wechseln!
Aber sieh dir erstmal an, was für Themes es gibt und wie sie funktionieren.
Ein Theme zu benutzen, ist super einfach!
Füge vor deiner layout Definition einfach diese Zeile ein:
sg.theme('GreenTan')
Und schon wird deine GUI in einem sanften Grün dargestellt.
Weitere Themes sind zum Beispiel:
- DarkTeal9
- BlueMono
- BrightColors
Eine Liste der verfügbaren Themes mit Vorschaubildern findest du in der offiziellen Dokumentation.
Ausführbare Datei
Mit dem Modul PyInstaller kannst du ganz schnell eine ausführbare Datei aus deinem Skript erstellen.
Dafür gibst du einfach den folgenden Befehl in dein Terminal ein und schon purzelt eine ausführbare Datei für dein aktuelles System heraus.
pyinstaller --onefile --noconsole --onedir excel_entry_gui.py
Wenn du mehr dazu wissen willst, habe ich hier und hier Videos für dich, die das Thema näher beleuchten.
Ingo Janssen ist ein Softwareentwickler mit über 10 Jahren Erfahrung in der Leitung seines eigenen Unternehmens.
Er studierte Wirtschaftsinformatik an der TH Deggendorf und hat Softwareentwicklung an der FOM Hochschule in München unterrichtet.
Ingo hat mit einer Vielzahl von Unternehmen zusammengearbeitet, von kleinen und mittelständischen Unternehmen bis hin zu MDAX- und DAX-gelisteten Unternehmen.
Ingo ist leidenschaftlich daran interessiert, sein Wissen und seine Expertise mit anderen zu teilen. Aus diesem Grund betreibt er einen YouTube-Kanal mit Programmier-Tutorials und eine Discord-Community, in der Entwickler miteinander in Kontakt treten und voneinander lernen können.
Sie können Ingo auch auf LinkedIn, Xing und Gulp finden, wo er Updates über seine Arbeit teilt und Einblicke in die Tech-Branche gibt.
YouTube | Discord | LinkedIn | Xing | Gulp Profile