how to work with dict() when using depth first search tree - python

Given:
class NoName:
def __init__(self):
self.some_dict = {}
def add_new_node(self, label):
self.some_dict[label] = {}
Consider I call the class how would I use the add_new_node method ? what prams will I need to pass in the add_new_node method ?
NoName.add_new_node('a':1)
obviously, this will not work. I need to understand how to make such positional arguments work.

It's this what you are looking for?
class NoName:
def __init__(self):
self.some_dict = {}
def add_new_pair_key_value(self, node, value):
self.some_dict[node] = value
def add_new_whole_node(self, whole_node):
self.some_dict.update(whole_node)
noname = NoName()
noname.add_new_pair_key_value('new_node', 'new_value')
print(noname.some_dict)
noname.add_new_whole_node({'label': {'new_whole_key': 'new_node_value'}})
print(noname.some_dict)
output first print:
{'new_node': 'new_value'}
output second print:
{'new_node': 'new_value', 'label': {'new_whole_key': 'new_node_value'}}

Related

How to convert dict to class attributes in Python

Instead of using a dict to store and pass data we are going completely OOPS approach of storing the data as class attributes and call the get methods defined according to need.
In Java i was able to achieve this but having some trouble in Python. Any Solution would be helpful.
import json
class InputModel:
def __init__(self, input_payload):
self.id1 = input_payload["id1"]
self.route = RouteModel(input_payload["route"])
self.id2 = input_payload["id2"]
self.id3 = input_payload["id3"]
self.id4 = input_payload["id4"]
self.id5 = input_payload["id5"]
def get_id1(self):
return self.id1
#similar for other ids
class RouteModel:
def __init__(self, input_payload_route):
self.id6 = input_payload_route["id6"]
self.id7 = input_payload_route["id7"]
def get_id6(self):
return self.id6
#similar for other ids
json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
json_dict = json.loads(json_str)
im = InputModel(json_dict)
print(im.get_id1())
print(im.get_id6())
not able to access the nested class attributes
Seems like you went for 1 extra indent in your class methods, thus you couldn't reach them.
Also, to reach id6 of RouteModel, you had to refer to 'route' first:
import json
class InputModel:
def __init__(self, input_payload):
self.id1 = input_payload["id1"]
self.route = RouteModel(input_payload["route"])
self.id2 = input_payload["id2"]
self.id3 = input_payload["id3"]
self.id4 = input_payload["id4"]
self.id5 = input_payload["id5"]
def get_id1(self):
return self.id1
#similar for other ids
class RouteModel:
def __init__(self, input_payload_route):
self.id6 = input_payload_route["id6"]
self.id7 = input_payload_route["id7"]
def get_id6(self):
return self.id6
#similar for other ids
json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
json_dict = json.loads(json_str)
im = InputModel(json_dict)
print(im.get_id1())
print(im.route.get_id6())
Output:
string
string
The problem is that you are only defining get_id* in your local scope, you need to assign it to the instance if you insist on defining it inside the __init__ method.
I minimized your code example to isolate your issue.
class RouteModel:
def __init__(self):
self.id6 = "foo"
def get_id6(self_=self):
return self_.id6
self.get_id6 = get_id6
rm = RouteModel()
print(rm.get_id6())
>>> "foo"
If I understand your question correctly, you want to be able to access the ids directly as attributes, no matter how deep they are nested in the dictionary.
This solution creates the attributes recursively:
import json
class InputModel:
def __init__(self, payload):
self.create_attrs(payload)
def create_attrs(self, d):
for key, value in d.items():
# if the value is a dict, call create_attrs recursively
if isinstance(value, dict):
self.create_attrs(value)
else:
# create an attribute key=value, e.g. id1="string"
setattr(self, key, value)
json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
json_dict = json.loads(json_str)
im = InputModel(json_dict)
print(im.id1)
print(im.id6)
After going through answers provided, mostly have defined instance attributes and not class attributes.
Correct me if I'm wrong here but I think this is how class attributes are defined right?
import json
class InputModel:
def __init__(self, input_payload):
InputModel.id1 = input_payload["id1"]
InputModel.route = RouteModel(input_payload["route"])
InputModel.id2 = input_payload["id2"]
InputModel.id3 = input_payload["id3"]
InputModel.id4 = input_payload["id4"]
InputModel.id5 = input_payload["id5"]
def get_id1():
return InputModel.id1
#OR
##classmethod
#def get_id1(cls):
# return cls.id1
#similar for other ids
class RouteModel:
def __init__(self, input_payload_route):
RouteModel.id6 = input_payload_route["id6"]
RouteModel.id7 = input_payload_route["id7"]
def get_id6():
return RouteModel.id6
#similar for other ids
json_str = '{"id1":"string","route":{"id6":"string","id7":"string"},"id2": "string","id3": "string","id4": "string","id5": "string"}'
json_dict = json.loads(json_str)
InputModel(json_dict)
print(InputModel.get_id1())
print(InputModel.route.get_id6())
print(RouteModel.get_id6())

divide classes into sub functions/classes python

