Python Forum
Mirroring disk structures in nested dictionaries
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Mirroring disk structures in nested dictionaries
#11
deanhystad,

Thank you, finally got to code that works.
from pprint import pprint 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 def add(old, new): # function by deanhystad - curbie comment """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 dskn = 0 # alpha micro up to 32mb disk number (16 bit logical disk) 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 dsk = {} # create blank dictionary for i in range(0, 4): # loop through adding files uuu = ufd[i] fff = file[i] bbb = blocks[i] aaa = active[i] lll = link[i] add(dsk, {dskn: {uuu: {fff: {"blocks": bbb, "active": aaa, "link": lll}}}}) get_all_values(dsk)



(Oct-01-2024, 05:17 PM)deanhystad Wrote: 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.

Done before I started this thread.
[1,2]	Link: 127	PW: | | [1,3]	Link: 1081	PW: | | [1,4]	Link: 2157	PW: | | plus 29 more UFDs ********************************************************* AAA .BAK Blocks: 1 Active: 2 Link: 2156 ABC .LIT Blocks: 19 Active: 60 Link: 2158 ABCLON.LIT Blocks: 29 Active: 373 Link: 2177 ABMAST.LIT Blocks: 17 Active: 370 Link: 2206 ABMON .CMD Blocks: 1 Active: 54 Link: 2223 ABREAD.LIT Blocks: 4 Active: 254 Link: 2224 ABRELI.EXP Blocks: 1 Active: 30 Link: 2228 ABRELI.LIT Blocks: 21 Active: 454 Link: 2229 ABRELI.OVR Blocks: 10 Active: 416 Link: 2250 ABRELI.RKT Blocks: 4 Active: 299 Link: 2260 ABRELI.RTB Blocks: 4 Active: 228 Link: 2264 ABRELI.SYS Blocks: 16 Active: 122 Link: 2268 ABRND .LIT Blocks: 5 Active: 20 Link: 2284 plus 1400 more full file specs distributed among the UFDs
Now on to studying your 'add' function to try to figure out where I goofed up.
Reply
#12
Why do you do this:
for i in range(0, 4): # loop through adding files uuu = ufd[i] fff = file[i] bbb = blocks[i] aaa = active[i] lll = link[i] add(dsk, {dskn: {uuu: {fff: {"blocks": bbb, "active": aaa, "link": lll}}}})
instead of this:
for i in range(0, 4): # loop through adding files add(dsk, {dskn: {ufd[i]: {file[i]: {"blocks": blocks[i], "active": active[i], "link": link[i]}}}})
Reply
#13
Because, I find it easier to read and debug while learning a new language, when everything works as intended, I can compress for speed and fewer lines.
Reply
#14
Over the last 50 years I’ve learned maybe a dozen programming languages, but python nested dictionaries is the first programming language concept that has frustrated me, the concept is simple enough, but working with them is frustrating, deanhystad posted an “add” function which functioned perfectly for everything but my understanding of working with them.

Now, I need to push the program I used deanhystad’s “add” function for, and start to chart the porting of my Alpha Micro disassembler to python because of the speed advantages of modern computers over a 8mhz 68000. Which brings me back to properly understanding nested dictionaries.

I went back to scratch just two dictionaries one for the logical disk name (‘dsk0’), and the second for the directories on that logical disk (‘dsk0’: {‘1,2’: 1}). The is typically about 25 directories on a logical disk, but could be many more.

Currently I’m building the nested directories by first starting one logical disk, then adding all directories on that logical disk, then all file names and their attributes for the first directory, before repeating for the next directories. Lastly, checking for another logical disk and repeating if found, halting if not.

Don’t know where I’m goofing up, my screwed up brain throws fits and kills my focus any time I try to code something with code I can’t visualize in my head.
[/python]
fs = {'dsk0': {}} # device name paired with empty dictionary fs['dsk0'] = {'1,2': {}} # add 1,2 fs['dsk0'] = {'1,4': {}} # add 1,4 fs['dsk0'] = {'1,6': {}} # add 1,6 print(fs) # print file system dictionaries
Output:
{'dsk0': {'1,6': {}}}
It seems apparent that my attempt to add an element is just changing the same element.

How do I add a (directory) dictionary nested a to logical disk directory?
Reply
#15
You keep changing the value for fs['dsk0']

Do this instead
fs = {"dsk0": {}} # device name paired with empty dictionary fs["dsk0"]["1,2"] = {} fs["dsk0"]["1,4"] = {} fs["dsk0"]["1,6"] = {} print(fs)
Output:
{'dsk0': {'1,2': {}, '1,4': {}, '1,6': {}}}
Reply
#16
Thanks deanhystad,

Your output pointed me to my issue, now everything works correctly on two nested dictionaries, after I play with this some more, I should be able to nest two more dictionaries for files and file attributes. After a little more tweaking, I was able to load the nested dictionary from variables:

dnam = 'dsk0' # variable for storage device name (dsk0 only) ufd = ['1,2', '1,4', '1,6'] # list for user file directories (for dsk0 only) fs = {'dsk0': {}} # device name paired with empty dictionary for x in ufd: # loop through directories fs[dnam][x] = {} # add directory to dsk0 logical disk 'dsk0' print(fs) # print directory progression print(fs) # print finished file system dictionaries
The finial output seems the same as yours:
Output:
{'dsk0': {'1,2': {}}} {'dsk0': {'1,2': {}, '1,4': {}}} {'dsk0': {'1,2': {}, '1,4': {}, '1,6': {}}} {'dsk0': {'1,2': {}, '1,4': {}, '1,6': {}}}
Reply
#17
This may interest you. In particular the __setitem__ part that builds a directory structure while adding files.
class File: """Represents a file in a file system.""" def __init__(self, content, name='', folder=None): self.content = content self.name = name self.folder = None if folder: folder.add(self) def move(self, folder, name=None): """Move to new location.""" if self.folder: self.folder.remove(self) if name: self.name = name folder.add(self, self.name) def path(self): """Return path as list of folders.""" path = [self] folder = self.folder while folder: path.insert(0, folder) folder = folder.folder return path def path_str(self): """Return path as str.""" return '/'.join(map(str, self.path())) def __str__(self): """Return pretty str.""" return self.name def __repr__(self): """Return descriptive str.""" return f"<{self.__class__.__name__} {self.name} in {self.folder}>" def __lt__(self, other): """For sorting.""" return str(self) < str(other) class Folder(File): """A special file who's content is a list of files and folders.""" def __init__(self, name='', folder=None): super().__init__({}, name, folder) def add(self, file, name=None): """Add file to folder.""" if file.folder: file.folder.remove(file) if name is not None: file.name = name file.folder = self self.content[file.name] = file def remove(self, file): """Remove file from folder.""" if file.name in self.content: self.content.pop(file.name) file.folder = None def __getitem__(self, path): """Get file/folder using relative path.""" def get(folder, part): """Return folder[part].""" if part == '..': return folder.folder return folder.content[part] file = self for part in path.split('/'): file = get(file, part) return file def __setitem__(self, path, file): """Add file to folder using relative path. Builds path if required.""" def get(folder, part): """Return folder[part]. Create folder if not found.""" if part == '..': return folder.folder elif part in folder.content: return folder.content[part] return Folder(part, folder) folder = self parts = path.split('/') for part in parts[:-1]: folder = get(folder, part) folder.add(file, parts[-1]) def __iter__(self): """Iterate through file names.""" return iter(self.content) def walk(self): """Walk through the folder and subfolder returning files.""" for file in self.content.values(): if isinstance(file, Folder): for subfile in file.walk(): yield subfile else: yield file root = Folder("") root["A/B/C/file1"] = File(1) root["A/B/file2"] = File(2) root["A/B/file3"] = File(3) root["D/file4"] = File(4) a = root["A"] b = a["B"] c = b["C"] d = root["D"] print("root:", *root.content) print("/A:", *a.content) print("/A/B:", *b.content) print("/A/B/C:", *c.content) print("/D:", *d.content) print("/D[../A/B/file3]:", d["../A/B/file3"]) for file in root.walk(): print(file.path_str(), "content =", file.content)
Output:
root: A D /A: B /A/B: C file2 file3 /A/B/C: file1 /D: file4 /D[../A/B/file3]: file3 /A/B/C/file1 content = 1 /A/B/file2 content = 2 /A/B/file3 content = 3 /D/file4 content = 4
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Nested Dictionaries, good programming practice? Curbie 6 2,007 May-28-2025, 10:45 PM
Last Post: Curbie
  Nested Lists & Dictionaries Hudjefa 5 2,195 Sep-23-2024, 08:20 PM
Last Post: DeaD_EyE
  DEC pack, unpack and disk-images Curbie 32 10,570 Aug-23-2024, 03:37 PM
Last Post: Curbie
  Windows Disk Cleanup Code Help Needed nal2us2 3 1,748 Jul-19-2024, 04:03 AM
Last Post: deanhystad
  Hard disk structure like a file selection dialog malonn 2 2,522 Aug-09-2023, 09:14 PM
Last Post: malonn
  Searching through Nested Dictionaries and Lists Dave_London 1 12,330 Jul-09-2020, 03:36 PM
Last Post: mrdominikku
  ctypes and custom data type (structures, pointer to structures) python_user_n 0 5,427 Jul-08-2020, 05:52 PM
Last Post: python_user_n
  How to Calculate CPU, Disk, Memory and Network utilization rate skvivekanand 1 3,174 Jun-16-2020, 08:53 PM
Last Post: jefsummers
  Creating Nested Dictionaries Confusion gw1500se 2 3,412 May-18-2020, 11:16 PM
Last Post: gw1500se
  how to write offset number to disk use python? Pyguys 4 5,168 Apr-11-2020, 07:53 AM
Last Post: Pyguys

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.