Seite 6 von 6
Re: python2to3
Verfasst: Samstag 1. September 2012, 13:17
von Nobuddy
Hallo snafu,
Dein Vorschlag vereinfacht das nochmal.
Der Wert 0 oder 1 für SPELLING, ist ja nur ein Zahlenwert der SPELLING zugewiesen wird.
Noch was zu Deiner Funktion 'get_formatted_table'.
Da bin ich am Überlegen, wie ich das hin bekommen kann, daß wenn die Zeilenausgabe größer als z.B. 20 Zeilen ist, 'formatted_lines' wieder eingefügt wird, um so immer einen Überblick zu haben, welchen Spaltenwert man sich gerade anschaut.
Einen kleinen Ansatz, habe ich evtl. hier, bin aber noch nicht sicher:
Code: Alles auswählen
dataline = dict()
headcount = HEADDISTANCE
for numeration, text_items in enumerate(contents, 1):
if len(contents) > headcount:
headcount = numeration + HEADDISTANCE
print(len(contents))
dataline[numeration] = [text_items]
numeration_string = '{}: '.format(numeration)
formatted_lines.append(line_template.format(numeration_string,
*text_items))
formatted_lines.append(blank_line)
formatted_lines.append(dashed_line)
print('\n'.join(formatted_lines))
Re: python2to3
Verfasst: Samstag 1. September 2012, 14:29
von snafu
Du brauchst auch hier keinen eigenen Counter mitzuführen. Ein Zeilenzähler wird doch bereits durch `enumerate()` verwaltet / zur Verfügung gestellt.
Meine Herangehensweise wäre hier wohl die Verwendung des Modulo-Operators. Zur Veranschaulichung:
Code: Alles auswählen
>>> max_lines_per_segment = 20
>>> 18 % max_lines_per_segment
18
>>> 19 % max_lines_per_segment
19
>>> 20 % max_lines_per_segment
0
>>> 21 % max_lines_per_segment
1
>>> 39 % max_lines_per_segment
19
>>> 40 % max_lines_per_segment
0
Das heißt also, immer wenn `numeration % max_lines_per_segment == 0` auftritt, dann weißt du, dass du die Kopfzeile einfügen musst.
Die Kopfzeile mitsamt der gestrichelten Linien kannst du ja einmalig erzeugen und dann jeweils einfügen. Ruhig weiterhin als Ansammlung von Zeilen:
Code: Alles auswählen
head_items = [dashed_line, headline, blank_line, dashed_line]
[...]
for line_number, text_items in enumerate(contents, 1):
needs_headings = (line_number % max_lines_per_segment == 0)
if needs_headings:
formatted_lines.extend(head_items)
Wie du siehst, sind die Benennungen für Variablen auch bei mir nicht in Stein gemeißelt...

Re: python2to3
Verfasst: Samstag 1. September 2012, 15:28
von Nobuddy
Ich war fast schon wieder dabei, das umständlicher zu machen ...
Wenn ich das richtig umgesetzt habe, sieht jetz der Abschnitt bei mir so aus:
Code: Alles auswählen
head_items = [dashed_line, headline, blank_line, dashed_line]
formatted_lines = [dashed_line, headline, blank_line, dashed_line]
dataline = dict()
for line_number, text_items in enumerate(contents, 1):
needs_headings = (line_number % MAX_LINES_PER_SEGMENT == 0)
dataline[line_number] = [text_items]
if needs_headings:
formatted_lines.extend(head_items)
numeration_string = '{}: '.format(line_number)
formatted_lines.append(line_template.format(numeration_string,
*text_items))
formatted_lines.append(blank_line)
formatted_lines.append(dashed_line)
print('\n'.join(formatted_lines))
Funktionieren tut er jedenfalls
Wenn ich so überlege, funktioniert jetzt alles so, wie ich es mir vorgestellt habe.
Das mit dem Zeilenumbruch innerhalb der Spalte, dürfte wohl nicht ganz so einfach werden.
Letztendlich würde nur noch eine GUI fehlen, in der das Ganze abläuft und die Einstellungen direkt gemacht werden können.
Aber das ist noch Zukunftsmusik, das wird noch ein sehr weiter Weg geben.
Re: python2to3
Verfasst: Samstag 1. September 2012, 15:47
von snafu
Den oberen Abschnitt würde ich anders schreiben:
Code: Alles auswählen
head_items = [dashed_line, headline, blank_line, dashed_line]
formatted_lines = head_items[:]
Dies sorgt dafür, dass eine Kopie von `head_items` für `formatted_lines` angelegt wird.
Wichtig dabei ist, dass du auch wirklich eine *Kopie* anlegst. Ein einfaches `formatted_lines = head_items` würde dazu führen, dass hinter beiden Namen dasselbe Objekt steckt. Veränderungen an einem würden damit auch zu Veränderungen am anderen führen, weil es nämlich dann gar kein "ein" und "anderes" gibt - es gäbe nur zwei verschiedene Wege *ein und dasselbe* Objekt zu erreichen (hoffe, du kannst mir folgen). Jedenfalls sparst du dir damit das Copy+Paste von Quelltext, vor allem in Hinblick darauf, dass sich das Design der Kopfzeilen vielleicht irgendwann mal ändert und du dann penibel darauf achten müsstest, dass es an beiden Stellen angepasst wird - was leicht vergessen werden kann. Durch ein "echtes" Kopieren des Listenobjektes umgehst du diese Gefahr.
Re: python2to3
Verfasst: Samstag 1. September 2012, 15:51
von Nobuddy
Das hatte ich auch schon überlegt und versucht
was aber nicht funktionierte.
Danke für den Tip!

