Columnizer (jetzt: shcol)

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
fail
User
Beiträge: 122
Registriert: Freitag 11. Januar 2013, 09:47

Gute Nachrichten.
Mit cmd und Powershell funktionert es.
Im IDLE:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\fail\Desktop\termwidth.py", line 71, in <module>
    print(test())
  File "C:\Users\fail\Desktop\termwidth.py", line 68, in test
    fd = sys.__stdout__.fileno()
AttributeError: 'NoneType' object has no attribute 'fileno'
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@fail: Naja, das Skript nutzt jetzt auch einfach eine Builtin-Funktion zur Ermittlung der Terminalgröße, die seit Python 3.3 neu hinzugekommen ist. Daher hatte ich auch nach der Python-Version gefragt.

Bitte ersetze mal den `if hasattr...`-Teil (ziemlich am Anfang) durch ein `if False:`, damit er zu Testzwecken wieder die "ctypes"-Variante nutzt. Die Tests in IDLE können weg bleiben. Das scheint ohne größere Verrenkungen nicht zu funktionieren. Schon mein (versuchter) Workaround mit `sys.__stdout__` ist IMHO keine wirklich saubere Lösung.
fail
User
Beiträge: 122
Registriert: Freitag 11. Januar 2013, 09:47

Auch so funktionert es in der cmd und Powershell.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Super. Nochmals herzlichen Dank. Ich gehe dann mal davon aus, dass ich den kompletten Code zur automatischen Ermittlung der Terminalbreite für das Projekt comitten kann. Ich arbeite nur noch an ein paar Feinheiten...
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

shcol 0.2-dev geht langsam aber sicher in Richtung Zielgerade. Ich habe auf der Github-Seite mal die Readme-Datei überarbeitet, damit ein größerer Fokus auf die neuen Highlevel-Funktionen (z.B. ``print_filenames()``) gelegt wird. In Kürze folgt noch eine Vorstellung der Kommandozeilen-Funktionalität des Tools. Nach Installation der Entwicklungsversion kann man sich dies bereits mittels ``shcol --help`` gerne ansehen. :)

Achso, und könnte jemand von den Mods den Thread ins Showcase-Forum verschieben? Danke.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

snafu hat geschrieben:Achso, und könnte jemand von den Mods den Thread ins Showcase-Forum verschieben? Danke.
Bitte schoen :)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

cofi hat geschrieben:
snafu hat geschrieben:Achso, und könnte jemand von den Mods den Thread ins Showcase-Forum verschieben? Danke.
Bitte schoen :)
Sehr viel Danke. :)
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Vor wenigen Tagen habe ich shcol 0.2-rc1 hochgeladen. Dabei handelt es sich um eine Art Vorschauversion auf die bevorstehende Version 0.2. Ich werde noch die Abdeckung durch Tests vergrößern und Dokumentation im HTML-Format herausbringen. Doku ist zwar schon relativ detailliert vorhanden, jedoch bisher nur in Form von Docstrings. Im Grunde kann dieses Release schon produktiv eingesetzt werden. Das finale shcol 0.2 wird auf jeden Fall kompatibel zu dem jetzigen Pre-Release sein. Man sollte nur beachten, dass es im Vergleich zu Version 0.1 neben zahlreichen Erweiterungen auch ein paar Umbenennungen gab. Version 0.2 ist daher *nicht* vollständig abwärtskompatibel zu Version 0.1.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Soeben habe ich shcol 0.2 auf PyPI hochgeladen.

Für eine grobe Doku muss man sich zunächst mit der README-Datei begnügen, deren Inhalt auch für die PyPI-Paketbeschreibung übernommen wurde. Die geplante HTML-basierte Dokumentation habe ich erstmal verschoben.

Zusätzlich ist `shcol` auch als Shell-Tool verwendbar. Sowohl für Linux als auch für die Windows PowerShell. Beispiele für beide "Welten" erhält man durch Eingabe von `shcol --help`:

Code: Alles auswählen

usage: shcol [-h] [-s N] [-w N] [-S] [-U] [-c N] [-v] [item [item ...]]

Generate columnized output for given string items.

Columize and sort:
shcol -S foo bar baz

Columnize command output on Linux (Debian):
shcol -S -c0 < /proc/modules
dpkg --get-selections 'python3*' | shcol -c0 -s4

Columnize process names on Windows PowerShell:
ps | foreach {$_.name} | shcol -U

positional arguments:
  item               an item to columnize
                     (read from stdin if item arguments are not present)

optional arguments:
  -h, --help         show this help message and exit
  -s N, --spacing N  number of blanks between two columns (default: 2)
  -w N, --width N    maximal amount of characters per line
                     (use terminal width by default)
  -S, --sort         sort the items
  -U, --unique       process only the first occurrence of an item
                     (i.e. doublets are eliminated)
  -c N, --column N   choose a specific column per line via an index value
                     (indices start at 0, column separator is whitespace)
                     will only work when items are supplied via stdin
  -v, --version      show program's version number and exit
