Index Problem beim Liste Sortieren

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.
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Hallo,
ich bin gerade am Verzweifeln und hoffe mir kann Jemand helfen:

Im Prinzip habe ich eine input.ods Datei.

Und will, dass in der die erste Zeile (von oben) gesucht wird, wo der Eintrag in Spalte 7 ungleich "nein" ist.
Deren Einträge will ich später extern für was verwenden.

Dann soll in jener Zeile die erste Zelle mit dem aktuellen Datum überschrieben werden.
Und am Ende die ganze Tabelle nach der ersten Spalte (die Datume(?) enthalten) sortieren.

und speichern.

Nur scheitere ich brachial am Schritt wo die Liste sortiert werden soll.
Die Tabelle hat totsicher 7 Spalten, also müssten die Spaltenindizes von 0 bis 6 gehen.

Ich gebe als "Sortierspaltenindex" 0 vor.

Und der sagt mir konsequent, ich wäre ausserhalb der zulässigen index range!


Habe mir da von chatgpt alle möglichen varianten probieren lassen woran es liegen könnte, aber ich scheitere brachial :-/

Hier mal der komplette Code, aktuell sind noch zu debug zwecken Sachen drin wo zeilen oder so geprintet werden:

Code: Alles auswählen

import pyexcel_ods3 as pe
from pyexcel_ods3 import save_data
import os
import datetime
import time

def find_first_valid_row(sheet, invalid_value="nein"):
    for row in sheet:
        if row[6] != invalid_value:
            return row

def print_sheet(sheet):
    for row in sheet:
        print(row)


def sort_and_save_ods_file(input_file, sort_column_index):
    output_file = "output.ods"
    sheet_name = "Sheet1"
    sort_ascending = True  # Change to True for ascending order, False for descending order

    # Read the data from the input file
    file = pe.get_data(input_file)
    sheet1 = file[sheet_name]

    # Find the first valid row from the top where the 7th cell isn't "nein"
    first_valid_row = find_first_valid_row(sheet1)
    if not first_valid_row:
        print("No valid row found.")
        return

    # Print the contents of the first valid row
    print("First valid row contents:")
    for cell in first_valid_row:
        print(cell)

    # Determine the legitimate values for sort_column_index
    print("Legitimate values for sort_column_index:")
    for idx, cell in enumerate(first_valid_row):
        print(f"{idx}: {cell}")

    # Update the first cell in the first column with the current date
    current_date = datetime.datetime.now().strftime("%Y-%m-%d")
    first_valid_row[0] = current_date

    # Filter out empty rows from sheet1
    sheet1 = [row for row in sheet1 if any(cell for cell in row)]

    # Print the range of valid column indices after filtering
    print("Valid column index range:", list(range(len(first_valid_row))))

    # Check if sort_column_index is within the valid range
    if sort_column_index not in range(len(first_valid_row)):
        print("Invalid sort_column_index. Please choose a valid column index.")
        return
    time.sleep(1)
        
     # Print the state of the sheet after sorting
    print("State of the sheet before sorting:")
    print_sheet(sheet1)
    time.sleep(1)

    # Decorate: Create a list of tuples with (value_in_specified_column, row_index, row_data)
    decorated = [(row[sort_column_index], i, row) for i, row in enumerate(sheet1)]

    # Sort based on the value in the specified column
    decorated.sort()

    # Undecorate: Extract the sorted rows based on the sorted indexes
    sorted_sheet1 = [row_data for _, _, row_data in decorated]
     # Print the state of the sheet after sorting
    print("State of the sheet after sorting:")
    print_sheet(sorted_sheet1)

    # Save the sorted data to the output file
    save_data(output_file, {sheet_name: sorted_sheet1})

    # Remove the input file and rename the output file to the input file name
    os.remove(input_file)
    os.rename(output_file, input_file)

# Example usage:
if __name__ == "__main__":
    input_file = "input.ods"
    sort_column_index = 0  # Index of the column to sort (0-based index)

    sort_and_save_ods_file(input_file, sort_column_index)

Und hier mal ein vereinfachtes Beispiel wie meine openoffice calc Tabelle aussieht:

Code: Alles auswählen

