Refactoring von Python zu .Net mit KI

Refactoring von Python zu .Net mit KI

23 Apr 2025
Joshua Heller

Refactoring – allein das Wort klingt schon nach einer Mammutaufgabe, besonders wenn es um die Migration zwischen zwei völlig unterschiedlichen Technologie-Stacks geht. Genau dieser Herausforderung habe ich mich gestellt, als ich beschlossen habe, mein Python-Projekt nach .NET zu überführen. Ohne .NET-Vorkenntnisse, aber mit viel Neugier und den richtigen KI-Tools wollte ich testen, was möglich ist.

Die Idee kam aus einem praktischen Anlass: Ein Projekt, das ich ursprünglich in Python entwickelt hatte, sollte in einer Sprache umgesetzt werden, die in unserem professionellen Umfeld besser unterstützt wird. Der Kunde setzt stark auf .NET. Konkret ging es um eine Konsolenanwendung, die Inhalte von Websites scrapte und mithilfe der ChatGPT-API zusammenfasste. Die Anwendung ist ursprünglich für unser Tool **imagetocaption.ai** entstanden.

Ziel des Experiments

Mein Experiment hatte zwei zentrale Ziele:

  1. Technische Machbarkeit: Kann ich es schaffen, innerhalb von nur vier Stunden eine funktionsfähige .NET-Version meines Projekts zu entwickeln – und das ohne jegliche .NET-Erfahrung?
  2. KI als Gamechanger: Wie viel Unterstützung können KI-Tools wie chatGPT, CursorAI oder GitHub Copilot leisten, um den Prozess zu beschleunigen und gleichzeitig ein solides Ergebnis zu liefern?

Ich wollte dabei nicht nur herausfinden, ob es technisch möglich ist, sondern auch, ob sich dieser Ansatz für andere lohnt. Die Frage war: Kann KI den Entwicklungsprozess revolutionieren, insbesondere für Entwickler, die in neue Technologien einsteigen?

Mit diesen Zielen und einer klaren Motivation bin ich in dieses Experiment gestartet. Und ich war gespannt: Würde ich es schaffen, eine saubere Lösung zu liefern – auch wenn sie nicht 100 % perfekt ist? In den nächsten Kapiteln erzähle ich dir, wie es gelaufen ist.

Das Projekt

Beschreibung der Anwendung

Das Projekt, um das es hier geht, war auf den ersten Blick simpel, hatte aber eine klare und nützliche Funktion: Es handelte sich um eine Konsolenanwendung, die Websites scrapt, die gesammelten Inhalte verarbeitet und mithilfe der ChatGPT-API relevante Informationen extrahiert. Die Anwendung diente in erster Linie als Prototyp für ein Tool wie imagetocaption.ai, das Texte automatisiert zusammenfasst oder analysiert. Hier ist das Original Repository: https://github.com/joshuaheller/web-summarizer

Es gibt ein paar Parameter. Sprache der Zusammenfassung, Fokus auf ein spezifisches Thema (z.B. Firma, Produkte oder Technologien) und Länge der Anwort (Stichpunkte, kurz, lang…).

Obwohl die Python-Version des Projekts funktionierte, sah ich Optimierungspotenzial: Zum einen hinsichtlich der langfristigen Wartbarkeit, zum anderen, weil das Team bevorzugt mit .NET arbeitet. Die Migration versprach also nicht nur technische Vorteile, sondern auch eine bessere Integration ins bestehende Entwicklungsökosystem.

Ursprünglicher Python-Code

Die ursprüngliche Python-Codebasis war nicht übermäßig komplex. Es bestand aus einer überschaubaren Anzahl von Modulen und Funktionen, die allesamt auf die Hauptaufgabe – Scraping und Datenverarbeitung – ausgerichtet waren.

Zusätzlich musste ich aber bedenken, dass Python dynamisch typisiert ist, während .NET ein stark typisiertes Ökosystem bietet. Das bedeutete, dass ich während der Migration nicht nur den Code übersetzen, sondern auch möglicherweise neue Typen und Klassenstrukturen entwerfen musste.

Zielsetzung für die .NET-Version

