Hallo zusammen,
Bin neu hier und versuch mich seit kurzem an Python. Vorkenntnisse von anderen Sprachen sind zumindest grundlegend vorhanden.
Ich habe jetzt ein kleines Projekt mit QPython 3 auf Android angefangen, in dem es letzten Endes um folgendes geht:
Benutzer soll eine Zahl eingeben und diese wird mit verschiedenen dict's abgeglichen. Ist die Zahl in einem der dict's vorhanden Soll ich der Wert dieses Eintrags um 1 erhöhen. Die dict's sollen am Ende gespeichert werden und auch als solche wieder lesbar sein.
Das mit dem Speichern und lesen will aber nicht so richtig funktionieren. Habe dazu jetzt schon einiges gefunden und getestet aber das Ergebnis waren entweder merkwürdige Zeichen bzw "0" in der Datei (hab's mit txt und bin versucht) oder Fehlermeldungen im Programm. Im Quelltext sind ein paar der Versuche mit # ausgeblendet (mit json und pickle).
#-*-coding:utf8;-*-
#qpy:3
#qpy:console
#import pickle
#import cPickle as pickle
#import json
#ah1 = open(/storage/emulated/0/Programmierung/test.txt, r")
ah1 = {1: 0, 2: 0}#, 3: 0, 4: 0, 5:0}
ah2 = {6: 0, 7: 0, 8: 0, 9: 0, 10:0}
#c_ah1 = ah1.values
#*******************************************
user_input = 100
while user_input > 0:
user_input = eval(input("welche zahl? "))
if user_input == 0:
break
elif user_input in ah1:
ah1[user_input] = ah1[user_input] +1
#ah1 = str(ah1)
elif user_input in ah2:
ah2[user_input] = ah2[user_input] +1
print("Falsche Eingabe")
with open("/storage/emulated/0/Programmierung/test.txt", "w") as save:
# user_input.write(pickle.dump(ah1))
# user_input.write(json.dump(ah1))
print(user_input, file=save)
print(ah1)
print(ah2)
Vielen Dank schon mal für eure Tipps
Dictionary speichern laden
Eingerückt wird mit 4 Leerzeichen pro Ebene, nicht 2. Die vielen Leerzeilen machen das Lesen schwierig.
Statt `user_input` mit einem Dummy-Wert zu belegen, solltest Du eine while-True-Schleife benutzen, zumal die Bedingung sowieso nie wahr wird, weil Du die Schleife vorher per break verläßt.
`eval` sollte nicht benutzt werden, `int` reicht hier. `json.dump` erwartet als Argument das Fileobjekt, was Dir auch die Fehlermeldug gesagt hätte, die Du hier am besten mit postest, wenn Du Fragen stellst.
Statt `user_input` mit einem Dummy-Wert zu belegen, solltest Du eine while-True-Schleife benutzen, zumal die Bedingung sowieso nie wahr wird, weil Du die Schleife vorher per break verläßt.
`eval` sollte nicht benutzt werden, `int` reicht hier. `json.dump` erwartet als Argument das Fileobjekt, was Dir auch die Fehlermeldug gesagt hätte, die Du hier am besten mit postest, wenn Du Fragen stellst.
Code: Alles auswählen
import json
ah1 = {1: 0, 2: 0}
ah2 = {6: 0, 7: 0, 8: 0, 9: 0, 10:0}
while True:
user_input = int(input("welche zahl? "))
if user_input == 0:
break
elif user_input in ah1:
ah1[user_input] += 1
elif user_input in ah2:
ah2[user_input] += 1
else:
print("Falsche Eingabe")
with open("/storage/emulated/0/Programmierung/test.txt", "w") as save:
json.dump(ah1, save)
- __blackjack__
- User
- Beiträge: 13110
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Ich würde die Kodierung beim `open()` explizit mit UTF-8 angeben.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
@_blackjack_:
Wenn ich den Startwert von ah1 oben im Programm gleich aus der (bestehenden) Datei herauslaufen will kommt folgender Fehler der mich glaube ich darauf verweist wenn ich das richtig verstehe.
TypeError: <_io.TextIOWrapper name ='/DATEIPFAD/Test.txt' mode='r' encoding='utf-8' > is Not json serializable
import json
ah1 = open("/storage/emulated/0/Programmierung/test.txt", "r")
#ah1 = {1: 0, 2: 0, .3: 0, 4: 0, 5:0}
ah2 = {6: 0, 7: 0, 8: 0, 9: 0, 10:0}
#c_ah1 = ah1.values
#*******************************************
user_input = 100
while True:
user_input = int(input("welche zahl? "))
if user_input == 0:
break
elif user_input in ah1:
ah1[user_input] = ah1[user_input] +1
elif user_input in ah2:
ah2[user_input] = ah2[user_input] +1
with open("/storage/emulated/0/Programmierung/test.txt", "w") as save:
json.dump(ah1, save)
print(ah1)
BTW: wie kann ich den Code richtig in einem Post platzieren? Bei den paar Zeilen geht das ja mal noch auch wenn's unschön aussieht aber wird ja unübersichtlich
Wenn ich den Startwert von ah1 oben im Programm gleich aus der (bestehenden) Datei herauslaufen will kommt folgender Fehler der mich glaube ich darauf verweist wenn ich das richtig verstehe.
TypeError: <_io.TextIOWrapper name ='/DATEIPFAD/Test.txt' mode='r' encoding='utf-8' > is Not json serializable
import json
ah1 = open("/storage/emulated/0/Programmierung/test.txt", "r")
#ah1 = {1: 0, 2: 0, .3: 0, 4: 0, 5:0}
ah2 = {6: 0, 7: 0, 8: 0, 9: 0, 10:0}
#c_ah1 = ah1.values
#*******************************************
user_input = 100
while True:
user_input = int(input("welche zahl? "))
if user_input == 0:
break
elif user_input in ah1:
ah1[user_input] = ah1[user_input] +1
elif user_input in ah2:
ah2[user_input] = ah2[user_input] +1
with open("/storage/emulated/0/Programmierung/test.txt", "w") as save:
json.dump(ah1, save)
print(ah1)
BTW: wie kann ich den Code richtig in einem Post platzieren? Bei den paar Zeilen geht das ja mal noch auch wenn's unschön aussieht aber wird ja unübersichtlich
- __blackjack__
- User
- Beiträge: 13110
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Mr_Martin: Du kannst ein Wörterbuch nicht einfach durch ein Dateiobjekt ersetzen. Das ``ah1 = open(…`` macht keinen Sinn. An der Stelle musst Du die Datei öffnen und dann den Inhalt der Datei mit `json.load()` laden und das daraus resultierende Wörterbuch an `ah1` binden.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Da wollte ich es mir wohl einfacher machen als es ist ^^
Habe das jetzt am Programmanfang anstelle des dict's eingefügt. Das Laden funktioniert so auch super, nur ändert sich ah1 nicht mehr bei Eingabe einer Zahl. Gebunden wurde das Wörterbuch richtig an ah1 ( print(ah1) nach obigem code gibt das Wörterbuch richtig aus. Bleibt halt aber auch so wie es ist.
Danke für die Geduld mit einem Neuling ^^
Code: Alles auswählen
with open("/storage/emulated/0/Programmierung/test.txt", "r") as nativ:
ah1 = json.load(nativ)
Danke für die Geduld mit einem Neuling ^^
- __blackjack__
- User
- Beiträge: 13110
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Mr_Martin: Dann muss sich auch am weiteren Code irgendwas geändert haben, wenn der vorher funktioniert hat.
Die Anmerkungen zur Einrückung etc. könntest Du bei Gelegenheit auch umsetzen. Und zumindest bei neuem Code nicht weiterhin gegen die Konventionen programmieren.
Den Dateinamen würde man als Konstante definieren, statt ihn zweimal im Programm stehen zu haben.
Und bessere Namen als `ah1`, `ah2`, `nativ`, und `save`. Bei den ersten beiden wird nicht klar was sie überhaupt bedeuten wenn man das nicht sowieso schon weiss. Was `nativ` hier bedeuten soll ist mir nicht so ganz klar, und `save` ist ein Name für eine Funktion oder Methode, aber nicht für ein Dateiobjekt.
Die Anmerkungen zur Einrückung etc. könntest Du bei Gelegenheit auch umsetzen. Und zumindest bei neuem Code nicht weiterhin gegen die Konventionen programmieren.
Den Dateinamen würde man als Konstante definieren, statt ihn zweimal im Programm stehen zu haben.
Und bessere Namen als `ah1`, `ah2`, `nativ`, und `save`. Bei den ersten beiden wird nicht klar was sie überhaupt bedeuten wenn man das nicht sowieso schon weiss. Was `nativ` hier bedeuten soll ist mir nicht so ganz klar, und `save` ist ein Name für eine Funktion oder Methode, aber nicht für ein Dateiobjekt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Vielen Dank für die bisherigen Tipps.
Habe versucht so viel wie möglich davon umzusetzen.
Mit der Variablenbennennung tu ich mich immer noch bisschen schwer ^^
Die Einträge in den Wörterbüchern sind jetzt Strings (ich will nur die Werte ändern also ist das kein Problem)
Soweit hat das ganze dann auch schon mal mit Speichern und Laden funktioniert.
Jetzt wollte ich das ganze wie folgt in eine for Schleife packen um Änderungen der Dicts zu erleichtern und vor allem um nicht alles für jedes dict schreiben zu müssen.
Bei "i = json.load(r) bringt er mir dann folgenden Fehler:
"valueerror no json object could be decoded"
Hier wollte ich das dict in die variable ah1 laden.
Die Variablen werden bis dahin soweit ich das erkennen konnte (mit print getestet) alle richtig übergeben.
Meine erste Frage dazu wäre: ist die Konstruktion prinzipiell so machbar oder hab ich mir de nur n Haufen Mist zusammengewürfelt?
Zu dem Fehler: Json scheint ja mit r nichts anfangen zu können wenn ich das richtig verstehe. Liegt der Fehler schon davor oder hab ich etwas vergessen? Oder ist das doch nur Müll so? ^^
"Falsche Eingabe" ist auch noch falsch platziert aber das ist erstmal nebensächlich.
Habe versucht so viel wie möglich davon umzusetzen.
Mit der Variablenbennennung tu ich mich immer noch bisschen schwer ^^
Die Einträge in den Wörterbüchern sind jetzt Strings (ich will nur die Werte ändern also ist das kein Problem)
Soweit hat das ganze dann auch schon mal mit Speichern und Laden funktioniert.
Jetzt wollte ich das ganze wie folgt in eine for Schleife packen um Änderungen der Dicts zu erleichtern und vor allem um nicht alles für jedes dict schreiben zu müssen.
Code: Alles auswählen
import json
index = ["ah1"]
while True:
user_input = input("Welche zahl? ")
if user_input == "0":
break
else:
for i in index:
source = "/storage/emulated/0/Programmierung/Test_" + i + ".txt"
data_r = open(source, "r")
data_w = open(source, "w")
with data_r as r:
i = json.load(r)
if user_input in i:
i[user_input] += 1
with data_w as w:
json.dump(i, w)
else: print("Falsche Eingaben")
"valueerror no json object could be decoded"
Hier wollte ich das dict in die variable ah1 laden.
Die Variablen werden bis dahin soweit ich das erkennen konnte (mit print getestet) alle richtig übergeben.
Meine erste Frage dazu wäre: ist die Konstruktion prinzipiell so machbar oder hab ich mir de nur n Haufen Mist zusammengewürfelt?
Zu dem Fehler: Json scheint ja mit r nichts anfangen zu können wenn ich das richtig verstehe. Liegt der Fehler schon davor oder hab ich etwas vergessen? Oder ist das doch nur Müll so? ^^
"Falsche Eingabe" ist auch noch falsch platziert aber das ist erstmal nebensächlich.
`i` ist ein schlechter Variablennamen, wie alle einbuchstabigen, weil sie nichts aussagen. Zudem benutzt Du `i` für verschiedene Werte in der selben Schleife. Die with-Statements werden seltsam verwendet, das open gehört ins with.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2 und mal 1. Statt "0" wäre Leerstring einleuchtender als Abbruchkriterium.
Strings setzt man nicht mit + zusammen sondern nutzt Formatierung.
Zum Fehler: Deine Datei ist leer.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2 und mal 1. Statt "0" wäre Leerstring einleuchtender als Abbruchkriterium.
Strings setzt man nicht mit + zusammen sondern nutzt Formatierung.
Zum Fehler: Deine Datei ist leer.
- __blackjack__
- User
- Beiträge: 13110
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Leer ist sie übrigens weil das öffnen mit 'w' die Datei leert. Zu dem Zeitpunkt weisst Du doch auch noch gar nicht ob in die Datei überhaupt geschrieben werden muss. Das sollte man also erst machen wenn das feststeht.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Für 'i' muss ich noch einen besseren Namen finden.
Aber ansonsten ist i doch nur dort wo es als ah1 bzw ah2 stehen soll oder irre ich mich da?
Mit dem with habe ich wirklich etwas quer gedacht ^^ würde verbessern (:
Habe jetzt (wenn nichts übersehen) überall 4 mal eingerückt, werd mich dran gewöhnen.
Abbruch Bedingung würde abgeändert. Mit der string-Formatierung müsste ich mich erstmal auseinandersetzen aber das Ergebnis scheint zu passen (:
Zu der Datei: bei mir ist sie nich leer weil sie schon von den Versuchen davor beschrieben war, das hab ich nicht bedacht. Da werde ich vll noch ne Abfrage einarbeiten bei der die Datei erstellt wird, wenn keine vorhanden ist.
Inhalt der Datei wäre: {"1": 2, "3": 0, "2": 1, "5": 2, "4": 0}
Aber erstmal Versuch ich die "Falsche Eingabe" an die richtige Position zu bringen. Dass sie dort falsch ist weiß ich ja schon ^^
Aber ansonsten ist i doch nur dort wo es als ah1 bzw ah2 stehen soll oder irre ich mich da?
Mit dem with habe ich wirklich etwas quer gedacht ^^ würde verbessern (:
Habe jetzt (wenn nichts übersehen) überall 4 mal eingerückt, werd mich dran gewöhnen.
Abbruch Bedingung würde abgeändert. Mit der string-Formatierung müsste ich mich erstmal auseinandersetzen aber das Ergebnis scheint zu passen (:
Code: Alles auswählen
import json
index = ["ah1", "ah2"]
while True:
user_input = input("Welche zahl? ")
if user_input == "":
break
else:
for i in index:
source = "/storage/emulated/0/Programmierung/Test_{0:1s}.txt".format(i)
with open(source, "r") as data_r:
i = json.load(data_r)
print(i)
if user_input in i:
i[user_input] += 1
with open(source, "w") as data_w:
json.dump(i, data_w)
print(i)
else: print("Falsche Eingaben")
Inhalt der Datei wäre: {"1": 2, "3": 0, "2": 1, "5": 2, "4": 0}
Aber erstmal Versuch ich die "Falsche Eingabe" an die richtige Position zu bringen. Dass sie dort falsch ist weiß ich ja schon ^^
- __blackjack__
- User
- Beiträge: 13110
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Mr_Martin: Du verwendest `i` einmal für den Dateinamen(teil) und etwas später dann für den Dateinhalt.
Listen (und andere Sequenztypen oder auch iterierbare Objekte) werden üblicherweise in der Mehrzahl von dem benannt was für ein einzelnes Element ein guter Name wäre. Also vielleicht `index_names` statt `index`, dann kann man das erste `i` in `index_name` umbenennen und die zweite Verwendung von `i` dann vielleicht `index` wenn so ein Wörterbuch ein Index sein soll.
Statt `user_input` könnte man einen Namen verwenden der sagt was der Wert *bedeutet*, nicht wie er zustande gekommen ist.
Das ``:1s`` im Platzhalter beim formatieren ist überflüssig.
Listen (und andere Sequenztypen oder auch iterierbare Objekte) werden üblicherweise in der Mehrzahl von dem benannt was für ein einzelnes Element ein guter Name wäre. Also vielleicht `index_names` statt `index`, dann kann man das erste `i` in `index_name` umbenennen und die zweite Verwendung von `i` dann vielleicht `index` wenn so ein Wörterbuch ein Index sein soll.
Statt `user_input` könnte man einen Namen verwenden der sagt was der Wert *bedeutet*, nicht wie er zustande gekommen ist.
Das ``:1s`` im Platzhalter beim formatieren ist überflüssig.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Das "i" bin ich jetzt los geworden. Hab versucht die variable so wie beschrieben aufzuteilen. Das hat auch gleich mehr oder weniger gut funktioniert. (Ausgabe ist richtig aber doppelt)^^
Zum ausprobieren ist mir user_input erstmal noch aussagekräftig genug aber werd das noch ändern
Wollte das mit dem Platzhalter einfach mal so ausprobieren weil es für mich eben neu ist aber hab mir schon gedacht dass ich mir das in dem Fall sparen kann (:
Zum ausprobieren ist mir user_input erstmal noch aussagekräftig genug aber werd das noch ändern
Wollte das mit dem Platzhalter einfach mal so ausprobieren weil es für mich eben neu ist aber hab mir schon gedacht dass ich mir das in dem Fall sparen kann (: