Need Help creating class hierarchy in Python - python-3.x

I have a hierarchy of data that i would like to build using classes instead of hard coding it in. The structure is like so:
Unit (has name, abbreviation, subsystems[5 different types of subsystems])
Subsystem ( has type, block diagram(photo), ParameterModel[20 different sets of parameterModels])
ParameterModel (30 or so parameters that will have [parameter name, value, units, and model index])
I'm not sure how to do this using classes but what i have made kindof work so far is creating nested dictionaries.
{'Unit':{'Unit1':{'Subsystem':{'Generator':{Parameter:{'Name': param1, 'Value':1, 'Units': 'seconds'}
like this but with 10-15 units and 5-6 subsystems and 30 or so parameters per subsystem. I know using dictionaries is not the best way to go about it but i cannot figure out the class sharing structure or where to start on building the class structure.
I want to be able to create, read, update and delete, parameters in a tkinter gui that i have built as well as export/import these system parameters and do calculations on them. I can handle the calculations and the import export but i need to create classes that will build out this structure and be able to reference each individual unit/subsystem/parameter/value/etc
I know thats alot but any advice? ive been looking into the factory and abstract factory patterns in hope to try and figure out how to create the code structure but to no avail. I have experience with matlab, visual basic, c++, and various arduio projects so i know most basic programming but this inheritance class structure is something i cannot figure out how to do in an abstract way without hardcoding each parameter with giant names like Unit1_Generator_parameterName_parameter = ____ and i really dont want to do that.
Thanks,
-A
EDIT: Here is one way I've done the implementation using a dictionary but i would like to do this using a class that can take a list and make a bunch of empty attributes and have those be editable/callable generally like setParamValue(unit, susystem, param) where i can pass the unit the subsystem and then the parameter such as 'Td' and then be able to change the value of the key,value pair within this hierarchy.
def create_keys(list):
dict = {key: None for key in list}
return dict
unit_list = ['FL','ES','NN','SF','CC','HD','ND','TH'] #unit abbreviation
sub_list = ['Gen','Gov','Exc','PSS','Rel','BlkD']
params_GENROU = ["T'do","T''do","T'qo","T''qo",'H','D','Xd','Xq',"Xd'","Xq'","X''d=X''q",'Xl','S(1.0)','S(1.2)','Ra'] #parameter names
dict = create_keys(unit_list)
for key in dict:
dict[key] = create_keys(sub_list)
dict[key]['Gen'] = create_keys(params_GENROU)
and inside each dict[unit][Gen][ParamNames] there should be a dict containing Value, units(seconds,degrees,etc), description and CON(#basically in index for another program we use)

Related

How would I pair class objects and lists that will be altered?

General Situation: First project using classes/objects. I'm trying to make a sudoku solver, so I have made a class for the tiles.
class Board:
def __init__(self,square,row,column,possibilities,defined):
self.square = square
self.row = row
self.column = column
self.possibilities = possibilities #Starts as [1,2,3,4,5,6,7,8,9]
self.defined = defined
I would like to design a function/method that would affect my "possibilities" list attribute, containing the possibilities of the tiles value. I added these objects to a list of tiles. I've tried many things, to delete or replace the "possibilities" list, but I consistently get TypeErrors with .remove() and using a method gave an error that the class wasn't iterable. I also tried using setItem().
I can provide these snippets of these attempted solutions, if needed; however, I'm more interested on if there is a better way to store this data and pair it with my list of objects as this feels very hacky.

django: simulate a flags Field using BInaryField

So I'm trying to simulate a flags field in Django (4.0 and Python3) the same way I could do in C or C++. It would look like this:
typedef enum{
flagA = 0,
flagB,
flagC
} myFlags;
Having a uint8 that by default is 00000000 and then depending on if the flags are on or off I'd do some bitwise operations to turn the three least significant bits to 1 or 0.
Now, I could do that in my model by simply declaring a PositiveSmallIntegerField or BinaryField and just creating some helper functions to manage all this logic.
Note that I DO NOT NEED to be able to query by this field. I just want to be able to store it in the DB and very occasionally modify it.
Since it's possible to extend the Fields, I was wondering if it would be cleaner to encapsulate all this logic inside a custom Field inheriting from BinaryField. But I'm not really sure how can I manipulate the Field value from my custom class.
class CustomBinaryField(models.BinaryField):
description = "whatever"
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 1
super().__init__(*args, **kwargs)
For instance, if I wanted to create a method inside CustomBinaryField, like the following, where the myFlagsStr contains a str representation of the enum.
def getActiveFlags(self):
// For each bit which is set to 1 in the Binary value
// add it to an array with it's name such as: [flagA, flagC]
array = []
if self.value & (1 << myFlags.flagA):
array.append(myFlagsStr[flagA])
if self.value & (1 << myFlags.flagB):
array.append(myFlagsStr[flagB])
if self.value & (1 << myFlags.flagC):
array.append(myFlagsStr[flagC])
return array
Not sure how to get the actual value stored in the DB to make this if comparisons.
Maybe mine is not the best approach to handle this, so I'm open to any suggestions you guys might have. But I think I could manage to do this the way I'm doing if I knew how to get the actual binary value from the DB from my functions.
I have seen there is a library https://github.com/disqus/django-bitfield that handles this but it limits to using only PostgreSQL and also, as mentioned before, I don't really need to filter by these flags, so something more simpler will do too.
Well, in django common approach for building such functionalities is using MultipleChoiceField. It presumes that data is stored in the related table, which, I believe, is not very what you want.
The second opportunity is to use ArrayField which also isn't suitable for you since you don't want your solution to be limited to PostgreSQL.
If you're going to do this quickly and straightforward, you might use JSONField and store the string or numeric IDs of your Choices. But if you are accustomed to C++, you're not gonna like it this way :)
JSONField is supported on MariaDB 10.2.7+, MySQL 5.7.8+, Oracle, PostgreSQL, and SQLite (with the JSON1 extension enabled).
If so, you should look at SmallIntegerField, it's stored as 16-bit signed int and use getter-setter approach to maintain it, like this. The idea of implementation of the methods you suggested is right in general.
Good luck :)

Contribution analyses - tagged.database

I need to get the single contribution of the processes and emissions I filled into my database - similar to this problem : Brightway2 - Get LCA scores of immediate exchanges
it works for single methods but i was wondering how to get these results for several methods similar to when doing the ordinary calculations which can then be saved as csv? is there a way to create a loop for this?
Thank you so much!
Miriam
There is a function called multi_traverse_tagged_database in bw2analyzer which should do what you need. It was part of a pull request so it's not in the docs.
I've copied in the docstring at the bottom which should give you some pointers. It's basically the same as the traverse_tagged_database function used in the question you've linked to, but for multiple methods. You'd use it like this:
results, graph = multi_traverse_tagged_databases(functional_unit, list_of_methods, label='name')
You should be able to use pandas to export the dictionary you get in results to a csv file.
def multi_traverse_tagged_databases(
functional_unit, methods, label="tag", default_tag="other", secondary_tags=[]
):
"""Traverse a functional unit throughout its foreground database(s), and
group impacts (for multiple methods) by tag label.
Input arguments:
* ``functional_unit``: A functional unit dictionary, e.g. ``{("foo", "bar"): 42}``.
* ``methods``: A list of method names, e.g. ``[("foo", "bar"), ("baz", "qux"), ...]``
* ``label``: The label of the tag classifier. Default is ``"tag"``
* ``default_tag``: The tag classifier to use if none was given. Default is ``"other"``
* ``secondary_tags``: List of tuples in the format (secondary_label, secondary_default_tag). Default is empty list.
Returns:
Aggregated tags dictionary from ``aggregate_tagged_graph``, and tagged supply chain graph from ``recurse_tagged_database``.
"""

Python, bulbs, resxter . Getting bool scalar returned by gremlin script from bulbs

I am writing python scripts to extract data from multiple sources and put it in a graph in a certain structure.
I am using bulbs models for all the data. I have models for all relevant node types and relationships. My edge models have not additional properties except 'label'.
As it is in development, I run the same script multiple times. I use get_or_create to prevent duplicate nodes but edges do not have that method. I do not have the object for existing edge since it was created in a previous run of the script.
I saw several question talking about similar things with answers from espeed like this, but I could not find a satisfactory answer for my specific issue.
What would be the simplest code for this method?
Presently I am trying to do this via loading a gremlin script; as suggested by Stephen; with following function:
def is_connected(parent, child, edge_label) {
return g.v(parent).out(edge_label).retain([g.v(child)]).hasNext()
}
And the the following python code.
g.scripts.update('gremlin_scripts/gremlin.groovy')
script = g.scripts.get('gremlin:is_connected')
params = dict(parent=parent_node.eid, child=menu_item_v.eid, edge_label='has_sub_menu_item')
response = g.gremlin.execute(script, params)
I can't quite figure out how to get the bool result into python. I've also tried the g.gremlin.query(script, param)
Here's one way to do it:
parent_v.out(rel_label).retain(child_v).hasNext()
So, from the parent, traverse out to all children (i assume that "out" is the direction of your relationship - how you choose to implement that is specific to your domain) and determine if that child is present at any point via retain.

python: manipulating __dict__ of the class

(All in ActivePython 3.1.2)
I tried to change the class (rather than instance) attributes. The __dict__ of the metaclass seemed like the perfect solution. But when I tried to modify, I got:
TypeError: 'dict_proxy' object does
not support item assignment
Why, and what can I do about it?
EDIT
I'm adding attributes inside the class definition.
setattr doesn't work because the class is not yet built, and hence I can't refer to it yet (or at least I don't know how).
The traditional assignment doesn't work because I'm adding a large number of attributes, whose names are determined by a certain rule (so I can't just type them out).
In other words, suppose I want class A to have attributes A.a001 through A.a999; and all of them have to be defined before it's fully built (since otherwise SQLAlchemy won't instrument it properly).
Note also that I made a typo in the original title: it's __dict__ of a regular class, not a metaclass, that I wanted to modify.
The creation of a large number of attributes following some rule smells like something is seriously wrong. I'd go back and see if there isn't a better way of doing that.
Having said there here is "Evil Code" (but it'll work, I think)
class A:
locals()['alpha'] = 1
print A.alpha
This works because while the class is being defined there is a dictionary that tracks the local variables you are definining. These local variables eventually become the class attributes. Be careful with locals as it won't necessarily act "correctly." You aren't really supposed to be modifying locals, but it does seem to work when I tried it.
Instead of using the declarative syntax, build the table seperately and then use mapper on it. see http://www.sqlalchemy.org/docs/05/ormtutorial.html# I think there is just no good way to add computed attributes to class while defining it.
Alternatively, I don't know whether this will work but:
class A(object):
pass
A.all_my_attributes = values
class B(declarative_base, A):
pass
might possibly work.
I'm not too familiar with how 3 treats dict but you might be able to circumvent this problem by simply inheriting the dictionary class like so:
class A(dict):
def __init__(self,dict_of_args):
self['key'] = 'myvalue'
self.update(dict_of_args)
# whatever else you need to do goes here...
A() can be referenced like so:
d = {1:2,3:4}
obj = A(mydict)
print obj['test'],obj[3] # this will print myvalue and 4
Hope this helps.

Resources