Das Ziel war klar: Eine funktionale .NET-Version, die das gleiche tut wie das Python-Original – nur strukturierter und langfristig wartbarer. Dafür hatte ich mir folgende Anforderungen gesetzt:

  1. Funktionsparität: Die Anwendung sollte, wenn möglich, alle Features der Python-Version abdecken.
  2. Klare Struktur: Ich wollte die Gelegenheit nutzen, um von Anfang an eine saubere Projektstruktur mit klaren Klassen und Methoden zu schaffen.
  3. Einsatz von KI-Tools: KI sollte nicht nur beim Refactoring, sondern auch bei der Architektur und Implementierung unterstützen.

Außerdem war mir bewusst, dass Perfektion nicht das Ziel war. Es ging um ein Experiment: Kann ich mit wenig Erfahrung und KI-Unterstützung in kurzer Zeit eine brauchbare Lösung entwickeln?

Im nächsten Kapitel erkläre ich dir Schritt für Schritt, wie ich vorgegangen bin und welche Tools und Methoden dabei zum Einsatz kamen.

Vorgehensweise beim Refactoring

Vorbereitung und Planung mit OpenAI

Bevor ich überhaupt eine Zeile .NET-Code geschrieben habe, stand die Vorbereitung im Mittelpunkt. Mein erster Schritt war, die KI (in diesem Fall chatGPT o1) in den Planungsprozess einzubinden. Ich ließ mir eine Schritt-für-Schritt-Anleitung erstellen, basierend auf einer kurzen Beschreibung des Python-Projekts, seiner Hauptfunktionen und meiner Ziele für die .NET-Version.

Das Ergebnis war gut: Die KI lieferte eine klare Struktur mit Aufgaben wie der Projektinitialisierung, der Definition von Klassen und Methoden sowie Tipps für den Umgang mit spezifischen Problemen wie der API-Integration. Dieser Plan war mein Leitfaden für den gesamten Prozess.

Erstellung der leeren .NET-Struktur

Als Nächstes habe ich die Grundstruktur für das .NET-Projekt aufgebaut. Hierbei ging es darum, die Verzeichnisse und Dateien entsprechend der zuvor erstellten Anleitung anzulegen.

  • Hauptverzeichnisse: Ich habe Ordner für Configuration, Models und Services (OpenAI und Scraping).
  • Dateistruktur: Für jede Funktion des Python-Codes legte ich eine entsprechende Klasse oder Datei an.
  • Tools: CursorAI war mein Hauptwerkzeug. CursorAI eröffnete die Möglichkeit, KI direkt in den Prozess zu integrieren und den Code mit leistungsstarken Modellen,  wie Antrophic Claude Sonnet, zu generieren.

Dieser Schritt war schnell erledigt und gab mir eine solide Basis, um weiterzuarbeiten.

KI-Tools

Jetzt kam der spannende Teil: die eigentliche Implementierung. Hier nutzte ich zwei Schlüsseltools, die mir den Prozess enorm erleichtert haben.

Tool-Tipp: CursorAI

CursorAI war ein echter Gamechanger, besonders bei der Codegenerierung und -bearbeitung. Da ich das ursprüngliche Python-Projekt bereits mit CursorAI entwickelt hatte, konnte ich es nahtlos auch für die .NET-Version einsetzen. Es bot nicht nur kontextbasierte Vorschläge, sondern half mir auch, typische Fehler wie falsche Datentypen oder Syntaxprobleme zu vermeiden. Für besseren Kontext habe ich außerdem vorerst das original Python Projekt in Ordner behalten und als Referenz in meinen Prompts verwendet.

Einsatz von Claude 3.5

Claude 3.5 (ein großes, fortschrittliches Sprachmodell) half mir dabei, den Python-Code Stück für Stück in C# zu übersetzen. Das Modell war besonders hilfreich, um komplexere Funktionen zu verstehen und in eine .NET-typische Syntax zu übertragen. Ich habe dem Modell den ursprünglichen Python-Code und die Projektbeschreibung gegeben, und es lieferte mir sehr präzise und fast fehlerfreie Codevorschläge.

Natürlich wären Alternativen wie Visual Studio oder Rider mit GitHub Copilot ebenfalls möglich gewesen, aber CursorAI war mir bereits vertraut und damit die naheliegende Wahl.

Grundlagen für die Implementierung

Folgende Informationen habe ich in dem Chat in CursorAI mitgegeben:

  • Die Anleitung aus Schritt 1 als Grundlage
  • Die komplette original Codebasis in Python (Stück-für-Stück)

Relevante Dokumentationen habe ich in Cursor indexiert. In meinem Fall war das die OpenAI SDK Dokumentation.

Schritt-für-Schritt-Umsetzung

Die Umsetzung folgte einer klaren Struktur:

  1. Datei für Datei: Ich ging systematisch durch jede Datei der Python-Version und implementierte deren Funktionalität in der entsprechenden .NET-Klasse.
  2. Fokus auf Funktionen: Ich konzentrierte mich zuerst auf die Kernlogik wie Scraping und API-Integration.
  3. Schrittweise Tests: Nach jeder größeren Änderung führte ich erste manuelle Tests durch, um sicherzustellen, dass der Code funktionierte.

Debugging und Feinschliff

Debugging war unvermeidlich – vor allem, weil ich kein .NET-Experte bin. Aber genau hier erwiesen sich die KI-Tools als unschätzbar hilfreich.

Manuelle Prüfung vs. Unit Tests

Da das ursprüngliche Python-Projekt keine Unit Tests enthielt, war ich bei der Validierung auf manuelle Prüfungen angewiesen. Für ein kleines Projekt wie dieses war das in Ordnung, aber ich merkte schnell, dass Unit Tests die Arbeit deutlich erleichtert hätten. Mein Ansatz:

  • Fokus auf Hauptfunktionen: Ich überprüfte gezielt, ob die Kernfeatures wie Scraping und API-Aufrufe korrekt liefen.
  • KI-Unterstützung: Die KI half mir dabei, typische Fehler wie falsche Rückgabewerte oder ungenutzte Variablen zu erkennen.

Im Endeffekt war dieser iterative Ansatz – Implementieren, Testen, Debuggen – zwar zeitaufwendig, aber unglaublich lehrreich und erfolgreich.

Im nächsten Kapitel teile ich die größten Herausforderungen, auf die ich gestoßen bin, und wie ich sie gelöst habe.

Herausforderungen und Lösungen

Umgang mit fehlender .NET-Erfahrung

Die größte Herausforderung für mich war, dass ich keinerlei Erfahrung mit .NET hatte. Während ich mich in Python wie zu Hause fühle, ist die Arbeit mit einer stark typisierten Sprache wie C# eine ganz andere Welt. Hier kamen zwei Probleme auf mich zu:

  1. Konzepte und Syntax: Viele .NET-spezifische Konzepte wie LINQ, Delegate oder die genaue Handhabung von Typen waren mir etwas fremd.
  2. Projektstruktur: Im Gegensatz zu Python, das oft mit einfacher Modulstruktur arbeitet, verlangt .NET eine klar definierte Architektur mit Klassen, Namespaces und strengen Konventionen.

Lösungen:

  • KI als Tutor: Ich habe die OpenAI-Modelle nicht nur zum Übersetzen des Codes genutzt, sondern auch, um mir unbekannte Konzepte erklären zu lassen. Zum Beispiel fragte ich: „Was ist der Unterschied zwischen List<T> und IEnumerable<T>?“ Die Antworten waren prägnant und halfen mir, die Grundlagen schnell zu verstehen.
  • Dokumentation und Ressourcen: Auch die offiziellen .NET-Dokumentationen erwiesen sich als Goldgrube. Mithilfe von CursorAI konnte ich diese Dokumente  indexieren und gezielt einsetzen. Dadurch muss ich mich nicht im Detail mit den Vorgaben des OpenAI-DotNet Nuget auseinandersetzen.

Sicherstellung von Clean Code ohne umfassende Tests

Ein zentraler Punkt bei der Migration von Python nach .NET war die Frage, wie sehr ich mich auf Clean Code-Praktiken konzentrieren konnte – und wo ich bewusst Abstriche gemacht habe. In einem Experiment wie diesem, das auf Schnelligkeit und Machbarkeit ausgelegt war, rückte die Perfektion in den Hintergrund. Trotzdem spielte Clean Code eine Rolle, denn langfristig ist er entscheidend für die Wartbarkeit und Erweiterbarkeit des Projekts.

