CSV Datei schreiben

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.
Antworten
roman_emperor
User
Beiträge: 10
Registriert: Montag 4. Oktober 2021, 10:58

Hey,

als stiller Mitleser verbringe ich die letzten Wochen einige Zeit hier und habe auch schon viele hilfreiche Lösungen gefunden.
Jetzt stoße ich auf ein Problem bei dem ich leider nichts für mich passendes gefunden habe.

Zu mir: habe in meiner Jugend viel in C++ programmiert und habe da einiges vor allem mit so Programmierlern Robotern und mit einfachen Sensoren gemacht.
Per Zufall kam mir auf der Arbeit die Idee, dass ich meinen Mitarbeitern viel Fleißarbeit ersparen könnte, wenn ich mir ein kleines Programm schreibe.

Zu meinem Programm:
Es geht darum, dass wir auf einem Panel viele kleine Teilchen haben, die dann wiederum in Liefernutzen angeordnet sind und einer unserer Maschinen muss man diese genauen Positionen angeben.
Anstatt alle Koordinaten aus der Konstruktionsdatei abzutippen, könnte ich doch ein Programm schreiben, dem man nur die unterschiedlichen Distanzen angibt und das Programm errechnet die Koordinaten.
Gesagt getan Programm läuft. Zwar unschön zum ansehen, aber es geht! (Juhu) [@Forum Experten, gibt es hier ein Sub-Forum in dem man über Design Entscheidungen im Code quatscht?]
Im meinem Drang die Thematik voll zu automatisieren wollte ich schauen, ob python auch csv dateien erstellen kann.

Zu meinem Problem:
Programm läuft soweit ist aber nicht ausgelegt auf die Erstellung einer csv datei.
Aktuell schreibe ich eine Pythonliste per +=. Wäre es sinnvoller die Daten direkt in eine CSV Datei zu speichern oder gibt es schlanke varianten ganze Listen in CSV Dateien zu "konvertieren"
Mein Programm ist schon ein ziemlicher Clusterf***... Das Programm arbeitet zum aktuellen Zeitpunkt ohne imports (Numpy, Panda, array, etc)

Falls das alles zu allgemein sein sollte um auf mein Problem sauber eingehen zu können, kann ich auch gerne Teile meines Codes hier teilen. :)

Vielen Dank bereits im Voraus!

Roman Emperor
The world survived the fall of the Roman empire
and will no doubt outlast our own so much more splendid civilisation.
Benutzeravatar
Dennis89
User
Beiträge: 1556
Registriert: Freitag 11. Dezember 2020, 15:13

Hallo,

ich bin absolut kein Python-Experte, aber es macht bestimmt Sinn deinen vollständigen Code zu posten. Dann kann man viel gezielter auf dein Problem eingehen und so kommen möglicherweise Alternativen zum Vorschein, an die man sonst nicht denkt.

Grüße
Dennis
"When I got the music, I got a place to go" [Rancid, 1993]
Benutzeravatar
__blackjack__
User
Beiträge: 14067
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

So ganz allgemein kann man da nur sagen, dass es ein `csv`-Modul in der Standardbibliothek gibt. Da sollte man auf die Argumente beim öffnen der Datei achten — siehe Dokumentation.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
roman_emperor
User
Beiträge: 10
Registriert: Montag 4. Oktober 2021, 10:58

Code: Alles auswählen

while durchlaufy < Anzahly :
    if xoffset != 0 and durchlaufy % 2:
        if neuezeile == 0:
            x = xoffset 
            koordinatenx += [x]
            koordinateny += [y]
            neuezeile += 1
        elif durchlaufx < Anzahlxos:
            x += xdis1
            koordinatenx += [x]
            koordinateny += [y]
            durchlaufx += 1
        else: 
            y += ydis1
            durchlaufy += 1
            x = float(0)
            durchlaufx = 1
            neuezeile = 0
    elif durchlaufx < Anzahlx:
        if neuezeile == 0:
            koordinatenx += [x]
            koordinateny += [y]
            neuezeile += 1
        x += xdis1
        koordinatenx += [x]
        koordinateny += [y]
        durchlaufx += 1
    else: 
        y += ydis1
        durchlaufy += 1
        x = float(0)
        durchlaufx = 1
        neuezeile = 0
koordinaten = zip(koordinatenx, koordinateny)
for einzelwert in koordinaten:
    print (einzelwert)
Das wäre der Hauptteil meines Scripts. Der Rest berechnet aus den hier erstellten Koordinaten die anderen Liefernutzen auf dem Panel.
The world survived the fall of the Roman empire
and will no doubt outlast our own so much more splendid civilisation.
Sirius3
User
Beiträge: 18275
Registriert: Sonntag 21. Oktober 2012, 17:20

Das sieht so aus, als ob Du zwei verschachtelte for-Schleifen in einer while-Schleife umgesetzt hast.
Für einzelne Werte benutzt man list.append statt +=.
Statt zwei Listen für x und y zu verwalten, packe alles gleich in eine Koordinaten-Liste:

Code: Alles auswählen

koordinaten = []
for index_y in range(anzahl_y):
    if index_y % 2 != 0:
        for index_x in range(anzahl_x_os):
            koordinaten.append((xoffset + index_x * xdis1, index_y * ydis1))
    else:
        for index_x in range(anzahl_x):
            koordinaten.append((index_x * xdis1, index_y * ydis1))
Zum Schreiben von csv-Dateien hat __blackjack__ ja schon das csv-Modul angesprochen.
roman_emperor
User
Beiträge: 10
Registriert: Montag 4. Oktober 2021, 10:58

Sirius3 hat geschrieben: Montag 4. Oktober 2021, 13:12 Das sieht so aus, als ob Du zwei verschachtelte for-Schleifen in einer while-Schleife umgesetzt hast.
Für einzelne Werte benutzt man list.append statt +=.
Statt zwei Listen für x und y zu verwalten, packe alles gleich in eine Koordinaten-Liste:

Code: Alles auswählen

koordinaten = []
for index_y in range(anzahl_y):
    if index_y % 2 != 0:
        for index_x in range(anzahl_x_os):
            koordinaten.append((xoffset + index_x * xdis1, index_y * ydis1))
    else:
        for index_x in range(anzahl_x):
            koordinaten.append((index_x * xdis1, index_y * ydis1))
Das sieht gut aus. Habs grad mal in meinen Code eingebaut und funktioniert. Vielen Dank.

Damit kommt aber ein neues Problem auf... Meine komplette Berechnung bestand aus der Berechnung der Liste für x und für y

Code: Alles auswählen

koordinatenbackup = koordinatenx
koordinaten = zip(koordinatenx, koordinateny)

print("Koordinatenerstellung beendet")
print("Koordinaten:")

for einzelwert in koordinaten:
    print (einzelwert)


#Liefernutzen Schleife
durchlaufxln = int(1)
durchlaufyln = int(1)
while durchlaufyln < Anzahlyln + 1:
    if durchlaufxln < Anzahlxln:
        a = len(koordinatenx)
        lnxdis_1 = [lnxdis] * a
        koordinatenx = list(map(lambda x,y: x+y ,koordinatenx,lnxdis_1))
        durchlaufxln += 1
        koordinatenln1 = zip(koordinatenx, koordinateny)
        for einzelwert in koordinatenln1:
            print(einzelwert)
    else:
        durchlaufyln += 1
        if durchlaufyln < Anzahlyln +1:
            b = len(koordinateny)
            lnydis_1 = [lnydis] * b
            koordinatenx = koordinatenbackup
            koordinateny = list(map(lambda x,y: x+y ,koordinateny,lnydis_1))
            koordinatenln1 = zip(koordinatenx, koordinateny)
            durchlaufxln = (1)
            for einzelwert in koordinatenln1:
                print(einzelwert)
Gibt es hierfür auch eine schöne Lösung, oder war meine Lösung dann doch benötigt?

VG
The world survived the fall of the Roman empire
and will no doubt outlast our own so much more splendid civilisation.
Sirius3
User
Beiträge: 18275
Registriert: Sonntag 21. Oktober 2012, 17:20

Du solltest dringend an der Benennung Deiner Variablen arbeiten. Was soll 1n bedeuten, das jetzt überall in den Variablennamen vorkommt?
Hier muß ich auch erst lange überlegen, was die while-Schleife eigentlich macht. Versuche das auch in for-Schleifen umzuschreiben.
Die lnxdis_1-Liste enthält nur gleiche Werte. Die Liste ist also unnötig:

Code: Alles auswählen

koordinatenx = list(map(lambda x: x+lnxdis, koordinatenx))
Dann scheint es nicht Absicht zu sein, koordinatenx zu überschreiben, also nennt man die neue Liste mit einem neuen Namen:

Code: Alles auswählen

verschobene_koordinaten_x = [x + lnxdis for x in koordinatenx]
Es ist besser, wenn man gleich wieder mit Paaren von x-y-Koordinaten arbeitet:

Code: Alles auswählen

verschobene_koordinaten = [(x + lnxdis, y) for x, y in koordinaten]
1 ist schon ein Int, das per int(1) nochmal in ein int umzuwandeln ist unsinnig.
Das selbe gilt für den ersten Code mit float(0), wenn man statt dessen 0. schreibt.
roman_emperor
User
Beiträge: 10
Registriert: Montag 4. Oktober 2021, 10:58

Du solltest dringend an der Benennung Deiner Variablen arbeiten. Was soll 1n bedeuten, das jetzt überall in den Variablennamen vorkommt?
Das liegt an dem Font das ist ein LN und steht für Liefernutzen. Ich weiß, dass es von außen betrachtet wahrscheinlich sehr schwer sein muss, das Skript zu verstehen.
Beim nächsten mal werde ich versuchen die Variablen klarer zu benennen.

Die Thematik mit Int und float finde ich auch sehr spannend. War mir nie ganz sicher, wann python die Zahlen so klassifiziert, wie ich es wollte und um unnötigen compiling zu ersparen.
Ist jetzt aber in meinem schlauen Buch und wird beim nächsten mal nicht mehr passieren :D

Ich danke dir vielmals für die guten Tipps und Codeschnipsel. Werde das jetzt in mein Programm einfügen und dann mich mal etwas mehr mit der einzeilenprogrammierung beschäftigen.

Danke und Gruß
Roman
The world survived the fall of the Roman empire
and will no doubt outlast our own so much more splendid civilisation.
roman_emperor
User
Beiträge: 10
Registriert: Montag 4. Oktober 2021, 10:58

Hallo nochmal,

ich habe gestern die Zeit gefunden meinen Code zu korrigieren und mich etwas in den csv import reinzufuchsen.

Soweit so gut. Ich bin nur wirklich unzufrieden wie ich mir das da hingemurkst habe. irgendwie nicht wirklich schön.

Außerdem entsteht meine Liste image_name folgendes ('PCBNr' , 1) (PCBNr, 2) etc. wie bekomme ich das komma da raus? ist bei einer csv Datei doch recht unpraktisch :?
Danke für die Hilfe

Code: Alles auswählen

#Erstellung der CSV Datei
kopfzeile = ('CircuitName','ImageName','PositionX','PositionY','Orientation')
#CircuitName hat immer den Inhalt Circuit1
a = len(koordinaten)
circuit_name = ('Circuit1') * a
#ImageName ist PCBNr+Fortlaufende Nr. PCBNrX
image_name = []
for idx, item in enumerate(circuit_name):
    image_name += ('PCBNr', idx+1)
#Orientation ist immer 0
orientation = ('0') * a
#Alle Daten zusammen zippen
daten = zip(circuit_name, image_name, koordinaten, orientation)


