alle None Werte einer Liste ersetzen. Mein 1. post :D

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
jobuntu
User
Beiträge: 1
Registriert: Freitag 26. März 2021, 16:23

Hallo an alle :)

Es geht um die Funktionen. Ich möchte einen Wert in der Tabelle sofern dieser None ist überschreiben, je nachdem in welcher Spalte mit einer Zahl oder einer Datetime, damit ich später den kleinsten Wert ausgeben kann. Schonmal viele dank im Voraus für eure Hilfe :D

Code: Alles auswählen

import openpyxl
import datetime

wb = openpyxl.load_workbook('test.xlsx')
ws = wb.active

c = input('Which column do you want to access? ')

def datum(x):
    if c == x:
        for index, value in enumerate(values):
            if value is None:
                values[index] = datetime.datetime(2030, 12, 12)

def zahlen(y):
    if c == y:
        for index, value in enumerate(values):
            if value is None:
                values[index] = 9999999999

values = []
i = 4

values.append(ws.cell(row=i, column=int(c)).value)
while i < int(ws.max_row) - 4:
    i = i + 1
    values.append(ws.cell(row=i, column=int(c)).value)

print(values)

if c == 3:
    datum(3)
else:
    zahlen(1)

print(values)

smallestNumber = min(values)
print(smallestNumber)

for count, value in enumerate(values):
    if value == smallestNumber:
        print(count)
        zahl = count

print(ws.cell(row=int(zahl) + 4, column=2 ).value)
PS der restliche Code funktioniert, da ich aber ein Anfänger bin freue ich mich auch über Tipps bezüglich der Lesbarkeit usw. :D
Sirius3
User
Beiträge: 17768
Registriert: Sonntag 21. Oktober 2012, 17:20

Man mischt keinen ausführbaren Code und Funktionsdefinitionen, so ist der Code sehr schwierig zu lesen. Auf oberster Ebene sollte eigentlich gar kein Code stehen, sondern alles in Funktionen. Auf diese Weise macht man auch nicht den Fehler, globale Variablen zu benutzen.
Variablennamen sollten aussagekräftig sein. Einbuchstabige Namen sind das fast nie.
Wenn `c` eine Zahl sein soll, dann wandelt man sie einmal per int um, und nicht bei jeder Verwendung. So vergisst man das auch nicht an der entscheidenden Stelle. Denn der String `c` ist niemals gleich der Zahl 3.
Sowohl ws.max_row als auch zahl sind schon Zahlen, dort ist also der Aufruf von int überflüssig.

Statt der while-Schleife benutzt man hier eine for-Schleife. Und sollen wirklich die ersten 4 und die letzten 3 Zeilen übersprungen werden?
Statt Werte einer Liste zu überschreiben, erzeugt man normalerweise eine neue Liste mit geänderten Werten.
Erwartest Du, dass es mehrere Zellen mit minimalem Wert gibt und Du suchst den letzten davon?

Code: Alles auswählen

import openpyxl
import datetime

def fill_nans(values, fill_value):
    return [
        fill_value if value is None else value
        for value in values
    ]


def main():
    workbook = openpyxl.load_workbook('test.xlsx')
    sheet = workbook.active

    column_index = int(input('Which column do you want to access? '))

    values = [
        ws.cell(row=i, column=column_index).value
        for i in range(4, sheet.max_row - 3)
    ]

    print(values)

    if column_index == 3:
        values = fill_nans(values, datetime.datetime(2030, 12, 12))
    elif column_index == 1:
        values = fill_nans(values, 9999999999)

    print(values)

    smallest_number = min(values)
    print(smallest_number)

    for count, value in enumerate(values):
        if value == smallest_number:
            print(count)
            minimal_value_index = count

    print(sheet.cell(row=minimal_value_index + 4, column=2).value)

if __name__ == "__main__":
    main()
Antworten