DEV Community

geraldew
geraldew

Posted on

Just some example work notes

Note for readers at Dev.to - this posting is not intended for general reading as is. However I may later write an article that refers to it. Not that anyone reads my posts here anyway.

The context for it, is some coding in progress at mexenum which comes from ongoing work on Foldatry and its companion application Diskartulary - but frankly that information while true would be way too tedious to try to describe.

Overview

This is some general musing as I seek to build out a general purpose body of code that will handle vital matters of custom values in my applications as well as the ability to save and reload them as "settings".

See "Stages of implementation" for what has come before this. These notes are being written to clarify ideas during the transition from stage "First abstraction" into "Second abstraction".

Layers

We're going to go over this set three times:

  • once just to list them
  • then with broad descriptions
  • then in more detail

List

  • Meta Extended Enumerations
  • Data types of Settings
  • A Settings Collection
  • Loadable Settings Collection
  • Savable Settings Collection

Descriptions

  • Meta Extended Enumerations = each Enumeration becomes a matrix of values, with a key and attributes - these will be used for various things throughout the program - really, everywhere that the application needs a definitive finite set of optional values.
  • Data types of Settings = because we will restrict this "Settings ability" to a fairly small number of data types - but it will include the ability to be told how to use other enumerations that are custom to each application
  • A Settings Collection = because each application will create and use (at least) one of these. This is something that can be used internally by the application. In that context, them being in a collection may or may not be of some use.
  • Loadable Settings Collection = which will provide an ability to reliably read settings in from a JSON file, which includes handling their custom enumerations
  • Savable Settings Collection = which will provide an ability to reliably save settings out to a JSON file, with an inherent facility for controlling which among all the settings will be thus output

Details

  • Meta Extended Enumerations
    • named-tuple of attributes with a type enforcement function for it
    • class of meta-extended-enumeration
  • Data types of Settings
    • an enumeration to cover five pairs of types
    • a named-tuple for extra attributes, including references for functions to handle custom enumerations
  • A Settings Collection
    • a class to hold a set of the settings
  • Loadable Settings Collection
  • Savable Settings Collection

As Seen From JSON

  • which application is it for
  • which version of the application made it
  • dictionary of keys and values
    • name of key
    • string representation of value (might be a single value, or a list of values)

When reading:

  • confirm it is for the application
  • confirm we know how to handle settings from that version
  • loop
    • read a key - confirm we recognise it
      • read the value, if this should be an enumeration value, then convert it

Therefore, things we need at read time are:

  • a function to check the application code
  • a function to check the version code
  • a function to look up a key
  • a function to handle the value for that key

Stages of implementation

Initial stage

Implemented "manually" inside Foldatry.

All the enumerations used around the application are separately declared and used where appropriate.

For each enumeration an addtional extended-enumeration was manually crafted, which included the generation of a list of tuples for passing to a combobox widget

The Settings collection was manually implemented as an enumeration that lists all the settings, plus a custom extended-enumeration for each. There is a run-time dictionary keyed on that enumeration, holding the extended-enumerations.

During loading from JSON file, the keys were manually given direction of which value enumeration to use (to decode from text values). In non-GUi mode, when loading from a file, all keys present in it are applied as settings.

An additional GuiSettings object then added a boolean flag per setting, allowing control of which gets saved and which gets loaded. Thus there is an ability to save a partial set of settings to a file, thereby allowing for separate files for subsets of settings, which could then be progressively loaded via the non-GUI mode.

locations of those in the modules

As for where the code for the above lives, in terms of the Foldatry Python project:

  • the extended-enumerations were all placed in the module "applitry"
  • the settings class-and-object and the gui-settings class-and-object were both placed in the main "foldatry" module, which currently handles both the GUI mode and command-line mode operation. It is desired to eventually split these.

First abstraction

The section of code that did extended enumerations was abstracted to a module, which consolidated the repetitious code from across the multiple extended enumerations. This could be given a keycode for each enumeration - actually using its class as the id - and then be fed all the extended attributes.

Second abstraction

Here, the goal is the do a similar abstraction for application settings.

The catch though, is how to:

  • not have to specify a lot of the enumeration extensions twice
  • abstract the way that the initial stage settings code, knew about all the custom enumerations used throughout the program

Python variables

Named Tuples

_nmdtpl_XenumAttrbt = fi_namedtuple('nmdtpl_XenumAttrbt', 'XenumJval XenumBrief XenumShow XenumSort')

Enter fullscreen mode Exit fullscreen mode

where those elements are:

  • XenumJval = JSON value string
  • XenumBrief = abbreviation
  • XenumShow = longer display (but not a full description, that's what documentation is for)
  • XenumSort = used to specify placement in GUI selection
nmdtpl_SettingAttrbt = fi_namedtuple('nmdtpl_SettingAttrbt', 'EnumMmb_DataType EnumTyp_Enum Value_Default Str_JSONkey Str_Show Fn_Val2EnumMmb Fn_EnumMmb2Val')

Enter fullscreen mode Exit fullscreen mode

where those elements are:

  • EnumMmb_DataType = integer, string, list of string, custom enumeration
  • EnumTyp_Enum = the class name if a custom enumeration
  • Value_Default = default value
  • Str_JSONkey = key used in the JSON
  • Str_Show =
  • Fn_Val2EnumMmb = conversion function
  • Fn_EnumMmb2Val = converse conversion function

Dictionaries

  • a first dictionary of the extended enumerations, keyed by the enumeration class, then each value being another dictionary keyed on the enumeration members (i.e. the run-time internal Python items) with each holding a _nmdtpl_XenumAttrbt
  • a second dictionary of the settings, keyed by an enumeration passed in when creating the dictionary. for each key is held a nmdtpl_SettingAttrbt where the use of a value in EnumTyp_Enum must have that already present in the first dictionary
  • a third object, which gets passed the second dictionary and which adds a third dictionary of boolean flags for each setting

For the providing abstraction, the first and second dictionaries will be inside an object each. While an application only needs one of each of those, it could perhaps do more of them. For example, settings being read from JSON could be done with a new object and then only merged to (or perhaps replacing) the "real" one if the load has no errors. Such things can then be implemented as application features that the service module has no "awareness" about.

Top comments (0)