The function append below takes a pair which is an immutable tuple as a parameter. In the processing of the append it is necessary to enclose all values with start and end single quotes. Because the tuple values are immutable I cannot simply do this:
if item[1][0] != "'" and item[1][-1] != "'":
item[1] = "'{0}'".format(item[1])
self.keyvalues[item[0]] = item[1]
Hence the handling as follows:
if item[1][0] != "'" and item[1][-1] != "'":
self.keyvalues[item[0]] = "'{0}'".format(item[1])
else:
self.keyvalues[item[0]] = item[1]
Full code appears below.
Is there a more elegant way to add the key and value to the dictionary.
class section(object):
"""class to hold a section. name is name of section. keyvalues is a key
value dictionary of keys and values"""
def __init__(self, name):
self.name = name
self.keyvalues = {}
print "Constructed section:", name
def append(self, item):
"""add a key value pair to section"""
if len(item) != 2:
return False
else:
print "adding:", item, "to", self.name, "object"
# cannot do this because tuple is immutable
#item[1] = "'{0}'".format(item[1])
# Would there be a more elegant way of doing this - given that
# parameter must be a immutable tuple?
if item[1][0] != "'" and item[1][-1] != "'":
self.keyvalues[item[0]] = "'{0}'".format(item[1])
else:
self.keyvalues[item[0]] = item[1]
return True
def __repr__(self):
s = "contains\n"
for k, v in self.keyvalues.iteritems():
s += "\t{0}={1}\n".format(k, v)
return s
__str__ = __repr__
mysection = section("section1")
dnpair = ("key1", "value1")
mysection.append(dnpair)
print mysection
Since the tuple is not used again, just split it to separate variables.
key, value = item
if value[0] != "'" and value[-1] != "'":
value = "'{0}'".format(value)
self.keyvalues[key] = value
Elegant is subjective, but this is the most elegant solution I could come up with. It allows value manipulation by passing it off to a function. Also the ugly
if item[1][0] != "'" and item[1][-1] != "'":
becomes
if not value[0] == value[-1] == "'":
Here's the full code with the modified append and newly created quote_wrap method.
def append(self, item):
"""add a key value pair to section"""
if len(item) != 2:
return False
else:
print( "adding:", item, "to", self.name, "object")
self.keyvalues[item[0]] = self.quote_wrap(item[1])
return True
def quote_wrap(self, value):
if not value[0] == value[-1] == "'":
value = "'{}'".format(value)
return value
Related
Given a string that contains only the following => ‘{‘, ‘}’, ‘(‘, ‘)’, ‘[’, ‘]’. At some places there is ‘X’ in place of any bracket. Determine whether by replacing all ‘X’s with appropriate bracket, is it possible to make a valid bracket sequence.
Examples:
Input : S = "{(X[X])}"
Output : Balanced
Input : S = "[{X}(X)]"
Output : Not balanced
I tried to work it out like this, and it works for examples above. But it doesn't work for all examples eg. (it should be balanced but it says it's not)
Input: S = "([X}])"
Output: Not balanced
I tried to work it out but i can't find a solution. Please help.
class Stack:
def __init__(self):
self.data = []
def insert(self, x):
self.data.append(x)
def empty(self):
return len(self.data) == 0
def remove(self):
if self.empty():
raise ValueError('Stack is empty.')
self.data.pop()
def top_element(self):
if self.empty():
raise ValueError('Stack is empty.')
return self.data[-1]
def is_matching(a, b):
if a == "(" and b == ")":
return True
elif a == "[" and b == "]":
return True
elif a == "{" and b == "}":
return True
elif a == "X":
return True
return False
def is_balanced(expression,elements=Stack(),ind=0):
if ind == len(expression):
return elements.empty()
pre_brackets = "([{"
post_brackets = ")]}"
char = expression[ind]
if char in pre_brackets:
elements.insert(char)
return is_balanced(expression,elements,ind+1)
elif char in post_brackets:
if elements.empty() :
return False
if not is_matching(elements.top_element(), char):
return False
elements.remove()
return is_balanced(expression,elements,ind+1)
elif char == "X":
temp = Stack()
temp.insert(char)
result = (is_balanced(expression,temp,ind+1))
if result:
return True
if elements.empty():
return False
elements.remove()
return is_balanced(expression,elements,ind+1)
expression = "([X}])"
if expression == "":
print("No brackets in expression!")
elif len(expression) % 2 != 0:
print("Not balanced")
elif is_balanced(expression):
print("Balanced")
else:
print("Not Balanced")
You can do it by recursively testing all possible replacements for an X:
def can_be_balanced(expr):
pairs = "{}[]()"
opening_brackets = pairs[::2]
closing_brackets = pairs[1::2]
closer = {o:c for o, c in zip(opening_brackets, closing_brackets)}
opener = {c:o for o, c in zip(opening_brackets, closing_brackets)}
stack = []
for item in expr:
if item in opening_brackets:
# we append opening brackets to the stack
stack.append(item)
elif item in closing_brackets:
if not stack or stack[-1] != opener[item]:
# the closing bracket doesn't match the top of the stack
return False
else:
# if it does, we remove the matching opening bracket
stack.pop()
elif item == 'X':
# X could be any of the opening brackets,
possible = list(opening_brackets)
if stack and stack[-1] in opening_brackets:
# or the closing bracket matching the top of the stack
possible.append(closer[stack[-1]])
for pos in possible:
# we replace this X, the first one remaining in expr
test_expr = expr.replace('X', pos, 1)
if can_be_balanced(test_expr):
# This is just in order to print the working solution we just found,
# you may remove these two lines
if not 'X' in test_expr:
print(test_expr)
return True
# None of the replacements for X gave a balanced expression
return False
else:
raise ValueError(f'Invalid item {item} in {expr}')
# The expression is balanced if and only if the stack ends up empty
return not stack
Testing on your sample data:
tests = [("[{X}(X)]", False),
("{(X[X])}", True),
("([X}])", True),
]
for test in tests:
print(test[0], ': should be', test[1])
print(can_be_balanced(test[0]))
print('-'*20)
correctly outputs (with the balanced expression in case it can be done):
[{X}(X)] : should be False
False
--------------------
{(X[X])} : should be True
{([[]])}
True
--------------------
([X}]) : should be True
([{}])
True
--------------------
Note that a major problem in your code is that you only test the end of the expression, starting at the position of the X. Beware also of the mutable default argument elements=Stack() that would leave you with the remnants of the previous call to the function instead of a fresh, empty Stack object.
I'm trying to define a function that receive infinite values in dictonary, but the the exit is taking only the characters of the last 2 key and value.
Any suggestion?
def infinityInvent():
infinityInvent = []
while True:
keys = input(f'Enter a item (or blank to stop): ')
values = input(f'What the value? ')
if keys == '':
break
infinityInvent = dict(zip(keys, values)) # or infinityInvent = {k: v for k, v in zip(keys, values)}
infinityInvent()
You need to set an item in the dict, not redefine the dict:
def infinityInvent():
infinityInvent = {}
while True:
key = input(f'Enter a item (or blank to stop): ')
if key == '':
break
value = input(f'What the value? ')
infinityInvent[key] = value
return infinityInvent
print(infinityInvent())
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):
This is my first time asking a question on here, and I am only doing this because I have spent the past week trying to figure this out and haven't been able to. I found similar questions, but the results did not help me. I have to take an infix expression and calculate the results using two stacks, one for the operator and one for the numbers. An example would be 6 - ( 5 - 3 ) * ( 4 + 2 ) = -6 or 3 * 11 / 8 + 5 – 4 * 7 = -18.875. I just cannot figure out how to get this to work. Currently my code is this:
class NumStack:
def __init__(self):
"""Create an empty stack."""
self._data = [] #nonpublic list instance
def __len__(self):
"""Return the number of elements in the stack."""
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
return len(self._data) == 0
def push(self,e):
"""Add element e to the top of the stack."""
self._data.append(e) #new item stored at end of list
print(self._data)
def top(self):
"""Return (but do not remove) the element at the top of the stack.
Raise Empty exception if the stack is empty"""
if self.is_empty():
return
return self._data[-1] #the last item in the list
def pop(self):
"""Remove and return the element from the top of the stack (i.e, LIFO)
Raise Empty exception if the stack is empty."""
if self.is_empty():
return "empty"
return self._data.pop() #remove last item from list
def str(self):
return self._data
class OperatorStack:
def __init__(self):
"""Create an empty stack."""
self._data = [] #nonpublic list instance
def __len__(self):
"""Return the number of elements in the stack."""
return len(self._data)
def is_empty(self):
"""Return True if the stack is empty."""
length = len(self._data)
if length == 0:
return True
else:
return False
def push(self,e):
"""Add element e to the top of the stack."""
self._data.append(e) #new item stored at end of list
print(self._data)
def top(self):
"""Return (but do not remove) the element at the top of the stack.
Raise Empty exception if the stack is empty"""
if self.is_empty():
return
return self._data[-1] #the last item in the list
def pop(self):
"""Remove and return the element from the top of the stack (i.e, LIFO)
Raise Empty exception if the stack is empty."""
length = len(self)
if length == 0:
print("list is empty")
else:
if self.is_empty():
return
return self._data.pop()
def str(self):
return self._data
def main():
expression = str(input("Enter an expression: "))
expression = expression.split()
print(expression)
N = NumStack()
O = OperatorStack()
new = []
NewOP = []
NewNum = [0,0]
for e in expression:
if e == '(' or e == ')' or e == '+' or e == '-' or e == '*' or e == '/':
O.push(e)
else:
N.push(e)
while O.is_empty() == False or N.is_empty() == False:
TmpOp = O.top()
if TmpOp == ')':
O.pop()
elif TmpOp == '(':
O.pop()
if TmpOp != '(' and TmpOp != ')':
new.append(N.pop())
new.append(O.pop())
print(TmpOp)
while TmpOp == ')':
if N.top() != "empty":
NewNum[1] = N.pop()
if N.top() != "empty":
NewNum[0] = N.top()
print(NewNum[0],NewNum[1])
if O.pop() == '+':
num = float(NewNum[1]) + float(NewNum[0])
new.append(num)
print(num)
O.pop()
break
elif O.pop() == '-':
num = float(NewNum[0]) - float(NewNum[1])
new.append(num)
print(num)
O.pop()
break
elif O.pop() == '*':
num = NewNum[1]*NewNum[0]
new.append(num)
print(num)
# O.pop()
break
elif O.pop() == '/':
num = NewNum[1]/NewNum[0]
new.append(num)
print(num)
# O.pop()
break
if O.top() == ')':
O.pop()
break
if O.__len__() == 0 and N.__len__() == 0:
break
continue
while TmpOp != ')' and TmpOp != '(':
new.append(N.pop())
new.append(O.pop())
print(new)
if O.__len__() == 0 and N.__len__() == 0:
break
print(new)
main()
I believe my classes to be correct, I just cannot find a way of extracting the needed information correctly. I am trying to pop the items into a list and when I get to a parenthesis I go ahead and perform the calculation. If I could just get the correct numbers into my list then I know I can get it to work. I just need to get the "new" to contain the correct numbers. With the problem: "6 - ( 5 - 3 ) * ( 4 + 2 )" I should get [6.0, '*', 2.0, '-', 6]. It is not coming out to that. I really appreciate any help that can be given.
I am trying to merge variables to keys existing in a dictionary.
Here are the rules:
If key already exists, then increment the value counter by one.
If partial match to key exists:
a. If variable length is smaller than key but re.search is not None, increment the value counter by one
b. If variable length is larger than key and re.search is not None, replace key by variable and increment counter by one
If variable exists after this but still has no match in dictionary, add variable to dictionary
I have been able to accomplish 1, 2a and 2b but I am not sure how to add 3. Any help/suggesstions will be appreciated.
Here is the script in its present form: I would also like to see "turtle" in the Dict.
Animals = ["phant", "eleph", "tiger", "turtle", "zebra", "ostrich"]
Dict = {"horse":1, "elephant":1, "iger":1, "ostrich":1}
for name in Animals:
if name in Dict:
Dict[name]=Dict[name]+1
else:
for key, val in Dict.items():
if len(name) < len(key):
m = re.search (name, key)
if m != None:
print ("Found match!", name)
Dict[key] = Dict[key] + 1
break
elif len(name) > len(key):
m = re.search (key, name)
if m != None:
print ("Found match!", name)
Dict[name] = Dict.pop(key) + 1
Dict[name] = Dict[name] + 1
break
One way to describe case #3 after looking at the code is "if neither of the break statements were executed". You can handle this case by putting an else statement after the for loop. The code within this block will only be executed if the for loop ran to completion (or in other words, there was no break statement run within the loop):
Animals = ["phant", "eleph", "tiger", "turtle", "zebra", "ostrich"]
Dict = {"horse":1, "elephant":1, "iger":1, "ostrich":1}
for name in Animals:
if name in Dict:
Dict[name]=Dict[name]+1
else:
for key, val in Dict.items():
if len(name) < len(key):
m = re.search (name, key)
if m != None:
print ("Found match!", name)
Dict[key] = Dict[key] + 1
break
elif len(name) > len(key):
m = re.search (key, name)
if m != None:
print ("Found match!", name)
Dict[name] = Dict.pop(key) + 1
Dict[name] = Dict[name] + 1
break
else: # this line and the one below it are new
Dict[name] = 1
for name in Animals:
if name in Dict:
Dict[name]=Dict[name]+1
else:
found= False
for key, val in Dict.items():
if len(name) < len(key):
m = re.search (name, key)
if m != None:
print ("Found match!", name)
Dict[key] = Dict[key] + 1
found= True
break
elif len(name) > len(key):
m = re.search (key, name)
if m != None:
print ("Found match!", name)
Dict[name] = Dict.pop(key) + 1
found= True
break
if not found
Dict[name] = 1
I'd prefer the following, though:
for name in Animals:
if name in Dict:
Dict[name]=Dict[name]+1
else:
found= False
for key, val in Dict.items():
m = re.search (name, key)
if m != None:
print ("Found match!", name)
if len(name) < len(key):
Dict[key] = Dict[key] + 1
else
Dict[name] = Dict.pop(key) + 1
found= True
break
if not found
Dict[name] = 1