Habe ein Problem
habe eine datei erhalten die aus zwei spalten zahlenwerten besteht nun meine frage:
Das öffnen und ausgeben der datei in python ist kein problem.
nur soll die datei ausgelesen werden und auf einen bestimmten zahlenwert durchsucht werden
und pyhton soll eine warnung ausgeben wenn der gesuchte zahlenwert gefunden wird.
bei diesem zahlenwert ist nur die zweite spalte zu durchsuchen
habe mir das so gedacht die datei in eine liste einzufügen und diese liste dann mit einer while funktion
durchsuchen zu lassen.
mein problem ist nur das ich nach einer woche erfolglosen versuchen es nicht schaffte diese datei in eine liste einzufügen.
könnt ihr mir helfen??
Danke für eure antworten
Datei bestehend aus Zahlenwerten und zwei Spalten
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Hier eine Session mit einer groben Loesung:
Die Datei in eine Liste einzulesen ist unnoetig, wenn du keinen Kontext fuer die Zahl brauchst, also immer nur die aktuelle Zeile wichtig ist. Funktionieren wuerde es aber mit `file.readlines`.
Code: Alles auswählen
In [7]: from StringIO import StringIO
In [8]: file_ = StringIO("""42 23
5 32
23 42""")
In [9]: target = '42'
In [10]: for line in file_:
....: first, second = line.split()
....: if second == target:
....: print 'target found'
....: break
....:
target found
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
@martinr.: Das sind eigentlich Grundoperationen und wenn man ein Tutorial durchgearbeitet hat, käme man wohl auch nicht auf die Idee eine Liste mit einer ``while``-Schleife zu verarbeiten. Arbeite mal ein Tutorial durch. Zum Beispiel das in der Python-Dokumentation oder für Anfänger wird Learn Python The Hard Way oft empfohlen.
Teile das Problem in kleinere Teilprobleme auf und löse die dann stückweise. Immer erst mit dem nächsten Stück weiter machen, wenn das bisherige Teilprogramm läuft, und das tut was es soll.
Man kann mit einem Programm anfangen was gar nichts tut. Dann eines was die Datei öffnet und die Zeilen ausliest und einfach ausgibt. Testen! Dann so erweitern das die Zeile in ihre Bestandteile aufgeteilt wird und die ausgegeben werden. Testen! Dann nur den Teil mit der zweiten Spalte nehmen und in eine Zahl umwandeln und ausgaben. Testen! Diese Zahl gegen den Suchwert testen und falls die gesuchte Zahl gefunden wurde, das irgendwie in der Ausgabe kenntlich machen. Testen. Jetzt kann man überlegen ob man mit einem ”Flag” arbeiten möchte das man am Anfang mit `False` initialisiert und auf `True` setzt wenn man den Wert gefunden hat, oder ob man das bisherige in eine Funktion steckt und im Fundfall `True` zurück gibt, und im anderen Fall `False`.
Wenn der Test — ob nun per Flag oder als Rückgabewert einer Funktion — wahr ist, kann man eine Warnung ausgeben.
Teile das Problem in kleinere Teilprobleme auf und löse die dann stückweise. Immer erst mit dem nächsten Stück weiter machen, wenn das bisherige Teilprogramm läuft, und das tut was es soll.
Man kann mit einem Programm anfangen was gar nichts tut. Dann eines was die Datei öffnet und die Zeilen ausliest und einfach ausgibt. Testen! Dann so erweitern das die Zeile in ihre Bestandteile aufgeteilt wird und die ausgegeben werden. Testen! Dann nur den Teil mit der zweiten Spalte nehmen und in eine Zahl umwandeln und ausgaben. Testen! Diese Zahl gegen den Suchwert testen und falls die gesuchte Zahl gefunden wurde, das irgendwie in der Ausgabe kenntlich machen. Testen. Jetzt kann man überlegen ob man mit einem ”Flag” arbeiten möchte das man am Anfang mit `False` initialisiert und auf `True` setzt wenn man den Wert gefunden hat, oder ob man das bisherige in eine Funktion steckt und im Fundfall `True` zurück gibt, und im anderen Fall `False`.
Wenn der Test — ob nun per Flag oder als Rückgabewert einer Funktion — wahr ist, kann man eine Warnung ausgeben.
Code: Alles auswählen
from itertools import islice
num = 17
with open('numbers.txt') as fl:
found = any(float(x)==num for x in islice(fl.read().split(),1,None,2))
So hier ist mein programmcode funktioniert wie es soll nur möchte eine kleine verbesserung vornehmen um es dem "nutzer " zu ermöglichen verschieden aufgebaute dateien zu verwenden
in der for schleife habe ich dem programm vorgeben zwischen welchen indizes das programm den grenzwert suchen soll
nun wäre es natürlich einfacher wenn man einfach sagen könnte suche ab ";" oder eben ab einem anderen trennungszeichen nach diesem grenzwert .
wie bekomme ich das hin ?
danke für eure hilfe
Code: Alles auswählen
werte = open("daten_zweiseitig.txt","r") # lISTE OEFFNEN
zeilenweise = werte.readline() # Daten zeilenweise auslesen
einzelzeile = zeilenweise.strip () # Jede Zeile einzeln auslesen
li = einzelzeile.split(";") # Zeile separiern
print "Programm gestartet!"
for li in werte:
if li [9:19] >= "5,8":
print "!!!!!!Ueberlast erreicht!!!!!!",li,"\a"
u = raw_input("druecke Enter zur Kenntnisnahme der Ueberlast")
else :
print "Gewicht im Rahmen ",li
b=raw_input("Programm beendet!")
nun wäre es natürlich einfacher wenn man einfach sagen könnte suche ab ";" oder eben ab einem anderen trennungszeichen nach diesem grenzwert .
wie bekomme ich das hin ?
danke für eure hilfe
Zuletzt geändert von Anonymous am Montag 26. November 2012, 13:24, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Grund: Quelltext in Python-Code-Tags gesetzt.
@martinr.: Erst einmal solltest Du das vorhandene Programm korrigieren. Die Kommentare passen teilweise ünerhaupt nicht zu dem was der Code tatsächlich tut. Die Datei wird in der zweiten Zeile zum Beispiel nicht zeilenweise ausgelesen, sondern nur die allererste Zeile wird gelesen.
`strip()` liest auch keine Zeilen. Und ein ``split(';')`` separiert keine Zeilen.
Zudem werden die Werte, die `zeilenweise`, `einzelzeile`, und `li` am Anfang zugewiesen werden, später überhaupt gar nicht verwendet. `li` ist zudem ein schlechter Name. Namen sollten dem Leser die Bedeutung des Wertes dahinter vermitteln. `werte` ist dementsprechend auch kein guter Name, denn auch wenn in der Datei Werte stecken, verarbeitet der Code aus diesem Objekt keine Werte sondern Zeilen (mit Werten).
Bei dem ``if`` vergleichst Du Zeichenketten, was sicher nicht das ist was Du haben möchtest. Beispiel:
Zeichenketten werden zeichenweise lexikografisch verglichen (je nach Zeichenkettentyp nach Bytewert oder Unicode-Codepoint) und das Zeichen '1' ist kleiner als das Zeichen '5', damit ist '10,4' kleiner als '5,8'. Du musst die Werte hier in den richtigen Datentyp, also `float` umwandeln um sie sinnvoll vergleichen zu können.
Werte die nirgends verwendet werden, sollte man entweder gar nicht nicht zuweisen oder das kenntlich machen. Konventionell wird der Name `_`, `dummy`, oder `unused` dafür verwendet, oder man verwendet einen *sinvollen* Namen und stellt dem einen Unterstrich vor (diese Konvention ist nicht so weit verbreitet). Ich würde im Fall von `u` und `b` die Zuweisung einfach komplett weg lassen.
Die letzte Zeile ist nur nötig wenn man ein Kommandozeilenprogramm nicht auf der Kommandozeile startet. Dafür sind die aber gedacht, also sollte man sie dort auch starten und damit ist die Zeile überflüssig. Sie hilft zum Beispiel auch nicht wenn Fehler enthalten sind, die zu einer Ausnahme führen.
Die Frage am Schluss ist sehr vage gestellt. Das bekommt man grundsätzlich hin, in dem man Code schreibt der das tut. Dazu haben Zeichenketten Methoden, die man in solchem Code verwenden kann. Wenn es komplexere Muster sind, kann man die mit dem `re`-Modul ausdrücken. Sollten die Muster *richtig* komplex werden, dann werden reguläre Ausdrücke unlesbar, dann sollte man eine Parsergenerator-Bibliothek wie zum Beispiel `pyparsing` verwenden.
Wenn Teile von so einer Operation variabel sein sollen, macht man diese zu Argumenten einer Funktion, welche die Operation implementiert. Wenn man die ganze Operation flexibel halten möchte, sieht man die Möglichkeit vor, dass eine Funktion an die Funktion übergeben wird, die die Datei verarbeitet.
`strip()` liest auch keine Zeilen. Und ein ``split(';')`` separiert keine Zeilen.
Zudem werden die Werte, die `zeilenweise`, `einzelzeile`, und `li` am Anfang zugewiesen werden, später überhaupt gar nicht verwendet. `li` ist zudem ein schlechter Name. Namen sollten dem Leser die Bedeutung des Wertes dahinter vermitteln. `werte` ist dementsprechend auch kein guter Name, denn auch wenn in der Datei Werte stecken, verarbeitet der Code aus diesem Objekt keine Werte sondern Zeilen (mit Werten).
Bei dem ``if`` vergleichst Du Zeichenketten, was sicher nicht das ist was Du haben möchtest. Beispiel:
Code: Alles auswählen
In [210]: '10,4' > '5,8'
Out[210]: False
Werte die nirgends verwendet werden, sollte man entweder gar nicht nicht zuweisen oder das kenntlich machen. Konventionell wird der Name `_`, `dummy`, oder `unused` dafür verwendet, oder man verwendet einen *sinvollen* Namen und stellt dem einen Unterstrich vor (diese Konvention ist nicht so weit verbreitet). Ich würde im Fall von `u` und `b` die Zuweisung einfach komplett weg lassen.
Die letzte Zeile ist nur nötig wenn man ein Kommandozeilenprogramm nicht auf der Kommandozeile startet. Dafür sind die aber gedacht, also sollte man sie dort auch starten und damit ist die Zeile überflüssig. Sie hilft zum Beispiel auch nicht wenn Fehler enthalten sind, die zu einer Ausnahme führen.
Die Frage am Schluss ist sehr vage gestellt. Das bekommt man grundsätzlich hin, in dem man Code schreibt der das tut. Dazu haben Zeichenketten Methoden, die man in solchem Code verwenden kann. Wenn es komplexere Muster sind, kann man die mit dem `re`-Modul ausdrücken. Sollten die Muster *richtig* komplex werden, dann werden reguläre Ausdrücke unlesbar, dann sollte man eine Parsergenerator-Bibliothek wie zum Beispiel `pyparsing` verwenden.
Wenn Teile von so einer Operation variabel sein sollen, macht man diese zu Argumenten einer Funktion, welche die Operation implementiert. Wenn man die ganze Operation flexibel halten möchte, sieht man die Möglichkeit vor, dass eine Funktion an die Funktion übergeben wird, die die Datei verarbeitet.
So hab jzt ein bisschen probiert und hoffe jetzt sind die groben schnitzer ausgebessert.
so hab nun das problem das zwei dateien mit verschiedenen trennzeichen habe , die erste datei ist kein problem da die zwei spalten einfach durch ein ; getrennt werden und durchgehend symmetrisch aufgebaut ist .
Bei dder zweiten datei jedoch ist das trennzeichen ein leerzeichen da aber mehrere an der anzahl unregelmäßig aukommende leerzeichen vorkommen bekomme ich dich meldung das es zu viele dateien wären die geöffnet werden müssten ,da pyhton an jedem leerzeichen trennt .
das ist der grobe aufbau der datei :
0 -0,353099
0,00005 -0,355661
0,0001 -0,351497
0,00015 -0,35438
0,0002 -0,347973
0,00025 -0,349895
0,0003 -0,34605
0,00035 -0,349254
0,0004 -0,347652
0,00045 -0,352458
0,0005 -0,349895
0,00055 -0,355021
dachte daran eine replace funktion anzuweden um die unnötigen leerzeichen in der ersten spalte durch nullen zu ersetzen
Danke für eure hilfe bis jetzt und für die weitere
Code: Alles auswählen
import time
z = raw_input ("Trennzeichen eingeben")
dateisatz = open ("daten_sprunanregung.txt","r")
allezeilen = dateisatz.readline()
einezeile = allezeilen.strip()
first = float()
second = float()
grenzwert = float()
grenzwert ="5,800000"
raw_input ("Programm starten")
for line in dateisatz:
first, second = line.split (z)
if second >= grenzwert :
print"Ueberlast erreicht bei ->", "\a"
print"Zeit in sec :"+ first
print"Spannung in V:"+ second
time.sleep (2)
else :
print"Gewicht im Rahmen!->",first , second
raw_input ("Programm beendet")
Bei dder zweiten datei jedoch ist das trennzeichen ein leerzeichen da aber mehrere an der anzahl unregelmäßig aukommende leerzeichen vorkommen bekomme ich dich meldung das es zu viele dateien wären die geöffnet werden müssten ,da pyhton an jedem leerzeichen trennt .
das ist der grobe aufbau der datei :
0 -0,353099
0,00005 -0,355661
0,0001 -0,351497
0,00015 -0,35438
0,0002 -0,347973
0,00025 -0,349895
0,0003 -0,34605
0,00035 -0,349254
0,0004 -0,347652
0,00045 -0,352458
0,0005 -0,349895
0,00055 -0,355021
dachte daran eine replace funktion anzuweden um die unnötigen leerzeichen in der ersten spalte durch nullen zu ersetzen
Code: Alles auswählen
line = line.replace(" ",0[0:6])
Hallo martin
Hast Du Dein Programm nur einmal laufen lassen???? So wie es da steht ist es voller Fehler.
1) Vor der Klammer "(" bei Funktionsaufrufen wird kein Leerzeichen gesetzt.
2 ) in Python werden keine Variablen deklariert, die Zeilen mit xyz=float() sind also nicht nur überflüssig sonder auch vollkommen unsinnig.
3) Dann setzt du den "grenzwert" als String, so dass der Vergleich >= mit Strings wieder, wie schon von Blackjack beschrieben, unsinnige Ergebnisse liefert.
4) um nach Leerzeichen zu splitten wird ein split ohne Argument verwendet, dann hast Du auch kein Problem mit Leerzeichen am Zeilenanfang, Tabs, usw.
5) alle allezeilen ist eine Liste. Liste haben keine strip-Funktion.
6) das Trennzeichen interaktiv zu lesen, den Dateinamen aber hardcodiert reinschreiben, was macht das für Sinn?
Grüße
Sirius
Hast Du Dein Programm nur einmal laufen lassen???? So wie es da steht ist es voller Fehler.
1) Vor der Klammer "(" bei Funktionsaufrufen wird kein Leerzeichen gesetzt.
2 ) in Python werden keine Variablen deklariert, die Zeilen mit xyz=float() sind also nicht nur überflüssig sonder auch vollkommen unsinnig.
3) Dann setzt du den "grenzwert" als String, so dass der Vergleich >= mit Strings wieder, wie schon von Blackjack beschrieben, unsinnige Ergebnisse liefert.
4) um nach Leerzeichen zu splitten wird ein split ohne Argument verwendet, dann hast Du auch kein Problem mit Leerzeichen am Zeilenanfang, Tabs, usw.
5) alle allezeilen ist eine Liste. Liste haben keine strip-Funktion.
6) das Trennzeichen interaktiv zu lesen, den Dateinamen aber hardcodiert reinschreiben, was macht das für Sinn?
Grüße
Sirius
Nicht alles davon sind echte Fehler, aber es sind einige Abweichungen von Python Style Guide vorhanden. Natürlich kann man von Style Guide abweichen wenn es gute Gründe gibt, aber die Gründe sehe ich hier nicht.Sirius3 hat geschrieben:So wie es da steht ist es voller Fehler.
PEP-8 -- Style Guide for Python Code hilft ungemein bei einem konsistenten Stil und ermöglicht es anderen, den Code schneller zu erfassen.
Ich ergänze mal die Anmerkungen von Sirius3 (Doppler können vorkommen).martinr. hat geschrieben:So hab jzt ein bisschen probiert und hoffe jetzt sind die groben schnitzer ausgebessert.
Du öffnest die Datei und schließt sie nicht wieder. Mit with wäre dir das nicht passiert.
Du liest eine Zeile aus der Datei und bindest sie an den Bezeichner allezeilen. Die Zeile ignorierst du damit in der folgenden Schleife völlig. Es mag ja Absicht sein die erste Zeile bei der Verarbeitung zu überspringen, aber das ist nirgendwo dokumentiert und so gehe ich von einem Fehler aus.
Du erstellst aus allezeilen einen String einezeile ohne führende und endende Whitespaces. Anschließend verwendest du diesen Wert nie mehr.
Überflüssiges Binden von Bezeichnern an floats.
Gemeingefährlicher Umgang mit dem Grenzwert. Das muss ein float sein, kein String. Natürlich musst du dann beim Vergleich den eingelesenen Wert auch in ein float konvertieren, aber überlege dir mal was sonst passiert, wenn der eingelesene Wert "10.0000" ist. Dieser Wert würde mit deiner Lösung nicht als Fehler erkannt.
Nach dem Programmaufruf noch mal ein zu bestätigender Hinweis "Programm starten". Ist das Teil eines neuen Evangeliums? "Alles was du von deinem Rechner willst sollst du dreimal mit OK bestätigen!"?
Statt first und second würde ich deskriptive Namen wählen. seconds für die Sekunden und volt für die Spannung.
Die print-Statements kann man mit Stringformatierung schöner gestalten.
Ein erster schneller Entwurf für aufgeräumteren Code sähe dann so aus:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
from __future__ import print_function
import time
grenzwert = 5.8
warning_message = """Überlast erreicht bei ->\a
Zeit in Sekunden: {seconds}
Spannung in V : {volt}"""
with open('daten_sprunanregung.txt', 'r') as datafile:
for line in datafile:
seconds, volt = line.split()
if float(volt.replace(',', '.')) >= grenzwert:
print(warning_message.format(seconds=seconds, volt=volt))
time.sleep(2)
else:
print('Gewicht im Rahmen! -> {} {}'.format(seconds, volt))
raw_input('Programm beendet')
Alternativ könnte man natürlich auch die Datei vorher parsen um den Trenner automatisch durch das Programm feststellen zu lassen.