01.03.54	o	2	44	44	44	wer
04.05.62	z	5	88	88	88	nein
21.05.92	u	4	1	1	1	ja
31.01.19	r	7	9	9	9	vielleicht
03.03.19	e	8	34	34	34	ja
04.04.19	q	0	12	12	12	nein
06.05.19	w	9	56	56	56	nein
09.08.20	t	6	76	76	76	wer
02.03.23	i	3	23	23	23	vielleicht
09.12.30	p	1	62	62	62	nein
in Realität enthält meine tabelle statt simpler Zahlen auch mal eine string adresse mit kommas drin oder so aber ich wäre schon happy wenn es wenigstens hiermit mal klappen würde! :-)
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Wie lautet denn der komplette Traceback und was steht wirklich in der Liste, die den Fehler auslöst?

Die Funktion `find_first_valid_row` sollte explizit None zurückgeben, oder noch besser eine Exception werfen, wenn keine passende Zeile gefunden worden ist.
`sort_ascending` wird gar nicht verwendet.
Ein Wörterbuch mit Listen `file` zu nennen ist komisch, `sheets` wäre da passender. Was soll die 1 bei `sheet1`?
Ein time.sleep nervt. Warum wird der Anwender gezwungen zwei Sekunden zu warten?
`sort` kennt das key-Argument:

Code: Alles auswählen

sorted_sheet = sorted((row for row in sheet1 if any(row)), key=operator.itemgetter(sort_column_index))
Eigentlich möchte man nicht, dass Inputdateien einfach so gelöscht oder überschrieben werden. Wenn was schief läuft, sind die Daten futsch.
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Na, die ursprüngliche Tabelle hat halt bspw. Adressen in einer Spalte oder so.
Aber es geht ja shcon nicht mit der oben geposteten Tabelle!

Die waits habe ich eingebaut weil ich dachte (bzw das chatgpt behauptete) vielleixht sit die tabelle noch nicht fertig mit überschreiben der enen zelle und will dann aber shcon sortieren, drum wollte ich zeitlich die shcritte voneinander trennen damit es da keine übershcneidungen geben kann.

Code kommt zu 90% von chatgpt, inklusive der teils komischen beschriftungen-
sheet1 ist einfahc der standardname des ersten sheets.

weil wenn man eine neue openoffice calc datei aufmacht, heißt die erste tabelle automatisch sheet1.
und nur die brauche ich, gibt in meinem fall keine weiteren "sheets".
dass auch die variable so heißt, hat wohl chatgpt so gemacht, ich habe den code nur gecopy und pasted

ja, es scheitert alles an dem sorted befehl.

dass die input datei letztlich übershcrieben wird, ist durchaus gewollt so.zumindest für den moment.

Habe mal ein paar an sich unnötige Sachen aus dem Code rausgeworfen, Code sieht nun so aus:

Code: Alles auswählen

import pyexcel_ods3 as pe
from pyexcel_ods3 import save_data
import os
import datetime
import time

def find_first_valid_row(sheet, invalid_value="nein"):
    for row in sheet:
        if row[6] != invalid_value:
            return row

def print_sheet(sheet):
    for row in sheet:
        print(row)


def sort_and_save_ods_file(input_file, sort_column_index):
    output_file = "output.ods"
    sheet_name = "Sheet1"
    sort_ascending = True  # Change to True for ascending order, False for descending order

    # Read the data from the input file
    file = pe.get_data(input_file)
    sheet1 = file[sheet_name]

    # Find the first valid row from the top where the 7th cell isn't "nein"
    first_valid_row = find_first_valid_row(sheet1)
    if not first_valid_row:
        print("No valid row found.")
        return


    # Update the first cell in the first column with the current date
    current_date = datetime.datetime.now().strftime("%Y-%m-%d")
    first_valid_row[0] = current_date

    # Filter out empty rows from sheet1
    sheet1 = [row for row in sheet1 if any(cell for cell in row)]


        




    # sort
    sorted_sheet = sorted((row for row in sheet1 if any(row)), key=operator.itemgetter(sort_column_index))
    

    # Save the sorted data to the output file
    save_data(output_file, {sheet_name: sorted_sheet})

    # Remove the input file and rename the output file to the input file name
    os.remove(input_file)
    os.rename(output_file, input_file)

# Example usage:
if __name__ == "__main__":
    input_file = "input.ods"
    sort_column_index = 0  # Index of the column to sort (0-based index)

    sort_and_save_ods_file(input_file, sort_column_index)

'
Console sagt nun das:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\d-sch\Desktop\Python kram\Python edit and sort ods file\ods.py", line 59, in <module>
    sort_and_save_ods_file(input_file, sort_column_index)
  File "C:\Users\d-sch\Desktop\Python kram\Python edit and sort ods file\ods.py", line 44, in sort_and_save_ods_file
    sorted_sheet = sorted((row for row in sheet1 if any(row)), key=operator.itemgetter(sort_column_index))
                                                                   ^^^^^^^^
NameError: name 'operator' is not defined
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

habe operator imported, nun kommt:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\d-sch\Desktop\Python kram\Python edit and sort ods file\ods.py", line 60, in <module>
    sort_and_save_ods_file(input_file, sort_column_index)
  File "C:\Users\d-sch\Desktop\Python kram\Python edit and sort ods file\ods.py", line 45, in sort_and_save_ods_file
    sorted_sheet = sorted((row for row in sheet1 if any(row)), key=operator.itemgetter(sort_column_index))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: '<' not supported between instances of 'datetime.date' and 'str'
Er stört sich offenbar dran dass nicht alles in der tabelle nur strings oder nur ints sind.
Kann ich aber nicht ändern, ist so
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Er stoert sich nicht offenbar daran, sonder daran, dass in der Spalte mit dem Datum auch andere Werte als eben nur Datumseintraege vorhanden sind. Wie vergleichst du denn zB "20.03.2023" mit "Huehnersuppe"? Da kommt nix bei rum, und das meckert Python an. Und natuerlich hast du Kontrolle darueber, du kannst diese Eintraege ausfiltern, oder zB auf einen Wert setzen, der vergleichbar ist. Statt operator.itemgetter muesste man dann eine Funktion schreiben, die fuer jeden Wert aus der Spalte sort_column_index prueft, ob der gegebene Wert ein datetime.date ist. Und wenn nicht ein default-Datum liefert, das sich dann doch vergleichen laesst. ZB ein sehr weit in der Zukunft liegendes, damit die Werte garantiert am Ende sind.

Das saehe zB so aus:

Code: Alles auswählen

import datetime
import operator

FAR_IN_THE_FUTURE = datetime.date(9999, 1, 1)

def date_or_future_date(row):
    date_value = row[0]
    if not isinstance(date_value, datetime.date):
        date_value =  FAR_IN_THE_FUTURE
    return date_value


def main():
    rows = [
        (datetime.date(2023, 7, i), f"zeile{i}")
         for i in range(1, 20)
    ]

    rows.insert(0, ("Datum", "Wert"))

    # Selber Fehler!
    try:
        print(sorted((row for row in rows if any(row)), key=operator.itemgetter(0)))
    except TypeError:
        pass
    print(sorted((row for row in rows if any(row)), key=date_or_future_date))


if __name__ == '__main__':
    main()
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Nur kommt gar keine Hühnersuppe vor wie man mit EINEM Blick auf die schon öfter erwähnte Tabelle sieht.
Da kommen in Spalte 1 ausschließlich Datumsangaben vor :-)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie man MIT EINEM BLICK auf die schon oefter erwaehnte Tabelle sieht, ist das irgeindein von dir redaktionell bearbeiteter Ausschnitt einer ansonsten hier nicht vorliegenden ODS-Datei. Was darin also enthalten ist, oder nicht, bleibt uns verborgen. Die Fehlermeldung hingegen ist da eindeutig. Da *ist* ein String in der Spalte. Und aus Sicht des Computers sind uebrigens auch "Huehnersuppe" und "" (der Leerstring) eben Strings. Auch der Vergleich von einem Datum mit dem leeren String provoziert das Problem.
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Du schreibst doch selbst einen String in die erste Zelle, via strftime.
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Hier ist die ods Datei:
https://file.io/n3QUKxo5FE54

Ich sehe jedenfalls nichts in der ersten Spalte, was kein Datum ist.
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

"
Du schreibst doch selbst einen String in die erste Zelle, via strftime."
Das wird dann ein String?
gut zu wissen. muss ich mal testen obs klappt wenn ich das rauslösche.

