Das Ding des Jahres

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.
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

Hallo Zusammen, nachdem ich mir über Weihnachten einen Teil von Python beigebracht habe und mich nun das Corona Virus ins Home Office verbannt hat widme ich mich nun meinem "Ding des Jahres".

Zum Projekt:
Über zwei Input Files (Input_manuell.txt und Input_iteration.txt) berechnet ein exe file Werte und gibt diese in einer Ausgabedatei (data.txt) aus. Ich möchte nun über ein Python Skript die Input Werte einzeln zB von 1 bis 100 in 10er Schritten ändern und anschließend immer das exe File um Berechnung bitten. Die Werte sollen samt den zugehörigen Eingabewerten in einer gesamten Ausgabedatei dargestellt werden. In Summe sollen so nun ca. 250.000 Ergebnisse produziert werden.

Was ich schon geschafft habe:
Ich habe die äußert schwierige Aufgabe, ein exe file über das python Skript zu starten, geschafft :) Auch geschafft habe ich folgenden Code.

Code: Alles auswählen

import os
import time



#Einlesen der FE Ergebnisse
fobj_in = open("data.txt")
input_iteration = open("input_iteration.txt")
input_manuell = open("input_manuell.txt")
fobj_out = open("gesamt.txt", "w")
for werte in input_manuell:
    fobj_out.write(werte)
for werte in input_iteration:
    fobj_out.write(werte)
for werte in fobj_in:
    fobj_out.write(werte)
fobj_in.close()
fobj_out.close()
Dieser ermöglicht die Ausgabe von Eingabedaten und Ergebnissen in ein TXT File (gesamt.txt). Besser wäre es wenn ein Ergebnis in einer Zeile als CSV dargestellt wird, da fällt mir nachher die Auswertung im Excel leichter.

Außer den Tipp an einen wirklich versierten Programmiere zu gehen, kann mir jemand einen Tipp geben mit welchen Modulen (zB Numpy mit Funktion XY) ich diese Projekt überhaupt realisieren kann??

Bin für jeden Tipp glücklich!!

SG Stefan
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich versteh nicht, welches Problem Du hast, was also konkret nicht so funktioniert, wie Du Dir das vorstellst.

Man sollte immer alle Dateien wieder schließen. Am besten mit dem with-Statement. os und time wird nicht benutzt. Bitte keine kryptischen Abkürzungen. Objekt ist alles in Python, etwas obj zu nennen ist also unsinnig.

Code: Alles auswählen

with open("gesamt.txt", "w") as output:
    with open("input_manuell.txt") as lines:
        output.writelines(lines)
    with open("input_iteration.txt") as lines:
        output.writelines(lines)
    with open("data.txt") as lines:
        output.writelines(lines)
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

danke für die rasche Rückmeldung! os und time wurde für den Teil zum Ausführen der exe Datei benötigt:

Code: Alles auswählen

import os
import time


#Starten der Iteration
os.startfile('prog_manuell.exe')
print("Iteration durchgeführt")

time.sleep(3.0) #erforderlich, da Iteration dauert,...

#Einlesen der FE Ergebnisse
ergebnis = open("data.txt", "r")
print(ergebnis.read())
Danke für deinen Code, die Probleme welche ich habe sind:
- die Werte werden mit diesen Codes vertikal angezeigt, ich benötige diese aber horizontal, getrennt mit Tabstopp
- diese Werte bei einer weiteren Iteration überschrieben werden (ich möchte jedoch eine weitere Zeile mit den nächsten Messwerten)


Sinngemäß sollte der Ablauf folgender sein:

-- Beginn einer Schleife
Schritt A = Eingabe/Änderung der Werte im Input File
--> dazu habe ich noch keinen Code
Schritt B = Start der Berechnung über exe File s. Code:

Code: Alles auswählen

import os
import time

#Starten der Iteration
os.startfile('prog_manuell.exe')
print("Iteration durchgeführt")

time.sleep(3.0) #erforderlich, da Iteration dauert,...
Schritt C = Einlesen der Ergebnisse aus data.txt und Speicherung samt den zugehörigen Input Werten in einer Zeile in ein CSV oder Excel File.
Schritt D = Schritt A solange bis alle Variantionen der Eingabe werte erledigt.

ich würde gerne die Input files ebenfalls hochladen, nur scheint das hier nicht zu funktionieren, sind aber im Prinzip vertikal angeordnete Werte welche alle einer Variation unterliegen.
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@fox1203: Zum ausführen von externen Programmen verwendet man das `subprocess`-Modul. Und dann braucht man auch nicht 3 Sekunden warten und hoffen, dass das lang genug war, sondern hat einen blockierenden Aufruf der zurück kehrt wenn das externe Programm zuende ist.

Textdateien sollte man immer mit einer expliziten Kodierung öffnen. Wenn man Dateien 1:1 kopieren möchte, macht es nicht so viel Sinn die als Textdatei zu öffnen. Ich würde da dann auch schauen welche der Funktionen aus dem `shutil`-Modul einem das Leben erleichtern können.

