pythondictionaryprettytable

Trying to open a dictionary like txt file and print its contents into PrettyTable in Python


I'm trying to create a small Python script based on a dictionary with a key "name" and value "age" which should accept user input, write the dictionary to a .txt file and open then output the contents of the file into Pretty Table with columns called "Name", "Age". All the names the user typed should go under the Name column with the same applying to age. The entire code is inside a while loop and only closes if the user types "quit". What I'm willing to achieve is when the user types quit the program should print all the previous names and ages inside the file including the ones typed before exiting the program into Pretty Table.

Here is my code:

from prettytable import PrettyTable
import os


sw_dir = "C:\\Users\\user\\Documents\\"
dir_change = os.chdir(sw_dir)

test_dict = {}
active = True

name_table = PrettyTable(["Name", "Age"])

filename = "name_dict.txt"

while active:
    with open(filename, "a") as a_file:
        user_name = input("Enter name: ")
        user_age = input("Enter age: ")
        user_exit = input("Type quit to exit: ")
        test_dict[user_name] = user_age

        if user_exit == "quit":
            active = False
            for name, age in test_dict.items():
                a_file.write(str(name) + ":" + str(age) + "\n\n")
                with open(filename, "r") as r_file:
                    for test_dict in r_file:
                        name_table.add_row([name, age])
                    print(name_table) 

The problem is that the program only prints out the names (multiple times) that were typed before quitting, but it doesn't print the folder names inside the file i.e. the entire file.

Output sample:

| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
+---------------+-----+
+---------------+-----+
|      Name     | Age |
+---------------+-----+
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Grace Johnson |  26 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
| Elliot McLane |  42 |
+---------------+-----+

I would really appreciate it if someone could give me a hand as I'm still kind of new to Python, and have been struggling with this issue for days.


Solution

  • Couple of things to watch out for.

    First is that a dictionary key can have only one value and keys cannot repeat. So, you will not get the results you seek with a dictionary that looks like:

    {
        "Grace Johnson": "26",
        "Grace Johnson": "26",
        #...
        "Elliot McLane": "42",
        "Elliot McLane": "42",
    }
    

    You would need a structure more like:

    [
        {"Name": "Grace Johnson", "Age": "26"},
        {"Name": "Grace Johnson", "Age": "26"},
        # ....
        {"Name": "Elliot McLane", "Age": "42"},
        {"Name": "Elliot McLane", "Age": "42"},
    ]
    

    In either case, the next hiccup is that a dictionary or a proper list of dictionaries really needs to write the complete file and if you just want to append as you go, you might look into the "json lines" data format. See: https://jsonlines.org/

    Anyways, with those restrictions in mind (and ignoring PrettyTable as it does not seem relevant to the issue) here is one way to proceed.

    import json
    
    file_name = "name_dict.txt"
    
    ## ---------------------------
    ## Open our datafile (creating it is needs be)
    ## ---------------------------
    with open(file_name, "a+") as a_file:
        a_file.seek(0)  # reset the pointer back to the start of the file
        test_dict = json.loads(a_file.read() or "{}")
    ## ---------------------------
    
    while True:
        if "quit" == input("Type quit to exit: "):
            break
    
        user_name = input("Enter name: ")
        user_age = input("Enter age: ")
        test_dict[user_name] = user_age
    
        ## ---------------------------
        ## Write the complete dictionary back out
        ## ---------------------------
        with open(file_name, "w") as a_file:
            json.dump(test_dict, a_file)
        ## ---------------------------
    
    for key, value in test_dict.items():
        print(f"{key} --> {value}")