Re: python2to3
Verfasst: Samstag 1. September 2012, 18:26
von Nobuddy
Eine weitere Änderung bei 'menu.py', ist das Arbeiten mit einer Kopie der Originaldatei, was wohl in Hyperionś ursprünglichem Code, mit der Menüoption 'save' wahrscheinlich auch so angedacht war.
Die Vorgehensweise ist die, daß bei Änderung (Daten verändern, Neue Daten hinzu, Daten löschen), eine Kopie der Originaldatei erstellt wird und mit dieser weitergearbeitet wird. Alle Änderungen sind zuerst nur in der Kopie vorhanden und erst durch den Menüpunkt 'Änderungen übernehmen', wird die Originaldatei aktualisiert und die Kopie wird anschließend gelöscht.
Jetzt sind zwar wieder ein paar Zeilchen mehr dazu gekommen, aber damit lässt es sich schon richtig gut arbeiten.

Re: python2to3
Verfasst: Dienstag 4. September 2012, 15:33
von Nobuddy
Hallo zusammen,
habe jetzt eine Version, die Ihr Euch anschauen könnt:
https://gist.github.com/3621627
Ich hoffe mal, daß Ihr den ersten Fehler nicht gleich nach 5 Sekunden findet.
Nein ehrlich, habe mir wirklich Mühe gegeben, Euren Anforderungen gerecht zu werden.
Den Code habe ich versucht in der maximalen Zeichenbreite unterzubringen.
Wenn also manches dadurch nicht so schön aussieht ... könnt Ihr mir ja Tipps geben.
Auch habe ich versucht LC im Code zu verwenden, wo es mir möglich war.
Bestimmt lässt sich das noch weiter verbessern und hoffe, daß Ihr mir dazu Tipps gebt!

Re: python2to3
Verfasst: Freitag 7. September 2012, 17:23
von Nobuddy
Sodele, da ich nach 5 Sekunden nichts von Euch gehört habe, komme ich zum Ende dieses Projektes.
In menu.py selbst gab es noch kleinere Korrekturen.
Was ich komplett neu gemacht habe, ist ein Modul für das Erstellen und Verwalten der Einstellungen, was mir recht gut geglückt ist,
Ich habe dafür den Namen settingmenu.py vergeben und die Datei in der die Einstellungen gespeichert werden, heißt nicht mehr privatparam.py sondern settings.py.
Für Diejenigen, dies es noch interessiert, hier die fertige Version:
https://gist.github.com/3667523
Danke, an Alle, die mir geholfen haben!

