Seite 1 von 1

Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 13:57
von tz_wuerzburg
Hallo zusammen,
ich arbeite mit dem Webframework Flask, welches bisher auch gut funktioniert.
Jetzt erhalte ich aber eine Fehlermeldung mit der ich so garnicht klar komme, bzw. verstehe ich den Hintergrund nicht.

Code: Alles auswählen

@app.route("/sorting")
def sorting():

    #Database import
    address = request.args.get("database")

    if address == "None" or address == "":
        ausgabe = "Keine Daten"
    else:
        database_read.original_file(address)

    # Überschrift in einen Tupel umwandeln (nummerieren)
    if address != "None":
        headline_selection = database_read.headline_numbering("header.csv", "header_with_number.csv")
        v_street = headline_selection

Code: Alles auswählen

# -*- coding: utf-8 -*-
import csv

def original_file(original_file_import):
    counter = 10000000
    with open(original_file_import, "r", encoding="utf-8") as input_cz, open("original_file_enriched.csv", "w", newline="",encoding="utf-8") as output_cz, open("header.csv", "w", newline="",encoding="utf-8") as header_cz:
        entry_address = csv.reader(input_cz, delimiter=";")
        cz_writer = csv.writer(output_cz, delimiter=";")
        cz_header = csv.writer(header_cz, delimiter=";")
        for address_line in entry_address:
            counter = counter + 1
            if counter == 10000001:
                cz_header.writerow(address_line)

            elif counter != 10000001:
                address_line.insert(0, counter)
                cz_writer.writerow(address_line)


def headline_numbering(header, headline_selection):
    with open(header, "r", encoding="utf-8") as input_cz, open(headline_selection, "w",newline="",encoding="utf-8") as output_cz:
        entry_address = csv.reader(input_cz, delimiter=";")
        cz_writer = csv.writer(output_cz, delimiter=";")
        for address_line in entry_address:
            headline_with_counter = list(enumerate(address_line))
            cz_writer.writerow(address_line)
            return str(headline_with_counter)

Code: Alles auswählen

{% extends "layouts/main.html" %}

{% block content %}

    <form method="get">
        <label for="database">Daten:</label>
        <input type="file" name="database" id="database" />
        </br>
        <input type="submit" value="Daten importieren" />
        </br>
        <label>PLZ Spalte:
            <select name="zipcode">
                <option>{{ v_street }}</option>
                <option>{{ v_zipcode }}</option>
                <option>{{ v_city }}</option>
            </select>
        </label>
        </br>
        </br>
        </br>
        <label for="weight">Gewicht(g):</label>
        <input type="number" name="weight" id="weight" />
        </br>
        </br>
        <label for="bundle_min">Bundminimum:</label>
        <input type="number" name="bundle_min" id="bundle_min" />
        <label for="bundle_max">Bundmaximum:</label>
        <input type="number" name="bundle_max" id="bundle_max" />
        </br>
        </br>
        <label for="pallet_min">Palettenminimum:</label>
        <input type="number" name="pallet_min" id="pallet_min" />
        <label for="pallet_max">Palettenmaximum:</label>
        <input type="number" name="pallet_max" id="pallet_max" />
        </br>
        </br>
        <input type="submit" value="Optimierung starten" />
        </br>
    </form>

        {{ v1 }}

{% endblock %}
Fehler:
TypeError: expected str, bytes or os.PathLike object, not NoneType

Das komische ist, wenn ich PyCharm und damit den Webserver neu starte geht es. Wenn ich dann mal ein paar Dateien eingelesen
habe kommt es zu problemen. Ich bin echt überfragt und hoffe auf Eure Hilfe.

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 14:10
von __blackjack__
@tz_wuerzburg: *Wo* tritt den die Ausnahme auf? Den gesamten Traceback bitte und nicht nur die letzte Zeile.

