Digitaler Warenkorb mit NFC Tags in einer Liste darstellen

Python auf Einplatinencomputer wie Raspberry Pi, Banana Pi / Python für Micro-Controller
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Hallo liebe Community!



Mein Projekt handelt von einem digiatlen Warenkorb. Ich verwende dazu einen Raspberry Pi Modell B+ und oben drauf als Lesegerät von NXP Element14. Tags verwende ich: NFC Tags (ntag216) und dort speichere ich einen Text (zb:. Paprika).

Durch das Programm von der Seite: https://www.nxp.com/webapp/sps/download/preDownload.jsp (explorenfc-basic) gibt es mir die auf dem Tag gespeicherten Daten aus. Hier meine konkrete Frage:

Kann man die Dateien die das Gerät ausliest, auf einer Liste darstellen? Ich habe einen gefühlten Tag danach im Internet gesucht und nichts dazu gefunden.

Also es ist wie ein Warenkorb bei einem Supermarkt. Legt man einen Gegenstand dazu (scannt ihn mit dem reader ein), erscheint er eben in einer Liste. Und wenn man ihn wieder rausnimmt (scannt den gleichen nfc tag wieder), wird er aus der Liste gelöscht.

Aber dazu habe ich wie gesagt nie etwas gefunden, die Daten die der Reader aus den Tags rausliest, in einer Liste darstellbar sind oder überhaupt weiterverarbeitet werden können.

Ich hoffe einer weiß was ich damit meine, und bin über jegliche Hilfe dankbar. (Außerdem programmiere ich in Python), ich habe es zwar geschafft, den Inhalt eines Tags der gerade gelesen wird, als Text datei auszugeben und wo zu speichern, aber nicht mit einer Liste, wo viele drinnen sind und wo die dann wieder gelöscht werden.

Nochmals wäre ich dankbar, wenn sich jmd damit auskennt und mir Lösungen sagen könnte.



LG Paraya
BlackJack

@Paraya21: Kann es sein, dass man sich bei der verlinkten Seite anmelden muss um etwas herunterladen zu können? Ohne mehr Informationen die einfach zugänglich sind, dürfte es schwer werden zu helfen.
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Hallo Paraya,

ganz grundsätzlich kann man erstmal alle Daten in einer Liste sammeln, ja.

Die Darstellung für den Benutzer kann dann nochmal eine Herausforderung werden.