Für Windows-Benutzer ist zu beachten, dass der Skript-Ordner vom verwendeten Python-Interpreter im PATH eingetragen sein muss, sofern man `shcol` als einfachen Befehl (also ohne umständliche Pfadangabe) verwenden möchte. Dies wurde bei der Python-Installation automatisch vorgenommen, sofern man das entsprechende Häkchen angeklickt hat.

`shcol` ist noch nicht komplett durchgetestet. Ich wollte aber mal wieder releasen, zumal ich intern einiges an Refactoring durchführen werde. Das wäre mir ein zu krasser Sprung vom vorherigen "rc1" gewesen.

Wie immer bin ich dankbar über jede Rückmeldung (Fehlermeldungen, Verbesserungsvorschläge, ...) und übernehme keinerlei Haftung für die Auswirkungen möglicher Fehlfunktionen seitens `shcol`.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Es ist nun HTML-Dokumentation verfügbar:

https://shcol.readthedocs.org/

Bisher gibt es bloß einen groben Überblick mit einigen Beispielen für CLI und Python-API (d.h. vom Modul `shcol.highlevel`). Zu beiden werde ich aber noch detailliert die Funktionsweise beschreiben.

Alle anderen Module sollen erstmal intern bleiben. Hier muss man sich mit den Docstrings im Python-Code begnügen und kann sich auch nicht auf eine garantierte Abwärtskompatibilität in späteren Releases verlassen. Früher oder später werde ich aber wohl zumindest eine offizielle Formatter-API dokumentieren, die dann auch stabil bleiben soll.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@snafu
Planst Du für eine kommende Version auch die Möglichkeit, separators zu definieren? Also sowas in der Art:

Code: Alles auswählen

>>> shcol.print_columnized(xrange(10), separator='|', spacing=6, line_width=25)
0   |   1   |   2   |   3
4   |   5   |   6   |   7
8   |   9
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

War bisher nicht geplant, kann ich aber durchaus einbauen, wenn Interesse besteht. Der Columnizer-Algorithmus macht übrigens eine spaltenweise Anzeige, d.h. von oben nach unten. Siehe: http://shcol.readthedocs.org/en/latest/ ... line-width

@mutetella: Welches Verhalten würdest du denn bei einem Spacing von 7 (ungerade Zahl) erwarten? Und würde sich deine Erwartung ändern, wenn der Trenner aus mehr als 1 Zeichen besteht?

Wenn ich so darüber nachdenke, dann ist es wahrscheinlich am besten, eine ``set_spacing(num_blanks, border='')``-Methode für Formatter-Klassen zu definieren. Dazu könnte man eine Standard-Implementierung bauen, die vom Anwender bei Bedarf überschrieben werden kann.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@snafu
Als Lösung könnte ich mir vorstellen, dass
  • sich die Übergabe eines `separators`- mit der Übergabe eines `spacing`- Parameters ausschließen. Somit liegt die Entscheidung, wie ein ungerades Spacing oder mehrzeichiger Separator gehandelt werden soll, beim Nutzer.
  • der `spacing`-Parameter in `spacing_left` und `spacing_right` aufgeteilt ist.
  • ein klitzekleines bischen Magie :wink: Ungerades einfach gerade macht.
Langsam aber stetig gelange ich endlich zu der Einsicht, nicht alles selbst machen zu können/müssen... :? Deshalb bin ich am Überlegen, Deinen Columnizer für meinen Kalender zu verwenden. Und da fände ich den Einsatz von Separatoren ganz schön.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Okay, das wird jetzt ein bißchen sehr speziell. Insbesondere sehe ich wenig Sinn in `spacing_left` und `spacing_right`. Wozu soll das gut sein?

Du kannst dir übrigens einen eigenen Formatter schreiben, basierend auf `shcol.core.IterableFormatter`. Kandidaten zum Überschreiben wären vermutlich mindestens eine der letzten 3 Methoden dieser Klasse (aktuell ab Zeile 293). Dort werden die Templates erstellt, welche dann an anderer Stelle für jede einzelne Zeile via ``template % items`` vom Formatter verwendet werden. Hier könntest du ja mit deinem Trenner ansetzen und einen abgeleiteten `CalendarFormatter` erstellen.

Die spätere Verwendung deines Formatters ist dann recht unkompliziert. Ein Beispiel mit den zuvor von dir genutzten Werten:

Code: Alles auswählen

formatter = CalendarFormatter.for_line_config(spacing=6, line_width=25)
print(formatter.format(items))
Und übrigens: Das `calendar`-Modul aus Pythons Standardbibliothek ist dir ja bekannt, oder? Reichen dir die dortigen Formatierungsmöglichkeiten nicht aus?
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@snafu
Das mit dem eigenen Formatter schau' ich mir an. Das `calendar` Modul kenn' ich natürlich, hilft mir aber bei der Ausgabe von Terminen mit all' seinen Infos nicht weiter.