with open('Dateipfad', 'w', encoding='UTF8', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(kopfzeile)
    writer.writerows(daten)
Gruß roman_emperor
The world survived the fall of the Roman empire
and will no doubt outlast our own so much more splendid civilisation.
Benutzeravatar
__blackjack__
User
Beiträge: 14067
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@roman_emperor: Das kann ich nicht nachvollziehen aber die Liste ist trotzdem falsch, denn die ist doppelt so lang wie die `koordinaten`-Liste weil immer abwechselnd "PCBNr" und eine Zahl in der Liste steht, also zwei Elemente für jedes Element in Koordinaten. Ich vermute mal Du willst da weder ``+=`` verwenden (was der `extend()`-Methode entspricht) noch ein Tupel mit zwei Werten erstellen, sondern ich vermute mal *eine* Zeichenkette‽ `enumerate()` kann man übrigens einen Startwert mitgeben.

Was auch falsch aussieht ist das `zip()` mit *vier* Argumenten, für eine CSV-Datei mit *fünf* Spaltenüberschriften. Kann es sein, dass `koordinaten` zwei Werte pro Element enthält?

Ah, und `circuit_name` ist *eine* Zeichenkette, weil:

Code: Alles auswählen

In [4]: a = 10                                                                  

In [5]: circuit_name = ('Circuit1') * a                                         

In [6]: circuit_name                                                            
Out[6]: 'Circuit1Circuit1Circuit1Circuit1Circuit1Circuit1Circuit1Circuit1Circuit1Circuit1'
Sicher so auch nicht gewollt. Da könnte man `itertools.repeat()` verwenden.

Analog `orientation`:

Code: Alles auswählen

In [7]: orientation = ('0') * a                                                 

In [8]: orientation                                                             
Out[8]: '0000000000
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
__blackjack__
User
Beiträge: 14067
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Letztlich werden ja nur die Koordinaten und die Nummer gebraucht um einen Datensatz zu erstellen. Das geht ohne `zip()` kürzer und vielleicht auch ein bisschen klarer:

Code: Alles auswählen

    with open("Dateipfad", "w", encoding="UTF8", newline="") as file:
        writer = csv.writer(file)
        writer.writerow(
            [
                "CircuitName",
                "ImageName",
                "PositionX",
                "PositionY",
                "Orientation",
            ]
        )
        writer.writerows(
            ["Circuit1", f"PCBNr {number}", x, y, "0"]
            for number, (x, y) in enumerate(koordinaten, 1)
        )
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Sirius3
User
Beiträge: 18275
Registriert: Sonntag 21. Oktober 2012, 17:20

Da Du hier nur die Koordinaten gegeben hast, und alles andere speziell für die csv-Datei erzeugst, würde ich das alles in einer Schleife kombinieren:

Code: Alles auswählen

kopfzeile = ('CircuitName', 'ImageName', 'PositionX', 'PositionY', 'Orientation')
with open('Dateipfad', 'w', encoding='UTF8', newline='') as f:
    writer = csv.writer(f)
    writer.writerow(kopfzeile)
    for index, (position_x, position_y) in enumerate(koordinaten, 1):
        writer.writerows(('Circuit1', f'PCBNr{index}', position_x, position_y, 0))
roman_emperor
User
Beiträge: 10
Registriert: Montag 4. Oktober 2021, 10:58

Kurze Verständnisfrage:
In der for Schleife verwendest du position_x, position_y diese Variablen habe ich bisher in meinem Script noch nicht. Werden diese quasi aus [koordinaten] "erstellt" oder müsste ich x und y davor dann auch so definieren?

Vielen vielen Dank für die guten Tipps. Finde es super spannend zu sehen wie einfach doch die Dinge lösbar sind, die ich so umständlich verpacke.
The world survived the fall of the Roman empire
and will no doubt outlast our own so much more splendid civilisation.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Man muss in Python keine Variablen vordeklarieren. Im Gegenteil, wer das macht, arbeitet außerhalb etablierter Konventionen.
Antworten