Re: python2to3
Verfasst: Mittwoch 12. September 2012, 17:50
von Nobuddy
Hallo snafu,
Dein letzter Post, ist ja eine kleine Weile her, möchte aber wenn möglich, nochmals daran anknüpfen.
snafu hat geschrieben:Hab jetzt einfach mal die komplette Formatierungs-Funktionalität geschrieben. Aufgrund der speziellen Anforderungen, die du an die Ausgabe stellst, sind es doch ein paar Zeilen mehr geworden. Manches kann man vermutlich noch besser machen, aber ich hoffe trotzdem, den Quelltext etwas verständlicher für die Allgemeinheit hinbekommen zu haben:
https://gist.github.com/3527463
Wie du siehst, habe ich den Info-Text bei den Testdatensätzen stark gekürzt, damit das schon von dir genannte Problem der Überlänge nicht auftritt. Wobei man auch hier sein Terminal-Fenster im Vollbildmodus laufen lassen sollte.
Eine Implementierung mit passendem Zeilenumbruch kommt dann in der nächsten Maus (irgendwann).

Deine Funktion, funktioniert wirklich prima. Einziger Wermutstropfen, sind überlange Zeilen, die dann das Layout sprengen.
Habe Deine Funktion als Modul laufen, damit ich von verschiedenen Modulen aus, darauf zugreifen kann.
Habe den Code für die neue Anforderung etwas erweitert, bin allerdings noch am Rätseln, wie ich das umsetzen kann, bei überlangen Zeilen, einen Zeilenumbruch innerhalb der jeweiligen Spalte zu erzeugen.
Code: Alles auswählen
def window_size():
# Fenstergröße des Terminals/Konsole ermitteln.
# Ausgabe: Zeilen, Zeichen
rows, columns = os.popen('stty size', 'r').read().split()
return rows, columns
def get_formatted_table(menupoint, HEADINGS, contents, spacing=4,
numeration_width=10):
rows, columns = window_size()
lines = [HEADINGS] + contents
column_widths = [max(len(item) for item in column_items)
for column_items in zip(*lines)]
total_width = sum(column_widths) + (len(column_widths) - 1) * spacing
total_width += numeration_width
if total_width > int(columns):
print('Layoutfehler, die Ausgabezeile ist um %s Zeichen größer, \
\nals die Breite des Terminals/Konsole!' %
(total_width - int(columns)))
dashed_line = total_width * '-'
blank_line = total_width * ' '
numeration_spec = '{{:>{}}}'.format(numeration_width)
column_specs = ['{{:{}}}'.format(width) for width in column_widths]
line_template = numeration_spec + (spacing * ' ').join(column_specs)
headline = line_template.format('Nummer: ', *HEADINGS)
head_items = [dashed_line, headline, blank_line, dashed_line]
formatted_lines = head_items[:]
dataline = dict()
for line_number, text_items in enumerate(contents, 1):
needs_headings = (line_number % MAX_LINES_PER_SEGMENT == 0)
dataline[line_number] = [text_items]
if needs_headings:
formatted_lines.extend(head_items)
numeration_string = '{}: '.format(line_number)
formatted_lines.append(line_template.format(numeration_string,
*text_items))
formatted_lines.append(blank_line)
formatted_lines.append(dashed_line)
print('\n'.join(formatted_lines))
return menupoint, dataline
Re: python2to3
Verfasst: Donnerstag 13. September 2012, 10:33
von snafu
Naja, man könnte entweder überlegen, ob man das vorhandene `line_template` benutzt und bei Überlänge in einer neuen Zeile die dementsprechend nicht zu benutzenden Spalten einfach mit leeren Strings füllt und in die Spalte mit Überlänge halt den Rest des Textes packt (in einer Schleife, damit auch mehr als nur *eine* zusätzliche Zeile genutzt werden können) oder aber man geht davon aus, dass eh immer nur die letzte Spalte befüllt werden muss und berechnet daher einfach vorab den nötigen Leerraum.
Ich würde wahrscheinlich die mir persönlich schon wieder viel zu aufgeblähte Funktion in mehrere einzelne Funktionen unterteilen und etwas einigermaßen abstraktes (und damit auch wiederverwendbares) erstellen. Eventuell sogar als Klasse. Das ist mir aber momentan etwas zu aufwändig, zumal ich zur Zeit andere wichtigere Dinge im Kopf bzw auf meiner TODO-Liste habe. Kann sein, dass ich zum Wochenende was dazu baue - soll aber kein Versprechen sein.
Re: python2to3
Verfasst: Donnerstag 13. September 2012, 19:17
von Nobuddy
Dies ist wirklich nicht so einfach, taste mich da Schritt für Schritt ran und habe schon 3 graue Haare mehr ...
Ein Problem ist auch, daß es sich nicht festlegen lässt, daß immer die letzte Spalte die Überlänge hat.
Könnte ja auch mal vorkommen, daß 2 oder 3 Spalten Überlängen haben.
Das wird dann schon eine recht kniffelige Sache.
Vielleicht habe ich auch schon bis zum Wochenende Codestücke fertig, die mich dem Ziel näher bringen.
Re: python2to3
Verfasst: Samstag 15. September 2012, 12:24
von Nobuddy
Sodele, war nicht untätig und bin ein großen Schritt weitergekommen.
Ich habe snafuś Code erweitert, so daß bei überlangen Spaltenbreiten, diese Umgebrochen werden und da durch das entsprechende Format ausgegeben wird.
Das Problem was noch besteht, ist daß der Code nicht automatisch sich auf den jeweiligen Zeilenbedarf einstellt.
Dies habe ich im Moment, manuell auf 2 Zeilen begrenzt.
Ich poste hier mal den Code:
https://gist.github.com/3727387
Dieser Code ist nur ein Provisorium!
Ich habe die Ausgabe von 'gist.github' gewählt, damit man sich auf Zeilennummern beziehen kann.
Weiter habe ich bei meinen Code '#-Infos' dazu getan und mit Leerzeilen vom übrigen Code getrennt.
Das was ich oben schon angesprochen habe, mit dem Automatismus auf den jeweiligen Zeilenbedarf, ist in der Code-Zeile 54-56 momentan manuell gelöst. Vielleicht, habt Ihr da bessere Ideen?
Über Euren Input und Tipps dazu würde ich mich freuen!