Für CSV-Dateien gibt es in der Python-Standardbibliothek das `csv`-Modul.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

@Blackjack: Vielen Dank für den Hinweis mit dem "subprozess", damit ist schon ein Problem gelöst, genial!

Betreffend dem CSV Modul in Python hätte ich noch eine Frage, damit ich die Schritte verstehe:
Die Ausgabe meiner exe Datei ist definitiv eine Textdatei. Diese Daten muss ich auf alle Fälle einlesen, zB mit dem read Befehl. Anschließend kann ich über das CSV Modul (entsprechende Befehle muss ich mir erst raussuchen) die Daten in ein CSV File schreiben. Habe ich das soweit richtig verstanden??
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

Mit dem csv Modul lassen sich Dateien im csv-Format lesen und schreiben.
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

Das war mir wohl bewusst, allerdings habe ich den Anwendungsfall, dass ich Daten aus einem TXT File (wobei die Daten durch einen Zeilenumbruch getrennt sind) in ein CSV File (wobei ich hier die Daten in einer Zeile, getrennt durch einen Tabstopp haben möchte) überführen will.

Nach einer weiteren Iteration soll die nun neuen TXT Daten in der nächsten Zeile des CSV landen usw.

Wie geht man da sinnvoll vor??
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@fox1203: Na in dem man zum lesen halt nicht das `csv`-Modul verwendet wenn es sich nicht um CSV-Dateien handelt und zum schreiben das `csv`-Modul verwendet wenn man CSV-Dateien schreiben will.

Dateien kann man in verschiedenen Modi öffnen. Da gibt es auch welche zum Anhängen an das Ende einer bestehenden Datei.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

OK, habe ich nun mal versucht und zwar wie folgt:

Code: Alles auswählen

#Einlesen der FE Ergebnisse
#Überführen der Input Werte und Ergebnisse in eine TXT Datei
with open("gesamt.txt", "w") as output:
    with open("input_manuell.txt") as lines:
        output.writelines(lines)
    with open("input_iteration.txt") as lines:
        output.writelines(lines)
    with open("data.txt") as lines:
        output.writelines(lines)
Dieser Code erstellt mir EIN txt File mit allen erforderlichen Werten, danke dafür an @sirius3 für das vereinfachen diese Schrittes. Dannach habe ich wie folgt folgenden Code erstellt:

Code: Alles auswählen

#Öffnen der CSV Sammeldatei und Schreiben der gesamt.txt Werte
with open("gesamt.csv", "wb") as csv_gesamt:
    reader = csv.reader(csv_gesamt, delimiter='\t')
    writer = csv.writer(csv_gesamt, delimiter='\t')
    with open("gesamt.txt") as lines:
        writer.writerow(lines)
wobei hier jedoch die Fehlermeldung kommt:
writer.writerow(lines)
TypeError: a bytes-like object is required, not 'str'

wie überführe ich die string werte vom txt nun in bytes, damit das CSV modul auch damit etwas anfangen kann?
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum öffnest Du die CSV-Datei als Binärdatei? Warum schreibst Du die Daten nicht gleich im richtigen Format?
einfachTobi
User
Beiträge: 512
Registriert: Mittwoch 13. November 2019, 08:38

Mich beschleicht das Gefühl, dass du dabei bist ein riesen Durcheinander zu schaffen. Daher habe ich ein paar Vorschläge:
- Strukturiere deinen Code sinnvoll. Damit meine ich: Erst alle Inputdaten in geeigneter Struktur (hier wahrscheinlich Listen oder Dictionaries mit Listen oder je nach Datenstruktur auch pandas-DataFrames) zusammenstellen, dann alle Inputdaten schreiben, Berechnungsprogramm ausführen, Ergebnisse lesen und mit den bereits vorhandenen Inputdaten gemeinsam in eine weitere Datei schreiben.
- Verwende sinnvolle Namen für deine Variablen. Nur `input` oder `output` macht es schwierig: Ist das Input zu deinem Programm oder dem Berechnungsprogramm? Input für das Berechnungsprogramm ist Output deines Programms. Ordne die Namen klar zu.
- Zu deinem Fehler: Du öffnest die Datei im Modus "wb", weshalb logischerweise ein byte-like Objekt erwartet wird. Wenn du das "b" entfernst, kannst du auch Strings schreiben (siehe Python Doku zu open()).
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und Funktionen sind da um Code zu strukturieren. Auf Modulebene gehört der Code da ja sowieso nicht.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

Danke für die Antworten. Nachdem ich wie gesagt ein Leihe bin in Sachen programmieren scheint es wohl etwas wirr sein was ich da vor habe. Bitte eure wertvollen Infos so verständlich wie möglich formulieren :)

Den Fehler habe ich behoben, die Werte stehen nun im CSV, allerdings leider wieder vertikal, anstelle horizontal in einer Zeile, getrennt durch einen Tabstopp.

