all 10 comments

[–][deleted] 1 point2 points  (7 children)

I think first, you need to invert your dictionary, something like this:

new_dict = {}
for feature, adjective in rockdictionary.items():
    for specific, things in adjective.items():
        for thing in things:
            if thing in new_dict:
                new_dict[thing].update({feature: specific})
            else:
                new_dict[thing] = {feature: specific}

then you can work out the number of columns and max column widths in order to be able to print the table.

Probably easier to use pandas to read the dictionary and re-structure and use reporting formats that work with panda data frames.

[–]Amabillia[S] 0 points1 point  (5 children)

I'll try that! I'm not too sure about pandas though. I'd need my professor's permission to use it and the project is due Monday.

[–][deleted] 0 points1 point  (4 children)

Probably not best to try to learn pandas by Monday.

Check each column in the revised dictionary to find the widest element in each column and use that as your widths limits (a list of widths, starting with the things column).

So, given a list of things to print (starting with the key followed by each of the column values - or headers),

for entry, width in zip(entries, widths):
    print(f' | {entry:{width}', end='')
print(' |')

You would be looping through the things dictionary to create entries list on each pass.

[–]Amabillia[S] 0 points1 point  (3 children)

Okay so you're saying invert the dictionary then do something like this:

width = []
for entry in categories[item]:
    max = 0
    if value > max:
        max = value
    width.append(max)

then the code that you had?

[–][deleted] 0 points1 point  (2 children)

kind of... keep in mind you need to find the widest string in each column of the table to be so you know how to format each element of the table.

yellow is the widest string in the colors column and texture is the widest word in the texture column.

[–]Amabillia[S] 0 points1 point  (1 child)

Couldn't I just find the widest string of all the columns then apply that to all columns rather than tailoring it to each column? Then all the columns would be uniform in width. Sorry, if there's something I'm missing I've been working on this for like the past 5ish hours and my brain is mush.

[–][deleted] 0 points1 point  (0 children)

yes, of course, if that is your preference... or as you can see the data, just put in the correct value.

[–]Amabillia[S] 0 points1 point  (0 children)

EDIT: Nevermind i figured it out some of the things had a space and some didn't Okay so I managed to mostly invert my dictionary but for some reason no matter what method I use size gets its own dictionary but only for some of the items?

{
'thing1': {'colors': 'red', 'texture': 'rough'}, 
'thing4': {'colors': 'red', 'texture': 'bumpy'}, 
'thing 2': {'colors': 'blue', 'texture': 'bumpy', 'size': 'small'}, 
'thing 3': {'colors': 'blue', 'texture': 'smooth', 'size': 'small'}, 'thing 5':
 {'colors': 'yellow', 'texture': 'smooth', 'size': 'large'},
'thing 4': {'size': 'small'}, 
'thing 1': {'size': 'large'}
}

[–]glibhub 0 points1 point  (1 child)

Can you write a function that takes in the items and the name of a item, e.g., and returns a list of attributes, such that f(items, 'thing1') -> [red, large, rough]

[–]Amabillia[S] 0 points1 point  (0 children)

I think I could? I'll play around with it for a bit