DRY – Don’t Repeat Yourself

Einer der Grundpfeiler von Clean Code ist das DRY-Prinzip: Vermeide Wiederholungen im Code. Während der Migration habe ich versucht, redundante Abschnitte zu minimieren, indem ich häufig wiederkehrende Abläufe – beispielsweise für API-Anfragen oder Datenverarbeitung – in separate Methoden ausgelagert habe. Doch mit dem engen Zeitrahmen und meiner begrenzten Erfahrung in .NET war das nicht immer konsequent umsetzbar. Manche redundanten Codeblöcke sind erhalten geblieben und könnten in einem nachfolgenden Refactoring bereinigt werden.

Der Zusammenhang ist klar: Wiederholungen führen zu unnötigen Wartungsaufwänden, da jede Änderung an mehreren Stellen vorgenommen werden muss. Dieser Aspekt sollte in der Nachbearbeitung des Codes Priorität haben.

SRP – Single Responsibility Principle

Das SRP besagt, dass jede Klasse oder Methode genau eine Aufgabe haben sollte. Während ich versucht habe, diese Regel in der .NET-Version einzuhalten, war das Ergebnis nicht immer ideal. Manche Klassen und Methoden übernehmen aktuell mehr Verantwortung, als sie sollten, was auf den schnellen Entwicklungsprozess und meine begrenzte Erfahrung mit der .NET-Architektur zurückzuführen ist.

Das Problem dabei ist, dass solche Strukturen schwer zu testen und noch schwerer zu erweitern sind. Nach dem Projektabschluss könnte ich hier gezielt ansetzen, indem ich die Verantwortlichkeiten klarer trenne und Methoden oder Klassen aufsplitte.

IOSP – Interface Segregation Principle

Das IOSP verlangt, dass Schnittstellen (Interfaces) nur die Methoden enthalten, die eine bestimmte Klasse auch wirklich benötigt. In der aktuellen Version meines Projekts habe ich darauf nicht aktiv geachtet, da die Hauptaufgabe die Funktionsparität mit der Python-Version war.

Ein Fokus auf IOSP könnte später dazu beitragen, den Code flexibler und wartbarer zu machen. Beispielsweise könnten kleinere, spezifischere Interfaces eine bessere Grundlage für Erweiterungen schaffen, ohne bestehende Implementierungen zu beeinflussen.

KISS – Keep It Simple, Stupid

Das KISS-Prinzip war der wichtigste Clean Code-Leitfaden während des Projekts. Ich habe versucht, die Funktionen und Strukturen so einfach wie möglich zu halten, um den Überblick zu bewahren und den Fokus auf die Machbarkeit zu legen. Doch Einfachheit ist nicht gleichbedeutend mit Sauberkeit. Manche Stellen des Codes wirken aktuell zwar simpel, sind aber nicht optimal strukturiert oder dokumentiert.

Hier zeigt sich, wie wichtig ein nachgelagertes Refactoring ist: Erst mit etwas Abstand kann man einfache Strukturen so überarbeiten, dass sie auch den Ansprüchen von Clean Code genügen.

Nachbearbeitung: Clean Code als nächster Schritt

Auch wenn nicht alles perfekt umgesetzt wurde, ist das in einem ersten Prototypen völlig in Ordnung. Der Fokus lag auf der Machbarkeit und nicht auf der Perfektion. Jetzt, wo das Projekt funktioniert, könnte ich folgende Schritte angehen:

  1. Analyse und Verbesserung: Mit einem Clean Code-Tool oder einem Agenten gezielt Schwachstellen im Code identifizieren.
  2. Refactoring nach Prinzipien: Wiederholungen eliminieren, Verantwortlichkeiten klarer zuweisen und Schnittstellen schlanker gestalten.
  3. Tests hinzufügen: Automatisierte Tests würden helfen, zukünftige Änderungen sicher durchzuführen und das Clean Code-Niveau zu halten.

Das Wichtigste ist: Dieses Experiment hat gezeigt, dass KI-Tools eine schnelle Umsetzung ermöglichen, aber menschliches Nachdenken und gezielte Nachbearbeitung bleiben unersetzlich, wenn es um nachhaltige Codequalität geht.

Fazit und Ausblick

