Ich würde gerne in einer TXT Datei nach gewissen Wörtern suchen wollen und diese dann ein einer anderen Datei einfügen wollen am liebsten wäre mir als pdf aber ist kein muss. Mein erster fersuch schlägt aber schon fehl kann mir einer sagen was verkehrt ist.
Inhalt TXT:
| | DONE TEST | NAME | PARTS | PARTOF | IMPLEMENTED | DEFINED | TEXT
|D-| 100% 0% | REQ-aliens | spc-aliens | REQ-purpose | | design\purpose.toml | There shall be a way to say hello to aliens, bu...
|D-| 100% 50% | REQ-purpose | REQ-aliens, REQ-world | | | design\purpose.toml | This is a project about saying hello to lots of...
|DT| 100% 100% | REQ-world | SPC-world | REQ-purpose | | design\purpose.toml | There shall be a way to say hello to the world....
|D-| 100% 0% | spc-aliens | | REQ-aliens | C:\Req_neu\src\hello.py[10] | design\purpose.toml | There shall be a way to say hello to aliens.
|DT| 100% 100% | SPC-world | TST-world | REQ-world | C:\Req_neu\src\hello.py[3] | design\purpose.toml | The hello-world function shall print hello
|DT| 100% 100% | TST-world | | SPC-world | C:\Req_neu\tests\hello_test.py[3] | design\purpose.toml | We will make a test later.
Code:
import os
import site
input = open ('report.txt','r')
output = open ('Ergebnisse.txt','w')
x = input.read()
whitespace = ' '
def reg():
i = 0
while i < len(x):
word = x[i:i+3]
if word == 'REQ':
string= x[i:i+10]
print(string)
output.write(string)
output.write(whitespace)
i+= 1
input.close()
output.close()
Parsen einer Textdatei
Was erwartest Du denn, was passiert? Und was passiert wirklich?
Du hast eine |-separierte Datei, die Du am besten mit dem csv-Modul einliest.
Funktionen sollten alles, was sie brauchen über ihre Argumente bekommen, input, output und x kommen einfach so rein. os und site werden importiert, aber nicht benutzt. `x` ist ein schlechter Name für den gesamten Dateiinhalt als ein String.
Du hast eine |-separierte Datei, die Du am besten mit dem csv-Modul einliest.
Funktionen sollten alles, was sie brauchen über ihre Argumente bekommen, input, output und x kommen einfach so rein. os und site werden importiert, aber nicht benutzt. `x` ist ein schlechter Name für den gesamten Dateiinhalt als ein String.
- __blackjack__
- User
- Beiträge: 13112
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Alex_1979: Du ignorierst ja komplett die Struktur der Daten. Soll denn wirklich jedes Wort in dem 'REQ' vorkommt mit seinen 10 nächsten Zeichen ausgegeben werden? Falls es nur Worte sein sollen die damit anfangen, dann hast Du Glück gehabt, das es nirgendwo *in* einem Wort vorkommt. Und was ist mit Mehrfachnennungen? Die gleichen Worte mit REQ kommen da ja mehrfach vor. Sollen die auch wirklich mehrfach ausgegeben werden? Oder vielleicht doch nur einmal? Und vielleicht auch nur aus einer bestimmten Spalte? In der TEXT-Spalte am Ende könnte ja auch ein REQ vorkommen, sollte das dort auch berücksichtigt werden?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Die Aufgabe kann man gut in drei Schritten angehen:
1. Parsen in eine geeignete Struktur
2. Filtern der gewünschten Infos
3. Schreiben in das gewünschte Dateiformat
Für jeden Schritt kann man eine eigene Funktion definieren. Für Schritt 1 wäre das recht trivial:
Erfordert allerdings schon gewisse Vorkenntnisse in Python, gerade bei der letzten Zeile. Man könnte alternativ auch alles in eine große Liste stecken und .append() verwenden, wenn man das einfacher findet.
1. Parsen in eine geeignete Struktur
2. Filtern der gewünschten Infos
3. Schreiben in das gewünschte Dateiformat
Für jeden Schritt kann man eine eigene Funktion definieren. Für Schritt 1 wäre das recht trivial:
Code: Alles auswählen
def parse(filename, sep='|'):
with open(filename) as source:
for line in source:
yield [item.strip() for item in line.split(sep)]
Hier die etwas anfängerfreundlichere Variante:
Aber den Rest werde ich nicht vorkauen. Hier bitte etwas Eigeninitiative mitbringen...
Code: Alles auswählen
def parse(filename, sep='|'):
all_items = []
with open(filename) as source:
for line in source:
row_items = []
for item in line.split(sep):
row_items.append(item.strip())
all_items.append(row_items)
return all_items
Warum nicht das csv Modul benutzen? Sieht sehr nach NIHS aus.
Code: Alles auswählen
>>> data = '''| | DONE TEST | NAME | PARTS | PARTOF | IMPLEMENTED | DEFINED | TEXT
... |D-| 100% 0% | REQ-aliens | spc-aliens | REQ-purpose | | design\purpose.toml | There shall be a way to say hello to aliens, bu...'''
>>> import csv
>>> import io
>>> r =csv.reader(io.StringIO(data), delimiter="|")
>>> list(r)
[['', ' ', ' DONE TEST ', ' NAME ', ' PARTS ', ' PARTOF ', ' IMPLEMENTED ', ' DEFINED ', ' TEXT'], ['', 'D-', ' 100% 0% ', ' REQ-aliens ', ' spc-aliens ', ' REQ-purpose ', ' ', ' design\\purpose.toml ', ' There shall be a way to say hello to aliens, bu...']]
- __blackjack__
- User
- Beiträge: 13112
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@__deets__: Gegen CSV spricht IMHO das es sich um ausgerichteten Text handelt und es nicht wirklich CSV ist. Original sieht das ja so aus:
Ich sehe nicht wo die Verarbeitung als CSV hier einen Vorteil gegenüber einfachem splitten bringt.
Code: Alles auswählen
| | DONE TEST | NAME | PARTS | PARTOF | IMPLEMENTED | DEFINED | TEXT
|D-| 100% 0% | REQ-aliens | spc-aliens | REQ-purpose | | design\purpose.toml | There shall be a way to say hello to aliens, bu...
|D-| 100% 50% | REQ-purpose | REQ-aliens, REQ-world | | | design\purpose.toml | This is a project about saying hello to lots of...
|DT| 100% 100% | REQ-world | SPC-world | REQ-purpose | | design\purpose.toml | There shall be a way to say hello to the world....
|D-| 100% 0% | spc-aliens | | REQ-aliens | C:\Req_neu\src\hello.py[10] | design\purpose.toml | There shall be a way to say hello to aliens.
|DT| 100% 100% | SPC-world | TST-world | REQ-world | C:\Req_neu\src\hello.py[3] | design\purpose.toml | The hello-world function shall print hello
|DT| 100% 100% | TST-world | | SPC-world | C:\Req_neu\tests\hello_test.py[3] | design\purpose.toml | We will make a test later.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Ich sehe nicht, warum das dagegen spricht. Eine Zeile Code vs mehrere. Warum das Rad neu erfinden? Den einzigen echten Grund mit gepaddeten Daten anders umzugehen würde der direkte Zugriff auf Teilstrings über dann ja leicht berechenbare offsets darstellen. Das wäre aber nur in Extremfällen wirklich relevant.
Das ist jetzt aber ein bißchen wie mit den Äpfeln und den Birnen. Als Einzeiler geht es mit weniger Effekt natürlich auch:
Das spart sogar zwei zusätzliche Imports.
Code: Alles auswählen
[line.split('|') for line in data.splitlines()]
- __blackjack__
- User
- Beiträge: 13112
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Welche mehreren Zeilen Code?
Was spart mir das `csv`-Modul denn hier? Beziehungsweise besser ohne die ganzen Leerzeichen und die erste ”Spalte”:
CSV macht bei CSV-Dateien Sinn, insbesondere weil das Format ja nicht so einfach ist, wie es auf den ersten Blick scheint.
Wenn man hier auf Nummer sicher gehen wollen würde, würde man sich einen „fixed width parser“ schreiben der die Feldgrenzen an den '|' in der Titelzeile erkennt. Denn so wie das Format aussieht, könnte ja sogar '|' in einem Feld vorkommen ohne das man das besonders escapen müsste, solange es in der Titelzeile nur als Trenner verwendet wird.
Code: Alles auswählen
>>> x = [line.rstrip().split('|') for line in f]
>>> x[:2]
[['',
' ',
' DONE TEST ',
' NAME ',
' PARTS ',
' PARTOF ',
' IMPLEMENTED ',
' DEFINED ',
' TEXT'],
['',
'D-',
' 100% 0% ',
' REQ-aliens ',
' spc-aliens ',
' REQ-purpose ',
' ',
' design\\purpose.toml ',
' There shall be a way to say hello to aliens, bu...']]
Code: Alles auswählen
>>> x = [[cell.strip() for cell in line.split('|')][1:] for line in f]
>>> x[:2]
[['',
'DONE TEST',
'NAME',
'PARTS',
'PARTOF',
'IMPLEMENTED',
'DEFINED',
'TEXT'],
['D-',
'100% 0%',
'REQ-aliens',
'spc-aliens',
'REQ-purpose',
'',
'design\\purpose.toml',
'There shall be a way to say hello to aliens, bu...']]
Wenn man hier auf Nummer sicher gehen wollen würde, würde man sich einen „fixed width parser“ schreiben der die Feldgrenzen an den '|' in der Titelzeile erkennt. Denn so wie das Format aussieht, könnte ja sogar '|' in einem Feld vorkommen ohne das man das besonders escapen müsste, solange es in der Titelzeile nur als Trenner verwendet wird.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Naja, dann stellt sich umgekehrt die Frage: warum jemals csv? Mit dem padding hat das doch alles nix was du hier zeigst. Außer eben bei Daten, bei denen Escapes oder in Anführungszeichen gepackte Strings eine Rolle spielen, könnte man dann ja immer mit einer solchen list comprehension arbeiten. Wird hier aber üblicherweise aber trotzdem zum csv Modul geraten. Eben weil plötzlich doch Randfälle auftreten, und weil sowas immer zu Fuß zu machen bedeutet, das ich den Code nachvollziehen muss, statt einfach mental abzuhaken “ok, liest ein csv ein, weiter im Text”.
Mal abgesehen davon, dass DU (und ich, etc) eine solche Vorgehensweise natürlich wählen können. Für den TE erspart die Nutzung des csv Moduls aber eine ganze Reihe von Konzepten zu erlernen, mit denen er offensichtliche noch auf dem Kriegsfuß steht. Das ist auch ein Wert.
Mal abgesehen davon, dass DU (und ich, etc) eine solche Vorgehensweise natürlich wählen können. Für den TE erspart die Nutzung des csv Moduls aber eine ganze Reihe von Konzepten zu erlernen, mit denen er offensichtliche noch auf dem Kriegsfuß steht. Das ist auch ein Wert.
- __blackjack__
- User
- Beiträge: 13112
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@__deets__: Warum `csv` habe ich ja geschrieben: Wenn man CSV hat nimmt einem das arbeit ab und produziert auch gültiges CSV das man „round trippen“ kann. Wenn man kein CSV hat, dann macht's a) keinen Sinn und b) könnte es Probleme machen wenn da Sachen vorkommen die in CSV eine Bedeutung haben. Wegen den möglichen '|' *in* Feldern würde ich hier eventuell auch eine eigene Funktion schreiben, denn da würde das `csv`-Modul ja auch drüber stolpern.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman