json.loads() finding my string to be None - python

hi there basically i keep getting
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 2 (char 1)
basically i am trying to insert their new score to the list of existing scores for the user who just got a new score (name), i need to get the list from the file and insert the score and then overwrite the old file with the added score
import json
import os
# placeholder values:
t = "A"
fileSuffix = ".txt"
score = 5
name = "john"
fileName = t + fileSuffix
if not os.path.exists(t + fileSuffix):
open(fileName, "w")
textFile = open(fileName, "r")
lines = textFile.readlines()
userExists = False
lineToEdit = 0
lineValue = ""
for line in lines:
if line.find(name) != -1:
userExists = True
lineValue = line
lineToEdit = lines.index(line)
textFile.close()
if userExists:
lineValue = json.loads(lineValue)
lineValue.insert(score)
lines[lineToEdit] = lineValue
print("user exists, inserted score into list")
else:
print("user no exist, appending file")
open(fileName, "a").write("\n" + name + " = ["+ str(score) + "]")

If you're trying to create key/value pairs, a list is the wrong format
to use in the first place; use a dict. {"user1": [1,2,3], "user2":
[4,5,6]}, etc. json.dumps() and similar calls will do the work of
dumping that dict back to JSON.
When you have a list of key/value pairs, you need to do an O(n) search to
find the specific key you want; when you have a dict that's
efficiently implemented, lookup is O(1). Granted, updating the file
in-place is slow, but that's why people who care about doing things
efficiently use something like a sqlite database instead of a JSON
file. (For a save game format, though, a JSON file that gets rewritten
from the beginning over and over may be good enough, as long as you're
not saving it too frequently; if you are rewriting it constantly, see
again re: sqlite)
answer from #CharlesDuffy
The issue was I was using an incorrect method to do what I was trying to do; I was using a list where I should have used a dictionary.

Related

Is there a way to insert curly braces around text to make it a dictionary in string format?

In my python program, I have a list of keys and values that are added to a text file and I need to be able to extract this string list and turn it into a dictionary.
For example:
counter = 0
add = str(counter)
counterDict = UserID + ": " + add + ", "
counter = counter + 1
#This should make counterDict look like: ""Smi39119": 0, "Joh38719": 1, " etc.
f = open("Dictionaries.txt","a")
f.write(counterDict)
f.close()
#Then I would like to be able to open the file and turn that string into a dictionary
f = open("Dictionaries.txt","r")
string = f.read()
#This way 'string' should still be a string, but look like this: "{"Smi39119": 0, "Joh38719": 1, }"
I do not know if this is possible, but if it is, all solutions would be greatly appreciated.
I'm guessing you are trying to save a dictionary to a file, * enter *: json file system,
you don't need to convert your dictionary to string, let json do it for you to dump it into a string.
import json
f = open("Dictionaries.json","a")
f.write(json.dumps(your_dictionary))
f.close()
# load it and use it like a dictionary
f = open("Dictionaries.json","r")
your_dictionary = json.loads(f.read())
also read Writing a dict to txt file and reading it back?
cheers!

Replacing data in files with new inputs

First of all my program must work with several files and 10 inputs in every file, this is just little piece, to be clear.
My code right now:
code = input(">> ")
print("\nPress <Enter> and parameter will be same!")
f = open("komad_namestaja.txt", "r")
allDATA = f.readlines()
f.close()
for line in allDATA:
lst = line.split("|")
if code == lst[0]:
print("\nName :", lst[1])
name = input("New Name >> ")
if name == "":
name = lst[1]
f = open("komad_namestaja.txt", "r")
allDATA = f.read()
f.close()
newdata = allDATA.replace(lst[1], name)
f = open("komad_namestaja.txt", "w")
f.write(newdata)
f.close()
print("\ndestination :", lst[2])
destination = input("New destination >> ")
if destination == "":
destination = lst[2]
#Writting function here
File before:
312|chessburger|Denmark
621|chesscake|USA
code input: 312
name input: Gyros
destination input: Poland
file after inputs:
312|Gyros|Poland
621|chesscake|USA
Problem is this replacing in file I cant write 7 lines code every time, because I have 10 x 5 inputs, and also I tried everything and cant make function of this.
I must write some function for reading/writing/replacing or replacing all inputs after last one.
You don't have to read the file in every time to modify one field, write it out, reopen it to change another field, and so on. That's inefficient, and in your case, causes code explosion.
Since your files are small, you could just read everything into memory at once and work on it in memory. Your code is easy to map via a dict.
Here's a function that takes a filename and converts your file into a dictionary.
def create_mapping(filename):
with open(filename, 'r') as infile:
data = infile.readlines()
mapping = {int(k): (i,d) for k,i,d in
(x.strip().split('|') for x in data)}
# Your mapping now looks like
# { 312: ('cheeseburger', 'Denmark'),
# 621: ('chesscake', 'USA') }
return mapping
Then you can update the mapping from user input since it's just a dictionary.
Once you want to write the file out, you can just serialize out your dictionary by iterating over the keys and rejoining all the elements using |.
If you want to use lists
If you want to stick with just using lists for everything, that is possible.
I would still recommend reading your file into a list, like so:
def load_file(filename):
with open(filename, 'r') as infile:
data = infile.readlines()
items = [(int(k), i, d) for k,i,d in
(x.strip().split('|') for x in data]
# Your list now looks like
# [(312, 'cheeseburger', 'Denmark'), (621, 'chesscake', 'USA')]
return items
Then when you get some user input, you have to traverse the list and find the tuple with what you want inside.
For example, say the user entered code 312, you could find the tuple that contained the 312 value from the list of tuples with this:
items = load_file(filename)
# Get input for 'code' from user
code = int(input(">> "))
# Get the position in the list where the item with this code is
try:
list_position = [item[0] for item in items].index(code)
# Do whatever you need to (ask for more input?)
# If you have to overwrite the element, just reassign its
# position in the list with
# items[list_position] = (code, blah, blah)
except IndexError:
# This means that the user's entered code wasn't entered
# Here you do what you need to (maybe add a new item to the list),
# but I'm just going to pass
pass

reading a file and parse them into section

okay so I have a file that contains ID number follows by name just like this:
10 alex de souza
11 robin van persie
9 serhat akin
I need to read this file and break each record up into 2 fields the id, and the name. I need to store the entries in a dictionary where ID is the key and the name is the satellite data. Then I need to output, in 2 columns, one entry per line, all the entries in the dictionary, sorted (numerically) by ID. dict.keys and list.sort might be helpful (I guess). Finally the input filename needs to be the first command-line argument.
Thanks for your help!
I have this so far however can't go any further.
fin = open("ids","r") #Read the file
for line in fin: #Split lines
string = str.split()
if len(string) > 1: #Seperate names and grades
id = map(int, string[0]
name = string[1:]
print(id, name) #Print results
We need sys.argv to get the command line argument (careful, the name of the script is always the 0th element of the returned list).
Now we open the file (no error handling, you should add that) and read in the lines individually. Now we have 'number firstname secondname'-strings for each line in the list "lines".
Then open an empty dictionary out and loop over the individual strings in lines, splitting them every space and storing them in the temporary variable tmp (which is now a list of strings: ('number', 'firstname','secondname')).
Following that we just fill the dictionary, using the number as key and the space-joined rest of the names as value.
To print the dictionary sorted just loop over the list of numbers returned by sorted(out), using the key=int option for numerical sorting. Then print the id (the number) and then the corresponding value by calling the dictionary with a string representation of the id.
import sys
try:
infile = sys.argv[1]
except IndexError:
infile = input('Enter file name: ')
with open(infile, 'r') as file:
lines = file.readlines()
out = {}
for fullstr in lines:
tmp = fullstr.split()
out[tmp[0]] = ' '.join(tmp[1:])
for id in sorted(out, key=int):
print id, out[str(id)]
This works for python 2.7 with ASCII-strings. I'm pretty sure that it should be able to handle other encodings as well (German Umlaute work at least), but I can't test that any further. You may also want to add a lot of error handling in case the input file is somehow formatted differently.
Just a suggestion, this code is probably simpler than the other code posted:
import sys
with open(sys.argv[1], "r") as handle:
lines = handle.readlines()
data = dict([i.strip().split(' ', 1) for i in lines])
for idx in sorted(data, key=int):
print idx, data[idx]

Python program to store values in an external file

How would I go about creating a python program to store a range of values (ie. apples=3, bananas=5, carrots=12.5) in an external file where I can later use those values for calculations later on?
Currently, I am able to print to and read from text files using fileinput and fileoutput, but I am unable to use those values in calculations later on.
with open("values.txt","w") as fileinput:
fileinput.write(value)
An example of what I am looking for is first being able to type a variable name (eg. Apples), then type a number or other value (eg. 3.3) and then print those values to the values.txt. That way, a separate program could view values.txt to be able to use the value of apples=3.3 in a calculation (eg. apples*3=9.9)
Assuming that you want to store fruit and values pairs into a dictionary (but you can adapt it to any data structure):
Writing to file:
fruits = {"apple":12, "banana":4}
with open("test.txt", 'w') as out:
for fruit,number in fruits.iteritems():
line = fruit + '=' + str(number) + '\n'
out.write(line)
Parse from file into dictionary
emptyDict = {}
with open("test.txt", 'r') as infile:
for line in infile:
tokens = line.strip().split('=')
fruit = tokens[0]
number = tokens[1]
emptyDict[fruit] = float(number)
What do you mean by "but I am unable to use those values in calculations later on.". But you could create a dictionary mapping the String to the values, for example:
mydata = {}
with open("values.txt", "r") as output:
for line in output:
tmp = line.split('=')
mydata[tmp[0]] = float(tmp[1])

How to write to a specific line in a text file

I hope I'm not reposting (I did research before hand) but I need a little help.
So I'll explain the problem as best as I can.
I have is a text file, and inside it I have information in this format:
a 10
b 11
c 12
I read this file and convert it to a dictionary with the first column as the key, and the second as the value.
Now I'm trying to do the opposite, I need to be able to write the file back with modified values in the same format, the key separated by a space, then the corresponding value.
Why would I want to do this?
Well, all the values are supposed to be changeable by the user using the program. So when the do decide to change the values, I need them to be written back to the text file.
This is where the problem is, I just don't know how to do it.
How might I go about doing this?
I've got my current code for reading the values here:
T_Dictionary = {}
with open(r"C:\NetSendClient\files\nsed.txt",newline = "") as f:
reader = csv.reader(f, delimiter=" ")
T_Dictionary = dict(reader)
ok,supposing the dictionary is called A and the file is text.txt i would do that:
W=""
for i in A: # for each key in the dictionary
W+="{0} {1}\n".format(i,A[i]) # Append to W a dictionary key , a space , the value corresponding to that key and start a new line
with open("text.txt","w") as O:
O.write(W)
if i understood what you were asking.
however using this method would leave an empty line at the end of the file ,but that can be removed replacing
O.write(W)
with
O.write(W[0:-1])
i hope it helped
Something like this:
def txtf_exp2(xlist):
print("\n", xlist)
t = open("mytxt.txt", "w+")
# combines a list of lists into a list
ylist = []
for i in range(len(xlist)):
newstr = xlist[i][0] + "\n"
ylist.append(newstr)
newstr = str(xlist[i][1]) + "\n"
ylist.append(newstr)
t.writelines(ylist)
t.seek(0)
print(t.read())
t.close()
def txtf_exp3(xlist):
# does the same as the function above but is simpler
print("\n", xlist)
t = open("mytext.txt", "w+")
for i in range(len(xlist)):
t.write(xlist[i][0] + "\n" + str(xlist[i][1]) + "\n")
t.seek(0)
print(t.read())
t.close()
You'll have to make some changes, but it's very similar to what you're trying to do. M

Categories

Resources