Flask bringt TypeError

Django, Flask, Bottle, WSGI, CGI…
tz_wuerzburg
User
Beiträge: 38
Registriert: Dienstag 7. März 2017, 17:51

Donnerstag 12. Juli 2018, 13:57

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

Donnerstag 12. Juli 2018, 14:10

@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.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
narpfel
User
Beiträge: 239
Registriert: Freitag 20. Oktober 2017, 16:10

Donnerstag 12. Juli 2018, 14:23

@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...
Sirius3
User
Beiträge: 8572
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 12. Juli 2018, 14:25

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.
tz_wuerzburg
User
Beiträge: 38
Registriert: Dienstag 7. März 2017, 17:51

Donnerstag 12. Juli 2018, 14:56

@__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!
Benutzeravatar
__blackjack__
User
Beiträge: 1401
Registriert: Samstag 2. Juni 2018, 10:21

Donnerstag 12. Juli 2018, 15:07

@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.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Sirius3
User
Beiträge: 8572
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 12. Juli 2018, 15:21

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.
tz_wuerzburg
User
Beiträge: 38
Registriert: Dienstag 7. März 2017, 17:51

Donnerstag 12. Juli 2018, 15:48

@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.
Sirius3
User
Beiträge: 8572
Registriert: Sonntag 21. Oktober 2012, 17:20

Donnerstag 12. Juli 2018, 16:27

Hört sich so an, als ob Du besser eine Datenbank verwenden solltest.
tz_wuerzburg
User
Beiträge: 38
Registriert: Dienstag 7. März 2017, 17:51

Freitag 13. Juli 2018, 14:57

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

Freitag 13. Juli 2018, 16:03

@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.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Sirius3
User
Beiträge: 8572
Registriert: Sonntag 21. Oktober 2012, 17:20

Samstag 14. Juli 2018, 09:38

@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?
tz_wuerzburg
User
Beiträge: 38
Registriert: Dienstag 7. März 2017, 17:51

Montag 16. Juli 2018, 09:14

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

Montag 16. Juli 2018, 09:46

@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.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
tz_wuerzburg
User
Beiträge: 38
Registriert: Dienstag 7. März 2017, 17:51

Montag 16. Juli 2018, 10:07

@__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!
Antworten