Txt Datei durchsuchen und bestimmten Teil ausgeben

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
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Hallo,
ich will aus einer Text Datei in welcher Daten, die immer mit Zeitstempeln versehen sind, die Daten aus einem Bestimmten Zeitraum (der über die Weboberfläche auswählbar ist) abrufen und dann auf der Webseite anzeigen lassen. Jetzt zu meiner Frage wie kann ich mit Python(3.6.6) eine Txt. Datei auf 2 Werte durchsuchen lassen und alles was dazwischen liegt ausgeben lassen?
Text datei sieht später ca. so aus:

Code: Alles auswählen

13-08-2018 20:00:00 713
13-08-2018 20:15:00 607
13-08-2018 20:30:00 643 
13-08-2018 20:45:00 621
13-08-2018 21:00:00 713
13-08-2018 21:15:00 607
13-08-2018 21:30:00 643 
13-08-2018 21:45:00 621
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Hypec: Da gibt es kein besonderes Geheimnis. Man muss halt die Schritte ausprogrammieren die dafür notwendig sind. Zeilenweise einlesen, Datumsangaben in etwas vergleichbares umwandeln, also `datetime.datetime`-Objekte und testen was zwischen den gewählten Grenzen liegt und was nicht. Man kann natürlich abbrechen sobald die erste Zeile ausserhalb der Grenzen liegt, wenn die aufsteigend sortiert in der Datei vorliegen.

Ich würde eine CSV-Datei verwenden oder zumindest Zeitstempel und Daten besser voneinander Trennen, also beispielsweise durch ein Komma oder Semikolon.

Beim Datum ist die Reihenfolge der Komponenten ungünstig. Üblich ist Jahr, Monat, Tag, damit lexikographisch sortiert auch gleichzeitig zeitlich richtig sortiert ist. Das ist auch die übliche Reihenfolge wenn '-' als Trenner zwischen den Datumskomponenten verwendet wird, und ist auch näher am ISO-Standard dran.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Die Struktur wie was aufgebaut sein muss vom Code weiß ich aber ich weiß nicht mit welchem Befehl ich die Zeilen einlese. Die Daten werden nacheinander in die Datei geschrieben und werden Deshalb immer aufsteigend sortiert sein.
Danke für den Tipp bei der Reihnfolge mit dem Datum.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das wird hier andauernd diskutiert. Gerade vor 2 Tagen haben wir das einlesen einer Datei ganz ähnlich zu deiner inklusive Konvertierung zweier Spalten zu einem Zeitstempel dargelegt. Stöber mal 5 Minuten rum.
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Kannst du dich noch erinern wie das Thema vor 2 Tagen hies?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du kannst hier alle miene postings mit einem Klick hier neben meinem Namen ansehen. Das sollte doch reichen.
Benutzeravatar
pixewakb
User
Beiträge: 1408
Registriert: Sonntag 24. April 2011, 19:43

Code: Alles auswählen

with open("filename.txt") as f:
    data = f.readlines()
Vom Handy aus - du musst dann über die Zeilen iterieren, sie splitten und das Datum in ein datetime.date-Objekt umwandeln. Für das kannst du dann prüfen, ob es zwischen deinen Datumswerten liegt.

Mal aus stackoverflow kopiert:

Code: Alles auswählen

d = datetime.strptime("27-07-2012","%d-%m-%Y")
Ich hoffe, dass es klappt. Ich kann es hier nicht testen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@pixewakb: dass man alle Zeilen einer Datei auf einmal einlesen muß, ist eher selten. Normalerweise nimmt man das Datei-Objekt direkt, um über die Zeilen zu iterieren.
Also typischerweise schreibt man:

Code: Alles auswählen

with open("filename.txt") as lines:
    for line in lines:
        do_something
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Wie Wandel ich das Datum am besten wieder in ein datetime.date um?
Und noch eine kleine Frage zum schreiben der Datei momentan nütze ich diesen code hier:

Code: Alles auswählen

from flask import Flask, render_template, url_for, request
import datetime         #Uhrzeit
import pytz             #Zeitzone

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html')

@app.route('/test')
def test():
    f = open('test.txt', "r")
    return render_template('test.html', test = f.read())

@app.route('/getdata', methods=['GET', 'POST'])
def getdata():
    if request.method == 'POST':
        file = open('test.txt', "a+")
        data = request.data
        my_date = datetime.datetime.now(pytz.timezone('Europe/Berlin'))
        fmt = "%Y-%m-%d %H:%M:%S"
        for i in data:
                file.write(my_date.strftime(fmt) + "; ")
                file.write(str(data) + '\n')
        file.close() 
        return data
    return render_template('getdata.html')

if __name__ == '__main__': app.run(debug=True)
test.html:

Code: Alles auswählen

{% extends "base.html" %}
{% block content %}
    <title>Gewächshaus</title>
    <h1>Gewächshaus</h1>
    <h2>Test </h2>
    <p>
        only a Test {{test}}
    </p>
    <br>
{% endblock %}
noch das base.html

Code: Alles auswählen

