How to remove 1 as a coefficient on my Python Code? - python

I have been looking at my code for awhile and need to return a polynomial given a dictionary. The polynomial output should not have any 1's as coefficients. Her e is my code:
class Polynomial:
# Constructor
def __init__(self, polyDict):
self.polyDict = polyDict
# String Method
def __str__(self):
polyStr = ""
firstTerm = True
for exp, coeff in sorted(self.polyDict.items(), reverse=True):
if coeff == 0:
continue
if firstTerm:
if coeff > 0:
polyStr += str(coeff)
else:
polyStr += str(coeff)
if exp > 1:
polyStr += "x^" + str(exp)
elif exp == 1:
polyStr += "x"
firstTerm = False
else:
if coeff > 0:
polyStr += "+" + str(coeff)
else:
polyStr += str(coeff)
if exp > 1:
polyStr += "x^" + str(exp)
elif exp == 1:
polyStr += "x"
return polyStr
print(Polynomial({6:-3, 5:6, 4:-1, 3:-2, 2:0, 1:1, 0:-3}))
I am unsure what else to try. I've staired at the code for a couple hours and dont know what to add.

I think this combines as much as can be combined.
class Polynomial:
# Constructor
def __init__(self, polyDict):
self.polyDict = polyDict
# String Method
def __str__(self):
polyStr = ""
firstTerm = True
for exp, coeff in sorted(self.polyDict.items(), reverse=True):
if coeff == 0:
continue
if coeff < -1 or (firstTerm and coeff > 1):
polyStr += str(coeff)
elif coeff == -1:
polyStr += '-'
elif coeff == 1:
if not firstTerm:
polyStr += '+'
else:
polyStr += '+'+str(coeff)
firstTerm = False
if exp > 1:
polyStr += "x^"+str(exp)
elif exp == 1:
polyStr += "x"
return polyStr
print(Polynomial({6:-3, 5:6, 4:-1, 3:-2, 2:0, 1:1, 0:-3}))

Related

Evaluate Postfix Expression Tree - Calculator

I have code to generate a postfix expression from infix and generate an expression tree from the postfix notation. The problem is, if I give it an expression like 45 / 15 * 3, it will give me the result 1 instead of 9, because it is solving the deepest levels of the tree first. Is there another traversal I can do to evaluate the expression properly?
def evaluate(self):
if not self.is_empty():
if not infix_to_postfix.is_operator(self._root):
return float(self._root)
else:
A = self._left.evaluate()
B = self._right.evaluate()
if self._root == "+":
return A + B
elif self._root == "-":
return A - B
elif self._root == "*":
return A * B
elif self._root == "/":
return A / B
def InfixToPostfix(exp: str):
exp = exp.replace(" ", "")
S = Stack()
postfix = ""
j = 0
for i in range(len(exp)):
if is_operand(exp[i]):
if i + 1 <= len(exp) - 1 and is_operand(exp[i+1]):
continue
else:
j = i
while j - 1 >= 0 and is_operand(exp[j - 1]):
if is_operand(exp[j]):
j -= 1
else:
break
postfix += exp[j:i + 1] + " "
elif is_operator(exp[i]):
while not S.is_empty() and S.top() != "(" and \ HasHigherPrecedence(S.top(), exp[i]):
if is_operator(S.top()):
postfix += S.top() + " "
else:
postfix += S.top()
S.pop()
S.push(exp[i])
elif exp[i] == "(":
S.push(exp[i])
elif exp[i] == ")":
while not S.is_empty() and S.top() != "(":
if is_operator(S.top()):
postfix += S.top() + " "
else:
postfix += S.top()
S.pop()
else:
print("There's an invalid character")
return
while not S.is_empty():
if S.top() == '(':
S.pop()
continue
if is_operator(S.top()):
postfix += S.top() + " "
else:
postfix += S.top()
S.pop()
return postfix
def HasHigherPrecedence(op1: str, op2: str):
op1_weight = get_operator_weight(op1)
op2_weight = get_operator_weight(op2)
return op1_weight > op2_weight
The postfix expression of your example 45 / 15 * 3 would be:
45 15 / 3 *
So the tree generated would look like:
*
/ 3
45 15
So your traversal algorithm appears correct, as it would do 45 / 15 = 3, then 3 * 3 = 9.
The issue is actually pretty minor in your postfix generator. Specifically, in the function HasHigherPrecedence, you should return op1_weight >= op2_weight. It should be greater than or equal to because in examples such as this one where the operators have the same precedence, they should be executed in the order they appear. So division would be done first.

adding parenthesis in recursive function

I'm simply looking to add a parenthesis at the end of my recursive function.. I'm literally just missing the final parenthesis, but I can't figure out how to add it in! Any help is greatly appreciated!
My code:
def sum( n ):
if n == 0:
return '1'
elif n == 1:
return '(1+1)'
elif n == 2:
return '((1+1)+(1+1))'
elif n == 3:
return '(((1+1)+(1+1))+((1+1)+(1+1)))'
else:
return '((((1+1)+(1+1))+((1+1)+(1+1)))' + ')'sum_power2( n - 1 )
Just switch the order in the last row, so it would be
def sum_power2( n ):
if n == 0:
return '1'
elif n == 1:
return '(1+1)'
elif n == 2:
return '((1+1)+(1+1))'
elif n == 3:
return '(((1+1)+(1+1))+((1+1)+(1+1)))'
else:
return '((((1+1)+(1+1))+((1+1)+(1+1)))' + sum_power2( n - 1 )+')'
Try this:
def sum_power(n,tmp=''):
tmp = '1' if not tmp else '(' + tmp + '+' + tmp + ')'
if n == 0:
return tmp
else:
n -= 1
return sum_power(n,tmp)
print(sum_power(2))

Python Recursion Double letters

So what the task is, is that your supposed to write a recursion function that counts the amount of "double" letters in a string, So for example the string "hmmm" would return 1 and the string "hmmmm" would return 2 and that a string "abb" would return 1. My code is here:
def num_double_letters(astr):
if astr == "" or len(astr) == 1:
return 0
elif len(astr) == 2:
if astr[0] == astr[1]:
return 1 + num_double_letters(astr[1:])
else:
return 0 + num_double_letters(astr[1:])
elif astr[0] != astr[1]:
return 0 + num_double_letters(astr[1:])
elif astr[0] == astr[1] != astr[2]:
return 1 + num_double_letters(astr[1:])
elif astr[0] == astr[1] == astr[2]:
return 0 + num_double_letters(astr[1:])
My problem is that a string with 4 same letters = 1 when its supposed to = 2. And also is there a cleaner way to do this?
I think you've made it a bit complicated for yourself... there's no need to go deeper into the recursion once the length of your string is 2, and you want to advance by 2, not 1 when you find a double to count the way I think you do. Try this:
def num_double_letters(astr):
if astr == "" or len(astr) == 1:
return 0
elif len(astr) == 2:
if astr[0] == astr[1]:
return 1
else:
return 0
elif astr[0] != astr[1]:
return 0 + num_double_letters(astr[1:])
elif astr[0] == astr[1]:
return 1 + num_double_letters(astr[2:])
print(num_double_letters('hmm'))
print(num_double_letters('hmmm'))
print(num_double_letters('hmmmm'))
Output:
1
1
2
You might consider the following more Pythonic and concise:
def num_double_letters(astr):
if len(astr) < 2:
return 0
if astr[0] == astr[1]:
return 1 + num_double_letters(astr[2:])
return num_double_letters(astr[1:])

Binary Subtraction - Python

I want to make a binary calculator and I have a problem with the subtraction part. Here is my code (I have tried to adapt one for sum that I've found on this website).
maxlen = max(len(s1), len(s2))
s1 = s1.zfill(maxlen)
s2 = s2.zfill(maxlen)
result = ''
carry = 0
i = maxlen - 1
while(i >= 0):
s = int(s1[i]) - int(s2[i])
if s <= 0:
if carry == 0 and s != 0:
carry = 1
result = result + "1"
else:
result = result + "0"
else:
if carry == 1:
result = result + "0"
carry = 0
else:
result = result + "1"
i = i - 1
if carry>0:
result = result + "1"
return result[::-1]
The program works fine with some binaries subtraction but it fails with others.
Can someone please help me because I can't find the mistake? Thanks a lot.
Short answer: Your code is wrong for the case when s1[i] == s2[i] and carry == 1.
Longer answer: You should restructure your code to have three separate cases for s==-1, s==0, and s==1, and then branch on the value of carry within each case:
if s == -1: # 0-1
if carry == 0:
...
else:
...
elif s == 0: # 1-1 or 0-0
if carry == 0:
...
else:
...
else: # 1-0
if carry == 0:
...
else:
...
This way you have a separate block for each possibility, so there is no chance of overlooking a case like you did on your first attempt.
I hope the answer below it helps.
def binarySubstration(str1,str2):
if len(str1) == 0:
return
if len(str2) == 0:
return
str1,str2 = normaliseString(str1,str2)
startIdx = 0
endIdx = len(str1) - 1
carry = [0] * len(str1)
result = ''
while endIdx >= startIdx:
x = int(str1[endIdx])
y = int(str2[endIdx])
sub = (carry[endIdx] + x) - y
if sub == -1:
result += '1'
carry[endIdx-1] = -1
elif sub == 1:
result += '1'
elif sub == 0:
result += '0'
else:
raise Exception('Error')
endIdx -= 1
return result[::-1]
normalising the strings
def normaliseString(str1,str2):
diff = abs((len(str1) - len(str2)))
if diff != 0:
if len(str1) < len(str2):
str1 = ('0' * diff) + str1
else:
str2 = ('0' * diff) + str2
return [str1,str2]

how to solve the print string error on python eclipse

I am not sure why do i get this error from the console:
<<
print stirngp[state[i][j]]
^
SyntaxError: invalid syntax
<<
Furthermore it seems that the IDE put a red close on the following code line
line = raw_input("Enter:")
I am not sure what did i do wrong, the following code is as shown below
def isTerminal(state):
stateT = zip(*state)
for i in range(3):
if all(state[i][0] == j for j in state[i]) and state[i][0] != 0:
return state[i][0]
if all(stateT[i][0] == j for j in stateT[i]) and stateT[i][0] != 0:
return stateT[i][0]
if (state[0][0] == state[1][1] == state[2][2]) or \
(state[0][2] == state[1][1] == state[2][0]):
if state[1][1] != 0:
return state[1][1]
for i in range(3):
if 0 in state[i]:
return None
return 0
def succ(state):
# print state
countX = 0
countO = 0
for i in range(3):
for j in range(3):
if state[i][j] == 1: countX = countX + 1
if state[i][j] == -1: countO = countO + 1
if countX > countO:
player = "MIN"
else:
player = "MAX"
succList = []
v = {"MIN":-1,"MAX":1}
for i in range(3):
for j in range(3):
if state[i][j] == 0:
succ = [k[:] for k in state]
succ[i][j] = v[player]
succList = succList + [succ]
# print succList
return succList
def nextplay(player):
if player == "MIN":
return "MAX"
else:
return "MIN"
def minimax(state,alpha,beta,player):
value = isTerminal(state)
if value != None:
# print "TERMINAL:", state, value, player
return value
if player == "MIN":
for y in succ(state):
beta = min(beta, minimax(y,alpha,beta,"MAX"))
if beta <= alpha: return alpha
return beta
if player == "MAX":
for y in succ(state):
alpha = max(alpha, minimax(y,alpha,beta,"MIN"))
if alpha >= beta: return beta
return alpha
def printing(state):
p = {-1:"O",0:".",1:"X"}
for i in range(3):
for j in range(3):
print p[state[i][j]],
print ""
print ""
def main():
state = [[0,0,0],
[0,0,0],
[0,0,0]]
val = isTerminal(state)
while val == None:
line = raw_input("Enter:")
x = line.split(",")
a = int(x[0]); b = int(x[1])
state[a][b] = 1
if isTerminal(state) != None:
printing(state)
return
# determine which successive state is better
succList = succ(state)
succValList = []
for i in succList:
succValList = succValList + [(minimax(i,-1,1,"MAX"),i)]
succValList.sort(key=lambda x:x[0])
state = succValList[0][1] # can also randomly choose other states of the same minimax value
printing(state)
val = isTerminal(state)
if __name__ == '__main__':
main()
As far as i know you can't use raw_input() in Python 3. It's been changed to just input()
http://docs.python.org/dev/whatsnew/3.0.html
also what is stringp? is it an existing list?
if so then state[i][j] MUST return an integer so you can retrieve the item at that index of stringp[]

Categories

Resources