Python Text splitten und auf Display ausgeben(Raspberry)

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Antworten
error404
User
Beiträge: 18
Registriert: Montag 24. Oktober 2016, 09:14

Hallo Community,

ich bin leider noch ein Beginner, was Python angeht, daher würde ich mich sehr über hilfe freuen :). Also, ich wollte mit Python ein Script erstellen, welches mit Text auf einem Display ausgibt. Ich scheitere leider daran, das ich nicht weiß, wie ich einer Variable(z1, z2) sagen kann, dass aus der Textdatei der Text, welcher in der 1. Zeile steht in eine Variable gespiechert wird und der Text der in der 2. Zeile steht in der zweiten Variable gespeichert wird und so weilter ...

So habe ich mir das gedacht:

Code: Alles auswählen

import lcddriver
from time import *
lcd = lcddriver.lcd()
f =open("test", "r")

lcd.lcd_clear()
lcd.lcd_display_string("------SD-Karte------", 1)
lcd.lcd_display_string("Text der ersten zeile aus der Textdatei", 2)
lcd.lcd_display_string("Text der zweiten zeile aus der Textdatei", 3)
lcd.lcd_display_string("Text der dritten zeile aus der Textdatei", 4)
sleep(10)
So sieht mein Script bis jetzt aus, funktioniert halt leider nicht:

Code: Alles auswählen

#--------------------------------#
import lcddriver
from time import *

lcd = lcddriver.lcd()
with open("test") as f:
        z1 =f.readlines()[0:1]
        z2 =f.readlines()[1:2]
#--------------------------------#
lcd.lcd_clear()
sleep(0.5)
lcd.lcd_display_string("------SD-Karte------", 1)
lcd.lcd_display_string( str(z1), 2)
lcd.lcd_display_string( str(z2), 3)

sleep(10)
lcd.lcd_clear()
Zuletzt geändert von Anonymous am Montag 24. Oktober 2016, 11:17, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Benutzeravatar
noisefloor
User
Beiträge: 3843
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

wenn du eine Textdatei mit X Zeilen hast (also beliebiger Länge), dann möchtest du die Zeilen nicht in einzelnen Variablen speichern, sondern einer Liste. Die ist dafür gemacht.

Je nach dem, was du vor hast, macht es aber vielleicht mehr Sinn, zeilenweise über die Eingabedatei zu iterieren statt wie du es im Moment machst, alles mit `readlines()`einzulesen.

Was hast du denn vor? Im Moment nutzt dein Code ja auch "nur" die ersten beiden Zeilen. Willst du die Datei zeilenweise auf dem Display ausgeben?

Gruß, noisefloor
BlackJack

@error404: `readlines()` kannst Du *einmal* auf einer geöffneten Datei aufrufen, dann sind alle Zeilen in eine Liste eingelesen und der Zeiger in der Datei steht am Ende, nach der letzten Zeile. Jedes weitere lesen liefert die leere Zeichenkette, weil das nichts mehr kommt nach dem Ende der letzten Zeile.

Du müsstest die Zeilen einzeln lesen und an die Namen binden. Also Beispielsweise:

Code: Alles auswählen

z1 = next(f)
z2 = next(f)
Allerdings ist das durchnummerieren von Namen ein „code smell“. Das ist in der Regel eine Zeichen, dass man gar keine einzelnen Namen haben möchte, sondern eine Datenstruktur. Oft ist das eine Liste.

Wenn man eine Liste hat und *ein* Element daraus haben möchte, sollte man einen Indexwert verwenden und nicht die Slice-Syntax, die wieder eine Liste liefert. Wenn man einen Ausdruck hat bei dem grundsätzlich eine Liste mit *einem* Element heraus kommt, dann braucht man diese einelementige Liste nicht. Falls es das jeweilige Element in der Ursprungsliste nicht zwingend gibt, sollte man besser den `IndexError` behandeln, oder vorher explizit dafür sorgen, dass alle Elemente mit sinnvollen Werten belegt sind.

Die `str()`-Aufrufe mit `z1` und `z2` sind falsch. Du willst hier das Element aus der Liste holen, statt die Liste mit dem einen Element in ihre Zeichenkettendarstellung umzuwandeln.

Wenn man nur `sleep()` aus dem `time`-Modul benötigt, dann sollte man nicht mit dem Sternchen *alles* aus dem Modul importieren. Das macht Programme unübersichtlicher und birgt die Gefahr von Namenskollisionen.

Ungetestet:

Code: Alles auswählen

from itertools import chain, islice
from time import sleep
import lcddriver


def main():
    lcd = lcddriver.lcd()
    lcd.lcd_clear()
    sleep(0.5)
    with open('test.txt') as lines:
        for i, line in enumerate(islice(chain(['------SD-Karte------'], lines), 4), 1):
            lcd.lcd_display_string(line.rstrip(), i)
    sleep(10)
    lcd.lcd_clear()


if __name__ == '__main__':
    main()
error404
User
Beiträge: 18
Registriert: Montag 24. Oktober 2016, 09:14

noisefloor hat geschrieben: Was hast du denn vor? Im Moment nutzt dein Code ja auch "nur" die ersten beiden Zeilen. Willst du die Datei zeilenweise auf dem Display ausgeben?
Gruß, noisefloor
Genau das will ich. Der Text der Textdatei ist halt in den Zeilen Gegliedert.
Beispiel Textdatei:
Zeile1: Kuchen
Zeile2: 500Gramm Mehl
Zeile3: 3 Eier
Zeile4: 2El Zucker

Dies soll dann so auf dem Display Ausgegeben werden:
Kuchen
500Gramm Mehl
3 Eier
2El Zucker

Vielen herzlichen Dank für eure Hilfe. Hat nun soweit alles geklappt :)
Antworten