Hello I have combed threw possible solutions and I can't figure this out, I got my program working for the most part but the problem is when I close the program it doesn't remember the changes made by the user. The program stored input into variables. It works like a dictionary (I wrote the code before I knew about the dictionary function) when I open the program I can enter the input but the problem is when I close the program it forgets all the changes and goes back to how it was when first compiled. Any ideas how I can allow the data to ramain available when I close the program and reopen it?
Probably you need shelve. It is awesome Python library, which allows you to read/write dict-like data from file. For example:
import shelve
dict_with_data = dict(key1='value1', key2='value2')
storage = shelve.open('shelve_file')
storage.update(dict_with_data)
storage.close()
It is very simple example which opens shelve storage and updates it with your data. Actually you can do whatever you do with regular dictionary object, because
A “shelf” is a persistent, dictionary-like object.
Another library that you could use is pickle. It allows you serialize every kind of Python objects, but since you have dictionary structure shelve should be better for your needs.
Please fill free to ask questions/post your code, I will be glad to update my answer appropriate to you needs.
I think you need to implement two things here.
1) Your program need to take an optional input file and the best way to do it is probably to use argparse. If you pass the input file, then you extract the data from the file and you initialize your dictionary_like object with that data.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--input', help='input file name')
args = parser.parse_args()
if args.input:
... # open the file, load the data, initialize a dict with the data
2) Just before quitting, you must save your data (key:value pairs) in the input file. If you want to save a dictionary like structure, a txt file with a key:value pairs for each line of the file should be good enough.
with open(input, 'w') as f:
for key,value in dictionary.items():
f.write(str(key)+':'+str(value)+'\n') #you can use '\t' or whatever instead the ':'
And that's it.
If you need more help on how to implement this let me know ;)
Related
I'm sick of doing
with open('my.json','r') as inf:
my_dict = json.load(inf)
each time I want to get the contents of a json file as a dict in python. It seems so trivial to simply add a function that just accepts 'my.json' as a path and then implicitly opens the file and then loads the json file with whatever additional keywords you want. I found the pandas.read_json() class, but if I tried that it gave me the same error that I get if I try to call json.load() on a filepath. Is it difficult to add my custon reading function to the json package? How do I add a function to a package that is easily callable from any script with an import statement, so I don't have to write the same function over and over again? Is there a particular reason why this isn't an available function? Am I just lazy?
I know what the code for my solution is, I just don't know where to add it so it's easily importable and whether or not this is a very bad idea to begin with, since it would require a modification of a builtin python package.
This seems like a pretty obvious/dumb question, but there are a few specifications that make this a bit harder.
Let's say I have a program that takes 3 numbers from a user and does mathematical processes to them to get outputs. Then I open("file", "r") to write those variables to a file.
Then, let's say another program then imports them and uses them for other processes. I need to be able to import that file as Python code. To be clear: I am not saving text, I am saving python code to a file that is not a .py file.
Is there any way to save and import Python code to and from a non-.py file? And how?
EDIT: In the file I'm saving and importing, I'm also saving Python functions. I cannot simply save the variables themselves; I need the variable names, values, and python functions to be saved as normal text in a file, but when I import the file, it should be parsed as Python code.
Probably not a good idea to store computation result as code & then import it from elsewhere. You should use a proper data format to store the results - and import it as data. Use JSON or pickle etc.
However, if you do want to shoot yourself in the foot, Python gives you the tools to do that:
Let's say i have some code in a file temp.txt
number3=30
def f():
return 'method'
Then you can do this:
with open('temp.txt') as f:
code = f.read()
exec(code)
print(number3)
print(f())
Which outputs:
30
method
If i got this right, this might be done via eval function e.g. you save all code to be executed into a string and then save into a file.
When you need that executed read the file, tke the string and eval it
I must say however that using eval is a bad (very bad) practice and i would advice against it unless there is no other solution that you can find
I am using tkinter to manage the GUI for a note retrieval program. I can pull my notes by typing a key word and hitting Enter in a text field but I would like to move my dictionary to a file so that my code space is not filled up with a massive dictionary.
I have been looking around but I am not sure how I would go about doing this.
I have the file in my directory. I know I can use open(“filename”, “mode”) to open said file for reading but how do I call each section of the notes.
For example what I do now is just call a keyword from my dictionary and have it write the definition for that keyword to a text box in my GUI. Can I do the same from the file?
How would I go about reading from the file the keyword and returning the definition to a variable or directly to the text box? For now I just need to figure out how to read the data. I think once I know that I can figure out how to write new notes or edit existing notes.
This is how I am set up now.
To call my my function
root.bind('<Return>', kw_entry)
How I return my definition to my text box
def kw_entry(event=None):
e1Current = keywordEntry.get().lower()
if e1Current in notes:
root.text.delete(1.0, END)
root.text.insert(tkinter.END, notes[e1Current])
root.text.see(tkinter.END)
else:
root.text.delete(1.0, END)
root.text.insert(tkinter.END, "Not a Keyword")
root.text.see(tkinter.END)
Sound's like you'd need to load the dictionary to memory at init time, and use it like a normal dictionary.
I am assuming your dictionary is a standard python dict of strings, so I recommend using the python json lib.
Easiest way to do this is to export the dictionary as json once to a file using something like:
with open(filename, 'w') as fp:
json.dump(dictionary, fp)
and then change your code to load the dict at init time using:
with open(filename) as fp:
dictionary = json.load(fp)
Alternatively, if your data is more complex than text, you can use python shelve which is a persistent, dictionary-like object to which you can pass any pickle-able object. Note that shelve has its drawbacks so read the attached doc.
sqlitedict is a project providing a persistent dictionary using sqlite in the background. You can use it like a normal dictionary e.g. by assigning arbitrary (picklable) objects to it.
If you access an element from the dictionary, only the value you requested is loaded from disk.
So I basically just want to have a list of all the pixel colour values that overlap written in a text file so I can then access them later.
The only problem is that the text file is having (set([ or whatever written with it.
Heres my code
import cv2
import numpy as np
import time
om=cv2.imread('spectrum1.png')
om=om.reshape(1,-1,3)
om_list=om.tolist()
om_tuple={tuple(item) for item in om_list[0]}
om_set=set(om_tuple)
im=cv2.imread('RGB.png')
im=cv2.resize(im,(100,100))
im= im.reshape(1,-1,3)
im_list=im.tolist()
im_tuple={tuple(item) for item in im_list[0]}
ColourCount= om_set & set(im_tuple)
File= open('Weedlist', 'w')
File.write(str(ColourCount))
Also, if I run this program again but with a different picture for comparison, will it append the data or overwrite it? It's kinda hard to tell when just looking at numbers.
If you replace these lines:
im=cv2.imread('RGB.png')
File= open('Weedlist', 'w')
File.write(str(ColourCount))
with:
import sys
im=cv2.imread(sys.argv[1])
open(sys.argv[1]+'Weedlist', 'w').write(str(list(ColourCount)))
you will get a new file for each input file and also you don't have to overwrite the RGB.png every time you want to try something new.
Files opened with mode 'w' will be overwritten. You can use 'a' to append.
You opened the file with the 'w' mode, write mode, which will truncate (empty) the file when you open it. Use 'a' append mode if you want data to be added to the end each time
You are writing the str() conversion of a set object to your file:
ColourCount= om_set & set(im_tuple)
File= open('Weedlist', 'w')
File.write(str(ColourCount))
Don't use str to convert the whole object; format your data to a string you find easy to read back again. You probably want to add a newline too if you want each new entry to be added on a new line. Perhaps you want to sort the data too, since a set lists items in an ordered determined by implementation details.
If comma-separated works for you, use str.join(); your set contains tuples of integer numbers, and it sounds as if you are fine with the repr() output per tuple, so we can re-use that:
with open('Weedlist', 'a') as outputfile:
output = ', '.join([str(tup) for tup in sorted(ColourCount)])
outputfile.write(output + '\n')
I used with there to ensure that the file object is automatically closed again after you are done writing; see Understanding Python's with statement for further information on what this means.
Note that if you plan to read this data again, the above is not going to be all that efficient to parse again. You should pick a machine-readable format. If you need to communicate with an existing program, you'll need to find out what formats that program accepts.
If you are programming that other program as well, pick a format that other programming language supports. JSON is widely supported for example (use the json module and convert your set to a list first; json.dump(sorted(ColourCount), fileobj), then `fileobj.write('\n') to produce newline-separated JSON objects could do).
If that other program is coded in Python, consider using the pickle module, which writes Python objects to a file efficiently in a format the same module can load again:
with open('Weedlist', 'ab') as picklefile:
pickle.dump(ColourCount, picklefile)
and reading is as easy as:
sets = []
with open('Weedlist', 'rb') as picklefile:
while True:
try:
sets.append(pickle.load(output))
except EOFError:
break
See Saving and loading multiple objects in pickle file? as to why I use a while True loop there to load multiple entries.
How would you like the data to be written? Replace the final line by
File.write(str(list(ColourCount)))
Maybe you like that more.
If you run that program, it will overwrite the previous content of the file. If you prefer to apprend the data open the file with:
File= open('Weedlist', 'a')
I want to copy the contents of a JSON file in another JSON file, with Python
Any ideas ?
Thank you :)
Given the lack of research effort, I normally wouldn't answer, but given the poor suggestions in comments, I'll bite and give a better option.
Now, this largely depends on what you mean, do you wish to overwrite the contents of one file with another, or insert? The latter can be done like so:
with open("from.json", "r") as from, open("to.json", "r") as to:
to_insert = json.load(from)
destination = json.load(to)
destination.append(to_insert) #The exact nature of this line varies. See below.
with open("to.json", "w") as to:
json.dump(to, destination)
This uses python's json module, which allows us to do this very easily.
We open the two files for reading, then open the destination file again in writing mode to truncate it and write to it.
The marked line depends on the JSON data structure, here I am appending it to the root list element (which could not exist), but you may want to place it at a particular dict key, or somesuch.
In the case of replacing the contents, it becomes easier:
with open("from.json", "r") as from, open("to.json", "w") as to:
to.write(from.read())
Here we literally just read the data out of one file and write it into the other file.
Of course, you may wish to check the data is JSON, in which case, you can use the JSON methods as in the first solution, which will throw exceptions on invalid data.
Another, arguably better, solution to this could also be shutil's copy methods, which would avoid actually reading or writing the file contents manually.
Using the with statement gives us the benefit of automatically closing our files - even if exceptions occur. It's best to always use them where we can.
Note that in versions of Python before 2.7, multiple context managers are not handled by the with statement, instead you will need to nest them:
with open("from.json", "r") as from:
with open("to.json", "r+") as to:
...