Zusammenfassung der Ergebnisse

Das Experiment hat bewiesen: Mit den richtigen Tools und Ansätzen ist es möglich, ein Python-Projekt in kurzer Zeit erfolgreich nach .NET zu migrieren – selbst ohne Vorkenntnisse in der Zieltechnologie. Innerhalb von nur vier Stunden konnte ich eine funktionierende .NET-Version meiner Anwendung entwickeln, die alle Kernfunktionen des Originals abdeckt.

Dabei war der Prozess alles andere als perfekt. Die Codequalität ließ an manchen Stellen noch zu wünschen übrig, und die Anwendung war mehr erstmal auf Funktionalität als auf langfristige Wartbarkeit ausgelegt. Trotzdem war das Experiment ein Erfolg: Es hat gezeigt, wie mächtig KI-Tools sein können, um Entwicklungszeiten zu verkürzen und Wissenslücken zu schließen. Hier ist die refaktorisierte Version zu sehen: https://github.com/genericdeAG/web-summarizer-dotnet

Potenziale von KI-Tools beim Refactoring

Die Rolle der KI in diesem Projekt war nicht nur unterstützend, sondern entscheidend. Tools wie chatGPT o1 oder CursorAI haben mir dabei geholfen, typische Herausforderungen zu meistern:

  • Schnelle Übersetzung: Der Python-Code konnte zügig in C# übertragen werden.
  • Fehlerreduktion: Typische Anfängerfehler wurden früh erkannt und behoben (durch Schritt-für-Schritt Vorgehen)
  • Wissenserweiterung: Die KI diente als Tutor, der mir neue Konzepte erklärte und konkrete Lösungsvorschläge lieferte.

Dieses Experiment verdeutlicht das Potenzial von KI-gestütztem Refactoring für Software Teams oder Einzelentwickler. Es erlaubt uns, effizienter zu arbeiten und schneller neue Technologien zu erlernen, ohne dabei die Qualität vollständig aus den Augen zu verlieren.

Nächste Schritte: Weiteres Refactoring und Optimierung

Das aktuelle Ergebnis ist ein Prototyp – funktionsfähig, aber ausbaufähig. Die nächsten Schritte könnten darauf abzielen, den Code systematisch zu optimieren und weiterzuentwickeln:

  1. Clean Code Refactoring: Im nächsten Schritt würde ich die bestehenden Klassen und Methoden gezielt überarbeiten, um Prinzipien wie DRY, SRP und IOSP konsequenter umzusetzen.
  2. Tests hinzufügen: Automatisierte Unit Tests könnten die Stabilität der Anwendung erhöhen und zukünftige Änderungen sicherer machen.
  3. Performance-Optimierung: Sobald die Codebasis bereinigt ist, könnte ich prüfen, ob die Performance der Anwendung in .NET verbessert werden kann.
  4. Erweiterungen: Schließlich könnte die Anwendung um neue Features ergänzt werden, etwa ein dynamischeres Parsing (für JavaScript-basierte Inhalte) oder für Scraping von mehreren Unterseiten aufeinmal.

Was bleibt?

Das Experiment hat gezeigt, dass KI-Tools nicht nur eine Abkürzung sind, sondern auch neue Perspektiven eröffnen. Sie nehmen uns nicht die Arbeit ab, sondern erweitern unsere Möglichkeiten – sei es durch Automatisierung, Wissensvermittlung oder die Reduktion von Fehlern.

Für mich war dieses Projekt ein Schritt in eine neue Welt. Es hat mir gezeigt, dass ich keine Angst vor neuen Technologien haben muss, solange ich bereit bin zu lernen und die richtigen Werkzeuge einzusetzen. Und das ist vielleicht die wichtigste Erkenntnis: Mit einer klaren Zielsetzung und etwas Experimentierfreude lässt sich fast alles erreichen.

The AI Software Company unterstützt kleine und mittelständische Softwarefirmen in der DACH-Region dabei, ihre Entwicklungsprozesse mit KI effizienter, schneller und zukunftssicher zu gestalten.

Neugierig, wie du KI in deinem Software Team sinnvoll einsetzt? Melde dich für unseren Newsletter an und erhalte wertvolle Tipps, Einblicke und Updates!