First time poster and python newbie here, this question is probably asked before, but I am not able to find any answer.
I have a Class that reads robot status data, this works fine and I am able to dive my data into methods that are working fine when i call them. But I would like to divide my class even more, so the data is structured better. for example
I have some methods the reads and return target_data
def target_joint_positions(self):
t_j_p = self.read_data()[1:7]
return t_j_p
def target_joint_velocities(self):
t_j_v = self.read_data()[7:13]
return t_j_v
def target_joint_currents(self):
t_j_c = self.read_data()[19:25]
return t_j_c
And similar methods returning actual_data:
def actual_joint_positions(self):
a_j_p = self.read_data()[31:37]
return a_j_p
def actual_joint_velocities(self):
a_j_v = self.read_data()[37:43]
return a_j_v
def actual_joint_currents(self):
a_j_c = self.read_data()[43:49]
return a_j_c
So what I would like to accomplish is that when i make a instance of my class, instead of getting all the methods i would like something like this:
inst = Class_Name()
inst.target. (list of target methods)
inst.actual. (list of actual methods)
I have looked into nested classes and inheritance but I have not been successful in achieving my goal. Thanks for any pointers.
Welcome!
You can do the following:
class TargetMetrics:
def __init__(self, data):
self.data = data
def joint_positions(self):
return self.data[1:7]
...
class ActualMetrics:
def __init__(self, data):
self.data = data
def joint_positions(self):
return self.data[31:37]
...
class RobotMetrics:
def __init__(self):
data = read_data()
self.actual = ActualMetrics(data)
self.target = TargetMetrics(data)
...

Initialise class without instantiate?

I'm trying to work on a simple class that fills in some lists and then tries to retrieve that information back, something like:
class Foo(object):
def __init__(self):
self.src = []
self.values = []
def addItems(self, name, val):
self.src.append(name)
self.values.append(val)
def getItem(self, item):
for i, x in enumerate(self.src):
if x == item:
return self.src[i], self.values[i]
To use this class, I first have to instanciate it, Foo(), and only then start adding and retrieving objects.
a = Foo()
a.addItems('A', '1')
a.addItems('B', '2')
a.src # ['A', 'B']
a.values # ['1', '2']
a.getItem('A') # ('A', '1')
Is there any way to add the elements without having to initialise the class first? Something like Foo.addItems('A', '1')(this gives a TypeError: addItems() missing 1 required positional argument: 'val').
I saw other related posts using #staticmethod, but couldn't figure out how to make it work in this example.
Not sure what exactly you have in mind. I guess you may get something close to what you have described. Two steps are needed.
First - create module, say, foo_module, where you create and instantiate your class:
class Foo:
def __init__(self):
self.src = []
self.values = []
def addItems(self, name, val):
self.src.append(name)
self.values.append(val)
def getItem(self, item):
for i, x in enumerate(self.src):
if x == item:
return self.src[i], self.values[i]
root_foo = Foo()
src = root_foo.src
values = root_foo.values
def addItems(*args):
return root_foo.addItems(*args)
def getItem(*args):
return root_foo.getItem(*args)
Second - import foo_module and use it:
import foo_module as f_m
f_m.addItems('A', '1')
f_m.addItems('B', '2')
print(f_m.getItem('A'))
print(f_m.src)
print(f_m.values)
Now you access the same Foo instance any time you access foo_module across all your scripts. By the way, it's how python logging module works (root logger).

Class Variable Updating

I built a class to handle a lot of different functions that take common inputs. However, I just ran into the situation where one of the variables that's fed down through self needs to be changed. How do I do this? This is an example:
class Test:
def __init__(self, test_variable):
self.test_var = test_variable
#property
def some_function(self):
if self.test_var < 0:
self.test_var = 'New Output' #this is the line that I can't get
#get to work and I was hoping to update it here
#so I could use it in later functions
return self.test_var
Thank you!
You should drop the #property attribute. Then, you can set it by just doing x.test_var = 5. E.g.,
class Test:
def __init__(self, test_variable):
self.test_var = test_variable
def some_function(self):
if self.test_var < 0:
self.test_var = 'New Output' #this is the line that I can't get
#get to work and I was hoping to update it here
#so I could use it in later functions
return self.test_var
x = Test(-1)
print(x.some_function())
x.test_var = 5
print(x.some_function())
returns
New Output
5

Best way to do many try-except blocks within Python class assignments?

I have a class which is pulling JSON data with keys, but the problem is that per instance of this class, the JSON data may not have keys for everything I am trying to grab. Currently, my class is set up like this:
class Show():
def __init__(self, data):
self.data = data
self.status = self.data['status']
self.rating = self.data['rating']
self.genres = self.data['genres']
self.weight = self.data['weight']
self.updated = self.data['updated']
self.name = self.data['name']
self.language = self.data['language']
self.schedule = self.data['schedule']
self.url = self.data['url']
self.image = self.data['image']
And so on, there are more parameters than that. I'm trying to avoid the messiness of having a try-except block for EACH AND EVERY one of those (27) lines. Is there a better way? Ultimately, I want a parameter to be assigned None if the JSON key doesn't exist.
If you're going to set a default value to the attribute if it's not in the data dictionary, use data.get('key') rather than data['key']. The get method will return None if the key does not exist, rather than raising a KeyError exception. If you want a different default value than None, you can pass a second argument to get and that is what will be returned.
So, your code could become:
class Show():
def __init__(self, data):
self.data = data
self.status = self.data.get('status')
self.rating = self.data.get('rating')
self.genres = self.data.get('genres')
self.weight = self.data.get('weight')
self.updated = self.data.get('updated')
self.name = self.data.get('name')
self.language = self.data.get('language')
self.schedule = self.data.get('schedule')
self.url = self.data.get('url')
self.image = self.data.get('image')
Use dict.get, which provides a default value instead of raising an exception for missing keys.
For example, you can change this:
self.status = self.data['status']
into this:
self.status = self.data.get('status')
You could change your code to something like:
class Show():
def __init__(self, data):
self.data = data
self.__dict__.update(data)
data = {'status': True, 'ratings': [1,2,3], 'foo': "blahblah"}
aShow = Show(data)
"""
>>> aShow.status
True
>>> aShow.ratings
[1,2,3]
>>> aShow.something_not_in_dict
AttributeError: Show instance has no attribute 'something_not_in_dict'
"""
Which does exactly the same, and trying to access something from your Show instance that isn't a key in your data dictionary would raise an AttributeError

Categories

Resources