Für mich gibt es gedanklich da eben drei Punkte:
1. Ist das Schreiben/Anpassen der Input Files
2. Das Ausführen der Exe Datei (ist ja bereits erledigt)
3. Das Sammeln der Daten in einer CSV

Nachdem der 3. Punkt für mich der schwierigste zu sein scheint, habe ich mich darauf mal konzentriert. Dannach wäre ich den 1. Punkt angegangen und Schritt für Schritt den Code so vervollständigt. Zu letzt wäre noch den Code in eine Schleife zu packen, damit er die Iterationen selbst erledigt.


Also back to the Topic, wie bringe ich die txt Werte (vertikal mit Enter getrennt) in meine CSV in eine Zeile getrennt durch Tabstopp
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Verzeih, normalerweise kuemmer mich Rechtschreibfehler nicht. Aber "Leihe" ist doch ein bisschen weit weg vom Schuss. Du leihst dir ein Boot, und wenn du keine Ahnung hast, wie du ruderst, dann bist du ein Laie.

Und zu deinem eigentlichen Problem - das hier gibt dir hoffentlich etwas Inspiration:

Code: Alles auswählen

import csv
import io
import sys

WERTE = """a
b
c
d
e
f"""


def main():
    test_file = io.StringIO(WERTE) # nur zum test
    writer = csv.writer(sys.stdout, delimiter="\t")
    werte = [line.strip() for line in test_file.readlines() if line.strip()]
    writer.writerow(werte)


if __name__ == '__main__':
    main()
Benutzeravatar
__blackjack__
User
Beiträge: 14052
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das `readlines()` würde ich noch weg lassen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

111
Zuletzt geändert von fox1203 am Mittwoch 25. März 2020, 20:59, insgesamt 1-mal geändert.
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

Den Vergleich mit dem Boot finde ich gut, danke für die Inspiration.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

__blackjack__ hat geschrieben: Mittwoch 25. März 2020, 20:23 Das `readlines()` würde ich noch weg lassen.
🤦‍♂️ Joa. Wohl war.
fox1203
User
Beiträge: 56
Registriert: Montag 23. März 2020, 15:19

Die Werte werden nun so dargestellt wie ich mir das so vorstelle, danke für die Hilfe.

Als nächsten Step habe ich anstelle "w" bei open "a" angeführt, sodass bei jeder neuen Iteration die zugehörig neuen Werte in eine neue Zeile geschrieben werden. Das funktioniert grundsätzlich, jedoch wird hierbei immer eine Zeile frei gelassen. Am Ende der letzten Datenreihe sind keine Leerzeichen oder Tabs, das gleiche gilt für die nächste leere Zeile. Lösche ich diese nächstkommende leere Zeile allerdings manuell, dann werden mir bei erneuten aufrufen des Skript die neuen Werte direkt in der nächsten Zeile eingefügt.

Da ich mit den Funktionen def etc. nicht rudern konnte sieht der Code nach mehrmaligen try and error versuchen wie folgt aus:

Code: Alles auswählen

import csv
import sys



#Einlesen der FE Ergebnisse
#Überführen der Input Werte und Ergebnisse in eine TXT Datei
with open("gesamt.txt", "w") as output:
    with open("input_manuell.txt") as lines:
        output.writelines(lines)
    with open("input_iteration.txt") as lines:
        output.writelines(lines)
    with open("data.txt") as lines:
        output.writelines(lines)


#Öffnen der CSV Sammeldatei und Schreiben der gesamt.txt Werte
with open("gesamt.csv", "a") as csv_gesamt:
    #reader = csv.reader(csv_gesamt, delimiter='\n')
    writer = csv.writer(csv_gesamt, sys.stdout, delimiter='\t')
    with open("gesamt.txt") as lines:
        lines = [line.strip() for line in lines if line.strip()]
        writer.writerow(lines)


Für Hinweise wäre ich sehr dankbar. --> Rechtschreibung überprüft durch unabhängigen Sachverständigen
Sirius3
User
Beiträge: 18272
Registriert: Sonntag 21. Oktober 2012, 17:20

Die selben Daten gleich wieder zu lesen, die man eben erst geschrieben hat, ist nicht so toll, das kann man in einem Schritt machen:

Code: Alles auswählen

all_lines = []
for filename in ["input_manuell.txt", "input_iteration.txt", "data.txt"]:
    with open(filename) as lines:
        all_lines.extend(lines)

with open("gesamt.txt", "w") as output:
    output.writelines(all_lines)

stripped_lines =  [line.strip() for line in all_lines if line.strip()]
with open("gesamt.csv", "a") as csv_gesamt:
    writer = csv.writer(csv_gesamt, sys.stdout, delimiter='\t')
    writer.writerow(stripped_lines)
Warum da eine Leerzeile kommt, kann man aus dem Code nicht sehen. Kannst Du hier den Inhalt der geschriebenen Listen posten?
Antworten