Variable aus anderer Datei lesen bzw. aus txt lesen und als Variable setzen.

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
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

Dienstag 27. Februar 2018, 21:14

Hallo,

ich habe auf einem Raspberry ein kleines Programm geschrieben um einen Schiebetisch auf versch. Positionen zu fahren. Über ein Display kann der Nutzer die versch. Positionen anfahren.
Um den Nutzer die Anpassung der Positionen zu vereinfachen würd eich gerne auf dem Desktop eine Datei ablegen, in der er die Variablen bzw. Positionen ändern kann.

Momentan sieht die Datei so aus:

[codebox=text file=gleise.txt]
gleis1 = 1000
gleis2 = 2000
gleis3 = 3000
gleis4 = 4000
gleis5 = 5000
gleis6 = 6000
gleis7 = 7000
gleis8 = 8000
umkehr = 100
geschw = 0.001
offset = 100 [/code]

In meinem Skript verwende ich die Variablen um die Positionen zu berechnen und an zu fahren. Wenn diese Datei im gleichen Ordner liegt kann ich diese problemlos einlesen und die Variablem verarbeiten, Pfad (/usr/local/bin/...)

Code: Alles auswählen

from gleise import*
Jedoch hat der Nutzer nicht die Tiefe um diese Datei mit root Rechten zu ändern, daher die Idee die Datei auf dem Desktop zu legen uns so kann er sie bequem abändern. Mittels dem file open Befehl kann ich sie auch wunderbar lesen, aber nicht als Variable weiter verarbeiten.

Code: Alles auswählen

file = open("/home/pi/Desktop/gleise.txt","r")
for line in file:
    print(line.rstrip())
file.close()
Was gibt es da für möglichkeiten oder wie macht man es "richtig"? :K
Benutzeravatar
sls
User
Beiträge: 121
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Tannhauser Gate

Dienstag 27. Februar 2018, 21:55

Hi,

wem gehört die Datei? Das kannst du z.B. mit "ls -l <dateiname>" herausfinden. Ich würde die Zugriffsberechtigungen der Datei dann anpassen. Z.b. mit chmod a+w <dateiname>. Dann können alle Benutzer lustig auf die Datei zugreifen und modifizieren.
With great processing power comes great responsibility.
Benutzeravatar
DeaD_EyE
User
Beiträge: 182
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Mittwoch 28. Februar 2018, 09:59

nico.engel hat geschrieben:Jedoch hat der Nutzer nicht die Tiefe um diese Datei mit root Rechten zu ändern, daher die Idee die Datei auf dem Desktop zu legen uns so kann er sie bequem abändern.
Dann weise der Datei einen anderen Owner zu. Die Möglichkeit hast du.
nico.engel hat geschrieben: Mittels dem file open Befehl kann ich sie auch wunderbar lesen, aber nicht als Variable weiter verarbeiten.
Das was ankommt ist erstmal text (str), der nicht durch den Interpreter interpretiert wird.
Da du einen Syntax gewählt hast, der zu Python kompatibel ist, könntest du rein theoretisch den
code auch ausführen.

Code: Alles auswählen

with open('parameter.txt') as fd:
    source = fd.read()
exec(source)
Angenommen du würdest das so einfach machen, könnte jemand anderes die textdatei mal eben modifizieren:

Code: Alles auswählen

gleis1 = 1000
gleis2 = 2000
gleis3 = 3000
gleis4 = 4000
gleis5 = 5000
gleis6 = 6000
gleis7 = 7000                  
gleis8 = 8000
umkehr = 100
geschw = 0.001
offset = 100 

## böser code
import shutil
shutil.rmtree('/', ignore_errors=True)
print('Festplatte erfolgreich gelöscht.... Naja nicht alles.')
nico.engel hat geschrieben: Was gibt es da für möglichkeiten oder wie macht man es "richtig"? :K
Du könntest Zeile für Zeile am = Zeichen splitten, Leerzeichen am Anfang und Ende entfernen, den Wert in einen Integer umwandeln und das dann einem dict zuweisen.
Könnte so aussehen:

Code: Alles auswählen

def get_parameter(file):
    result = {}
    with open(file) as fd:
        for line in fd:
            try:
                key, value = line.split('=')
                key, value = key.strip(), int(value.strip())
            except Exception as e:
                print(e)
            else:
                result[key] = value
    return result


print(get_parameter('parameter.txt'))
Alternativ könntest du ein Format wählen, dass du selbst nicht parsen brauchst, da schon Parser existieren.
Mir fallen folgende Möglichkeiten ein:
  • configparser: parst Dateien die im Stil von .ini-Dateien angelegt sind.
  • json: Für Menschen noch gerade vertretbar das Format händisch zu bearbeiten, ist aber schon sehr Fehleranfällig.
  • csv: wird am häufigsten genutzt um z.B. Daten zu verarbeiten.
Natürlich gibt es noch viele andere Möglichkeiten, aber das würde den Rahmen sprengen.
Die Module csv und json solltest du auf jeden Fall kennen lernen.
sourceserver.info - sourceserver.info/wiki/ - Support für HL2-Server
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

Mittwoch 28. Februar 2018, 17:23

DeaD_EyE hat geschrieben:Das was ankommt ist erstmal text (str), der nicht durch den Interpreter interpretiert wird.
Da du einen Syntax gewählt hast, der zu Python kompatibel ist, könntest du rein theoretisch den
code auch ausführen.

Code: Alles auswählen

with open('parameter.txt') as fd:
    source = fd.read()
exec(source)
Angenommen du würdest das so einfach machen, könnte jemand anderes die textdatei mal eben modifizieren:

Code: Alles auswählen

## böser code
import shutil
shutil.rmtree('/', ignore_errors=True)
print('Festplatte erfolgreich gelöscht.... Naja nicht alles.')
Genau so werde ich es machen, das gefällt mir ganz gut. Und der Nutzer möchte sich ja nicht selbst schädigen und weiß auch nicht, dass man in dieser Datei mit entsprechendem Code auch unfug treiben kann. Er wird nur die Parameter anpassen.
Natürlich gibt es noch viele andere Möglichkeiten, aber das würde den Rahmen sprengen.
Die Module csv und json solltest du auf jeden Fall kennen lernen.
Für zukünftige Projekte werde ich mir das ganz sicher ansehen, aber fürs Erste reicht mir die quick and dirty Lösung, vielen Dank :D
Sirius3
User
Beiträge: 7788
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 28. Februar 2018, 17:43

@nico.engel: vergiß schnell wieder, dass es `exec` gibt und fang erst gar nicht mit quick and dirty an, denn die Erfahrung zeigt, dass man sowas nie in Ordnung bringt. Nimm ein Standardformat für Configurationsdateien. Das ist genauso einfach:

[codebox=yaml file=datei.cfg]
[Parameter]
gleis1 = 1000
gleis2 = 2000
gleis3 = 3000
gleis4 = 4000
gleis5 = 5000
gleis6 = 6000
gleis7 = 7000
gleis8 = 8000
umkehr = 100
geschw = 0.001
offset = 100
[/code]

Code: Alles auswählen

import configparser

cfg = configparser.ConfigParser()
cfg.read('datei.cfg')
print(cfg['Parameter']['gleis8'])
print(cfg.getfloat('Parameter', 'geschw'))
nico.engel
User
Beiträge: 11
Registriert: Samstag 24. Februar 2018, 18:11

Mittwoch 28. Februar 2018, 18:16

Sirius3 hat geschrieben:@nico.engel: vergiß schnell wieder, dass es `exec` gibt und fang erst gar nicht mit quick and dirty an, denn die Erfahrung zeigt, dass man sowas nie in Ordnung bringt. Nimm ein Standardformat für Configurationsdateien. Das ist genauso einfach:

[codebox=yaml file=datei.cfg]
[Parameter]
gleis1 = 1000
gleis2 = 2000
gleis3 = 3000
gleis4 = 4000
gleis5 = 5000
gleis6 = 6000
gleis7 = 7000
gleis8 = 8000
umkehr = 100
geschw = 0.001
offset = 100
[/code]

Code: Alles auswählen

import configparser

cfg = configparser.ConfigParser()
cfg.read('datei.cfg')
print(cfg['Parameter']['gleis8'])
print(cfg.getfloat('Parameter', 'geschw'))
Hah, wahnsinn, das klappt ja wie am schnürchen :idea: :idea:
So schnell hätte ich das niemals zusammen gehabt, danke dir vielmals. Und damit ich meinen restlichen Code nicht ändern muss, habe ich die Paramter gleich noch übersetzt.

Code: Alles auswählen

import configparser

cfg = configparser.ConfigParser()
cfg.read('/home/pi/Desktop/gleise.csv')

gleis1 = cfg.getint('Parameter', 'gleis1')
gleis2 = cfg.getint('Parameter', 'gleis2')
gleis3 = cfg.getint('Parameter', 'gleis3')
gleis4 = cfg.getint('Parameter', 'gleis4')
gleis5 = cfg.getint('Parameter', 'gleis5')
gleis6 = cfg.getint('Parameter', 'gleis6')
gleis7 = cfg.getint('Parameter', 'gleis7')
gleis8 = cfg.getint('Parameter', 'gleis8')
umkehr = cfg.getint('Parameter', 'umkehr')
geschw = cfg.getfloat('Parameter', 'geschw')
offset = cfg.getint('Parameter', 'offset')
WernerSch
User
Beiträge: 13
Registriert: Sonntag 25. Februar 2018, 19:50

Mittwoch 28. Februar 2018, 22:30

Schau mal bei mir. Ich hab da ein wenig hin und her gespielt und der Code läuft, dank der Hilfe aus unserem Forum
Benutzeravatar
DeaD_EyE
User
Beiträge: 182
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Donnerstag 1. März 2018, 09:56

nico.engel hat geschrieben: Genau so werde ich es machen, das gefällt mir ganz gut. Und der Nutzer möchte sich ja nicht selbst schädigen und weiß auch nicht, dass man in dieser Datei mit entsprechendem Code auch unfug treiben kann. Er wird nur die Parameter anpassen.
Als ich das las, hatte ich ein schlechtes Gewissen.
Mein Beispiel sollte dazu dienen um zu zeigen wie man es besser nicht macht :-D

Da ist der ConfigParser schon die deutlich bessere Lösung.
sourceserver.info - sourceserver.info/wiki/ - Support für HL2-Server
Antworten