Re: python2to3
Verfasst: Montag 17. September 2012, 09:02
von Nobuddy
UPDATE!
Wie ich selbst bemerkt habe, ist mein zuletzt geposteter Code fehlerhaft.
Beim dritten Anlauf, bin ich jetzt auf dem richtigen Weg.
Es wird noch ein paar Tage dauern, bis ich alles komplett habe und bitte daher, von Tipps und Hilfestellung abzusehen.
Möchte es einfach selber erreichen!

Re: python2to3
Verfasst: Mittwoch 19. September 2012, 18:05
von Nobuddy
Hallo zusammen,
endlich ist es soweit, daß ich Euch meine funktionierenden Code zeigen möchte.
snafus Code ist der echt super ist, habe ich mit ein paar weiteren Codezeilen vervollständigt.
Als erstes wird die Größe des Terminals ermittelt, welche in der weiteren Verarbeitung, eine Bezugsgröße bildet.
Es ist nun möglich, Tab-getrennte Dateien auszugeben, bei der eine oder mehr Spalten Überbreiten haben.
Ich das mit einer Datei getestet, welche ca. 20 Spalten hat. Davon habe ich dann die ersten 6 Spalten ausgewählt, bei der zwei davon Überbreite haben. Die Ausgabe im Terminal sah überzeugend aus und jede Spalte war für sich ausgerichtet.
Hier ist es ratsam, die Größe des Terminals zu maximieren.
Hier ist mal der Code, bei dem noch Kurzerläuterungen enthalten sind:
https://gist.github.com/3750805
Würde mich freuen, wenn Ihr Euch den Code anschauen und mir Input darüber geben würdet, auch was sich besser machen lässt!

Re: python2to3
Verfasst: Donnerstag 20. September 2012, 10:54
von Nobuddy
Eine Kleinigkeit, mußte ich doch noch korrigieren.
Es entstand ein Layout-Fehler bei weiterer Filterung der Daten, der jetzt behoben ist.
Das betraf die Zeile 96, die an dieser Position entfällt.
Neu hinzu kam dieser Code, der nach der Zeile 76 eingefügt ist.
Code: Alles auswählen
for line_number, text_items in enumerate(contents, 1):
for i in range(len(text_items)):
text_items[i] = text_items[i].replace('\n', '')
text_items[i] = text_items[i].replace(' ', '')
dataline[line_number] = [text_items]
Dies lässt sich bestimmt noch besser machen, zumindest erfüllt es vorerst die Funktion.
Re: python2to3
Verfasst: Donnerstag 20. September 2012, 18:33
von snafu
Deine `True`-`False`-Wörterbuchgebilde lassen sich vereinfachen:
Code: Alles auswählen
# schlecht
total_width = {True: columns, False: total_width}[total_width > columns]
# besser
total_width = min(columns, total_width)
# schlecht
normal_width = {True: normal_width, False: round(normal_width / len(xtra_width) + 0.5)}[len(xtra_width) == 1]
# besser
if len(xtra_width) != 1:
normal_width = round(normal_width / len(xtra_width) + 0.5)
Und das, was du im letzten Post dazugeschrieben hast, lässt sich auch so ausdrücken:
Code: Alles auswählen
text_items = [item.replace('\n', '').replace(' ', '') for item in text_items]
Ich wette aber, dass man dies noch anders lösen kann. Wahrscheinlich mittels `item.strip()`. Aber dazu müsste ich mir den Quelltext genauer ansehen, wozu mir momentan einfach die Zeit/Motivation fehlt. Fraglich ist ja auch, wieso etwas namens `items` überhaupt Whitespace (vermutlich) am Ende drin hat...
EDIT: Und der Ausdruck von Zeile 86-93 ist echt der Knüller. Oh Mann.