<!DOCTYPE html>
<html lang="en">

    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    {% if title %}
        <title> {{title}} </title>
    {% else %}
        <title> Myapp </title>
    {% endif %}
    <link rel="stylesheet" type="text/css" href="{{url_for('static', filename='css/style.css') }}" >
    </head>
    <body>
        <div class="menu">
                 <nav>
                        <li>
                            <a href="{{url_for('index')}}"> Home </a>
                        </li>
                        <li>
                            <a href="{{url_for('test')}}"> Test </a>
                        </li>
                        <li>
                            <a href="{{url_for('getdata')}}"> Daten </a>
                        </li>
                        <li>
                            <a href="{{url_for('writedata')}}"> File </a>
                        </li>
                </nav>
                <h1><br></h1>
        </div>       
        <div class="container">
            {% block content %}{% endblock %}
        </div>
    </body>
Ausgabe auf der Test.html seite ist dannn : 2018-08-14 15:25:12; b'354\r\n' 2018-08-14 15:25:12; b'354\r\n' 2018-08-14 15:25:12; b'354\r\n' 2018-08-14 15:25:12; b'354\r\n' 2018-08-14 15:25:12; b'354\r\n' also das ganze wird nicht wie gewollt ein mal hineingeschrieben sondern 5 mal, zudem steht vor dem Messwert ein b' und dahinter \r\n', weiß jemand wie ich das nur einmal schreiben kann und die 3 sachen die nicht dort stehen sollen weg lasse?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Hast du meinen Rat befolgt & dir die Diskussion zum einlesen einer CSV-Datei mit Datumsumwandlung angeschaut? Was davon ist dir unklar?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und in deinem Code oben schreibst du in der for-Schleife nicht i (den also sehr schlecht gewaehlten Namen fuer die Zeile ueber die du gerade iterierst), sondern fuer jedes (edit) Zeichen jedes mal die ganze Datei...
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hypec: Du schreibst für jedes Byte aus `data` die Stringrepresentation von `data` in die Datei. Die Frage ist da natürlich, was willst Du eigentlich?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

'a+' ist auch ziemlich sicher nicht der Dateimodus den man haben möchte. '+' braucht man echt sehr selten und wenn dann in der Regel bei Binärdateien wo man auch `seek()` verwenden. Sonst ist es eigentlich immer besser lesen und schreiben zu trennen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

@__deets__ also ich probier jetzt eine csv datei aus, und wollte als erstes einmal ausprobieren die Datei auszulesen dazu habe ich diesen Code hier genützt:

Code: Alles auswählen

from flask import Flask, render_template, url_for, request
import datetime         #Uhrzeit
import pytz             #Zeitzone
import csv              #Csv Datei schreiben

app = Flask(__name__)

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html')

@app.route('/file')
def writedata():
    csvfile = "test.csv"
    return render_template('file.html', test = open(csvfile, 'r').read())

if __name__ == '__main__': app.run(debug=True)
und habe dabei dann diesen Fehler hier bekommen:

Code: Alles auswählen

2018-08-14T19:25:10.321664+00:00 app[web.1]:   File "/app/app.py", line 38, in writedata

2018-08-14T19:25:10.321665+00:00 app[web.1]:     return render_template('file.html', test = open(csvfile, 'r').read())

2018-08-14T19:25:10.321666+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/codecs.py", line 321, in decode

2018-08-14T19:25:10.321667+00:00 app[web.1]:     (result, consumed) = self._buffer_decode(data, self.errors, final)

2018-08-14T19:25:10.321673+00:00 app[web.1]: UnicodeDecodeError: 'utf-8' codec can't decode byte 0x94 in position 4: invalid start byte
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@Hypec: Du brauchst das richtige Encoding, also das, mit dem Du die Datei geschrieben hast.

Nur weil eine Datei die Endung `csv` hat, ändert sich nichts auf magische Weise. Wenn Du csv-Dateien lesen oder schreiben willst, brauchst Du das csv-Modul.
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

Hab ich das nicht oben importiert?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Nur weil Du irgendwo ein Modul importierst, heißt das noch nicht, dass das dann überall verwendet wird. Lies mal die Dokumentation zum csv-Modul durch, wie das verwendet wird.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

@Hypec du scheinst noch eine Menge Verstaendnisprobleme zu haben. Das ist nicht weiter wild, hatte jeder mal. Eine Sache, mit der du dir selbst das Leben bestaendig schwerer machst ist der Versuch, gleich alles in ein grosses Ganzes zu giessen. Das geht in die Hose. Denn ob dein CSV-einlese-Code noch so gut funktioniert is irrelevant, wenn du zum gleichen Zeitpunkt ein Fehler in Flask oder JavaScript gebaut hast.

Schreib dir ein NEUES Skript, das NUR den einlese- und filter-Teil behandelt. Mit FUNKTIONEN die das machen. Benutz eine CSV-Datei, die so aussieht, wie sie aussehen SOLL, und nicht eine, die du durch andere Bugs irgendwie verfummelt produzierst. Wenn du die Datei dann einlesen und prozessieren kannst, kannst du dich dem naechsten Problem widmen - die Funktionen in deiner Flask Anwendung zu benutzen. Und danach irgendwann die Datei auch zu schreiben aus Flask heraus (wenn das ist was du willst, mir ist da noch vieles unklar).
Hypec
User
Beiträge: 183
Registriert: Mittwoch 1. August 2018, 16:11

@__deets__ ja du hast wahrscheinlich recht das ich mal wieder zu groß anfangen wollte. Dann schreib ich mir jetzt ein Script und wenn das läuft dann integrier ich es in flask.
Antworten