Ich hatte vor einer ganzen Weile mal ein sehr ähnliches Projekt, was aber irgendwann eingeschlafen ist. Hier der Neustart (objektorientiert und beschränkt auf die Basics):
`Column` lässt sich an zwei Stellen etwas vereinfachen: `__iter__()` könnte einen Generator per Generatorausdruck zurückgegeben. Und `max()` kennt ein `key`-Argument:
class Column:
def __init__(self, strings, adjuster=str.ljust):
self.strings = strings
self.adjuster = adjuster
def __iter__(self):
width = self.get_width()
return (self.adjuster(string, width) for string in self.strings)
def get_width(self):
return max(self.strings, key=len)
`rng` ist eine übliche Abkürzung für „random number generator“. Muss man dem `range()`-Objekt an der Stelle denn überhaupt einen Namen geben? Der ist ja supergenerisch und das wird auch nur an einer Stelle und zwar gleich in der nächsten Anweisung verwendet.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
__blackjack__ hat geschrieben: ↑Sonntag 16. Oktober 2022, 16:08
`Column` lässt sich an zwei Stellen etwas vereinfachen: `__iter__()` könnte einen Generator per Generatorausdruck zurückgegeben.
Ich weiß, sehe da aber jetzt nicht so den großen Unterschied.
__blackjack__ hat geschrieben: ↑Sonntag 16. Oktober 2022, 16:08
Und `max()` kennt ein `key`-Argument
Dann tut es aber auch etwas ganz anderes. Die Länge wird zwar ebenso geprüft, aber das Ergebnis ist der längste String der Spalte. Gewünscht ist jedoch die Länge des größten Strings als Zahl.
Und bezüglich rng: Gerade weil die Verwendung direkt im Anschluss folgt, werden es wohl die meisten Leute verstehen. Ich versuche, zu lange Zeilen zu vermeiden und habe das deshalb so geschrieben.
return [
Column(self.strings[i : i + lines_per_column])
for i in range(0, len(self.strings), lines_per_column)
]
Ja, eine Zeile mehr, aber ein zusätzliches ] auf einer Zeile ist ja visuell ”leichtgewichtig”. Wobei ich an der Stelle wahrscheinlich auch auf etwas aus `more_itertools` zurückgegriffen hätte, dann wäre das wieder eine Zeile:
chunked() ist ganz nett, aber ich tue mich schwer mit externen Abhängigkeiten, die man mit einem Zweizeiler nachbauen kann. Das lohnt sich IMHO dann nicht wirklich. Übrigens habe ich gerade gesehen, dass mit itertools.batched() ab Python 3.12 wohl etwas ähnliches Einzug in die Standard-Bibliothek halten wird. Siehe Commit: https://github.com/python/cpython/commi ... 520504fa7e
Ich tue mich im Gegensatz dazu schwer damit in jedem Projekt immer wieder selber die immer gleichen Zweizeiler zu schreiben, wenn es die in einem Modul gibt das in der Standardbibliothek in der Dokumentation von `itertools` erwähnt wird, das da die ganzen Rezepte und mehr schon implementiert sind. Irgendwann macht man doch mal einen Fehler, in *dem* Modul haben die einen Namen der dann bei allen, die das benutzen gleich ist, und manche von den Rezepten sind unschön oder nicht so ganz offensichtlich umgesetzt, aus Performancegründen, da ist es nett das nicht selbst im Quelltext stehen haben zu müssen.
“I am Dyslexic of Borg, Your Ass will be Laminated” — unknown
Es wird nun das externe Modul ``more_itertools`` benötigt (die passende setup.py wird nachgeliefert). Hinzugekommen ist die Unterstützung für Wörterbücher. Hier gibt es aber noch Probleme, wenn die Werte zu lang sind, um in eine Zeile zu passen. Es gibt zwar keine Fehlermeldung, aber der Zeilenumbruch des Terminals verschiebt dann halt alles. Da bin ich aktuell dran und habe in der Item-Klasse bereits eine Methode für's Wrapping eingebaut, die aber bisher noch ungenutzt ist. Im nächsten Schritt füge ich das zum "großen Ganzen" zusammen, dann wird die Darstellung von bestimmten Wörterbüchern (z.B. os.environ) wesentlich hübscher aussehen.