Re: python2to3
Verfasst: Donnerstag 20. September 2012, 18:40
von Nobuddy
Hallo snafu,
Dein Input, dieser hilft mir weiter, die Dinge einfacher zu gestalten!
Mach Dir keinen Kopf über Zeit und Motivation, Du hast mir sehr geholfen, Danke dafür!
Nachtrag:
snafu, Deine letzte Zeile ist mir erst im Nachhinein aufgefallen ...

... keine Frage, diese Codezeilen sind verbesserungswürdig, daher kommt auch das fehlerhafte Zeilenformat beim Filtern.
Habe den Zeilenumbruch durch Leerzeichen ersetzt.
Versuche den Code noch weiter zu vereinfachen.

Re: python2to3
Verfasst: Freitag 21. September 2012, 14:30
von Nobuddy
Sodele, habe diesen Bereich nochmals überarbeitet.
Code: Alles auswählen
for line_number, text_items in enumerate(contents, 1):
for i in xtra_width:
rang = i[0]
true_width = len(text_items[rang])
if true_width > normal_width:
start_width = (sum(column_widths[:rang])
+ numeration_width + ((rang) * spacing))
lines = round((true_width / normal_width) + 0.5)
text_items[rang] = ('{}'.format(''.join([
(text_items[rang][normal_width * i:
normal_width * (i + 1)])
+ {True: (total_width - normal_width) * ' ',
False: (normal_width * (i + 1) - true_width)
* ' '}[i + 1 < lines]
for i in range(lines)])))
needs_headings = (line_number % MAX_LINES_PER_SEGMENT == 0)
if needs_headings:
formatted_lines.extend(head_items)
numeration_string = '{}: '.format(line_number)
formatted_lines.append(line_template.format(numeration_string,
*text_items))
formatted_lines.append(blank_line)
text_items = [item.replace(' ', '') for item in text_items]
dataline[line_number] = [text_items]
formatted_lines.append(dashed_line)
print('\n'.join(formatted_lines))
Jetzt läuft von der funktionalen Seite alles rund.
Wie ich Euch kenne, habt ihr dafür bestimmt bessere Vorschläge.
Was mich jetzt aber grundsätzlich interessiert, ist ob dieser Bereich des Codes mit den Einrückungen so gut ist, daß man die einzelnen Bereiche besser erkennt
Code: Alles auswählen
text_items[rang] = ('{}'.format(''.join([
(text_items[rang][normal_width * i:
normal_width * (i + 1)])
+ {True: (total_width - normal_width) * ' ',
False: (normal_width * (i + 1) - true_width)
* ' '}[i + 1 < lines]
for i in range(lines)])))
oder ob man dies hier besser einheitlich, links ausrichtet so wie hier?
Code: Alles auswählen
text_items[rang] = ('{}'.format(''.join([
(text_items[rang][normal_width * i:
normal_width * (i + 1)])
+ {True: (total_width - normal_width) * ' ',
False: (normal_width * (i + 1) - true_width)
* ' '}[i + 1 < lines]
for i in range(lines)])))
Re: python2to3
Verfasst: Freitag 21. September 2012, 14:52
von cofi
Weder noch. Der Abschnitt ist komplex genug fuer mindestens eine Funktion.
Ich will mir das nicht en detail durchlesen, aber nur weil man 100 Sachen in 1 Ausdruck erledigen kann, sollte man es noch lange nicht tun.