Need help using json in python

Hey!
So for ex36 I wanted to try and make a mock up game where a mechanic in it is that the program remembers how many times you have opened the game (and will say things based on how many times you opened it, smth like a narrator that keeps getting annoyed because you wake it up when opening the program).

I did some research on how to import and change a specific variable in a separate file, and came to the conclusion that the best option for me is using json files.

Now, I did some research on dicts and with and as and in general loading and dumping to json files, but I get error that I tried fixing but can’t seem to.

in my python file (testing.py)

import json

with open('config', 'w+') as config_file:
    json.load(config_file)

And in my json file (config.json)

{"restarted": 0}

The error:

json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

When i tested working with loads() and dumps() I didn’t have a problem, but somehow if its a file and not string I can’t even load the data.

tldr:
My goal is getting a value from a json file, and consequently being able to change and dump it back again.

Would really appreciate some help :slight_smile:

Not sure why it hates that file, but here’s some things to try:

  1. Open it with ‘r’ only. You’re using a with open() so using ‘w+’ isn’t helping you as the file gets closed after this, so you can’t reuse the variable anyway.
  2. It looks like you’re not actually reading the file. Add config_file.read()
  3. Make triple sure this file contains what you think it does. Print out its contents before attempting the json.load.

In general, if you get an error like this, you need to ask what could possibly cause it and how to get more information. If you simply went “it could be the file is bad so I’ll see what’s in it” then you’d have known to print it out.

But, that’s doing “hindsight 20/20”. A general rule is you cannot know what a program does by staring at code. Never. Print, print, print, print, print, print, print, print, print. Every variable. Every code path. Print print print print print.

That’s usually the only way to find a bug. No reading code will tell you what’s in a variable.

Ok so I tried what you said, though in every tutorial that I encountered there was no need for .read() so Idk what’s up with that.

the code executed fine when I did this:

with open('config.json', 'r') as config_file:
    file = config_file.read()
    #json.load(file)
    print(file)

but I want to able to access my dict and change parts in it.
If I do it with .read() and .write() I’ll have to rewrite the entire file to only change one thing which is not what I want to do.

So I also tried:

with open('config.json', 'r') as config_file:
    #file = config_file.read()
    data = json.load(config_file)
    print(data)

    dict['restarted'] = 1

    print(dict)

But it just gave me the same error as the first one I posted.
Idk if it matters but this was the entire error:

PS C:\Users\Yael\python\EX36> python testing.py
Traceback (most recent call last):
  File "testing.py", line 8, in <module>
    data = json.load(f)
  File "C:\Users\Yael\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py", line 293, in load
    return loads(fp.read(),
  File "C:\Users\Yael\AppData\Local\Programs\Python\Python38-32\lib\json\__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "C:\Users\Yael\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Users\Yael\AppData\Local\Programs\Python\Python38-32\lib\json\decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

If it doesn’t change anything, is it possible that someone just can’t use json files?
Should I just use json strings and dump them inside a python file?
I’ll need to truncate the file and .write() to it, which could be a hassle, but I don’t see any other option at this point…

I want to access data from a different file, change it and then store it back in its file.
What should I do?

I believe your code should work, and it looks to me like some nasty encoding error. Can you try this once, if you haven’t already:

with open("config.json", "r") as f:
    s = f.read()
    d = json.loads(s)
    print(d)

At any rate, if you want to save the changes back to the file, you’ll have to write the whole thing again.

Alright, you’re trying to think in code but you need to start with plain old English:

# open the config file
# read the file contents
# convert to json

Then translate that to pseudo-code:

# with open config.json:
# contents = config.read()
# data = json load(contents)

Then translate that to Python:

# with open config.json:
with open('config.json') as config_file:
    # contents = config.read()
    contents = config_file.read()
    # data = json load(contents)
    data = json.load(contents)

Then delete the comments once it’s working:

with open('config.json') as config_file:
    contents = config_file.read()
    data = json.load(contents)

Write out what you want your program to do in plain English comments, then slowly translate those comments to working Python. Next tip:

Run this repeatedly as you do it. Each line of Python that you can run you should run. Remember you can use pass to make an empty block:

with open('config.json') as config_file:
    pass

Run that, then add the next line, run that, then add the next line, run that. I think I run my code about 2 times for every 1 line of code I write. I run it so often I have another program that just automatically runs my code when something changes.

Now, you have the desire to “read my config, change it, write my config”. Each of these would be one operation, and you would write them out like I did above, running it each time to make sure it works.

You should also type in all of the examples from the docs to study the library:

https://docs.python.org/3/library/json.html

And, if you’re going to load the contents you want to use json.loads instead. That means I would do this so you can figure it out:

# open the config.json
# read the contents
# print out the contents
# use json.loads() to convert to Python dict (NOTE: loadSSSSSSS)
# return the loaded dict

That will help you debug it, and you should do the reverse process.

Final final note: I see you might be doing this thing where you hit a problem and immediately come asking for help. Try to spend at least 48 hours solving it yourself, and write down what you did to solve it. There’s no way you spent enough time working this between when I replied and when you wrote this. You should put in at least a couple days trying different things, googling errors, printing everything, and trying to solve it.

See you in a few days.

1 Like

Last tip: Make triple sure the json file is in the directory where Python expects it to be. That JSONDecodeError is what I get when I try to decode a non-existing file opened in read+write mode.

Ah that’s a good one. Also, that’s an absolutely terrible error if that’s the case.

I didn’t manage to fix it with json but I did manage to make it work with read/write. I guess I’ll find another module to parse data in the future when the need comes up but for now I’m good.

Also, I come here to the forum as a last resort but I do appreciate it when people assume things, especially teachers that I’m trying to ask for help.

On a non sarcastic note Mr. Shaw, I do love the book and forum - they’re a great asset, but it took me literal years to be able to ask people for help, so.

Thank you for taking the time and effort to respond though :slight_smile:

Ayy I tried defining a path (even though the json file was in the same directory as the .py file) but it didn’t work for some reason…
Thank you though! I’ll keep that in mind for any other errors that may pop up.

Hmm. Did you also launch Python from that directory? In my experience the json library is a very useful tool, it’d be a shame if you decided not to use it anymore.

Please don’t feel discouraged from asking questions here. :slight_smile:

Yeah the script file and the json file are in the same directory. I’ve looked online and json does seem to be useful, but I can’t make it work with actual json files, only strings…

:slight_smile:

Yes, but did you do

$ python3 myfile.py

or

$ python3 somedir/myfile.py

in the shell?

Oh, I enter the directory where my file is and then open python with my file.
Like:

cd directory\otherdir\other

then

python myfile.py

Then I’m out of ideas. :frowning:

1 Like

I had a quick google and found a few instances of similar issues:

Check the response data-body, whether actual data is present and a data-dump appears to be well-formatted.

In most cases your json.loads - JSONDecodeError: Expecting value: line 1 column 1 (char 0) error is due to :

  • non-JSON conforming quoting
  • XML/HTML output (that is, a string starting with <), or
  • incompatible character

Ultimately the error tells you that at the very first position the string already doesn’t conform to JSON.


I notice you have your JSON as:

{"restarted": 0}

Have you tried escaping the “ “? Or removing them as it’s not string specific? I saw a few Google solutions like this.

Or formatting as below, or adding a comma at the end?

{
    "restarted": 0,
}

This is the sort of stuff Zed was on about. Sometimes bugs are massively frustrating but it’s part of the process of becoming a programmer. You need the resilience to keep trying other things; take a break, write your code by hand, email it to yourself, have a day off and read it again, Nuke the whole file and location and start again. Try your code online with a interpreter at repl.it or similar to rule out a windows or power shell nuisance.

I wouldn’t take the comments as criticism, but tough love. And it’s worth continuing to problem solve it, as you get loads of satisfaction when you finally crack it and know how to fix similar things next time.

A free service run by Zed A. Shaw for learncodethehardway.org.