Maya Python: Check to see if the attribute has any keyframes - python

I am trying to write a python script for Maya that will copy keyframes from one rig to another. I have found objects and matched them up. What I am trying to do now is copy the keys from the original objects if the original objects have keys to be copied. I was hoping to use the Keyframe command to check to see if the object has keys.
Example: if cmds.keyframe(oldObjPath attribute=oldAttr,sl=True, q=True, tc=True ) > 0:
This however always returned false. When I print out the attributes of oldObjPath I do get all the attributes printed out. Any idea what I am doing wrong here? Full code is below
Documentation on Keyframe Command:
http://download.autodesk.com/global/docs/maya2014/en_us/index.html?url=files/Python_Python_in_Maya.htm,topicNumber=d30e813275
#create a decunary of the object names and paths for faster searching
#[search_name:path]
originalObjectDic = {}
newObjectDic = {}
for obj in originalObjects:
#First remove the full path to give us somthing to search the new object with
subStrLoc = 0
index = 0
for char in obj:
if char == ':':
subStrLoc = index
index=index+1
searchName = obj[subStrLoc+1:]
originalObjectDic.update({searchName:obj})
#next look at all the names of the new object and see if they match up
for nObj in newObjects:
#correct the new objects name
subStrLoc=0
index=0
for char in nObj:
if index != 0:
if char == '_' and nObj[index-1] == 'r' and nObj[index-2] == 'u' and nObj[index-3] == 'F':
subStrLoc = index
index = index + 1
if subStrLoc == 0:
index = 0
for char in obj:
if char == ':':
subStrLoc = index
index=index+1
searchName = nObj[subStrLoc+1:]
newObjectDic.update({searchName:nObj})
#now that we have to dicunaries to check agaenst we will match up the two obj paths
# and copy the keys on all attributes on each node
for key in newObjectDic:
newObjPath = newObjectDic.get(key)
oldObjPath = originalObjectDic.get(key)
#if there is a match between the two dics
if newObjPath != None and oldObjPath != None:
#get a list of all the attributes
newObjAttributes = cmds.listAttr(newObjPath,v=True,r=True, w=True)
oldObjAttributes = cmds.listAttr(oldObjPath,v=True,r=True, w=True)
for x in range(len(newObjAttributes)-1):
newAttr = newObjAttributes[x]
oldAttr = oldObjAttributes[x]
if cmds.keyframe(oldObjPath attribute=oldAttr,sl=True, q=True, tc=True ) > 0:
print oldObjPath
print oldAttr
print 'Has Key'
print '----------------------------'

Got help from a freands. Had the wrong option on. sl which stands for selection should be false or not there at all so...
if cmds.keyframe(oldObjPath, attribute=oldAttr, sl=False, q=True, tc=True):

Related

Given a C++ file with many function definitions, how to get the starting and ending index of a particular function using Python?

The purpose is to comment the entire function void test_func with many nested {} using Python.
file = open(path_of_file)
data = file.readlines()
for item in data:
if item.find('void test_func') != -1:
point = data.index(item)
data.insert(point, '/*')
stack = []
for i in data[point+1:]:
if i.find('{') != -1:
stack.append('{')
elif i.find('}') != -1:
stack.pop()
if len(stack) == 0:
point1= data.index(i)
data.insert(point1+1,'*/')
Using the find() method I can find the starting index of the function while iterating over the lines. I was trying to use the balanced parenthesis method, to reach the end of the function, So when my stack is empty I will reach the end of the test_func.
This is not working in this example:
void test_func(arguments,\
arguments)
{
It is inserting */ just after the line:
/*void test_func(arguments,\
*/arguments)
{
Assuming that a "}\n" line only happens at the end of a function and always happens at the end of a function, you want something like:
in_func = False
for line in file.readlines():
line = line.strip('\r\n') # remove line breaks since print will add them
if in_func:
print("// " + line)
if line == "}":
in_func = False
elif line.startswith('void test_func('): # paren required to not match test_func2
print("// " + line)
in_func = True
else:
print(line)
Assuming that both ( / ) pairs and { / } pairs are balanced, you can look for the ) that balances the parameter list's ( and then the } that balances the body's first {.
We want to ensure that void test_func() {} etc is also caught, so I've pulled out the checks into local functions, so we start looking on the same line for the next pair of characters.
file = open(path_of_file)
data = file.readlines()
start = None
params = None
body = None
open = 0
close = 0
for index, line in enumerate(data):
def balanced(o, c):
open += line.count(o)
close += line.count(c)
return open > 0 and open = close
def checkBody():
if balanced('{', '}'):
body = index
def checkParams():
if balanced('(', ')'):
params = index
open = 0
close = 0
checkBody()
def checkStart():
if line.find('void test_func') != -1:
start = index
checkParams()
if start is None:
checkStart()
elif params is None:
checkParams()
elif body is None:
checkBody()
if start is not None and body is not None:
data.insert(start, '/*')
data.insert(body + 1, '*/')

how to check if a cell is empty in openpyxl python

I'm making a conditional statement in openpyxl Python to check if a cell is empty. Here's my code:
newlist = []
looprow = 1
print ("Highest col",readex.get_highest_column())
getnewhighcolumn = readex.get_highest_column()
for i in range(0, lengthofdict):
prevsymbol = readex.cell(row = looprow,column=getnewhighcolumn).value
if prevsymbol == "None":
pass
else:
newstocks.append(prevsymbol)
looprow += 1
#print (prevsymbol)
print(newlist)
I tried if prevsymbol == "": and if prevsymbol == null: to no avail.
You compare prevsymbol with str "None", not None object. Try
if prevsymbol == None:
Also here
prevsymbol = readex.cell(row = looprow,column=getnewhighcolumn).value
you use looprow as row index. And you increment looprow only if cell.value is not empty. Here
newstocks.append(prevsymbol)
you use newstocks instead of newlist. Try this code
newlist = []
print ("Highest col",readex.get_highest_column())
getnewhighcolumn = readex.get_highest_column()
for i in range(0, lengthofdict):
prevsymbol = readex.cell(row = i+1,column=getnewhighcolumn).value
if prevsymbol is not None:
newlist.append(prevsymbol)
print(newlist)
Take the quotes away from the None.
if prevsymbol is None:
This is the python equivalent of checking if something is equal to null.

How to split up xml tags in Python from an input.txt then format them nicely(tabs, newlines, nesting)?

I'm trying to take file.txt that contains text like:
<a> hello
<a>world
how <a>are
</a>you?</a><a></a></a>
and turn it into text like:
<a>
hello
<a>
world how
<a>
are
</a>
you?
</a>
<a>
</a>
my original thought was to create an XML item that holds a tag and content(list) and then just nest more XML items inside that list that hold content, but after spending some time I feel like I'm going about it the wrong way.
For this I can't use an libraries like Element tree, I want to solve the problem from scratch. I'm not looking for all the answers I'm just hoping someone can help me choose the right direction to head in so I don't waste more hours coming up with a useless code base.
-----------------------------------Answer Below--------------------------
from stack import Stack
import re
import sys
def findTag(string):
# checks to see if a string has an xml tag returns the tag or none
try:
match = re.search(r"\<(.+?)\>", string)
return match.group(0), match.start(0)
except:
return None
def isTag(string):
# checks to see if a string is a tag and returns true or false.
try:
match = re.search(r"\<(.+?)\>", string)
match.group(0)
return True
except:
return False
else:
return False
def split_tags_and_string(string):
#splits up tag and string into a list
L = []
for line in s.split("\n"):
temp = line
while len(temp) >0: #string still has some characters
#print("line: " + temp)
tag_tuple = (findTag(temp)) #returns a tuple with tag and starting index
#print("tag_tuple: "+ str(tag_tuple))
if tag_tuple is not None: #there is a tag in the temp string
if tag_tuple[1] == 0: #tag is the front of temp string
L.append(tag_tuple[0].strip())
temp = temp.replace(tag_tuple[0], '', 1)
temp = temp.strip()
else: #tag is somewhere else other than the front of the temp string
L.append(temp[0:tag_tuple[1]].strip())
temp = temp.replace(temp[0:tag_tuple[1]], '', 1)
temp = temp.strip()
else: #there is no tag in the temp string
L.append(temp.strip())
temp = temp.replace(temp, '')
return L
def check_tags(formatted_list):
# verifies that the xml is valid
stack = Stack()
x=0
try:
#print(formatted_list)
for item in formatted_list:
tag = findTag(item)
#print("tag: "+ str(tag))
if tag is not None:
if tag[0].find('/') == -1:
endtag = tag[0][0:1] + '/' +tag[0][1:]
#print(endtag)
if formatted_list.count(tag[0]) != formatted_list.count(endtag):
#print("tag count doesn't match")
return False, x
if tag[0].find('/') == -1:
#print("pushing: "+tag[0])
stack.push(tag[0])
else:
#print("popping: "+tag[0])
stack.pop()
x+=1
except:
return False,x
if stack.isEmpty():
return True,x
else:
return False,x
def print_xml_list(formatted_list):
indent = 0
string = str()
previousIsString = False
#print(formatted_list)
for item in formatted_list:
#print("previous = " + str(previousIsString))
#print(item)
if len(item) > 0:
if isTag(item) == True and item.find('/') == -1:#the item is a tag and not and end tag
if previousIsString == True and string[len(string)-5:].find('\n') == -1:
#add a newline if there isn't one already
string+='\n'
string+=(' '*indent+item+'\n')
indent+=1 #increases indent
previousIsString = False #previous isn't a string
if isTag(item) == True and item.find('/') != -1: #the item is a tag and also an end tag
if previousIsString == True:
string+='\n'
indent-=1 # reduces indent
string+=(' '*indent+item+'\n')
previousIsString = False #previous isn't a string
if isTag(item) == False:
if previousIsString:
string+=(' '+item+' ') #adds item and no tab space
else:
string+=(' '*indent+item+' ') #adds item with tabs before
previousIsString = True # previous is a string
return string
if __name__ == "__main__":
filename = input("enter file name: ")
file = open(filename, 'r')
s = file.read()
formatted = split_tags_and_string(s) #formats the string and tags into a list called formatted
isGood = check_tags(formatted) # makes sure the xml is valid
if isGood[0] == False: #if the xml is bad it says so and ends the program
print("The xml file is bad.")
else:
string = print_xml_list(formatted) #adds indentation and formatting to the list and turns it into a string
print(string) #prints the final result
No one provided an answer so here is my basic way to parse xml, it does not have the functionality to handle things like
I provided the answer above. Hopefully this will be useful to someone with a similar curiosity.

Python: Dictionary being returned by func as string? What the heck am I doing wrong?

I'm generating a dictionary in a function and then returning this dictionary. I can't seem to access the returned dict as a dictionary though despite it being the correct format.. It is treating the data as a string only, ie i can print it but can't print d.keys() or d.items() What the heck am I doing wrong?????
data when printed as a str()
{1: '214902885,214902909', 2: '214902910,214902934', 3: '214902935,214902959', 4: '214902960,214902984', 5: '214902985,214903009', 6: '214903010,214903034', 7: '214903035,214903059', 8: '214903060,214903084', 9: '214903085,214903109', 10: '214903110,214903139'}
Error when I try to print d.items() or d.keys()
print bin_mapping.keys()
AttributeError: 'str' object has no attribute 'keys'
Once I have returned the dict from a function do I have to redefine it as a dictionary? I'd really appreciate some help as I'm super frustrated :/
Thanks,
As suggested here is the code.. Function I'm calling to return the dictionary first..
def models2bins_utr(id,type,start,end,strand):
''' chops up utr's into bins for mC analysis'''
# first deal with 5' UTR
feature_len = (int(end) - int(start))+1
bin_len = int(feature_len) /10
if int(feature_len) < 10:
return 'null'
#continue
else:
# now calculate the coordinates for each of the 10 bins
bin_start = start
d_utr_5 = {}
d_utr_3 = {}
for i in range(1,11):
# set 1-9 first, then round up bin# 10 )
if i != 10:
bin_end = (int(bin_start) +int(bin_len)) -1
if str(type) == 'utr_5':
d_utr_5[i] = str(bin_start)+','+str(bin_end)
elif str(type) == 'utr_3':
d_utr_3[i] = str(bin_start)+','+str(bin_end)
else:
pass
#now set new bin_start
bin_start = int(bin_end) + 1
# now round up last bin
else:
bin_end = end
if str(type) == 'utr_5':
d_utr_5[i] = str(bin_start)+','+str(bin_end)
elif str(type) == 'utr_3':
d_utr_3[i] = str(bin_start)+','+str(bin_end)
else:
pass
if str(type) == 'utr_5':
return d_utr_5
elif str(type) == 'utr_3':
return d_utr_3
Calling the function and trying to access the dict
def main():
# get a list of all the mrnas in the db
mrna_list = get_mrna()
for mrna_id in mrna_list:
print '-----'
print mrna_id
mrna_features = features(mrna_id)
# if feature utr, send to models2bins_utr and return dict
for feature in mrna_features:
id = feature[0]
type = feature[1]
start = feature[2]
end = feature[3]
assembly = feature[4]
strand = feature[5]
if str(type) == 'utr_5' or str(type) == 'utr_3':
bin_mapping = models2bins_utr(id,type,start,end,strand)
print bin_mapping
print bin_mapping.keys()
You return a string early on:
bin_len = int(feature_len) /10
if int(feature_len) < 10:
return 'null'
Perhaps you wanted to raise an exception instead here, or at the very least, return an empty dictionary or use None as a flag value.
If you use None do test for it:
bin_mapping = models2bins_utr(id,type,start,end,strand)
if bin_mapping is not None:
# you got a dictionary.
I'm wondering what return 'null' is supposed to achieve. My guess is that once in a while, you call the function with the wrong parameters and get this string back.
I suggest to throw an exception instead (raise Exception('Not enough arguments') or similar) or to return an empty dict.
You should also learn about repr() because it gives you more information about an object which makes debugging much easier.

Inteviewstreet Median in python. Fails on all but the first test case

So i wrote this code and it passes the first test case, and fails all the rest. However, I can't seem to find an input that breaks it. Maybe it's because I've been staring at the code too long, but i would appreciate any help.
The algorithm uses two priority queues for the smallest and largest halves of the current list. Here's the code:
#!/bin/python
import heapq
def fix(minset, maxset):
if len(maxset) > len(minset):
item = heapq.heappop(maxset)
heapq.heappush(minset, -item)
elif len(minset) > (len(maxset) + 1):
item = heapq.heappop(minset)
heapq.heappush(maxset, -item)
N = int(raw_input())
s = []
x = []
for i in range(0, N):
tmp = raw_input()
a, b = [xx for xx in tmp.split(' ')]
s.append(a)
x.append(int(b))
minset = []
maxset = []
for i in range(0, N):
wrong = False
if s[i] == "a":
if len(minset) == 0:
heapq.heappush(minset,-x[i])
else:
if x[i] > minset[0]:
heapq.heappush(maxset, x[i])
else:
heapq.heappush(minset, -x[i])
fix(minset, maxset)
elif s[i] == "r":
if -x[i] in minset:
minset.remove(-x[i])
heapq.heapify(minset)
elif x[i] in maxset:
maxset.remove(x[i])
heapq.heapify(maxset)
else:
wrong = True
fix(minset, maxset)
if len(minset) == 0 and len(maxset) == 0:
wrong = True
if wrong == False:
#Calculate median
if len(minset) > len(maxset):
item = - minset[0]
print int(item)
else:
item = ((-float(minset[0])) + float(maxset[0])) / 2
if item.is_integer():
print int(item)
continue
out = str(item)
out.rstrip('0')
print out
else:
print "Wrong!"
Your original was not so legible, so first I made it object-oriented:
MedianHeapq supports methods rebalance(), add(), remove(), size(), median(). We seriously want to hide the members minset,maxset from the client code, for all sorts of sensible reasons: prevent client from swapping them, modifying them etc. If client needs to see them you just write an accessor.
We also added a __str__() method which we will use to debug visually and make your life easier.
Also added legibility changes to avoid the indexing with [i] everywhere, rename s,x arrays to op,val, add prompts on the raw_input(), reject invalid ops at the input stage.
Your actual computation of the median confuses me (when do you want float and when integer? the rstrip('0') is a bit wack), so I rewrote it, change that if you want something else.
A discussion of the algorithm is here.
Now it is legible and self-contained. Also makes it testable.
You might be making sign errors in your code, I don't know, I'll look at that later.
Next we will want to automate it by writing some PyUnit testcases. doctest is also a possibility. TBC.
Ok I think I see a bug in the sloppiness about locating the median. Remember the minset and maxset can have a size mismatch of +/-1. So take more care about precisely where the median is located.
#!/bin/python
import heapq
class MedianHeapq(object):
def __init__(self):
self.minset = []
self.maxset = []
def rebalance(self):
size_imbalance = len(self.maxset) - len(self.minset)
if len(self.maxset) > len(self.minset):
#if size_imbalance > 0:
item = heapq.heappop(self.maxset)
heapq.heappush(self.minset, -item)
#elif size_imbalance < -1:
elif len(self.minset) > (len(self.maxset) + 1):
item = heapq.heappop(self.minset)
heapq.heappush(self.maxset, -item)
def add(self, value, verbose=False):
if len(self.minset) == 0:
heapq.heappush(self.minset,-value)
else:
if value > self.minset[0]:
heapq.heappush(self.maxset, value)
else:
heapq.heappush(self.minset, -value)
self.rebalance()
if verbose: print self.__str__()
return False
def remove(self,value,verbose=False):
wrong = False
if -value in self.minset:
minset.remove(-value)
heapq.heapify(self.minset)
elif value in maxset:
maxset.remove(value)
heapq.heapify(self.maxset)
else:
wrong = True
self.rebalance()
if verbose: print self.__str__()
return wrong
def size(self):
return len(self.minset)+len(self.maxset)
def median(self):
if len(self.minset) > len(self.maxset):
item = - self.minset[0]
return int(item)
else:
item = (-self.minset[0] + self.maxset[0]) / 2.0
# Can't understand the intent of your code here: int, string or float?
if item.is_integer():
return int(item)
# continue # intent???
else:
return item
# The intent of this vv seems to be round floats and return '%.1f' % item ??
#out = str(item)
#out.rstrip('0') # why can't you just int()? or // operator?
#return out
def __str__(self):
return 'Median: %s Minset:%s Maxset:%s' % (self.median(), self.minset,self.maxset)
# Read size and elements from stdin
N = int(raw_input('Size of heap? '))
op = []
val = []
while(len(val)<N):
tmp = raw_input('a/r value : ')
op_, val_ = tmp.split(' ')
if op_ not in ['a','r']: # reject invalid ops
print 'First argument (operation) must be a:Add or r:Remove! '
continue
op.append(op_)
val.append(int(val_))
mhq = MedianHeapq()
for op_,val_ in zip(op,val): # use zip to avoid indexing with [i] everywhere
wrong = False
if op_ == 'a':
wrong = mhq.add(val_)
elif op_ == 'r':
wrong = mhq.remove(val_)
assert (mhq.size()>0), 'Heap has zero size!'
assert (not wrong), 'Heap structure is wrong!'
if not wrong:
print mhq.__str__()

Categories