Posts: 48
Threads: 9
Joined: Jun 2024
I’m trying to learn nested directories, by mirroring an ancient disk structure in nested directories, the nested directory structure is intended to be loaded by looping through an entire disk (have not gotten to that yet).
The basic disk attributes, and mirrored nested directory structure at this point, looks like this:
dskn = 0 # alpha micro up to 32mb disk number (16 bit logical disk)
ufds = '1,2' # alpha micro disk user file directory 16 bit, 2 bytes comma separated
file = 'BADBLK.SYS' # file name
blocks = 3 # number of full blocks in file
active = 500 # number of bytes in last block of file
link = 1242 # link to first block of file
# alpha micro disk structure dsk number, ufds, file *** blown apart for understanding ***
dsk = {
dskn: {
ufds: {
file: {
'blocks': blocks,
'active': active,
'link': link
}
}
}
} So my current question is, does it matter whether adding dictionary elements as individual key/value pairs or another loaded dictionary (cleared after each file), is one more appropriate than the other for this use, or a yet better way?
curbie
Posts: 6,800
Threads: 20
Joined: Feb 2020
Are you asking about using update() vs assignment?
Assignment:
from pprint import pprint
dsk = {0: {"1, 2": {"BADBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}}
dsk[0]["1, 2"]["SOMEFILE"] = {"blocks": 2, "active": 100, "link": 4567}
dsk[0]["1, 3"] = {"GOODBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}
dsk[1] = {"1, 3": {"AROUNDTHEBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}
pprint(dsk) Output: {0: {'1, 2': {'BADBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242},
'SOMEFILE': {'active': 100, 'blocks': 2, 'link': 4567}},
'1, 3': {'GOODBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242}}},
1: {'1, 3': {'AROUNDTHEBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242}}}}
Update:
from pprint import pprint
dsk = {0: {"1, 2": {"BADBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}}
dsk.update({0: {"1, 2": {"SOMEFILE": {"blocks": 2, "active": 100, "link": 4567}}}})
dsk.update({0: {"1, 3": {"GOODBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}})
dsk.update({1: {"1, 3": {"AROUNDTHEBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}})
pprint(dsk) Output: {0: {'1, 3': {'GOODBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242}}},
1: {'1, 3': {'AROUNDTHEBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242}}}}
Not the same results.
If doing assignment, do not re-use the same dictionary as implied by "another loaded dictionary (cleared after each file)". Create a new dictionary for each entry.
Posts: 48
Threads: 9
Joined: Jun 2024
deanhystad,
My newbee understanding, is that directories require a key/value pair, but the value of that key value pair could be another dictionary.
Like:
file = 'AMOSL.DIR' # file name
blocks = 2 # number of full blocks in file
active = 222 # number of bytes in last block of file
link = 1462 # link to first block of file
addf = { # dictionary to add file attributes
'blocks': blocks,
'active': active,
'link': link
}
dsk[dskn][ufds][file] = addf # add file attributes
addf.clear() # clear directory for next file in loop or individual assignments as in your Assignment: example.
Posts: 6,800
Threads: 20
Joined: Feb 2020
Quote:individual assignments as in your Assignment: example
Not sure what you mean by this. All assignments are "individual". You add a key and a value to the dictionary. The key has to be hashable (any immutable object will do). The value can be anything.
Dictionaries hold values, not variables. The code below shows there is no relationship between blocks and addf["blocks"]
blocks = 2
active = 222
link = 1462
addf = {
'blocks': blocks,
'active': active,
'link': link
}
print(addf)
blocks = 3
active = 1
link = 42
print(addf) Output: {'blocks': 2, 'active': 222, 'link': 1462}
{'blocks': 2, 'active': 222, 'link': 1462}
Using variables to build a dictionary is fine, but you cannot "reload" a dictionary by changing the variables you used to build it. I might be reading something into your example, so this might be off base.
Posts: 48
Threads: 9
Joined: Jun 2024
Sep-26-2024, 05:26 PM
(This post was last modified: Sep-26-2024, 05:26 PM by Curbie.)
Deanhystad,
Thank you for your patients with a newbee, I know I must be frustrating, my frustration is after doing many tutorials I have found on nested dictionaries, I’m sure all by competent well meaning programmers (thank goodness for that), explaining different ways to use nested dictionaries, but not explaining why and under what circumstances to use one way over the other.
I know I wasn’t clear in using the proper examples when asking the question:
“So my current question is, does it matter whether adding dictionary elements as individual key/value pairs or another loaded dictionary (cleared after each file), is one more appropriate than the other for this use, or a yet better way?“
dskn = 0 # alpha micro up to 32mb disk number (16 bit logical disk)
ufds = '1,2' # alpha micro disk user file directory 16 bit, 2 bytes
file = 'AMOSL.DIR' # file name
blocks = 63 # number of full blocks in file
active = 222 # number of bytes in last block of file
link = 5222 # link to first block of file
dsk[dskn][ufds][file] = {"blocks": blocks, "active": active, "link": link} # new file w/attr In the above example the value of file 'AMOSL.DIR's "block", "active", and "link" elements are seemed to be assigned as a single dictionary (although, it seems it could be a separate dictionary), where as in the following example each file attribute is assigned individually:
dsk[dskn][ufds][file]["blocks"] = blocks
dsk[dskn][ufds][file]["active"] = active
dsk[dskn][ufds][file]["link"] = link Is one way more appropriate for this use than the other???
Posts: 6,800
Threads: 20
Joined: Feb 2020
Posts: 48
Threads: 9
Joined: Jun 2024
I must have some fundamental misunderstanding because I can’t load more than one full file specification, no matter what I try.
I wrote a little ‘post able” program to illustrate the issues I’m having, this program uses parallel lists to simulate building the dictionary from a SD card with multiple sub-directories each with multiple files with the same multiple attributes.
def get_all_values(obj, level=0): # not my function
"""Walk through a dictionary of dicts and lists."""
if type(obj) is dict:
for key, value in obj.items():
if type(value) in [dict, list]:
print(' ' * level, key, sep='')
level = level + 1
get_all_values(value, level)
level = level - 1
else:
print(' ' * (level), key, ': ', value, sep='')
elif type(obj) is list:
for i, element in enumerate(obj):
if type(element) in [dict, list]:
print(' ' * level, i, sep='')
level = level + 1
get_all_values(element, level)
level = level - 1
else:
print(' ' * (level), element, sep='')
else:
raise ValueError
dsk = {} # create empty directory
dskn = 0 # alpha micro up to 32mb disk number (16 bit logical disk)
#dsk = {dskn: {'1,2': {'INIT.DIC': {'blocks': 55, 'active': 66, 'link': 77}}}}
ufd = ['1,2', '1,2', '1,4', '1,4'] # list for user file directories
file = ['BADBLK.SYS', 'AMOSL.DIR', 'AMOSL.INI', 'AMOS32.INI'] # file name
blocks = [3, 42, 2, 4] # list for number of full blocks in file
active = [500, 400, 300, 200] # list for number of bytes in last block of file
link = [1600, 1500, 1400, 1300] # list for link to first block of file
for i in range(0, 4): # loop through adding dsk number
# overwrites all ufds but last
dsk[dskn] = ufd[i]
print(dsk)
for i in range(0, 4): # loop through adding ufd
uuu = ufd[i]
fff = file[i]
bbb = blocks[i]
aaa = active[i]
lll = link[i]
# dsk[dskn][uuu] = {fff: {'blocks': bbb, 'active': aaa, 'link': lll}}
# raises -> Class 'str' does not define '__setitem__', so the '[]' operator cannot be used on its instances
dsk.update({dskn:{uuu:{fff: {'blocks': bbb, 'active': aaa, 'link': lll}}}})
# overwrites all full files but last
for i in range(0, 4): # loop through adding ufd
uuu = ufd[i]
fff = file[i]
bbb = blocks[i]
aaa = active[i]
lll = link[i]
# dsk[dskn][uuu] = {fff: {'blocks': bbb, 'active': aaa, 'link': lll}}
# raises -> Class 'str' does not define '__setitem__', so the '[]' operator cannot be used on its instances
dsk.update({dskn:{uuu:{fff: {'blocks': bbb, 'active': aaa, 'link': lll}}}})
# raises -> SyntaxError: invalid syntax
get_all_values(dsk) There is a couple of commented out tries and their errors here too.
Basically, I'm trying to load nested dictionaries with all full files on the SD, but can't. What do I have goofed up???
Posts: 6,800
Threads: 20
Joined: Feb 2020
Oct-01-2024, 02:17 PM
(This post was last modified: Oct-01-2024, 02:17 PM by deanhystad.)
I finally understand your question.
As I showed in an earlier post, you cannot use update for this.
dsk.update({dskn:{uuu:{fff: {'blocks': bbb, 'active': aaa, 'link': lll}}}}) Will replace the existing value of dsk[dskn] with {uuu:{fff: {'blocks': bbb, 'active': aaa, 'link': lll}}}
Posts: 48
Threads: 9
Joined: Jun 2024
deanhystad,
I assume this is the code I should use, instead of dsk.upgrade()???
I’ve commented your example code lines as to what I think they’re doing, are my interpretations correct???
# initialize intended disk structure, while adding dsk0, 1,2 and full file?
# dsk = {0: {"1, 2": {"BADBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}}
# add file attributes to existing dsk0 and 1,2 and file name?
# dsk[0]["1, 2"]["SOMEFILE"] = {"blocks": 2, "active": 100, "link": 4567}
# add full file to existing dsk0 and new 1,3?
# dsk[0]["1, 3"] = {"GOODBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}
# add full file to new dsk1 with new 1,3?
#dsk[1] = {"1, 3": {"AROUNDTHEBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}} If my current interpretation is correct, it seems that the ‘parent?’ dictionary must have an item loaded, before ‘child?’ dictionary can be hung off it???
Posts: 6,800
Threads: 20
Joined: Feb 2020
"A dictionary must exist before you can use it." is more accurate. If you want to add a directory to the disk #1 dictionary, there must be a disk #1 dictionary.
You could write you own function that "adds" a dictionary to an existing dictionary. Something like this:
from pprint import pprint
def add(old, new):
"""Add new dictionary to old."""
while True:
key, value = next(iter(new.items()))
if key in old:
old = old[key]
else:
old[key] = value
break
new = value
dsk = {}
add(dsk, {0: {"1, 2": {"BADBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}})
add(dsk, {0: {"1, 2": {"SOMEFILE": {"blocks": 2, "active": 100, "link": 4567}}}})
add(dsk, {0: {"1, 3": {"GOODBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}})
add(dsk, {1: {"1, 3": {"AROUNDTHEBLK.SYS": {"blocks": 3, "active": 500, "link": 1242}}}})
pprint(dsk) Output: {0: {'1, 2': {'BADBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242},
'SOMEFILE': {'active': 100, 'blocks': 2, 'link': 4567}},
'1, 3': {'GOODBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242}}},
1: {'1, 3': {'AROUNDTHEBLK.SYS': {'active': 500, 'blocks': 3, 'link': 1242}}}}
But before writing this, make sure you need it. I would start this project by writing the code that loops through the entire disk (the part you are putting off). That code may reveal disks, dictionaries and files in an order that naturally lends itself to making a nested dictionary without much effort.
|