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

Montag 13. August 2018, 22:22

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: 1223
Registriert: Samstag 2. Juni 2018, 10:21

Montag 13. August 2018, 22:42

@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.
“Pets are always a great help in times of stress. And in times of starvation too, o'course.” — Terry Pratchett, Small Gods
Hypec
User
Beiträge: 72
Registriert: Mittwoch 1. August 2018, 16:11

Montag 13. August 2018, 22:56

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: 3477
Registriert: Mittwoch 14. Oktober 2015, 14:29

Montag 13. August 2018, 23:08

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: 72
Registriert: Mittwoch 1. August 2018, 16:11

Montag 13. August 2018, 23:16

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

Montag 13. August 2018, 23:25

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

Dienstag 14. August 2018, 07:24

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: 8412
Registriert: Sonntag 21. Oktober 2012, 17:20

Dienstag 14. August 2018, 09:11

@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: 72
Registriert: Mittwoch 1. August 2018, 16:11

Dienstag 14. August 2018, 14:34

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: 3477
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dienstag 14. August 2018, 14:43

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: 3477
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dienstag 14. August 2018, 14:45

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: 8412
Registriert: Sonntag 21. Oktober 2012, 17:20

Dienstag 14. August 2018, 14:50

@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: 1223
Registriert: Samstag 2. Juni 2018, 10:21

Dienstag 14. August 2018, 16:47

'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.
“Pets are always a great help in times of stress. And in times of starvation too, o'course.” — Terry Pratchett, Small Gods
Hypec
User
Beiträge: 72
Registriert: Mittwoch 1. August 2018, 16:11

Dienstag 14. August 2018, 20:30

@__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: 8412
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 15. August 2018, 07:23

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