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.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@bernd13: Das ' das da zu viel ist bedeutet das eine Zeichenkette in der Spalte gespeichert wird und kein Datum. Das diese Zeichenkette ein Datum repräsentiert ändert nichts daran das weder die Tabellenkalkulation noch weitere Programme die das verarbeiten damit ordentlich umgehen können. Das ist einfach nur Murks was da passiert und produziert wird.

Das mit `dates` und `rank_order` ist gruseliger, umständlicher Code zum sortieren den man so nicht schreiben würde wenn man `sort()` und das `key`-Argument verstanden hätte.

Das ``else`` im `convert_to_date()` macht nicht was der Kommentar behauptet und was man an der Stelle auch tatsächlich machen sollte.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Peh, das wär ja zu shcön wenn das Chatgpt produziert hätte.

Habe ich in Kleinarbeit selbst zusammengecodet und halt kopiert vom alten Code was noch nutzbar war (praktisch alle Befehle bzgl der Bibliothek)

Ich weiß, ich habe nun mehr oder weniger Datumsangaben als strings in der ods Datei, wandle die wo nötig in Datetime.date Objekte um (vor Alem beim sortieren ja nötig) und wandle es wieder zurück.

Meine Datei hat aktuell nur so 40 zeilen a je 7 zellen, da kann ich den kompltten code locker 2-3 mal pro sekunde durhclaufen lassen ohne Probleme :-)


Nachdm nun endlich der ods Part fertig ist (von dem ich dachte, ne Zeile anzupassen und alles zu sortieren dürfte ein shcneller Zweizeler werden -.-)
kann ich mich dem nächsten part widmen:
Die daten aus dr zu veränderten Zeile nehmen und in ein paar odt dateien einfügen
(da nehm ich dann auch so eine bibliothek wie hier. in der theorie habe ich da shcon codemässig was, aber da kommen sicher genug fehlermeldungen wenn ich dort auch nur einen befehel verändere )
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

__blackjack__ hat geschrieben: Dienstag 25. Juli 2023, 22:43 @bernd13: Das ' das da zu viel ist bedeutet das eine Zeichenkette in der Spalte gespeichert wird und kein Datum. Das diese Zeichenkette ein Datum repräsentiert ändert nichts daran das weder die Tabellenkalkulation noch weitere Programme die das verarbeiten damit ordentlich umgehen können. Das ist einfach nur Murks was da passiert und produziert wird.

Das mit `dates` und `rank_order` ist gruseliger, umständlicher Code zum sortieren den man so nicht schreiben würde wenn man `sort()` und das `key`-Argument verstanden hätte.

Das ``else`` im `convert_to_date()` macht nicht was der Kommentar behauptet und was man an der Stelle auch tatsächlich machen sollte.
oh verstanden, geh mir doch nicht auf den S...
Das tut chatgpt und Co shcon genug.

Weißt du wie viele verschiedene Varianten an key lambda bullshit ich shcon in die sorted() Methode reingesteckt habe?

Entweder wird gar nix sortiert, irgendein Dreck gemacht.

Oder, weil python für den A.. ist, wir dimmer nur die scheiß 44255 Zahlen gespeichert statt einem gescheiten Datum.

Das ist mir zu blöd, wenn er string will kriegt er String,
dann erzwinge ich eben dass er verf nochmal sowas wie 06.05.2020 und nicht diese Rotz 44255 zahlen!

Ist mir mittlerweile egal, ob es elegant ist, es funktioniert wenigstens einmal im Leben!

Spätestens wenn ich einfach mal das Datum in der einen Zelle geändert habe, war hinterher Alles für den A... und wurde nur immer schlimmer,
geändert haben sich nur von Zeit zu Zeit mal die Fehlermeldungen.


Warum soll da überhaupt ein Apostroph vor einem String?

Andere "Strings" in der Tabelle habens doch auch nicht davor und sind trotzdem Strings?
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Nur um meinen Punkt zu beweisen:
So ziemlich der gleiche Code, ich habe sprichwörtlich nur den Part auskommentiert wo die erste Spalte vor dem Speichern in Strings umgewandelt wird.
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:
        # print name and type
        print(type(obj).__name__)
        return obj


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
    
#zu Testzwecken damit nicht immer die erste Zeile geändert wird
replace_row_index=4

# 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)




Endergebnis:;
Das wird jetzt sicherlich für uns Alle zu einer unglaublichen Überraschung werden, aber.. man halte sich fest...
*Trommelwirbel*

Es kommen die verschissenen Dreckszahlen wieder!

Aus der input ods Datei

Code: Alles auswählen

28.04.21	z	10	88	88	88	ja
27.04.21	u	9	1	1	1	wer
25.04.21	r	8	9	9	9	wer
26.03.21	e	7	34	34	34	vielleicht
25.03.21	q	6	12	12	12	vielleicht
28.02.21	zuersetzen	5	56	56	56	nein
26.02.21	t	4	76	76	76	nein
23.02.21	i	3	23	23	23	nein
30.01.21	o	2	44	44	44	nein
29.01.21	p	1	62	62	62	ja
wird dann

Code: Alles auswählen

44225	p	1	62	62	62	ja
44226	o	2	44	44	44	nein
44250	i	3	23	23	23	nein
44253	t	4	76	76	76	nein
44255	zuersetzen	5	56	56	56	nein
44281	e	7	34	34	34	vielleicht
44311	r	8	9	9	9	wer
44313	u	9	1	1	1	wer
44314	z	10	88	88	88	ja
45133	q	6	12	12	12	vielleicht
Das Ersetzen und sortieren hat da wohl shcon geklappt, nur werden keine gescheiten Datumsangaben gespeichert.
Benutzeravatar
__blackjack__
User
Beiträge: 13122
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@bernd13 Deinen Beweis kann ich nicht nachvollziehen, bei mir werden Datums-Objekte in LibreOffice nicht als Zahlen angezeigt.

