5

Okay so my question is pretty specific and I apologize in advance. I'm a new programmer and tried developing on my own from scratch. It was relatively successful only I have one last problem, that I can see. You can view my code here in its entirety.

Project

So the problem I'm having is related to the way I save the file. I first tried to pickle it since it's a dictionary but I kept getting an error because my dictionary is
(name, class) pairs.

I searched around on here and saw I could try JSON to do the same. Ended up with the same kind of errors. Eventually I found the klepto module which worked. I saved my dictionary successfully and loaded it successfully. It wasn't until later I found that I can add new items to the file but whenever I remove something from my dict and save. The next time I load it. The key I removed is still there.

TLDR: Can add things just fine to my dict and save to txt file but when I remove from the dict and save it won't save the removed key.

Anyway I'm stumped on where my problem lies in the way I'm saving the file or the way I'm loading it or both? Any help would be very appreciated.

Edit: Ok I'm assuming it's the way I have it currently set to save and load.

try:
    alcohols = file_archive('Alcohols.txt')
    alcohols.load()
except IOError:
    alcohols = {}
    print('alcohols doesn\'t exist.')

and

print('Exiting and saving the data.')
        alcohols.dump('Alcohols.txt') #saves the dictionary data as is

It saves the dictionary fine while adding new items but say I have to make an edit and remove something then save and exit. Next time loaded up it would have the old items as well as any new ones. Oddly enough I seem to have broken something in all my editing. Doesn't save new entries.

Edit2:

                del alcohols[name] #deletes the key out of the dict

This is how I remove the keys. Originally I was using the pop method but when it wouldn't save the changes I tried this. As a note it DID remove they key, value from the dictionary but saving and reloading wouldn't reflect that change.

                alcohols[name] = Alcohol() #instantiates the new class

Ths is how I am creating new key, value pairs.

SOLVED edit:

My problem was with the way I deleted them from the dictionary. In case anyone stumbles into here later. Look at @Mike Mckerns answer. Had to remove from the archived dictionary.

shx2
  • 61,779
  • 13
  • 130
  • 153
Mario ER
  • 53
  • 1
  • 7
  • 1
    I'm the author of `klepto`. Can you post a reduced snippet of code that demonstrates your issue? That would help elucidate what your issue/problem/question is... – Mike McKerns Mar 26 '15 at 04:37
  • `klepto` provides a dictionary interface to a caching-backed (like a directory of files, a file, or a database) -- and you have to `pop` or `update` the appropriate key from the dictionary. `klepto` allows you to have both "in-memory" caching and a backend that you can choose when and how to synchronize. So, I still don't see what your issue is… but if you post code that pinpoints you are trying and show it not working as expected, I bet I can show you what you need to do. How are you editing the entries? – Mike McKerns Mar 26 '15 at 12:57

1 Answers1

8

Basically, you are deleting from the "in-memory" cache, and not from the "file" cache. A klepto archive by default gives you "in-memory" cache, which you use directly through the dict interface, and it also gives you an archive which is the back-end.

Thus, when you dump, you transfer the in-memory items to the back-end. To delete from the cache and from the archive, you have to delete from both.

>>> from klepto.archives import *
>>> arch = file_archive('foo.txt')
>>> arch['a'] = 1
>>> arch['b'] = 2
>>> # look at the "in-memory" copy
>>> arch
file_archive('foo.txt', {'a': 1, 'b': 2}, cached=True)
>>> # look at the "on-disk" copy
>>> arch.archive
file_archive('foo.txt', {}, cached=False)
>>> # dump from memory to the file
>>> arch.dump()
>>> arch.archive
file_archive('foo.txt', {'a': 1, 'b': 2}, cached=False)
>>> arch 
file_archive('foo.txt', {'a': 1, 'b': 2}, cached=True)
>>> # delete from the in-memory cache
>>> arch.pop('a')
1
>>> # delete from the on-disk cache
>>> arch.archive.pop('a')
1
>>> arch
file_archive('foo.txt', {'b': 2}, cached=True)
>>> arch.archive
file_archive('foo.txt', {'b': 2}, cached=False)

I guess I could make it easier to delete from both in a single function call...

Mike McKerns
  • 33,715
  • 8
  • 119
  • 139
  • Perfect I figured it was something like in memory cache but don't know enough of the terminology and specifics to have guided you to this. That's why I changed my own pop to a del because I knew pop can leave it in memory. Anyway this is exactly what I was missing to removing a value from my dict. – Mario ER Mar 27 '15 at 00:25
  • @MarioER: `del` will also work. You just have to `del` from both. – Mike McKerns Mar 27 '15 at 00:39