Join-Methode
- __blackjack__
- User
- Beiträge: 13117
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@bahmady: In die Vorlage kann man deutlich mehr als einfach nur "{}" für Platzhalter rein schreiben. Das ist eine eigene kleine ”Formatbeschreibungssprache” und da wurde auch schon ein Link zur Dokumentation in diesem Thema gepostet. Man kann da unter anderem auch ausdrücken, dass das was da eingesetzt werden soll, eine bestimmte Breite haben soll, und ob das links- oder rechtsbündig in diesen Platz eingesetzt werden soll.
Wenn Du `format()` nicht verwenden möchtest, gibt es wie schon gesagt die `ljust()`-Methode auf Zeichenketten, mit der man auch eine angegebene Breite pro Spaltenwert erreichen kann.
Dir nützt es nichts *ein* `l` am Ende einer Schleife zu haben, und zwar das der letzten Spalte. Du brauchst für jede Spalte den Wert der Breite der Spalte.
Wenn Du `format()` nicht verwenden möchtest, gibt es wie schon gesagt die `ljust()`-Methode auf Zeichenketten, mit der man auch eine angegebene Breite pro Spaltenwert erreichen kann.
Dir nützt es nichts *ein* `l` am Ende einer Schleife zu haben, und zwar das der letzten Spalte. Du brauchst für jede Spalte den Wert der Breite der Spalte.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Ein Formatstring ist quasi eine Vorschrift zur Formatierung. Da ein Beispiel oft mehr sagt als tausend Worte:bahmady hat geschrieben: ↑Dienstag 1. Juni 2021, 10:10 Ich verstehe immernoch nicht wie ich mit den Längenangaben einen Format-String ausgeben soll bzw. was überhaupt mit einem "Format-String" gemeint ist. Und wenn ich die beiden Format-Strings habe, wie soll ich die dann richtig formatiert untereinander ausgeben?
Code: Alles auswählen
eins = 'eins'
formatstring = 'a{!r:>30s}e'
print(formatstring.fomat(eins)) # huhu
Code: Alles auswählen
a 'eins'e
Als Variablennamen am Besten gar nicht. Bitte versteh' mich nicht falsch, für kleine Demo- und Wegwerfskripte habe ich keine sonderlich großen Schwierigkeiten mit Variablennamen, die aus nur einem Buchstaben bestehen, aber I, l, 1 und i lassen sich je nach Schriftart leider kaum unterscheiden und sind deswegen schwer zu lesen.
Wie ich oben in meinem 'huhu'-Beispiel: mit einem Formatstring.
Du, sag' mal, wann mußt Du Deine Hausarbeit eigentlich fertig haben?
[1] https://docs.python.org/3/library/string.html
[2] https://pymotw.com/3/string/
[3] https://realpython.com/python-formatted-output/
[4] https://www.geeksforgeeks.org/python-format-function/
@LukeNukem
Ich kann meine Hausarbeit abgeben wann ich will. Diese Aufgabe ist die 4.) von 6 Aufgaben mit mehreren Aufgabenteilen. Ich wollte aber nächste Woche mit Datenbanken anfangen (ich mache ein Fernstudium). Ich habe nun mehrere Stunden alles Mögliche ausprobiert, habe in der Dokumentation für die format-Funktion reingeschaut, nichts klappt. Es wäre echt nett wenn du oder ein anderer mir einfach zeigen würde, wie ich die Format-Funktion hier richtig einsetzte. Ich habe soooo viel Zeit in dem kleinen Aufgabenteil investiert, da wird schon ein Lerneffekt da sein!
Ich kann meine Hausarbeit abgeben wann ich will. Diese Aufgabe ist die 4.) von 6 Aufgaben mit mehreren Aufgabenteilen. Ich wollte aber nächste Woche mit Datenbanken anfangen (ich mache ein Fernstudium). Ich habe nun mehrere Stunden alles Mögliche ausprobiert, habe in der Dokumentation für die format-Funktion reingeschaut, nichts klappt. Es wäre echt nett wenn du oder ein anderer mir einfach zeigen würde, wie ich die Format-Funktion hier richtig einsetzte. Ich habe soooo viel Zeit in dem kleinen Aufgabenteil investiert, da wird schon ein Lerneffekt da sein!
- __blackjack__
- User
- Beiträge: 13117
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@bahmady: Dann lass das mit `format()` und verwende `ljust()`. Was Du bisher gezeigt hast, deutet aber auf sehr viel grundlegendere Probleme bei der Planung und Strukturierung von Code hin. Das ist durch das verstehen von `format()` nicht getan, das ist nur ein Detailproblem, von etwas was vom Konzept her in dem bisher gezeigten noch nicht gelöst ist. Und es sieht so ein bisschen so aus, als würdest Du versuchen das durch herumprobieren angehen zu wollen.
Beschreibe doch mal in Worten was Du machen müsstest, und in welcher Reihenfolge, wenn Du das manuell auf Kästchenpapier lösen wolltest, das die Spalten so breit sind wie die Zeilen/Werte in der ersten Datei (plus Trennzeichen).
(Wobei ich die Aufgabenstellung immer noch verwirrend finde, denn sie hält sich nicht an das verhalten von ``paste`` und scheint so formuliert, das die Zeilen in Datei 1 grundsätzlich länger sein müssen als die korrespondierenden Zeilen in Datei 2.)
Beschreibe doch mal in Worten was Du machen müsstest, und in welcher Reihenfolge, wenn Du das manuell auf Kästchenpapier lösen wolltest, das die Spalten so breit sind wie die Zeilen/Werte in der ersten Datei (plus Trennzeichen).
(Wobei ich die Aufgabenstellung immer noch verwirrend finde, denn sie hält sich nicht an das verhalten von ``paste`` und scheint so formuliert, das die Zeilen in Datei 1 grundsätzlich länger sein müssen als die korrespondierenden Zeilen in Datei 2.)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Najaaa... im Prinzip willst Du ja zwei Dateien lesen, deren Dateinamen auf der Kommandozeile übergeben werden sollen, dann für jede Zeile n die maximale Länge max([len(strings in n. Zeile der Dateien)]) ermitteln und daraus einen Formatstring bauen. Also eine Vorschrift, wie breit das betreffende Feld ausgegeben werden soll.bahmady hat geschrieben: ↑Dienstag 1. Juni 2021, 15:40 @LukeNukem
Ich kann meine Hausarbeit abgeben wann ich will. Diese Aufgabe ist die 4.) von 6 Aufgaben mit mehreren Aufgabenteilen. Ich wollte aber nächste Woche mit Datenbanken anfangen (ich mache ein Fernstudium). Ich habe nun mehrere Stunden alles Mögliche ausprobiert, habe in der Dokumentation für die format-Funktion reingeschaut, nichts klappt. Es wäre echt nett wenn du oder ein anderer mir einfach zeigen würde, wie ich die Format-Funktion hier richtig einsetzte. Ich habe soooo viel Zeit in dem kleinen Aufgabenteil investiert, da wird schon ein Lerneffekt da sein!
Der erste Schritt ist also, die Parameter zu parsen, die auf der Kommandozeile übergeben wurden. Wie für so vieles, hat Python dafür natürlich eine (eigentlich sogar mehrere) eingebaute Module, ich persönlich verwende dafür gerne das Modul "argparse", das die Klasse "ArgumentParser" bereitstellt -- der dann natürlich entsprechend konfiguriert werden muß. Und das könnte für Deinen Anwendungsfall etwa so aussehen:
Code: Alles auswählen
from argparse import ArgumentParser
if __name__ == '__main__':
parser = ArgumentParser(description='mimic paste(1)')
parser.add_argument('filenames', nargs='+', help='the files')
parser.add_argument('--serial', '-s', action='store_true', help='output as columns')
args = parser.parse_args()
Code: Alles auswählen
args.filenames = ["names.txt", "numbers.txt"]
args.serial = True
Code: Alles auswählen
contents = list()
for filename in args.filenames:
with open(filename, 'r') as ifh: # diesen abgekürzten Variablennamen mögen manche hier nicht, ich schon ;-)
content = ifh.read().splitlines() # das entfernt im Gegensatz zu ifh.readlines() auch die Zeilenumbrüche
contents.append(content)
Code: Alles auswählen
contents = [
["Mark Smith", "Bobby Brown", ...],
["555-1234", "555-9876", ...]
]
Code: Alles auswählen
linecount = len(contents[0])
if not all(len(content) == linecount for content in contents[1:]):
raise ValueError('Files do not all have the same linecount')
Code: Alles auswählen
corresponding_lines = list(zip(*contents))
Code: Alles auswählen
corresponding_lines = [('Mark Smith', '555-1234'), ('Bobby Brown', '555-9876'), ...]
Code: Alles auswählen
maxlengths = [max([len(string) for string in corresponding_lines[linenumber]]) for linenumber in range(len(corresponding_lines))]
Code: Alles auswählen
maxlengths = list()
for linenumber in range(len(corresponding_lines)):
maxlength = 0
for string in corresponding_lines[linenumber]:
length = len(string)
if length > maxlength:
maxlength = length
maxlengths.append(maxlength)
Code: Alles auswählen
maxlengths = [30, 10, 11, 10, 12]
Code: Alles auswählen
formatstrings = ' '.join(['{:<%ds}'%(maxlength) for maxlength in maxlengths])
Also, was haben wir jetzt? Genau: wir haben unsere Dateiinhalte in contents und einen Formatstring, also auf zur Ausgabe:
Code: Alles auswählen
for content in contents:
print(formatstring.format(*content))
Code: Alles auswählen
#!/usr/bin/env python
from argparse import ArgumentParser
if __name__ == '__main__':
parser = ArgumentParser(description='mimic paste(1)')
parser.add_argument('filenames', nargs='+', help='the files')
parser.add_argument('--serial', '-s', action='store_true', help='output as columns')
args = parser.parse_args()
contents = list()
for filename in args.filenames:
with open(filename, 'r') as ifh: # diesen abgekürzten Variablennamen mögen manche hier nicht, ich schon ;-)
content = ifh.read().splitlines() # das entfernt im Gegensatz zu ifh.readlines() auch die Zeilenumbrüche
contents.append(content)
# validate input(s)
linecount = len(contents[0])
if not all(len(content) == linecount for content in contents[1:]):
raise ValueError('Files do not all have the same linecount')
if args.serial:
# output files as lines
corresponding_lines = list(zip(*contents))
formatstring = ' '.join(
['{:<%ds}'%(maxlength) for maxlength in [
max([len(string) for string in corresponding_lines[linenumber]])
for linenumber in range(len(corresponding_lines))]])
for content in contents:
print(formatstring.format(*content))
else:
# @todo output files as columns
pass # this part is left as an excercise to the reader
- __blackjack__
- User
- Beiträge: 13117
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@LukeNukem: Du hast jetzt den normalen Teil gemacht, also das müsste eigentlich im ``else`` stehen wo das @todo steht. Der ``--serial``-Fall gibt eine Datei pro Zeile aus.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Also äh... ja, nein, vielleicht... Sorry, unter Linux ist das nicht so. Aus "man 1 paste" (GNU Coreutils):__blackjack__ hat geschrieben: ↑Dienstag 1. Juni 2021, 22:51 @LukeNukem: Du hast jetzt den normalen Teil gemacht, also das müsste eigentlich im ``else`` stehen wo das @todo steht. Der ``--serial``-Fall gibt eine Datei pro Zeile aus.
Code: Alles auswählen
-s, --serial
paste one file at a time instead of in parallel
Natürlich kann ich nicht ausschließen, daß Du mit einer anderen UNIX-Implementierung (SCO, Sinix, ...?) arbeitest als ich, aber... ich halte das Verhalten meines Programms auch nach mehreren Tests für weitestgehend korrekt -- diesbezüglich jedenfalls.
[1] https://pubs.opengroup.org/onlinepubs/0 ... paste.html
[2] https://www.freebsd.org/cgi/man.cgi?query=paste
[3] https://linux.die.net/man/1/paste
Um die Längen der Dateien zu prüfen, ist der erste Schritt, die Längen zu ermitteln, dann zu schauen, ob sie unterschiedlich sind. Das geht mit einem Set:
Über einen Index iteriert man in Python nicht. Bei corresponding_lines gibt es eigentlich auch gar keinen Grund dafür, das ist einfach nur umständlich.
Auch die doppelte for-Schleife ist unnötig kompliziert.
Code: Alles auswählen
if len(set(map(len, contents))) > 1:
raise ValueError('Files do not all have the same linecount')
Code: Alles auswählen
formatstring = ' '.join(
'{:<%ds}'%(maxlength) for maxlength in [
max(len(string) for string in lines)
for lines in corresponding_lines])
Code: Alles auswählen
formatstring = ' '.join('{:<%ds}' % max(map(len, lines)) for lines in zip(*contents))
- __blackjack__
- User
- Beiträge: 13117
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@LukeNukem: Okay, das ``list(zip(*contents))`` hatte mich zu der Annahme verleitet, denn das braucht man wenn man den Fall ohne ``-s`` implementiert, aber es ist falsch für den Fall mit ``-s``. Die Aufgabenstellung spricht da explizit nur von ``file1``. Was ich auch komisch finde an der Aufgabenstellung.
Mit dem original ``paste``-Programm hat das auch nichts zu tun, denn dem sind die Längen der Zeilen in beiden Fällen völlig egal, das setzt einfach ein Tabulatorzeichen ohne da irgendwas mit Leerzeichen auszurichten. Oder was anderes als ein Tab wenn man die ``-d``-Option benutzt um etwas anderes anzugeben.
Mit dem original ``paste``-Programm hat das auch nichts zu tun, denn dem sind die Längen der Zeilen in beiden Fällen völlig egal, das setzt einfach ein Tabulatorzeichen ohne da irgendwas mit Leerzeichen auszurichten. Oder was anderes als ein Tab wenn man die ``-d``-Option benutzt um etwas anderes anzugeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Hallo LukeNukem!
Ich habe letzte Woche die restlichen Aufgaben meiner Hausarbeit fertig gemacht. Unter anderem habe ich ein Problem geschrieben, mit dem man das Cäsar-Chiffre knacken kann.
Um ehrlich zu sein, dein Code ist für mich recht kompliziert. Die Klasse ArgumentParser ist für mich neu. Um die Klasse ein wenig zu verstehen, habe ich mir folgendes Video angeschaut: https://www.youtube.com/watch?v=cdblJqEUDNo&t=32s
Was ich von deinem Code verstehe:
Hier soll eine Fehlermeldung auftauchen, falls die beiden Textdateien unterschiedlich lange Zeilen haben.
Hier bildest du den Formatstring. Was ich an deinem Code nicht verstehe ist, wie du contents verwendest und wie du die Bezüge darstellst:
Wo ist der Bezug von filename zu meinen beiden Textdateien???
Kannst du mir den Bezug von 'filenames' zu contents erklären? Ich bin übrigens schon für Datenbanksysteme am lernen. Die nächsten Klausurtermine sind erst ab Oktober -.-. Die Klausur ist am 17.07...
LG
bahmady
Ich habe letzte Woche die restlichen Aufgaben meiner Hausarbeit fertig gemacht. Unter anderem habe ich ein Problem geschrieben, mit dem man das Cäsar-Chiffre knacken kann.
Um ehrlich zu sein, dein Code ist für mich recht kompliziert. Die Klasse ArgumentParser ist für mich neu. Um die Klasse ein wenig zu verstehen, habe ich mir folgendes Video angeschaut: https://www.youtube.com/watch?v=cdblJqEUDNo&t=32s
Was ich von deinem Code verstehe:
Code: Alles auswählen
# validate input(s)
linecount = len(contents[0])
if not all(len(content) == linecount for content in contents[1:]):
raise ValueError('Files do not all have the same linecount')
Code: Alles auswählen
if args.serial:
# output files as lines
corresponding_lines = list(zip(*contents))
formatstring = ' '.join(
['{:<%ds}'%(maxlength) for maxlength in [
max([len(string) for string in corresponding_lines[linenumber]])
for linenumber in range(len(corresponding_lines))]])
for content in contents:
print(formatstring.format(*content))
Code: Alles auswählen
contents = list()
for filename in args.filenames:
with open(filename, 'r') as ifh: # diesen abgekürzten Variablennamen mögen manche hier nicht, ich schon ;-)
content = ifh.read().splitlines() # das entfernt im Gegensatz zu ifh.readlines() auch die Zeilenumbrüche
contents.append(content)
Wo ist der Bezug von filename zu meinen beiden Textdateien???
Code: Alles auswählen
texteins = 'C:/Users/bah90/Desktop/t1.txt'
textzwei = 'C:/Users/bah90/Desktop/t2.txt'
Code: Alles auswählen
def paste_s(texteins, textzwei):
if __name__ == '__main__':
parser = ArgumentParser(description='mimic paste(1)')
parser.add_argument('filenames', nargs='+', help='the files')
parser.add_argument('--serial', '-s', action='store_true', help='output as columns')
args = parser.parse_args()
contents = list()
for filename in args.filenames:
with open(filename, 'r') as ifh: # diesen abgekürzten Variablennamen mögen manche hier nicht, ich schon ;-)
content = ifh.read().splitlines() # das entfernt im Gegensatz zu ifh.readlines() auch die Zeilenumbrüche
contents.append(content)
LG
bahmady
Korrekt.
Mein Trick ist, daß ich mit der zip()-Funktion zunächst eine Liste von Tupeln baue, und jedes der Tupel-Elemente in der Liste enthält die Inhalte der korrespondierenden Zeilen. Also das Tupel mit dem Index 0 in der Liste enthält die Daten der ersten, das Tupel-Element mit dem Index 1 in der Liste die aus der zweiten Zeile, und so weiter. Dadurch kann ich ganz einfach über eine weitere List Comprehension die Längen der Strings in den Zeilen ermitteln und mit der max()-Funktion die größte Länge dort herausziehen, und mit dieser Länge baue ich dann einen Teil-Formatstring wie "{:<30s}" für einen linksbündig ausgerichteten String mit 30 Zeichen. Diese Teil-Formatstrings werden dann über die str.join()-Methode zum Gesamt-Formatstring zusammengefaßt.
Nun habe ich meine originalen Inhalte aber noch in der Variablen "content", die ebenfalls eine Liste von Listen ist und in jeder der enthaltenen Listen die eingelesenen Inhalte einer meiner Textdateien enthält -- also das, was ich bei '--serial' oder '-s' in einer Zeile ausgeben möchte. Und genau darauf wende ich dann ganz einfach meinen oben zusammengebauten Formatstring an und gebe das Resultat aus.
Na klar. Ich habe den ArgumentParser so konfiguriert, daß er sogenannte "positional arguments" entgegennehmen kann, sowas kennst Du vielleicht (hoffentlich) von etlichen Kommandozeilenprogrammen wie less(1), cat(1) oder grep(1). So kannt Du mein Programm im Prinzip mit so vielen Dateinamen aufrufen, wie Du möchtest, bei Dir zum Beispiel mit zwei: "./programm.py names.txt numbers.txt", aber "./programm.py names.txt numbers.txt numbers.txt names.txt" oder andere Dateien gehen natürlich auch. (Es gibt da eine Grenze, die Deine Kommandozeilenumgebung festlegt, aber die ist heutzutage recht groß und soll uns jetzt hier nicht weiter interessieren). Der Name "filenames" und der Parameter "nargs='+'" in "parser.add_argument()" sorgen dafür, daß die übergebenen Dateinamen von parser.parse_args() in einer Liste (hier: "args") abgelegt werden, die Dein Programm dann im Folgenden über das Attribut "args.filenames" lesen, und -- wie ich hier -- darüber iterieren kann. Wenn Du das Programm also mit "./programm.py names.txt numbers.txt" aufrufst, enthält args.filenames nach dem Aufruf von parse_args() die Liste "['names.txt', 'numbers.txt']" -- und wenn ich mit "for filename in args.filenames:" darüber iteriere... genau.
Naja, die "args.filenames" sind wie gerade erklärt die übergebenen Dateinamen, und "filename" enthält dann für jeden Durchlauf der for-Schleife einen der Dateinamen. Ich öffne dann die Datei mit einem sogenannten "Context Manager" (with open()") zum Lesen, lese die Datei komplett ein, splitte den gelesenen Inhalt zeilenweise ("ifh.read().splitlines()") und hänge die so gewonnene Liste von Zeilen an meine Liste "contents" an, so daß "contents" am Ende eine Liste enthält, bei der jedes Element wiederum eine Liste der Zeilen aus der angegebenen Textdatei ist.
Tipp: füg' doch mal' nach dem "corresponding_lines" jeweils ein "print(contents)" und ein "print(corresponding_lines)" ein... viel Spaß und Erfolg!
Man kann dir bestimmt helfen. Viele von uns, mich inbegriffen, haben aber anscheinend immer noch nicht ganz verstanden was die genaue Anforderung ist.
Zeig doch nochmal wie die Ausgabe aussehen soll, aber mit [\code] - tags damit die Formatierung nicht verändert wird.
Bisher hattest du auch nur einen Teil der Aufgabe gepostet, daher ist es nicht ganz klar wie das mit dem Rest des Programms zusammenspielen soll.
Es ist wohl auch zielführender, wenn du uns deinen Code zeigst und wir dir Hilfestellung an deinem Code geben.
Najaaa... Du möchtest oder mußt die Programmiersprache Python lernen. Zum Erlernen einer Programmiersprache ist es meist sehr nützlich, fremden Code zu lesen und zu verstehen -- oder sich jedenfalls ein Verständnis dafür zu erarbeiten. Und zwar, ja, auch Code von Leuten, die mehr Erfahrung haben als man selbst, dabei lernt man gemeinhin am meisten. Und wenn ich Dein Eröffnungsposting richtig verstanden habe, möchtest Du Dir das Verständnis ja auch erarbeiten und keine schlüsselfertige Lösung.
Deswegen, mach's doch einfach so: nimm meinen Code und arbeite ihn Abschnitt für Abschnitt durch. Wenn Du Dich fragst, was in "args.filenames" steht, dann füg' doch einfach mal temporär ein "print('args.filenames:', args.filenames)" oder ein "print('args:', args)" ein. "print()" ist quasi das "Debugging des kleinen Mannes", und auch die Builtin-Funktionen "dir()", "vars()", "type()" und ggf. "getattr()" können dabei sehr nützlich sein, um ein Python-Objekt zu untersuchen. Wenn Du Dein "print()"-Statement eingebaut hast, rufst Du das Programm einfach mal auf und schaust, was in Deinen Variablen steht. Dabei kann es nützlich sein, das Programm nach dem Aufruf von "print()" direkt zu beenden, das ginge mit einem "sys.exit(0)". Wenn Du das Programm einige Male mit verschiedenen Kommandozeilenargumenten aufgerufen und den Zusammenhang zwischen den Argumenten und den Inhalten von "args.filenames" bzw. "args" verstanden hast, nimmst Du das (oder die) "print()"-Aufrufe wieder heraus und wendest Dich dem nächsten Abschnitt des Code zu.
Mein Code benutzt -- bewußt -- viele Comprehensions, also im Prinzip eine Art von syntaktischem Zucker. Dabei ist die List Comprehension
Code: Alles auswählen
dingsbums = [1, 2, 3]
bumsdings = [value**value for value in dingsbums]
Code: Alles auswählen
dingsbums = [1, 2, 3]
bumsdings = list()
for value in dingsbums:
bumsdings.append(value**value)
Auf diese Weise arbeitest Du Dich durch den Code und verstehst Stück für Stück das Programm -- und wenn sich dabei Fragen ergeben, dann stell' sie einfach hier. Ja, ich weiß, das ist zeit- und arbeitsaufwändig, aber am Ende, wenn Du alles verstanden hast, wirst Du mit Deinen Python-Kenntnissen ein bedeutendes Stück weiter gekommen sein.
Wie gesagt, ich weiß, das ist aufwändig, aber leider ist es der einzige Weg. Wir können ja schlecht Deinen Kopf aufmachen und unser Wissen hineinkopieren, und wenn wir Dir die einfachste und Deinem aktuellen Niveau angepaßte Lösung vorkauen, hast Du auch nicht viel gelernt. Da können wir Dir helfen und ich glaube, wir haben gezeigt, daß wir das auch gerne tun, aber mehr können wir nicht tun...
Hallo zusammen!
Sorry für die späte Antwort. Ich lerne gerade für eine andere Klausur. Nach der Klausurphase mache ich einen Python-Bootcamp, um beim Programmieren besser zu werden. Dies wird jedoch leider erst im September sein -.-
@LukeNukem ich habe die Aufgabe mittlerweile gelöst. Hierzu habe ich deinen Code genommen, den Argparser entfernt und den Code entsprechend modifiziert. Hier mein Code:
Den Argparser und die gesamte Thematik dahinter werde ich versuchen, im Bootcamp nach der Klausur zu erlernen. Der entscheidende Code, den ich die ganze Zeit nicht selbst hingekriegt habe, ist der hier:
Ich verstehe hier was die einzelnen Variablen bedeuten. Aber ich habe noch nicht gelernt, wie du all die Variablen mit for und in range() verbunden hast bzw. wie oder wo du die Syntax mit for und in range() gelernt hast. Dazu habe ich keine Schritt für Schritt Erklärung gefunden und wäre für eine Erklärung dankbar.
LG
Belal Ahmady
Sorry für die späte Antwort. Ich lerne gerade für eine andere Klausur. Nach der Klausurphase mache ich einen Python-Bootcamp, um beim Programmieren besser zu werden. Dies wird jedoch leider erst im September sein -.-
@LukeNukem ich habe die Aufgabe mittlerweile gelöst. Hierzu habe ich deinen Code genommen, den Argparser entfernt und den Code entsprechend modifiziert. Hier mein Code:
Code: Alles auswählen
texteins = 'C:/Users/bah90/Desktop/names.txt'
textzwei = 'C:/Users/bah90/Desktop/numbers.txt'
def paste_s(texteins, textzwei):
#texteins lesen und splitten
texteins = open('C:/Users/bah90/Desktop/names.txt', encoding='utf-8')
namen = texteins.read()
namen_split = namen.splitlines(False)
texteins.close()
#testzwei lesen und splitten
textzwei = open('C:/Users/bah90/Desktop/numbers.txt', encoding='utf-8')
nummern = textzwei.read()
nummern_split = nummern.splitlines(False)
textzwei.close()
#Inhalt beider Dateien zu einer Gesamtliste hinzufügen
listen = list()
listen.append(namen_split)
listen.append(nummern_split)
#Gesamtliste in zusammengehörige Elemente aufteilen
zusammengehörige_zeilen = list(zip(*listen))
#Formatstring rstellen mit der Join-Methode, gekoppelt mit der max() - und der range()-Funktion
formatstring = ' '.join(
['{:<%ds}'%(maxlength) for maxlength in [
max([len(string) for string in zusammengehörige_zeilen[linenumber]])
for linenumber in range(len(zusammengehörige_zeilen))]])
#Ausgabe der formatierten Liste
for liste in listen:
print(formatstring.format(*liste))
Code: Alles auswählen
formatstring = ' '.join(
['{:<%ds}'%(maxlength) for maxlength in [
max([len(string) for string in zusammengehörige_zeilen[linenumber]])
for linenumber in range(len(zusammengehörige_zeilen))]])
LG
Belal Ahmady
- __blackjack__
- User
- Beiträge: 13117
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Stichwort ist „list comprehension“ LC und die kann man auch verschachteln. Und man kann die auch „entschachteln“. Schau Dir LCs in der Dokumentation mal an und versuch mal den Ausdruck mit normalen Schleifen zu schreiben. Dann wird Dir der Zusammenhang vielleicht/hoffentlich klarer.
Vielleicht hilft es das erst einmal einfach etwas weniger kompakt zu formatieren:
Wobei ich die innerste wohl mit `map()` gelöst hätte:
Und das mit dem `for linenuber in range(len(…))`` ist ein „anti pattern“. Man kann direkt über die Elemente iterieren, ohne den Umweg über `linenumber`:
Dann stellt sich die Frage ob man den Ausdruck für die `maxlength`\s nicht einfach direkt ohne eine zwischengeschaltete LC berechnet:
Aus der LC könnte man noch einen Generatorausdruck machen und da braucht man dann die Klammern nicht mehr, weil man die vom `join()`-Aufruf ”mitbenutzen” kann:
Vielleicht hilft es das erst einmal einfach etwas weniger kompakt zu formatieren:
Code: Alles auswählen
formatstring = " ".join(
[
"{:<%ds}" % maxlength
for maxlength in [
max(
[
len(string)
for string in zusammengehörige_zeilen[linenumber]
]
)
for linenumber in range(len(zusammengehörige_zeilen))
]
]
)
Code: Alles auswählen
formatstring = " ".join(
[
"{:<%ds}" % maxlength
for maxlength in [
max(map(len, zusammengehörige_zeilen[linenumber]))
for linenumber in range(len(zusammengehörige_zeilen))
]
]
)
Code: Alles auswählen
formatstring = " ".join(
[
"{:<%ds}" % maxlength
for maxlength in [
max(map(len, zeilen)) for zeilen in zusammengehörige_zeilen
]
]
)
Code: Alles auswählen
formatstring = " ".join(
[
"{:<%ds}" % max(map(len, zeilen))
for zeilen in zusammengehörige_zeilen
]
)
Code: Alles auswählen
formatstring = " ".join(
"{:<%ds}" % max(map(len, zeilen)) for zeilen in zusammengehörige_zeilen
)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman