Python class declare by passing variables - python

I try to create an object by passing the variables, but it seems not work.
I put a simple example below to show what I want. Please help me to deal with this issue.
Successfully
temp = catalog.TEST
temp = catalog.PROD
Not works, it pass string "i" instead of the list element as attributes
lists = ['TEST,'PROD']
for i in lists:
temp = catalog.i
Complete code
I'm using dremio-client this package (https://dremio-client.readthedocs.io/en/latest/readme.html)
import dremio_client as dc
mydremio = dc.init(os.getcwd() + '/.config')
catalog = mydremio.data
# TEST and PROD are the folders that exist in my dremio server
a = catalog.TEST
b = catalog.PROD
# Cannot pass the list element to object "catalog"
list = ["TEST","PROD"]
for i in list
temp = catalog.i
Thanks Pavel for the solution, but I have a one more complicated question.
list = ["TEST","TEST.DEMO"]
# what's work - directly declare
test = catalog.TEST.DEMO
# works for "TEST" not works for TEST.DEMO
for i in list:
temp = getattr(catalog, i)

When you do temp = catalog.i, you actually trying to set an attribute i of the catalog, not value under variable i.
You can try using getattr instead:
import dremio_client as dc
mydremio = dc.init(os.getcwd() + '/.config')
catalog = mydremio.data
# TEST and PROD are the folders that exist in my dremio server
a = catalog.TEST
For the second case you can try to do something like this:
for i in list:
fields = i.split('.')
temp = catalog
for field in fields:
temp = getattr(temp, field)
What I do here is split i by . symbol to create a list of fields that I need to access.
So "TEST.DEMO".split('.') will become ["TEST", "DEMO"]
Not sure if it will work, but I just wanted to show the main idea.

Related

Calling existing variable (list) reconstructed with StringVar()

I have a several lists that I am trying to activate or use that are named as follows:
public_forum_jr_soc = []
parliamentary_jr_soc = []
european_jr_soc = []
etc...
I have a bunch of radiobuttons that has variables to recreate these lists names, and it outputs something like this.
print(self.select_league.get()+self.select_age.get()+self.select_grade.get())
append_name = self.select_league.get()+self.select_age.get()+self.select_grade.get()
>>>
european_jr_soc
I try to proceed to use this list in as an argument for a function.
output_data(append_name)
def master_groper2(outof48):
for i in outof48:
if i[15] in ['ENGLISH','english','']:
i[15] = 'English'
elif i[15] in ['Mandarin','CHINESE',]:
i[15] = 'Chinese'
However, I get a IndexError: string index out of range as python reads it as european_jr_soc, instead of the actual list, despite sharing the same name, how could I have python have it read it as the variable list?

I am making a todo list program where i can add my works

I am trying to make a To-Do list in python.I want to add new tasks in my dictionary and want them to appear when i call them.How can I do that?
dictionary = {} # creating a empty dictionary
while True: # to run the program infinite times
qs = input('->').lower() # command?
if "todo" in qs: # check the command
p = dictionary
print(p)
elif "add" in qs: # command
i = input("what to add?") # what to add in the todo list
dictionary = i
print("Added " + i + " to your To Do list")
else:
print("There was a error!")
The code I tried worked but not as I expected.
It only gave one todo work though I wanted to get all the works I added to the dictionary.
So, what can I try?
You're reassigning the dictionary to an individual item:
dictionary = i
You want to add to the dictionary, presumably like this:
n += 1
dictionary[n] = i
It looks like you're overwriting the dictionary rather than adding a new key/value.
Change
dictionary = i
To
index += 1
dictionary[index] = i
and this should work. You could also use update(), or even a list []
The way you seem to want to use it, you are probably better of using a list
Replace dictionary = {} with dictionary = [] and then replace dictionary = i with dictionary.append(i)

Sorting nested list

Im trying to sort my list which contains of 3 nested lists: paths, file names and finally file creation time. So I want to sort them to be able to get the latest files.
So Ive seen people been using lambda for this, but I dont feel comfortable using those and kind of dont get how to the sorting with that works.
I think the best way is just to switch the list components, but this does not work:
class FILE:
PATH = 0
NAME = 1
DATE = 2
mayaFiles = [[],[],[]]
mayaFiles[FILE.DATE] = [0,56,3,12,7,35,16]
doSwitch = True
while (doSwitch):
for ma in range(0, len(mayaFiles[FILE.DATE])-1):
doSwitch = False
doSwitch = mayaFiles[FILE.DATE][ma] > mayaFiles[FILE.DATE][ma+1]
hi = mayaFiles[FILE.DATE][ma]
lo = mayaFiles[FILE.DATE][ma+1]
if doSwitch:
mayaFiles[FILE.DATE][ma] = lo
mayaFiles[FILE.DATE][ma+1] = hi
else:
break
print mayaFiles[FILE.DATE]
Assuming these lists are already aligned, you'll have a much easier time by combing the there separate lists into a list of tuples arranged by your sort order. the namedtuple construct in the collections module is great for this sort of thing. I'm assuming you can get your data into three lists: paths, dates and names. I'm supplying some dummy data here so you can see what I'm assuming.
names = "a.ma", "b.ma", "c.ma", "d.ma"
paths = "c:/test", "c/test", "c:/other", "d:/extra"
dates = "17-01-01", "16-01-01", "17-02-01", "17-06-30"
# this creates a namedtuple, which is a
# mini-class with named fields that otherwise
# works like a tuple
from collections import namedtuple
record = namedtuple("filerecord", "date name path")
# in real use this should be a list comp
# but this is easier to read:
records = []
for date, name, path in zip(dates, names, paths):
records.append(record(date, name, path))
records.sort(reverse=True)
for item in records:
print item
# filerecord(date='17-06-30', name='d.ma', path='d:/extra')
# filerecord(date='17-02-01', name='c.ma', path='c:/other')
# filerecord(date='17-01-01', name='a.ma', path='c:/test')
# filerecord(date='16-01-01', name='b.ma', path='c/test')
You could sort on other fields using the 'key' argument to sort():
records.sort(key=lambda k: k.name)
for item in records:
print item
# filerecord(date='17-01-01', name='a.ma', path='c:/test')
# filerecord(date='16-01-01', name='b.ma', path='c/test')
# filerecord(date='17-02-01', name='c.ma', path='c:/other')
# filerecord(date='17-06-30', name='d.ma', path='d:/extra')

Python code to automatically assign parsed json objects to their original names

I have dumped a couple of variables I need to store in a json object as shown here-
def write_json():
variable = {}
variable['p_id'] = p_id
variable['s_id'] = s_id
variable['t_id'] = t_id
variable['b_start'] = b_start
variable['b_end'] = b_end
variable['wsp_after'] = wsp_after
variable['h_id'] = h_id
variable['word'] = word
variable['norm_word'] = norm_word
variable['lemma'] = lemma
variable['pos'] = pos
variable['ner'] = ner
variable['dep'] = dep
variable['quote'] = quote
variable['ch_id'] = ch_id
with open('variable.json', 'w') as fp:
json.dump(variable,fp, sort_keys = True)
I want to write a piece of code that would automatically get these variables assigned appropriately as would happen if you wrote from 'X.py' import *
This is what I tried-
def get_variables():
with open('variable.json', 'r') as fp:
variable = json.load(fp)
for key in variable:
global key
key = variable[key]
However, when I tried to print the original value-
print t_id
NameError: name 't_id' is not defined
What do I need to do to achieve what I want rather than cumbersomely typing
t_id = variable['t_id']
.
.
.
For every variable I have dumped?
Your current code doesn't work because the following lines just bind (and rebind, for the later values in the loop) a global variable named 'key':
global key
key = variable[key]
While I'm not sure your design is really a good one, if you're sure you want all the values from your json file as global variables, I'd replace the loop with:
globals().update(variable)
The globals() function returns a dictionary that contains all the current module's global variables. Unlike the dictionary you get from locals() (which may be a copy of the local namespace, not the actual implementation of it), you can modify the globals() dictionary and use the variables like normal afterwards.
Here's the solution -
with open('variable.json', 'r') as fp:
variable = json.load(fp)
for key in variable.keys():
exec(key + " = variable['" + key + "']")
The problem before was that each 'key' was a string, not an object.
Using the exec function successfully parses each string into an object and using it as given above gets the results as was asked in the question.

setting up iterative item query in python

I am trying to set up a function that will query an item for its sub components if those exists and return those else return the item itself.
Imagine an object that can contain more objects within it. To access those objects i would do object.GetSubComponentIds() now if that object contains sub objects it would return a list of those sub objects or EmptyList if there are none. In case that there are sub objects contained within it I want to keep going and then for each subobject i want to check if there are any subobjects contained within them. So for every SubObject.GetSubComponentIds() now if those do not contain anything then i would love to return them while maintaining nested structure of objects that they came from.
object1(contains 3 sub objects)
object2(contains 3 sub object and each sub object contains one more sub object)
object3(does not contain sub objects)
inputlist = [object1, object2]
outputlist = [[obj1sub1, obj1sub2, obj1sub3],[[obj2sub1sub1],[obj2sub2sub1],[obj2sub3sub1]],[obj3]]
I am interested in maintaining that nested list structure that will allow me to always trace back the origin of the sub object. Again, a method to get a sub object list is object.GetSubComponentIds() and it will either return a list or Empty List.
Can anyone help me set up an iterative function to retrieve them. Keep in mind that I do not know whether there are any sub objects contained within an object or haw many levels deep are they. It's basically that if it returns a list i need to check every item on that list for more sub objects.
Thank you in advance
Here's my humble first try:
#unwrap all elements to use with API
elements = []
for i in IN[0]:
elements.append(UnwrapElement(i))
#create element set from python list
elementSet = Autodesk.Revit.DB.ElementSet()
for i in elements:
elementSet.Insert(i)
#convert element set to List[Element]
setForCheck = List[Autodesk.Revit.DB.Element]()
elemIter = elementSet.ForwardIterator()
elemIter.Reset()
while elemIter.MoveNext():
curElem = elemIter.Current
setForCheck.Add(curElem)
#iterate throuh all elements to extract nested elements
setLoop = List[Autodesk.Revit.DB.Element]()
elemSet = List[Autodesk.Revit.DB.Element]()
itemOut = []
counter = 0
while setForCheck.Count >= 1:
setLoop.Clear()
for i in setForCheck:
itemOut.append(i)
if i.GetSubComponentIds().Count >= 1:
elem = Autodesk.Revit.DB.ElementSet()
for j in i.GetSubComponentIds():
elem.Insert(doc.GetElement(j))
elemIterA = elem.ForwardIterator()
elemIterA.Reset()
while elemIterA.MoveNext():
curElemA = elemIterA.Current
setLoop.Add(curElemA)
setForCheck.Clear()
elemIterB = setLoop.GetEnumerator()
elemIterB.Reset()
while elemIterB.MoveNext():
curElemB = elemIterB.Current
setForCheck.Add(curElemB)
counter += 1
if counter > 1000:
break
#Assign your output to the OUT variable
OUT = itemOut
You're using some specific libraries, like Autodesk, that I'm not familiar with. Let me answer your question in terms of an abstract example.
Suppose we're dealing with Thing objects, where Thing is defined as:
class Thing(object):
def __init__(self, name):
self.name = name
self.inside = []
We can make Things and put other things inside of them. The example you give in your post can be written:
ob1 = Thing("ob1")
ob1.inside.extend([Thing("ob1sub1"), Thing("ob1sub2"), Thing("ob1sub3")])
ob2 = Thing("ob2")
for i in xrange(1,4):
name = "ob2sub{}".format(i)
thing = Thing(name)
thing.inside.append(Thing(name + "sub1"))
ob2.inside.append(thing)
ob3 = Thing("ob3")
things = [ob1, ob2, ob3]
This makes a sort of tree. Now we'd like to return a nested list of all of the leaf nodes in the tree:
def search_things(things):
names = []
for thing in things:
if not thing.inside:
names.append(thing)
else:
names.append(search_things(thing.inside))
return names
A test:
>>> search_things(things)
[['ob1sub1', 'ob1sub2', 'ob1sub3'],
[['ob2sub1sub1'], ['ob2sub2sub1'], ['ob2sub3sub1']],
'ob3']
I'll let you transform this to your specific problem, but this is the general idea. Note that the algorithm is recursive, not iterative. You said you wanted an iterative algorithm -- and the above can be written iteratively -- but this gives you the idea.

Categories