Edit: Habs getestet, nun lautet die Fehlermeldung anders:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Users\d-sch\Desktop\Python kram\Python edit and sort ods file\ods.py", line 60, in <module>
    sort_and_save_ods_file(input_file, sort_column_index)
  File "C:\Users\d-sch\Desktop\Python kram\Python edit and sort ods file\ods.py", line 45, in sort_and_save_ods_file
    sorted_sheet = sorted((row for row in sheet1 if any(row)), key=operator.itemgetter(sort_column_index))
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: can't compare datetime.datetime to datetime.date
Also offensichtlich hängt es wohl wirklich mit der abgeänderten Zelle zusammen.
jetzt muss ich nur noch gucken wie ich es auf das selbe format kriege
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die Birnen und Äpfel bleiben eben. Für den Computer ist ein Datum etwas anderes als ein Zeitstempel, der aus Datum + Tageszeit besteht. Du musst dann den Datumsteil aus dem Zeitstempel holen, das steht in der Dokumentation des datetime Moduls, wie das geht.
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Aktuell hantiere ich nun mit dem Code:

Code: Alles auswählen

import pyexcel_ods3 as pe
from pyexcel_ods3 import save_data
import os
import datetime
import time
import operator

def find_first_valid_row(sheet, invalid_value="nein"):
    for row in sheet:
        if row[6] != invalid_value:
            return row

def print_sheet(sheet):
    for row in sheet:
        print(row)


def sort_and_save_ods_file(input_file, sort_column_index):
    output_file = "output.ods"
    sheet_name = "Sheet1"
    sort_ascending = True  # Change to True for ascending order, False for descending order

    # Read the data from the input file
    file = pe.get_data(input_file)
    sheet1 = file[sheet_name]

    # Find the first valid row from the top where the 7th cell isn't "nein"
    first_valid_row = find_first_valid_row(sheet1)
    if not first_valid_row:
        print("No valid row found.")
        return

    print("Typ vorher von first_valid_row[0]:")
    print(type(first_valid_row[0]))

    # Update the first cell in the first column with the current date
    formatted_date_object = datetime.datetime.now().strftime('%d.%m.%y')
    current_date = datetime.datetime.strptime(formatted_date_object, '%d.%m.%y').date()

    
    first_valid_row[0] = current_date
    print("Typ von first_valid_row[0]:")
    print(type(first_valid_row[0]))

    # Filter out empty rows from sheet1
    sheet1 = [row for row in sheet1 if any(cell for cell in row)]


        

    #sort
    sorted_sheet = sorted((row for row in sheet1 if any(row)), key=operator.itemgetter(sort_column_index))
    

    # Save the sorted data to the output file
    save_data(output_file, {sheet_name: sorted_sheet})

    # Remove the input file and rename the output file to the input file name
    os.remove(input_file)
    os.rename(output_file, input_file)

# Example usage:
if __name__ == "__main__":
    input_file = "input.ods"
    sort_column_index = 0  # Index of the column to sort (0-based index)

    sort_and_save_ods_file(input_file, sort_column_index)




