Freitag, 29. Januar 2010

Python und die Newlines

Klingt nach ner lustigen Sketchcomedy, ist aber gar nicht witzig:

Wie ich bei der Arbeit mit codeextract herausgefunden habe können die unsichtbaren Voodoozauber von Python manchmal auch murks erzeugen. Python arbeitet, wenn es um Strings geht, intern mit \n also Unix-Zeilenumbruchszeichen. Windows verwendet hingegen eine Kombination von \r\n.

Python macht es sich beim speichern eines Strings in eine Datei (meinedatei.write(string)) ganz einfach: Wenn das Skript unter Windows läuft ersetzt der Interpreter \n durch \r\n.

Preisfrage: Was passiert wenn der String ein Windows-Format aufweist und in eine Datei gespeichert wird?
Antwort: Aus \r\n wird \r\r\n!

Das führt dazu dass die Textdatei entweder (Je nach Texteditor) gar nicht angezeigt werden kann, oder zwischen jeder Zeile eine Leerzeile entsteht.

Bei den ActiveState Recipies bin ich aber auf eine elegante und einfache Lösung gestoßen. Per Regular Expression werden hier jegliche Newline-Formate auf Unix-Format (\n) normalisiert:


import re
windows_string = 'Zeile 1\r\nZeile 2'
unix_string = re.sub(r'(\r\n\r\n)', '\n', string)
# unix_string --> 'Zeile 1\nZeile 2'


Das ganze hab ich schon in codextract ausprobiert. Funktioniert blendend!

Mittwoch, 20. Januar 2010

Wie man Excel seinen Code entlockt

Wie ich das letzte mal festgestellt habe komme ich um eine Code-Extraktion marke Eigenbau nicht herum. Ich hab mich erst mal informiert wie ich über pywin per COM Excel steuern kann. Das gestaltete sich einfacher als ich gedacht hatte!

Excel öffnen und schließen


import win32com.client

# Neue Instanz von Excel
excel = win32com.client.Dispatch("Excel.Application")
# Sicherheitsrichtlinien speichern und Makros deaktivieren
security = excel.AutomationSecurity
excel.AutomationSecurity = 3
# Workbook öffnen
wbook = excel.Workbooks.Open("C:/Pfad/zur/Excel/datei.xls)

# Code hier einfügen!!

# Sicherheitsrichtlinien zurücksetzen
excel.AutomationSecurity = security
# Workbook schließen (Ohne zu speichern)
wbook.Close(False)
# Excel Instanz schließen
excel.Quit()



Die Sicherheitsrichtlinien stelle ich deshalb um, damit während der Extraktion nicht die wildesten
Makros abgefeuert werden.

Ab hier kommt man mit der gut versteckten aber extrem nützlichen Microsoft Excel 2003 Language Reference weiter, da der zugriff auf die Excel-Objekte wie in VBA läuft ... nur eben toller über listen und so ... Schöööntoll!

Herausgekommen ist das kleine Tool codeXtract, das ihr euch hier herunterladen könnt

Wichtig: Es müssen pywin (Python Library) sowie Excel installiert sein !!

Die Bedienung ist denkbar einfach:
python codeextract.py -i inputpath -o outputpath

wobei inputpath eine XLS-Datei sein kann oder ein Verzeichnis, in dem dann rekursiv alle XLS-Dateien durchsucht werden. Outputpath muss ein Verzeichnis sein. Wenn es noch nicht existiert wird es angelegt. Bei der Extraktion wir die Verzeichnisstruktur (im rekursiven Modus) beibehalten, wobei der Inhalt der XLS-Dateien in ein Verzeichnis mit dem Namensschema [FILE] Dateiname geschrieben wird.

Die Module, Classfiles, etc. werden darin wiederum in Unterordner gepackt, so dass sich eine Struktur ähnlich der im VBA Editor ergibt. Macht man das vor jeden neuen Commit, so lässt sich der Code in Zukunft sauber Versionieren.

Wenn ihr meinen Code nützlich findet würde ich mich über nen kurzen Kommentar freuen. Wenn ich codeXtract noch weiter ausbauen sollte werde ich dann die Ergebnisse hier posten.