Das Einfügen und Entfernen beim mehrmaligen Scannen wird es vermutlich nicht als "fertiges" Tutorial irgendwo geben, das müsstest du vielleicht selbst programmieren. Klingt aber halbwegs leicht machbar. :mrgreen:
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Ja klar, kann man grundsätzliches vieles in Listen darstellen, doch ich weiß nicht, wie ich das angehen
soll, da ich jetzt nicht so ein Profi beim Raspberry Pi bin. Mein einziges Problem ist, dass ich
die Tags einlese und die Message von dem Tag soll am Raspberry Pi in einer Art liste einfach ausgegeben
werden. Da muss noch iwie machbar sein. Wäre sehr lieb, wenn mir einer helfen würde ;(
Verwende den Raspberry Pi modell b+ mit dem Element14 board drauf(damit man die Nfc tags lesen kann).
Tags: nTag 216.
BlackJack

@Paraya21: Mir ist die Problembeschreibung ja irgendwie noch viel zu vage. Welches ganz konkrete Problem mit welchem ganz konkreten Code hast Du denn jetzt?

Und wir scheinen bezüglich Listen ein wenig aneinander vorbei zu reden. Ich, und ich denke auch Kebap, denken bei dem Wort an den Datentyp `list` in Python. Jetzt habe ich aber den Verdacht Du meinst damit die Anzeige in Form einer Liste‽ Da stellt sich dann die nächste Frage wie die genau aussehen soll‽ Textbasiert? GUI? Welches GUI-Rahmenwerk?
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Ja mit der Liste meinte ich nicht den list befehl, sondern eher wie man die Daten der Tags in einer Liste darstellen kann.
Mit dem command: explorenfc-basic >> mains.txt
liest er mir folgendes aus:
Waiting for tag or device...
on_name_lost(): :org.neardal
Found record /org/neard/nfc0/tag0/record0
Record type: Text
URI:
Title: Kugelschreiber
Action:
Language: de
Encoding: UTF-8
<noch irgendwelche nummern, wie uid>

So erstens möchte ich, dass es mir hier nur den Titel: Kugelschreiber rausliest. Wäre sehr nett, wenn dieses Problem gelöst ist.
Das andere ist folgendes: Die Daten die kommen (wie im bsp: Kugelschreiber) untereinander in einem Textfile angibt.
Wäre nett, wenn ihr einen code wüsstet, ich weiß wirklich nicht mehr weiter.
Vielen lieben Dank im voraus.
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Code: Alles auswählen

#!/usr/bin/python
# coding=utf-8

re_in = open("mains.txt")
re_out = open("mains.txt", "w")
i = 1
for line in re_in:
	print(line.rstrip())
	re_out.write(str(i) + ": " + line)
	i = i + 1
re_in.close()
re_out.close()
Zuletzt geändert von Anonymous am Montag 27. Juni 2016, 08:52, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@Paraya21: was hat jetzt der Code mit Deinem Problem zu tun?
Man kann nicht gleichzeitig aus einer Datei lesen und in eine neue Datei mit dem selben Namen schreiben. Wenn man einen Zähler braucht nimmt man enumerate. Wenn man nur einzelne Zeilen ausgeben will, dann prüft man, ob die Zeile eine bestimmte Bedingung erfüllt, z.B. mit "Title:" anfängt.
BlackJack

@Paraya21: Anstelle des Beispielprogramms zum auslesen zu verwenden um die Ausgabe in eine Datei zu schreiben und diese dann als Text auszuwerten, würde es sich anbieten die Daten direkt im eigenen Programm zu verarbeiten. Soweit ich die Dokumentation verstanden habe, basiert das ganze auf einem `neard`-kompatiblen Daemon der eine DBus-Schnittstelle anbietet.
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Danke für die Antwort!. @Sirius3
Wie prüft man, ob die Zeile mit Title: beginnt und das nur diese angezeigt wird?

Vielen Dank im voraus
BlackJack

@Paraya21: Dazu müsste man Python programmieren lernen. In der Python-Dokumentation befindet sich beispielsweise ein Tutorial. Falls so ein Test dort nicht vorkommen sollte, gibt es dort aber zumindest einen Verweis auf die Dokumentation zum Zeichenkettentyp. Und da sind dann alle Operationen mit diesem Typ dokumentiert.
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Code: Alles auswählen

#!usr/bin/python
# coding=utf-8

with open("mains.txt") as rfile:
	lines = rfile.readlines() [5]

f1 = open("NewFile", "w")

f1.write(lines + '\n')
DIe Frage zu diem Code: Er überschreibt mir jedes Mal die neuen Daten in NewFile. Könnt ihr mir helfen, sodass er diese Zeile in NewFiles nicht mehr überschreibt? Wäre sehr lieb von euch <3
Sirius3
User
Beiträge: 17746
Registriert: Sonntag 21. Oktober 2012, 17:20

@Paraya21: was willst Du stattdessen? Etwas an die Datei "a"nhängen? Du sagst jetzt aber nicht, dass immer die Zeile 5 in der Datei die Titel-Zeile ist? Mit magischen Indizes zu hantieren ist nicht robust!
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Ok. Ich habs folgendermaßen gelöst:
Erstes Script (Script):

Code: Alles auswählen

cd /home/pi/explore-nfc
explorenfc-basic > mains.txt
Zweites Script (bzr.py):

Code: Alles auswählen

#!/usr/bin/python
# coding=utf-8

with open("mains.txt") as rfile:
	lines = rfile.readlines() [5]

f1 = open("NewFile", 'a')

f1.write(lines + '\n')
Und drittes (allscript):

Code: Alles auswählen

./Script
python bzr.py
Ausgabe von NewFile:
Title: Kugelschreiber

So nun erneute Frage:
Ich würde gerne, wenn 2x Title: Kugelschreiber kommt, dieses hochzählen. So in der Art: Title: Kugelschreiber (2)
Ich habe gelesen, dass es mit list.count gehen soll, doch ich weiß nicht wie ich das in meinem Script umsetzen soll bzw kann?

Könnte mir einer von euch, dieses vlt in meinem Script umsetzen?
BlackJack

@Paraya21: Wo soll das hochgezählt werden? Du willst jetzt hoffentlich kein ”Programm” aus einer Sammlung loser Skripte in verschiedenen Dateien zusammen pfriemeln mit Variablen die irgendwelchen Textdateien existieren damit sie über die Programme hinweg nicht verloren gehen‽

Lern doch einfach erst einmal Python. Danach weisst Du dann auch was `list.count()` macht oder zumindest wo Du das nachlesen kannst. Und dann schreib *ein* Programm, das dauerhaft läuft und nicht eine Skript-Sammlung die immer wieder aufgerufen werden muss für den nächsten Programmschritt. Falls Du dabei immer noch darauf bestehst ein in C geschriebenes Beispielprogramm produktiv zur Abfrage der Tags zu verwenden und dafür dessen Textausgabe zu parsen, äh nicht zu parsen sondern magisch davon auszugehen das die 6. Zeile immer das gewünschte Datum enthält, dann ruf das von Python aus auf und werte dessen Ausgabe ohne den Umweg über eine Datei aus (`subprocess`-Modul). Das diese 5 nicht robust ist, hat Sirius3 ja schon erwähnt.
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

Ich weiß, dass list.count() Daten aus einer Liste zählen kann, wie oft welches vorkommt.
Doch bei meinem habe ich keine vorgefertigte Liste, sondern Daten die in der Liste reinkommen.
Ja das die Zeile 5 nicht robust ist, ist mir klar, aber es ist jedes Mal die gewünschte Zeile die ich benötige.

Doch es muss doch mit einem command möglich sein, dass es erkennt, wenn dasselbe Element bereits im Dokument drinnen ist (
das Zeile für Zeile die Daten einträgt), dieses 2 mal zählt, anstatt nochmal dasselbe hinzuschreiben.
MFG :shock:
BlackJack

@Paraya21: Wenn Zeile 6 wirklich jedes mal die Zeile wäre, dann wäre es ja robust. Das ist aber nur so eine Annahme von Dir die nicht stimmen muss. Solange Du nicht in der Dokumentation oder im Programm die Stelle findest, an der garantiert wird, dass in der 6. Zeile immer der Titel steht, ist das ein Programmierfehler dort hart den Index 5 rein zu schreiben.

Das was Du willst ist nicht mit einem ”command” möglich. So ein Verhalten muss man sich programmieren. Das Problem in kleinere Schritte aufteilen und die einzelnen Schritte dann mit Befehlen und Funktionen, gegebenenfalls auch anderen Objekten, in Python als Programm umsetzen. Wobei man sich an der Stelle auch gleich um geeignete Datenstrukturen Gedanken machen könnte/sollte, denn mit einer einfachen Liste von Zeilen ist es ja nicht getan wenn eine Zeile aus zwei Werten besteht und eine davon auch keine Zeichenkette, sondern eine Zahl ist.

Wobei man das Gesamtproblem hier schon sinnvoll auf mehrere Funktionen aufteilen sollte. Mindestens das einlesen und das schreiben der Datei, wobei das beim lesen in eine geeignete Datenstruktur überführt werden sollte und beim schreiben dann wieder in die Repräsentation, die man in der Textdatei haben möchte. Und das wird dann von einer Funktion aus verwendet die das Hauptprogramm beinhaltet. Auf Modulebene gehört das nämlich nicht. Da gehören nur Definitionen von Konstanten, Funktionen, und Klassen hin.

Dein nächster Schritt sollte ein Anfängertutorial für Python sein. Wie gesagt, es gibt eines in der Python-Dokumentation. Für absolute Programmieranfänger wird auch oft Learn Python The Hard Way empfohlen (nicht vom Namen abschrecken lassen).
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

bei folgendem Code:
with open("mains.txt") as rfile:
lines = rfile.readlines() [5]

f1 = open("NewFile", 'a')
f1.write(lines + '\n')

zwischen open und write, muss man doch eine if bedingung festlegen können:
if (der Title: Paprika schon vorhanden im NewFile)
then count
else not count

Könnte mir da einer mit dem Code behilflich sein?
Paraya21
User
Beiträge: 14
Registriert: Donnerstag 23. Juni 2016, 14:54

So ich habs bis hier:

Code: Alles auswählen

#!/usr/bin/python

with open("mains.txt") as rfile:
	lines = rfile.readlines() [5]

f1 = open("NewFile.txt", "r")
text = f1.read()
f2 = open("NewFile.txt", 'a')

if lines in text: 
	print("Hier soll es hochzählen: 1,2,3,4)
else:
	f2.write(lines + '\n')
In der Zeile wo print steht, soll eben der Text, wenn er doppelt vorkommt (Title: Paprika), es so ausgeben:
Title: Paprika (2)
wenns 3 mal dasselbe ist, dann:
Title: Paprika (3)

Könnt ihr mir da beim Code helfen?
BlackJack

@Paraya21: Das machst Du Dir zu einfach. Der Name `lines` ist falsch; `f1` und `f2` sehr schlecht. Du öffnest zweimal Dateien die nicht wieder geschlossen werden. ``with`` kennst Du doch bereits. Zu testen ob der Titel *irgendwo* in der Datei vorkommt ist falsch, weil ein Artikelname ja auch Teil eines anderen sein kann, dann hat man falsche Treffer, und wenn man einen Treffer hat, dann müsste man diese Zeile in ihre Bestandteile zerlegen, die Zahldarstellung tatsächlich in eine Zahl umwandeln um sie um eins zu erhöhen, und dann nützt einem der Dateimodus ”anhängen” irgendwie nichts, denn dann muss man alle Daten, inklusive der veränderten neu zusammen gesetzten Zeile mit dem neuen Anzahlwert wieder schreiben.

Du benutzt immer noch die ”magische” 5 statt nach der Zeile mit dem Titel-Präfix zu suchen, und der Präfix macht in der Datei für's zählen keinen Sinn. Da sollte der nicht drin stehen.

Und das alles nicht einfach so auf Modulebene, sondern am besten in der Funktionsaufteilung die ich schon beschrieben hatte. Hauptprogramm, einlesen der Anzahldatei, schreiben der Anzahldatei, und noch eine Funktion die den Titel aus der Datei holt die vom NFC-Beispielprogramm geschrieben wird. Da macht eine eigene Funktion zum Beispiel Sinn, weil man deren Inhalt später durch den direkten Aufruf dieses NFC-Programms ersetzen kann, ohne das man dann noch ein Shellskript und eine Datei dafür braucht.

Lern Python! So ganz allgemein kann Dir das niemand abnehmen, das muss sich jeder selber erarbeiten. Es sei denn jemand hat Lust Dein Programm für Dich zu schreiben. Du kannst konkrete Fragen zu konkreten Problemen stellen, aber bitte zeig etwas Eigeninitiative. Nicht nur schnell irgendwas zusammenhacken und dann hier rein stellen und sagen macht mal.
Gesperrt