L.C
L.C

Reputation: 57

Python 3.5 Tkinter how to save dict to file

So my my problem is that I'm running a program once it has finished base functions a pop up box appears asking the user if they would like to save file, if 'yes' then a save dialog box appears. Because the data I'm saving is a dict value I'm receiving an Error from tkinter. I have attempted to use the ".csv" extension as a save point as i read somewhere that dict's can be saved to them, but i'm either going about this wrong way or there is an issue within my code.

Updated Code and explanation why below

Original snippet of code:

def flag_detection():

total_count = Counter(traffic_light)
total_count.keys()
for key, value in total_count.items():

    EWT = tkinter.messagebox.askquestion('File Level', 'Would you like to save')

    file_opt = options = {}
    options['filetypes'] = [('all files', '.*'), ('text files', '.csv')]
    options['initialfile'] = 'myfile.csv'

    if EWT == 'yes':
        savename = asksaveasfile(file_opt, defaultextension=".csv")
        savename.write(key, ':', value)

Error message:

    Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Lewis Collins\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1550, in __call__
    return self.func(*args)
  File "C:/Users/Lewis Collins/PycharmProjects/program_06.01.17/Home.py", line 108, in run_language_model
    main.flag_detection()
  File "C:\Users\Lewis Collins\PycharmProjects\program_06.01.17\main_code\main.py", line 179, in flag_detection
    savename = asksaveasfile(file_opt, defaultextension=".csv")
  File "C:\Users\Lewis Collins\AppData\Local\Programs\Python\Python35-32\lib\tkinter\filedialog.py", line 423, in asksaveasfile
    return open(filename, mode)
TypeError: open() argument 2 must be str, not dict

Because of Tkinter throwing back that it can not save a dict to file i tried the below solution of converting the dict to a str which has also caused problems

Code Snippet of Function attempt to convert to str for tkinter:

def flag_detection():


total_count = Counter(traffic_light)
total_count.keys()
for key, value in str(total_count.items()):
    EWT = tkinter.messagebox.askquestion('File Level', 'Would you like to save')
    file_opt = options = {}
    options['filetypes'] = [('all files', '.*'), ('text files', '.csv')]
    options['initialfile'] = 'myfile.csv'

    if EWT == 'yes':
        savename = asksaveasfile(file_opt, defaultextension=".csv")
        savename.write(key, ':', value)

So I've updated my code to try and use the str(total_count.items()): to convert to dict as i didn't quite understand the json and pickle libraries after reading them they seemed to complicated for what i needed which is a simple output to a file for a user to be able to go and view.

I am now receiving this Error:

    Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Lewis Collins\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 1550, in __call__
    return self.func(*args)
  File "C:/Users/Lewis Collins/PycharmProjects/program_05.0.17/Home.py", line 108, in run_language_model
    main.flag_detection()
  File "C:\Users\Lewis Collins\PycharmProjects\program_05.0.17\main_code\main.py", line 169, in flag_detection
    for key, value in str(total_count.items()):
ValueError: not enough values to unpack (expected 2, got 1)

Any suggestions or feedback is welcome, Thanks in advance.

Upvotes: 1

Views: 1094

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 386275

The first problem is this line:

savename = asksaveasfile(file_opt, defaultextension=".csv")

That is simply not how to call asksaveasfile. asksaveasfile doesn't take a dictionary as its first argument. You should call it this way if you want to use the options in file_opt1:

savename = asksaveasfile(defaultextension=".csv", **file_opt)

When you fix that, the next problem is where you try to write with this statement:

savename.write(key, ':', value)

You get this error message: TypeError: write() takes exactly 1 argument (3 given). It means exactly what it says: you need to provide a single argument rather than three arguments. You can solve that by giving write exactly 1 argument:

savename.write("%s: %s" % (key, value))

However, if all you want to do is save a dictionary to a file, the json module makes this quite easy, without having to iterate over the values.

To save as json, change your flag_detection method to look like this:

import json
...
def flag_detection():

    total_count = Counter(traffic_light)

    EWT = tkinter.messagebox.askquestion('File Level', 'Would you like to save')

    file_opt = options = {}
    options['filetypes'] = [('all files', '.*'), ('text files', '.json')]
    options['initialfile'] = 'myfile.json'

    if EWT == 'yes':
        savefile = asksaveasfile(defaultextension=".json", **file_opt)
        json.dump(total_count, savefile)

If you want to save as a csv file, read the documentation on the DictWriter class which works in a similar way.

Upvotes: 2

Related Questions