'''
    import pyexcel_ods3 as pe
from pyexcel_ods3 import save_data
import os
import datetime
import time

def find_first_valid_row(sheet, invalid_value="nein"):
    for row in sheet:
        if row[6] != invalid_value:
            return row

def print_sheet(sheet):
    for row in sheet:
        print(row)


def sort_and_save_ods_file(input_file, sort_column_index):
    output_file = "output.ods"
    sheet_name = "Sheet1"
    sort_ascending = True  # Change to True for ascending order, False for descending order

    # Read the data from the input file
    file = pe.get_data(input_file)
    sheet1 = file[sheet_name]

    # Find the first valid row from the top where the 7th cell isn't "nein"
    first_valid_row = find_first_valid_row(sheet1)
    if not first_valid_row:
        print("No valid row found.")
        return

    # Print the contents of the first valid row
    print("First valid row contents:")
    for cell in first_valid_row:
        print(cell)

    # Determine the legitimate values for sort_column_index
    print("Legitimate values for sort_column_index:")
    for idx, cell in enumerate(first_valid_row):
        print(f"{idx}: {cell}")

    # Update the first cell in the first column with the current date
    current_date = datetime.datetime.now().strftime("%Y-%m-%d")
    first_valid_row[0] = current_date

    # Filter out empty rows from sheet1
    sheet1 = [row for row in sheet1 if any(cell for cell in row)]

    # Print the range of valid column indices after filtering
    print("Valid column index range:", list(range(len(first_valid_row))))

    # Check if sort_column_index is within the valid range
    if sort_column_index not in range(len(first_valid_row)):
        print("Invalid sort_column_index. Please choose a valid column index.")
        return
    time.sleep(1)
        
     # Print the state of the sheet after sorting
    print("State of the sheet before sorting:")
    print_sheet(sheet1)
    time.sleep(1)

    # Decorate: Create a list of tuples with (value_in_specified_column, row_index, row_data)
    decorated = [(row[sort_column_index], i, row) for i, row in enumerate(sheet1)]

    # Sort based on the value in the specified column
    decorated.sort()

    # Undecorate: Extract the sorted rows based on the sorted indexes
    sorted_sheet1 = [row_data for _, _, row_data in decorated]
     # Print the state of the sheet after sorting
    print("State of the sheet after sorting:")
    print_sheet(sorted_sheet1)

    # Save the sorted data to the output file
    save_data(output_file, {sheet_name: sorted_sheet1})

    # Remove the input file and rename the output file to the input file name
    os.remove(input_file)
    os.rename(output_file, input_file)

# Example usage:
if __name__ == "__main__":
    input_file = "input.ods"
    sort_column_index = 0  # Index of the column to sort (0-based index)

    sort_and_save_ods_file(input_file, sort_column_index)

'''

Nun macht er mir aus normalen Datumsangaben wie 28.04.21 plötzlich Zahlen wie 44225

Ob da dann noch irgendwas sortiert ist, keine Ahnung :-/
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum wandelst Du ein Datum in einen String um, um dann in der nächsten Zeile das gleich wieder in ein Datum umzuwandeln???

Code: Alles auswählen

import os
import datetime
import operator
import pyexcel_ods3 as pe

OUTPUT_FILENAME = "output.ods"
SHEET_NAME = "Sheet1"

def find_first_valid_row(sheet, invalid_value="nein"):
    for row in sheet:
        if row[6] != invalid_value:
            return row
    return None

def print_sheet(sheet):
    for row in sheet:
        print(row)

def sort_and_save_ods_file(input_filename, sort_column_index):
    sheets = pe.get_data(input_filename)
    sheet = sheets[SHEET_NAME]

    # Find the first valid row from the top where the 7th cell isn't "nein"
    first_valid_row = find_first_valid_row(sheet)
    if not first_valid_row:
        print("No valid row found.")
        return

    first_valid_row[0] = datetime.date.today()
    sorted_sheet = sorted(
        (row for row in sheet if any(row)),
        key=operator.itemgetter(sort_column_index))

    # Save the sorted data to the output file
    pe.save_data(OUTPUT_FILENAME, {SHEET_NAME: sorted_sheet})

    # Remove the input file and rename the output file to the input file name
    os.remove(input_filename)
    os.rename(OUTPUT_FILENAME, input_filename)

def main():
    input_file = "input.ods"
    sort_column_index = 0  # Index of the column to sort (0-based index)
    sort_and_save_ods_file(input_file, sort_column_index)

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

@Sirius3: Weil ChatGPT das so gesagt hat vielleicht. Über diesen Unsinn mit `sleep()` weil die Daten vielleicht noch nicht fertig in der Liste geschrieben sind vor dem Sortieren komme ich gerade gar nicht hinweg.

@bernd13: ”Normale Datumsangaben” gibt es in Excel nicht, das sind immer Zahlen und eine Formatierungsangabe sagt dann wie das dargestellt werden soll. Da die verwendete Bibliothek offenbar die *Daten* aus den Arbeitsblättern holt und die Metadaten zur Zelle nicht, liefert das Speichern wahrscheinlich Zellen ohne Formatierung. Wobei der 28.04.2021 der Wert 44314 ist. 44225 ist der 29.01.2021.