Aber ok, ich schau' mir `shcol` jetzt mal tiefer an. Danke für Deine Arbeit!

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

`shcol` hat übrigens neben dem, was ich inzwischen in der HTML-Doku aufgeführt habe, noch so nette Features wie `shcol.print_attr_names()`, welches dir auf Basis von `dir()` alle Attribute eines übergebenen Objektes übersichtlich darstellt. Diese Ausgabe finde ich persönlich schöner als die Listenform oder die IPython-Ausgabe. Ebenso ist ``shcol.print_columnized(os.environ)`` sicherlich mal einen Blick wert. Dort sieht man, dass lange Werte in Wörterbüchern bei Bedarf durch `shcol` über mehrere Zeilen verteilt werden und dabei trotzdem in "ihrer" Spalte verbleiben, so wie man es z.B. bei einer Tabelle erwarten würde, wenn man eine mehrzeilige Tabellenzelle hat.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

mutetella hat geschrieben:Aber ok, ich schau' mir `shcol` jetzt mal tiefer an.
Verwende zum Ausprobieren am besten, wie hier beschrieben, den folgenden Befehl:

Code: Alles auswählen

pip install git+git://github.com/seblin/shcol.git
Damit installierst du dir den aktuellen Stand aus dem Github-Repo. Ich achte darauf, dass ich nur lauffähige Versionen ins Repo hochlade.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@mutetella: Ich habe mal zum Spaß die Version auf meinem Rechner umgeschrieben. Ich bekommen nun folgende Ausgabe hin:

Code: Alles auswählen

>>> print(formatter.format(range(1, 31)))
1   |   9    |   17   |   25
2   |   10   |   18   |   26
3   |   11   |   19   |   27
4   |   12   |   20   |   28
5   |   13   |   21   |   29
6   |   14   |   22   |   30
7   |   15   |   23
8   |   16   |   24
Hast du dir das so in der Art vorgestellt?

Realisiert habe ich dies durch ein `spacer`-Argument. Dafür müsste ich aber an etlichen Stellen Änderungen vornehmen, wenn man den Spacer von Anfang an übergeben könnte. Die hinzugekommene Methode sieht so aus:

Code: Alles auswählen

    def make_column_separator(self, spacing):
        if self.spacer:
            padding = (spacing // 2) * ' '
            sep = padding + self.spacer + padding
        else:
            sep = spacing * ' '
        return sep
Diese wird verwendet in der letzten Zeile von `make_line_template()` (auf die ich bereits verwiesen hatte). Sie lautet dann:

Code: Alles auswählen

return self.make_column_separator(props.spacing).join(parts)
Du kannst dies gerne als Orientierung für den eigenen Formatter benutzen. Ich möchte bald shcol 0.3 rausbringen und aktuell keine Änderungen an der dokumentierten Schnittstelle vornehmen. Daher wird es keinen Spacer in shcol 0.3 geben.

Für Version 0.4 kannst du aber sehr wahrscheinlich damit rechnen. Dafür plane ich, die eigentliche Template-Erzeugung aus dem Formatter-Code rauszunehmen und über einen `TemplateGenerator` zu realisieren. Das ist auf Dauer flexibler sowohl für den Anwender als auch für mich und schränkt die Menge an Argumenten für eine Formatter-Instanz mithilfe der Auslagerung etwas ein. Außerdem möchte ich bis dahin die Erzeugung von Templates für modernes String-Formatting (``'{}'.format('spam')``) als Alternative zum klassischen String-Formatting anbieten. Auch dafür stelle ich mir die Implementierung mit einer gesonderten Klasse einfacher bzw sauberer vor.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

shcol 0.3 ist draußen!

Habe es vor wenigen Minuten auf PyPI hochgeladen. Installation wie immer mittels ``pip install --upgrade shcol``.

Informationen zu den wichtigsten Features gibt es in der Doku.

@mutetella:
Die Sache mit dem konfigurierbaren Trennzeichen habe ich nicht vergessen, auch wenn sie es nicht ins aktuelle Release geschafft hat. Du kannst davon ausgehen, dass ich dies neben einigen anderen Dingen in die kommende Version einbringen werde.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

snafu hat geschrieben:Die Sache mit dem konfigurierbaren Trennzeichen habe ich nicht vergessen, […]
Ich auch nicht :wink: , bin aber auch immer noch bzw. wieder einmal mit den Innereien meines Kalenders beschäftigt. Das Thema UI hat also noch Zeit… einfach blöd, wenn man oft über Wochen hinweg keine Zeit hat und dann immer wieder erst den Faden aufnehmen muss, bevor man ein Stück weiter kommt…
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten