Using JSON files to store and retrieve list data

Viewed 122

Every time I pull the JSON file during the next program execution/session, the previous data is overwritten. Ultimately, what I'm trying to do is save my data to a file and retrieve it the next time I want to run the program. I want to append data to the list whenever I run the program.

import json
import os.path

income = []

def file_exists():
    if os.path.exists('income.json') == True:
        with open('income.json') as f:
            income = json.load(f)
    else:
        pass

def desire_func():
  x = input('What do you want to do? ')
  if x != 'n':
    transactions()
    print(income)
  else:
    return

def transactions():
    with open('income.json', 'w') as g:
        entry = float(input('Transaction info: '))
        income.append(entry)
        json.dump(income, g)
        desire_func()

file_exists()
transactions()
print(income)

Any help would be greatly appreciated as I've attempted to tackle this from multiple angles and always run into a different issue. Initially, I was trying to pickle the data and that seemed far less robust, but I am open to anything that may work.

Thanks in advance for your help.

EDIT: Added in desire_func() so you can easily add multiple times to the same list (income) while troubleshooting.

2 Answers

Use append mode a instead of the write mode w:

Change this:

with open('income.json', 'w') as g:

to this:

with open('income.json', 'a') as g:

Edit:

The list is initialized everytime the program is ended. You could use a loop to keep reading the files unless you dont want to, something like:

income = []

def populate_list():
    income.append(input('Enter something to add to list: '))

def show_list():
    print(income)

while True:
    x = input("Press 1 to exit: ")
    if x is not'1':
        populate_list()
        show_list()
    else:
        break

it seems like rather than appending, you want to set the loaded JSON into income in order to prevent nesting the array deeper and deeper with each iteration.

def file_exists():
if os.path.exists('income.json') == True:
    with open('income.json') as f:
        income (json.load(f))
else:
    pass

should become

def file_exists():
if os.path.exists('income.json') == True:
    with open('income.json') as f:
        income = json.load(f)
else:
    pass

The list form factor of the income variable should then be preserved in the JSON file.

Example:

>>> testlist = ['test', 'test2']
>>> import json
>>> with open('income.json', 'w') as g:
...     json.dump(testlist, g)
...

exit and restart

>>> import json
>>> with open('income.json') as f:
...     testlist = json.load(f)
... 
>>> testlist
['test', 'test2']

edit: so, one thing I though might have been an issue, is regarding variable scope. Usually functions take parameters. this ensures that it is clear what value a function variable will take in cases where you use the same variable name in other places in the code. With your current code, if you print the income variable within the transactions function, you will see that it is an empty list.

you can fix this by passing the list to your functions:

import json
import os.path

def file_exists():
    if os.path.exists('income.json') == True:
        with open('income.json') as f:
            income = json.load(f)
            print(income)
            return income
    else:
        return []

def transactions(income):
    print(income)
    with open('income.json', 'w') as g:
        entry = float(input('Transaction info: '))
        print(entry)
        income.append(entry)
        print(income)
        json.dump(income, g)

income = file_exists()
transactions(income)
print(income)
Related