Bei Tabellenkalkulationsdateien würde ich immer mit ”Müll” rechnen. Also das es leere Zellen gibt, das Datums oder Zahlenangaben als Text in der Zelle stehen, oder auch umgekehrt, das Zellen wo man eigentlich Text erwartet, eine Zahl steht wenn der Text aus Ziffern besteht. Das kann man auch nur zum Teil den Anwendern anlasten. Die automagische Erkennung von Tabellenkalkulationen macht da auch gerne mal Mist. So ganz grundsätzlich gilt halt das man Benutzereingaben nicht trauen darf. 😎
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Hm, also ich habe jetzt keinen wirklichen Plan mehr, was ich tun soll.
Wenn ich die komischen Nummern habe wie 44255 (was wohl Minuten seit 1.1.1990 oder so sein soll, würde ich vermuten),
kann ich die dann wieder in ein normales 06.07.2021 Format überführen?

Ich blicke noch nicht wirklich durch wie das mit datetime, date und so funktioniert, weil ich selbst mit einem Date objekt immer noch nur so eine sch... Zahl habe und nciht ein richtiges Datum :-/
Sirius3
User
Beiträge: 18274
Registriert: Sonntag 21. Oktober 2012, 17:20

Dann wird es der ods-schreiber einfach nicht können. Warum muss es überhaupt ODS sein? Warum kein Excel-Format?
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Weil ich openoffice calc nutze.
Da heißen die Dateien so :-)
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@bernd13: Ich kann das Problem nicht nachvollziehen. Bei mir wird ein ”richtiges Datum” gespeichert.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

So, mir war es jetzt gar zu blöd mit den blöden Datetime Typen und dem nicht funktionierenden Sortieren, das mir die Formatierung versaut.

Drum habe ich es from scratch mit den normalen Lsitenmethoden und halt auch entsprechend laienhaft selbst gecodet.
Aber es funktioniert, was mich happy macht.
Auch wenn jetzt ein Eintrag in der ods Datei die Form '01.01.2020 hat (also mit unnötigem Apostroph davor).

Hier der Code:

Code: Alles auswählen

import datetime
import pyexcel_ods3 as pe
from pyexcel_ods3 import save_data
import os
import datetime
import time
import operator

def convert_to_date(obj):

    # Check if the input is a string
    if isinstance(obj, str):
        # Convert the string to datetime.date format
        #date_obj = datetime.datetime.strptime(obj, "%d.%m.%y").date()
        date_obj = datetime.datetime.strptime(obj, "%d.%m.%Y").date()
        return date_obj
    elif isinstance(obj, datetime.date):
        # If it's already a datetime.date object, return it as it is
        return obj
    else:
        # If it's neither a string nor a datetime.date object, raise an error or handle accordingly.
        print(type(obj).__name__)


def convert_to_string(date_obj):
    # Check if the input is a datetime.date object
    if isinstance(date_obj, datetime.date):
        # Convert the datetime.date object to a string in the format "27.09.1992"
        formatted_string = date_obj.strftime("%d.%m.%Y")
        return formatted_string
    else:
        # If it's not a datetime.date object, raise an error or handle accordingly.
        raise ValueError("Invalid input. Expected a datetime.date object.")




input_file = "input.ods"
output_file = "output.ods"
sheet_name = "Sheet1"
sort_ascending = True  # Change to True for ascending order, False for descending order
    
# Read the data from the input file
file = pe.get_data(input_file)
sheet = file[sheet_name]

# Print the sorted sheet
for row in sheet:
    row[0]=convert_to_date(row[0])

replace_row_index=2

for i in range(len(sheet)):
    if(sheet[i][6]!='nein'):
        replace_row_index=i
        break
    

# Get the current date as a datetime.date object
current_date = datetime.date.today()

#change value of the first cell in the replace_row_index th row
sheet[replace_row_index][0]=datetime.date.today()

# Convert date strings to datetime.date objects and get the rank order
dates = [convert_to_date(row[0]) for row in sheet]
rank_order = sorted(range(len(dates)), key=lambda x: dates[x])



# Sort the entire sheet based on the rank order
sorted_sheet = [sheet[i] for i in rank_order]
sheet=sorted_sheet



for row in sheet:
    row[0]=convert_to_string(row[0])


# Save the sorted data to the output file
save_data(output_file, {sheet_name: sheet})

# Remove the input file and rename the output file to the input file name
os.remove(input_file)
os.rename(output_file, input_file)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich sehe da immer noch die datetime Typen und Sortieren. Aber schön, wenn ChatGPT nach genug drauf kloppen geliefert hat.
Antworten