Verarbeiten einer Datei mit Python3 und Bottle

Django, Flask, Bottle, WSGI, CGI…
BlackJack

@Mars_ars: Wenn der `ValueError` immer kommt, dann geht irgendwo auf dem Weg der Schlüssel kaputt, denn das sollte funktionieren:

Code: Alles auswählen

In [7]: u = uuid.uuid1()

In [8]: str(u)
Out[8]: '9477da1c-ed4f-11e6-a1cf-901b0e8d499b'

In [9]: uuid.UUID(str(u))
Out[9]: UUID('9477da1c-ed4f-11e6-a1cf-901b0e8d499b')

In [10]: uuid.UUID(str(u) + 'z')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-10-ec471a35591a> in <module>()
----> 1 uuid.UUID(str(u) + 'z')

/usr/lib/python2.7/uuid.pyc in __init__(self, hex, bytes, bytes_le, fields, int, version)
    134             hex = hex.strip('{}').replace('-', '')
    135             if len(hex) != 32:
--> 136                 raise ValueError('badly formed hexadecimal UUID string')
    137             int = long(hex, 16)
    138         if bytes_le is not None:

ValueError: badly formed hexadecimal UUID string
Mars_ars
User
Beiträge: 16
Registriert: Freitag 3. Februar 2017, 12:09

Herzlichen Dank, beides hat weitergeholfen :D
Mars_ars
User
Beiträge: 16
Registriert: Freitag 3. Februar 2017, 12:09

Hallo liebe Community,
ich bin nun mit dem Projekt größtenteils bzw. ganz fertig und habe heute an den Rechnern der Uni einen merkwürdigen bug entdeckt, der bei mir bisher nicht vorkam:
der User lädt eine Datei hoch, kann diese Bearbeiten und am Ende des Prozesses bekommt er eine graphische Auswertung der Datei (matplotlib). wenn der Benutzer nun wieder zur Startseite geht und erneut eine Datei hochlädt, werden die Graphen stark zerschoßen angezeigt (z.b. werden jeweils die Werte und die Legenden miteinander verwurschtelt bzw. werden doppelt so lang). Ich habe festgestellt, dass es mit dem Serverneustart zutun hat. Damit alles richtig angezeigt wird, muss der Server mit strg+c neugestartet werden. Irgendwie macht das doch keinen Sinn in der Praxis, da man ja einen Server nicht nach jeder Benutzereingabe neu startet/ starten kann.

Code: Alles auswählen

run(reloader=True)
ist im code drin. was könnte schief gehen?
BlackJack

@Mars_ars: Du operierst da mit *einem* Plot. Du musst für jede Anfrage einen neuen erstellen und nicht auf dem einen globalen operieren.
Mars_ars
User
Beiträge: 16
Registriert: Freitag 3. Februar 2017, 12:09

Das verstehe ich leider nicht ganz. Der Plot/ die Plots sind doch in einer eigenen Funktion, müssen doch jedesmal die Werte aus der neue hochgeladenen Datei verwenden. Wird etwa nicht für jede Anfrage ein eigener Plot generiert?
BlackJack

@Mars_ars: Nein es wird nicht für jede Anfrage ein neuer Plot generiert. Wo sollte das denn aus welchem Grund auf magische Weise passieren? Der Plot ist kein lokaler Wert in der Funktion. Du rufst da ausschliesslich Funktionen auf denen Du nie irgendwie angibst *auf welchen Plot* die sich eigentlich beziehen. Das ist halt der eine globale den `matplotlib` für diese Funktionen erstellt, die für die interaktive Nutzung gedacht, und da auch praktisch sind.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@Mars_ars: Du rufst plt.plot auf, das in ein globales Diagramm etwas einzeichnet. Und was da gezeichnet wurde, wird über mehrere Anfragen hinweg auch gespeichert. Was Du brauchst, ist für jede Anfrage eine eigene Figure, in die Du dann z.B. per fig.plot etwas zeichnen kannst.
Mars_ars
User
Beiträge: 16
Registriert: Freitag 3. Februar 2017, 12:09

ich hatte eigentlich schon davor jedem plot eine Nr. zugewiesen: z.b.

Code: Alles auswählen

plt.figure(1)
nun habe ich

Code: Alles auswählen

fig1=plt.figure()
fig1.plot(x_range, n, label='N %')
und so weiter... quasi überall plt durch fig1 ersetzt :D
doch hat ein Figure-object kein attribut plot.

in dem Tutorial zu matplotlib verwendeten sie einfach nur zahlen. ich hätte nicht erwartet, dass alles so kompliziert ist^^ (http://matplotlib.org/users/pyplot_tutorial.html)

Soll ich vielleicht die Plots nach plt.safig() mit clear() bereinigen?
BlackJack

@Mars_ars: Dann kümmert sich ein globaler „FigureManager“ um die Plots, das heisst die werden wohl nie wieder aus dem Speicher entfernt. Ungünstig für einen Server. Ich würde `pyplot` ganz weg lassen. Das ist ja eigentlich nur dazu da um interaktiv so was ähnliches wie Matlab zu haben. Wo der Benutzer die Funktionen direkt aufruft, oder für kleine Skripte die einfach nur mal einen Plot erstellen und danach beendet sind.

Wenn man etwas lang laufendes hat, sollte man IMHO die normale `matlotlib`-API verwenden. Also sich beispielsweise den `FigureCanvasAgg` aus dem Agg-Backend-Modul holen, damit ein `Figure`-Objekt erstellen, darauf dann einen Subplot, und auf dem kann man dann fröhlich plotten. Die Objekte werden bei jeder Anfrage neu erstellt, und wenn die Funktion wo die an lokale Namen gebunden sind, abgearbeitet ist, dann können die Objekte von Python auch wieder abgeräumt werden.
Mars_ars
User
Beiträge: 16
Registriert: Freitag 3. Februar 2017, 12:09

Vielen Herzlichen Dank euch beiden. Diesmal insbesondere BlackJack für die sehr ausführliche Antwort.
Da am Freitag schon die Abgabe ist und ich eh sehr viel neues Wissen angeeignet habe (dank euch), ist es nicht zielführend jetzt auf die Schnelle zu versuchen sich krampfartig in das Agg_Backend Modul einzuarbeiten (habe es mir kurz angeschaut und es sieht recht komplex aus). Ich habe das Problem folgendermaßen "lösen" können:

Code: Alles auswählen

plt.figure(1)
        plt.clf()
        und dann den eigentlichen plot
Aus eurer Antwort weiß ich nun, was ich beachten muss, wenn ich mal tatsächlich so etwas auf die Beine stelle. Anscheinend sind solche tiefen Kenntnisse, wie ihr sie versucht zu vermitteln, in dem Einführungsmodul Bioinformatik leider nicht erforderlich. (Die sind schon froh, wenn jeder Depp dem Stoff folgen kann. Soviel zum Pädagogischen^^) Habe mich aber riesig über eure Hilfe zu bottle gefreut, da ich alleine wohl damit gescheitert wäre. Damit habe ich die Mindestanforderungen, die an uns gestellt wurden, fröhlich hinter mir gelassen. Zitat vom Professor: "Mensch, die anderen werden weinen, wenn du denen das vorstellst." :D Ein wunderhübsches und elegantes (selbsterstelltes) Design der Templates war sehr förderlich. :mrgreen:

Liebe Grüße
Mars_ars
BlackJack

@Mars_ars: Das Backend-Modul ist im Grunde egal, Du brauchst da nur die eine Klasse draus. Das `Figure`-Objekt braucht halt irgendetwas wo es drauf zeichnen kann.

Was bei Deiner Lösung noch zu beachten ist wäre dass das nicht „thread safe“ ist. Das können so nicht mehrere Leute gleichzeitig nutzen, die malen dann alle auf dem selben Canvas.
Antworten