Und Du scheinst da lustig auf globalen Listen zu operieren. Das geht gar nicht.

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 14:23
von narpfel
@tz_wuerzburg: Was passiert, wenn der Schlüssel `"database"` nicht in `request.args` enthalten ist? Eventuell hilft es, das ganze Schritt für Schritt (mit einem normalen Dictionary) interaktiv durchzuprobieren...

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 14:25
von Sirius3
Meinst Du bei »sorting« nicht None statt "None"? Warum fängst Du bei counter = 10000000 an? Wenn Du einen Index brauchst, benutze enumerate. Warum willst Du den Header in eine separate Datei schreiben? Ein elif das exakt das Gegenteil der if-Bedingung ist, ist eigentlich ein `else`. `original_file` ist ein schlechter Funktionsname, weil er nichts aussagt, was denn die Funktion tut. Ein `return` direkt in einer for-Schleife sieht für mich wie ein Programmierfehler aus. Wenn Du nur ein Element eines Iterable verwenden willst, nutze die next-Funktion.
Warum liefert die Funktion › headline_numbering‹ die Stringrepresentation eines Strings zurück. Die ist eigentlich nur für Debug-Ausgaben gedacht.

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 14:56
von tz_wuerzburg
@__blackjack__
- Was heißt auf globalen Listen zu operieren? Hast du einen Hinweis für eine Lösung?

@Sirius3
- Ich meinte None. Hiermit wurde das Problem auch behoben, der Fehler tritt nun nicht mehr auf.
- Ich arbeite an einem Projekt bei dem die Nummerierung immer mit 10000000 begonnen hat. Ist die Lösung mit enumerate besser, oder nur einfacher?
- Der Header ist seperate, da ich ein Auswahlfeld für eine seperate Spalte im Browser benötige und ich erst nach dem Datenimport weiß, welche Spalte es betrifft.
Habe bisher keine bessere Lösung gefunden. Bzw. möchte ich das als nächstes lösen.
- Das mit dem return ist dann bestimmt ein Fehler, ich bin noch nicht so lange dabei :) Die next Funktion kenne ich noch granicht.
- str(headline_with_counter) ist ein Fehler

Ich danke euch vielmals!

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 15:07
von __blackjack__
@tz_wuerzburg: Sorry, bei den Listen hatte ich mich verlesen. :oops:

`enumerate()` ist einfacher und damit besser. Und ich würde auch in der Schleife kein ``if`` mit dem `counter` machen das nur für das erste Element gilt. Das kann man *vor* der Schleife abfrühstücken in dem man vor der Schleife einfach den ersten Datensatz in der andere Datei kopiert. Da ist dann `next()` wieder nützlich.

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 15:21
von Sirius3
Dieses hin und herkopieren von Dateien ist so seltsam, dass es schwer ist, dahinter einen Sinn zu erkennen. Der Name ›sorting‹ läßt erwarten, dass irgendwas sortiert wird, ist aber nicht so.
Ich befürchte, Du machst etwas sehr kompliziert, was einfacher möglich wäre.

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 15:48
von tz_wuerzburg
@Sirius3
Es geht hier nur um den Datenimport, die tatsächliche Sortierung der Daten findet später statt und das funktioniert schon sehr gut.
Ich bastel gerade an einem sauberen Import, aus dem ich einzelne Spalten einer großen Datei entnehmen kann um diese zu sortieren.
Später, nach der Sortierung spiele ich diese wieder zusammen um nicht zu viel speicher zu verwenden.

Re: Flask bringt TypeError

Verfasst: Donnerstag 12. Juli 2018, 16:27
von Sirius3
Hört sich so an, als ob Du besser eine Datenbank verwenden solltest.

Re: Flask bringt TypeError

Verfasst: Freitag 13. Juli 2018, 14:57
von tz_wuerzburg
Bisher speichere ich die Daten in .csv Dateien zwischen. Diese Dateien werden dann sooft verarbeitet bis die
Dateisortierung abgeschlossen ist. Ich dachte immer, dass nur die Ausgangs- und die Enddatei in einer Datenbank
gepseichert werden soll, Zwischenschritte nicht. Wobei eine .csv höchstwahrscheinlich auch nicht das Richtige ist.
Macht es den Sinn, direkt auf Django umzusteigen, bezüglich der besseren Datenbankanbindung?
Gibt es ein gutes Python - CSS Tutorial das ihr empfehlen könnt?
Vielen Dank schonmal.

Re: Flask bringt TypeError

Verfasst: Freitag 13. Juli 2018, 16:03
von __blackjack__
@tz_wuerzburg: Dateien würde ich normalerweise gar nicht in relationalen Datenbanken speichern, sondern Daten. Also Ausnahme wäre wenn die Dateien jeweils ein einzelnes Datum wären und entweder sehr klein oder das DBMS mit Dateien als Werten gut umgehen kann. Also beispielsweise „streaming“ direkt in/aus der Datenbank machen könnte.

Was in die DB kommt hängt auch von der Anwendung ab. Bei einer Desktopanwendung braucht man die Zwischenschritte nicht zwischenspeichern, das kommt ja hauptsächlich durch die von HTTP her zustandslose Anfrage/Antwort-Semantik bei Webanwendungen zustande. Und wenn man dort Dateien verwendet, muss man in der Datenbank ja mindestens den hoffentlich ”zufällig” generierten Dateinamen und den Verarbeitungsschritt zwischenspeichern, weil das mit besagter Semantik sonst sehr komisch wird.

Was meinst Du mit besserer Datenbankanbindung bei Django?

Zum sortieren: Muss das tatsächlich auf den Eingabedaten passieren? Datenbanken sind eigentlich ganz gut darin bei der Abfrage auch gleich eine Sortierung anzuwenden.

Re: Flask bringt TypeError

Verfasst: Samstag 14. Juli 2018, 09:38
von Sirius3
@tz_wuerzburg: wenn ich Deine sonstigen Beiträge hier so ansehe, bekomme ich das Bild, als ob Du eigentlich nur Ausgangsdaten hast, die sich gut in einer Datenbank abbilden lassen und alle Zwischenschritte nicht nötig sind, weil man die auch direkt in Datenbankabfragen formulieren kann.

Um da besser helfen zu können, müßtest Du nochmal alle Ausgangs- und Enddaten genauer beschreiben.

Python und CSS haben keine Schnittmenge, von daher ist es unwahrscheinlich, dass sie zusammen in einem Tutorial auftauchen. Was möchtest Du denn da lernen?

Re: Flask bringt TypeError

Verfasst: Montag 16. Juli 2018, 09:14
von tz_wuerzburg
Guten Morgen zusammen,
Ausgangspunkt ist eine Adressdatei (keine festgelegte Struktur).
Die Daten werden mit diversen postalischen Informationen angereichert (Postbezirk, usw.). Die Daten dazu kommen
aus einer fixen Datei und werden über die PLZ abgeglichen.
In erster Instanz werden Daten mit falscher PLZ aussortiert. Danach geht es dann an die eigentliche Sortierung.
Die Adressen werden erst zu Bunden und danach zu Palletten zusammengefasst (abhängig von den jeweilig gewünschten Bund-
und Palettenangaben), aktuell durchlaufen die Daten dazu etwa 90 Funktionen.
Die Funktionen Zählen, setzen Flags oder sortieren. Das funktioniert auch alles schon sehr gut und ich habe das
ganze im Einsatz.
Nur möchte ich nicht der einzige sein, der das ganze bedienen kann. Also kam die Idee mit Flask und der Weboberfläche.
Wie ich die Daten dann mal in eine Datenbank ablegen kann oder für längere Zeit abrufbar mache habe ich noch
nicht durchdacht. So richtig mit dem programmieren beschäftige ich mich erst seit Anfang des Jahres und hätte nie
gedacht überhaupt so schnell Erfolge zu erzielen :)
Vielleicht umschreibt das die Thematik.

Mein Problem mit CSS ist, dass ich nicht weiß, wie ich eine Liste von Variablen in mein Formular bekomme.

Code: Alles auswählen

 <label>Testspalte:
            <select name="zipcode">
                <option>{{ zipcode }}</option>
                </br>
        <input type="submit" value="Abschicken" />
        </br>

            </select>
</label>
zipcode enthält eine Liste (den header der Datei), die Werte der Liste möchte ich jeweils zur Auswahl haben. Genauer gesagt ist es die oben beschriebene
Adressdatei und die PLZ Spalte soll durch einen User ausgewählt werden, da ich nur diese zur Optimierung benötige.


PS. Die Ausgangsdatei soll dann die Eingangsdatei mit den jeweilige angereicherten Informationen sein (Bundnummer, Palettennummer, usw.).

Re: Flask bringt TypeError

Verfasst: Montag 16. Juli 2018, 09:46
von __blackjack__
@tz_wuerzburg: Also hast Du eigentlich gar keine Webanwendung wie man das so erwarten würde, sondern nur ein Webfrontend für eine lokale Desktopanwendung die nicht auf einem Server läuft. Denn dazu verletzt die IMHO zu viele Erwartungen.

Ganz grob gesprochen ist CSS ist ein Sprache um das aussehen von HTML-Elementen zu beschreiben. Das hat nichts damit zu tun wie man in HTML irgendwelche Informationen in ein Formular bekommt.

Vermutlich meinst Du Jinja2 statt CSS.

Zum HTML: <input> und <br> haben innerhalb eines <select> nichts verloren.

</br> gibt es nicht. Das ist entweder <br> (HTML) oder <br /> (XHTML). Letzteres verwendet keiner mehr in neuen Projekten seit HTML 5. Bei <input> braucht man dort auch kein / am Ende.

Wenn `zipcode` eine Liste von Postleitzahlen ist, sollte es `zipcodes` heissen. Mehrzahl. Denn innerhalb der Schleife die Du schreiben musst um für jede Postleitzahl einen Eintrag zu bekommen, braucht die Schleifenvariable ja einen passenden Namen für *eine* Postleitzahl. Was `zipcode` wäre (ungetestet):

Code: Alles auswählen

  <label>Testspalte:
    <select name="zipcode">
      {% for zipcode in zipcodes %}
        <option value="{{ zipcode }}">{{ zipcode }}</option>
      {% endfor %}
    </select>
  </label>
  <br>
  <input type="submit" value="Abschicken">
  <br>
Eventuell möchtest Du noch eine leere Option am Anfang einfügen, damit der Benutzer eine Wahl treffen muss und nicht aus versehen die erste Postleitzahl verwendet wird, weil der Benutzer da nicht dran gedacht hat etwas auszuwählen.

Re: Flask bringt TypeError

Verfasst: Montag 16. Juli 2018, 10:07
von tz_wuerzburg
@__blackjack__
Die Anwendung soll intern auf einem Server laufen und die Kollegen sollen darauf zugreifen können wenn Sie es benötigen.
Es soll nicht nach einem bestimmten Zipcode gesucht, sondern die Spalte Zipcode gewählt werden.
Das ich eine Schleife direkt in meiner .html Datei einbauen kann wusste ich nicht und du hast mir damit sehr weitergeholfen.
Jinja2 ist dann genau das womit ich mich erstmal beschäftigen sollte.
Vielen Dank!

Re: Flask bringt TypeError

Verfasst: Montag 16. Juli 2018, 10:43
von __blackjack__
@tz_wuerzburg: Wenn das auf einem Server laufen soll, für mehrere Kollegen, dann sehe ich da Probleme mit dem jetzigen Vorgehen. Bei einer Webanwendung würde man erwarten, das mehrere Leute die gleichzeitig verwenden können, und das es kein Problem sein darf wenn der Browser mitten drin geschlossen und wieder gestartet wird. Schön wäre auch wenn man den Rechner/Browser wechseln könnte. Und dann kommt man nicht wirklich darum herum den aktuellen Zustand der Bearbeitung in einer Datenbank zu speichern. Es muss da ja nicht gleich die Eingabedatei gespeichert werden, aber mindestens der Name der Datei auf dem Server, und der darf nicht mit anderen kollidieren. Üblicherweise erstellt man einen ”zufälligen” Namen beispielsweise mit einer UUID. Python hat da ein Modul in der Standardbibliothek für UUIDs.

Wenn `zipcode` gar keine Postleitzahl(en) enthält sondern Spaltennamen, dann sollte es nicht `zipcode` sondern `colum_names` heissen. Und das Formularelement dann vielleicht auch besser `zipcode_column_name`.

Re: Flask bringt TypeError

Verfasst: Montag 16. Juli 2018, 17:00
von tz_wuerzburg
@ __blackjack__
Ok, ich habe verstanden.
Dann macht es ja Sinn, gleich eine größere "Geschichte" außenrum zu bauen.
Gibt es Projekte in Python für einen Benutzerlogin, bzw. dass jeder User seine eingene Oberfläche hat?
Als Datenbank verwende ich am besten SQlite, oder?