Programmieren durch raten funktioniert halt nicht wirklich. Ich weiss nicht wie viele verschiedene ``lambda``-Ausdrücke Du da als `key`-Argument übergeben hast, aber anscheinend hast Du nicht verstanden was das bedeutet und wie es funktioniert.

Programme machen das was der Programmierer dem Rechner *sagt*, nicht was er *meint*. Wenn da ”irgendein Dreck” gemacht wird, dann hat der Programmierer gesagt das dieser ”Dreck” gemacht werden soll. Darum muss man wissen was man da macht, was die einzelnen Syntaxkonstrukte bedeuten und wie sich Datentypen verhalten und was Funktions- und Methodenaufrufe zur Folge haben.

44255 *ist* ein gescheites Datum. Das ist der Wert, der in der Zelle gespeichert ist. Ob das als Datum oder als Zahl *angezeigt* wird, ist eine Frage der Formatierung der Zelle. Und bei mir funktioniert das wie gesagt, dass ein `datetime.date`- oder ein `datetime.datetime`-Objekt in LibreOffice auch als Datum angezeigt wird. Wenn ich das wieder lade, werden auch wieder diese Objekte daraus und keine einfachen Zahlen:

Code: Alles auswählen

In [306]: pyexcel_ods3.save_data("test.ods", {"Blatt": [[1, 2], [3, 4], [datetime.date.today(), datetime.datetime.now()]]})

In [307]: pyexcel_ods3.get_data("test.ods")
Out[307]: 
OrderedDict([('Blatt',
              [[1, 2],
               [3, 4],
               [datetime.date(2023, 7, 26),
                datetime.datetime(2023, 7, 26, 9, 47, 7)]])])
Das Apostroph hat nichts mit Python zu tun. Das macht/braucht die Tabellenkalkulation um Zahlen von Text zu unterscheiden. Wenn man 42 eingibt, wird das als Zahl gespeichert. Wenn man '42 eingibt, dann wird das als Text gespeichert. Genauso bei Datumsangaben. Wenn man 06.05.2020 eingibt, wird das als Zahl gespeichert (43957), die als Datum formatiert angezeigt wird. Wenn man '06.05.2020 eingibt, dann bleibt das Text.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Liegr wohl dran dass ich kein Libreoffice nutze sondern Openoffice Calc.

Na, entweder sagt er mir, man kann mit< keine DatTime.date mit strings vergleichen, oder anderer Kram.

Scheinbar hast du wohl recht, wenn ich die erste Spalte (wieder) als Datum formatiere, stehts gescheit da.

Nichtsdestotrotz versaut mir Openoffice Calc da die Formatierung offensichtlich
bernd13
User
Beiträge: 26
Registriert: Sonntag 25. Juni 2023, 11:13

Nur der Vollständigkeit halber mein finaler Code, zumindest was die ods.py Datei angeht:

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
import copy

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:
        # print name and type
        print(type(obj).__name__)
        return obj


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.")



def get_next_row():
    input_file = "bewerbungzykler.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]

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


    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
        
    #zu Testzwecken damit nicht immer die erste Zeile geändert wird
    #replace_row_index=4

    # Create a deep copy of the row before sorting and updating
    original_row = copy.deepcopy(sheet[replace_row_index])

    #print(sheet[replace_row_index])

    # 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




    # 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)

    # Extract individual components from the original row before sorting and updating
    original_date = convert_to_string(original_row[0])
    components = original_row[1:]  # Get all components except the first one

    return convert_to_string(current_date), *components
    #return original_row

Was es tut:

Man rugft von ausserhalb die get_next_row() funktion auf.
die guckt in die ods datei rein, sucht die erste zeile wo die 6te(?) zelle ungleich "nein" ist.

Und ändert die erste zelle in der zeile mit dem aktuellen datum ab und sortiert die datei noch aufsteigend nahc der 1. spalte.

die funktion gibt dann die abgeänderte zeile als lsite zurück, damit man extern mit den daten weiterarbeiten kann.

Mittlerweile bin ich am punkt, wo ich noch 2-3 weitere python dateien habe und mit der ausgelesenen zeile aus der ods datei ersetzungen in 2 odt dateien vornehme.
habe also 2 verschiedene "Template" odt dateien und ershcaffe damit neue odt dateien, wo bestimte begriffe ersetzt wurden.
was womit ersetzt wird, basiert uf der ausgelesenen zeile der obigen funktion.

und natürlich kann die funktion mehrfahc aufgerufen werden, sodass man der reihe nahc die daten der zeilen, von der ältesten der jüngsten, erhält.

nur wens interessiert, was ausser mir vermutlich niemand sein wird. :-)

Ich hätte nun gerne die 2 erzeugten odt noch in pdfs umgewandelt, aber zumidnest laut chatgpt brauche ich entweder libreoffice (-.-) dazu oder eine der wenigen funktionierenden module hierfür erzeugt zwar pdfs, allerdings sit dann jegliche formatierung weg UND die bilder wurden von der odt nicht ins pdf übernommen.
also auch nicht das gewünschte.

Da hängts nun aktuell dran, was brauchbares zum umwandeln zu finden :-)
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da libreoffice genauso frei ist wie OO, nimm es doch einfach 🤷🏼‍♂️
Antworten