Ausgabe in Spalten wie beim Befehl "ls"

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Allerdings hat auch deine Version leider so ihre Schwächen:

Code: Alles auswählen

In [1]: import os; from columnize import columnize

In [2]: print columnize(os.listdir('.'))
------> print(columnize(os.listdir('.')))
test.pyc              teleopti.py~               plan.py
simplecsv.py          Desktop                           
Vorlagen              schedule.py~                      
Videos                bin                               
.nautilus             schedule.png                      
.xsession-errors      .local                            
.macromedia           schedule-ie.png                   
test.csv              columnize.py~                     
.pulse-cookie         .xine                             
[...]
Grundlage war das. Es folgte tatsächlich noch eine ganze Reihe weiterer Zeilen und in der dritten Spalte dann die einzelne Datei. Ziel ist aber, eine optimale Aufteilung, d.h. möglichst gleich große Spalten, zu haben. Natürlich immer unter Beachtung der Maximalbreite.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

snafu hat geschrieben:Ziel ist aber, eine optimale Aufteilung, d.h. möglichst gleich große Spalten, zu haben. Natürlich immer unter Beachtung der Maximalbreite.
Oh. Ich vermutete, das Ziel war möglichst wenig Zeilen zu gebrauchen, und dass nur die letzte Spalte kürzer sein soll. Da kenne ich "ls" wohl nicht gut genug - habe keinen GNU zur Hand...

Wie ist denn genau das Kriterium? Jede Spalte höchstens so lang wie die vorhergehende, und jede höchstens eins kürzer als die erste? Dann ist das wohl was ganz anderes...
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das Kriterium ist, möglichst gleich viele Zeilen mit den Spalten zu verbrauchen. Nur die letzte kann weniger haben, sollte aber eben nicht zu krass rausstechen. -1/-2 wäre optimal.
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Um das nochmal zu verdeutlichen:

Code: Alles auswählen

urx@murx:~/test$ touch a b c
urx@murx:~/test$ ls
a  b  c
urx@murx:~/test$ touch a b c d e f g h i j k l m n o p q r s t u v w x y z
urx@murx:~/test$ ls
a  b  c  d  e  f  g  h  i  j  k  l  m  n  o  p  q  r  s  t  u  v  w  x  y  z
urx@murx:~/test$ touch a1
urx@murx:~/test$ ls
a   b  d  f  h  j  l  n  p  r  t  v  x  z
a1  c  e  g  i  k  m  o  q  s  u  w  y
Die Priorität liegt also bei gleich großen Spalten, selbst wenn dadurch nicht der komplette Bildschirm ausgefüllt wird. Zunächst werden die Namen nebeneinander sortiert und sobald mehrere Zeilen nötig werden, geschieht die Sortierung spaltenweise, d.h. untereinander.

Wer `touch` nicht kennt: `touch` legt Dateien an bzw erneuert den Zeitstempel bei vorhandenen Dateien.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

snafu hat geschrieben:Die Priorität liegt also bei gleich großen Spalten, selbst wenn dadurch nicht der komplette Bildschirm ausgefüllt wird.
Ja, in dem Beispiel ist das einfach; das haben glaube ich alle vorgestellten Programme auch so gemacht.
Interessant wirds z.B. bei sowas: Was passiert bei 17 Dateien, wenn 6 nicht mehr nebeneinander passen, aber 5?
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Da macht ls: 4x4 (also gleich große) + 1 Zeile in der letzten Spalte. Okay, 6+6+5 wäre auch gegangen. Die Priorität ist wohl eher, möglichst wenig Zeilen zu verbrauchen und nur bei der letzten Spalte eine andere Zeilenzahl zu haben.
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Ok, dann müsste eigentlich passen, was columnize macht.
Schafft ls in dem von dir zitierten Fall, wo columnize die echt ziemlich unschöne Ausgabe liefert, was vernünftiges? Oder gehen dir die blöden Fragen auf die Nerven ? :wink:

Ich find's aber ganz interessant... :-)
Benutzeravatar
snafu
User
Beiträge: 6881
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich find's auch interessant, sonst hätt ich den Thread nicht gemacht... Ich habe die Ausgabe von deiner Funktion direkt im selben Verzeichnis mit ls verglichen und ls bringt in gewissen Fällen immer mal eine Spalte mehr unter als deine Funktion. Zum ausgiebigen Testen solltest du dir wohl eine Windows-Version von ls installieren, da das Frage-Antwort-Spiel zwar nicht direkt nervig, aber doch recht ineffektiv ist. ;)

Ich habe jetzt mal eine objektorientierte Implementierung angefangen, die den Vorstellungen aber bisher nur rudimentär entspricht. Es ging mir dort erstmal um die Lesbarkeit und weniger um Geschwindigkeit, da ich durch die bisher gezeigten Funktionen kaum durchgeblickt habe und sie auch nicht sonderlich schön fand. Das habe ich bis jetzt:

Code: Alles auswählen

from curses import setupterm, tigetnum

class Columnizer(object):
    def __init__(self, indent=2, width=None):
        self.spacer = indent * ' '
        self.width = width

    def drop_overage(self, strings):
        if self.width is None:
            setupterm()
            width = tigetnum('cols')
        else:
            width = self.width

        while len(self.spacer.join(strings)) > width:
            strings = strings[:-1]

        return strings

    def make_lines(self, strings):
        lines = []

        while strings:
            remaining = self.drop_overage(strings)
            lines.append(remaining)
            strings = strings[len(remaining):]

        return lines
Werde das erstmal so belassen, da ich morgen leider früh raus muss. TODO ist halt, die Spaltenbreite einheitlich zu bekommen unter der Beachtung, dass einzelne Elemente dann in die nächste Spalte rutschen können und sich damit wieder alles nachfolgende ändert. Wenn man das Glück hat, dass der längste Eintrag ziemlich am Schluss ist, hat man sicher noch mehr Spass. :)
bords0
User
Beiträge: 234
Registriert: Mittwoch 4. Juli 2007, 20:40

Das Verhalten von ls ist mir zu ungenau spezifiziert. Ich glaube, es wäre sinnvoller, wenn du einfach deine eigenen Prioritäten umsetzt, als genau auf ls zu achten.

(Wie ls allerdings mehr Spalten unterbringen kann als columnize, verstehe ich nicht.)
Antworten