Forming a polynomial from the input - python

I need to write a program that, when provided inputs by the user, will create a polynomial based on the position of the input order.
For example, if the user input: 1 2 3
The polynomial should be printed x^2 + (2.0)x^1 + 3 and this answer should be in float form. How do I do that?
This is what I have done so far
def get_expression(x1):
x1=""
power = len(x1) - 1
for i in range(len(x1)):
if x1[i] < 0:
x1 += str(x1[i])
else:
x1 += "+" + str(x1[i])
if x1[i] == 0:
continue
if power == 1:
x1 += "x"
elif power == 0:
x1 = x1
else:
x1 += "x" + str(power)
power = power - 1
if sum(x1)==0:
return float(0)
return x1
The code should satisfy the code below and give results correctly in the form: -4.5x - 5 & 2x^2 - 3
p1=[-4.5,-5.0]
print(get_expression(p1))
p2=[2.0,0.0,-3.0]
print(get_expression(p2))
Please help me and advise how I could correct my code and get an answer in float form.

You could build the string naively and then make it look nicer with string replacements:
def poly(*C):
result = "+".join(f" {c}x^{-p} " for p,c in enumerate(C,1-len(C)) if c)
result = result.replace("+ -","- ") # subtract for negative coefficient
result = result.replace("^1 "," ") # implicit x^1
result = result.replace("x^0","") # implicit x^0
result = result.replace(" 1x"," x").replace("-1x","-x") # implicit 1x
return result.strip()
for example: poly(-1,0,3,-1,5)
result = ' -1x^4 + 3x^2 + -1x^1 + 5x^0 ' # naive build (skips zero coeff.)
result = ' -1x^4 + 3x^2 - 1x^1 + 5x^0 ' # subtract for negative coefficient
result = ' -1x^4 + 3x^2 - 1x + 5x^0 ' # implicit x^1
result = ' -1x^4 + 3x^2 - 1x + 5 ' # implicit x^0
result = ' -x^4 + 3x^2 - x + 5 ' # implicit 1x
return '-x^4 + 3x^2 - x + 5' # strip extra space for return
output:
print(poly(1,2,3)) # x^2 + 2x + 3
print(poly(-4.5,-5)) # -4.5x - 5
print(poly(2,0,-3)) # 2x^2 - 3
print(poly(-1,0,-1.5,5,0,-32)) # -x^5 - 1.5x^3 + 5x^2 - 32
print(poly("a","b","-c")) # ax^2 + bx - c

Sort of follow your logic and re-write your code, FYI.
def get_expresultsion(x1):
result = "" # use another variable instead of x1
power = len(x1) - 1
for i in range(len(x1)):
if x1[i] < 0:
result += str(x1[i])
elif x1[i] == 0:
# put this into the same IF logic since this part is checking x1[i] as well
power = power - 1
continue
else:
result += "+" + str(x1[i])
# check power then
if power == 1:
result += "x"
elif power == 0:
pass
else:
# add "^"
result += "x^" + str(power)
power = power - 1
if sum(x1) == 0:
return float(0)
return result

At the time of viewing your question, I couldn't understand the logic you were following so I wrote it from scratch as simple as I can.
def get_expression(coefficient_list):
power = 0
expression = "" #Our final result (instead of x1)
if len(coefficient_list) == 1: #For the case having just the constant
return(coefficient_list[0])
elif len(coefficient_list) > 1:
for coefficient in reversed(coefficient_list): #We reverse the list
if power == 0: #Dealing with constant
expression += str(coefficient)
else: #Here it puts the coeff and power together and adds to the left side of expression
expression = f"({coefficient})x^{power} + " + expression
power += 1
return expression

Related

how do I identify sequence equation Python

Am I able to identify sequence, but not formula
I have the whole code
def analyse_sequence_type(y:list[int]):
if len(y) >= 5:
res = {"linear":[],"quadratic":[],"exponential":[],"cubic":[]}
for i in reversed(range(len(y))):
if i-2>=0 and (y[i] + y[i-2] == 2*y[i-1]): res["linear"].append(True)
elif i-3>=0 and (y[i] - 2*y[i-1] + y[i-2] == y[i-1] - 2*y[i-2] + y[i-3]): res["quadratic"].append(True)
for k, v in res.items():
if v:
if k == "linear" and len(v)+2 == len(y): return k
elif k == "quadratic" and len(v)+3 == len(y): return k
return
print(f"A relation cannot be made with just {len(y)} values.\nPlease enter a minimum of 5 values!")
return
I can identify linear and quadratic but how do I make a function
So, firstly we will need to create two functions for linear and quadratic (formulae attached below).
def linear(y):
"""
Returns equation in format (str)
y = mx + c
"""
d = y[1]-y[0] # get difference
c = f"{y[0]-d:+}" # get slope
if d == 0: c = y[0] - d # if no difference then intercept is 0
return f"f(x) = {d}x {c} ; f(1) = {y[0]}".replace("0x ","").replace("1x","x").replace(" + 0","");
We apply a similar logic for quadratic:
def quadratic(y):
"""
Returns equation in format (str)
y = ax² + bx + c
"""
a = logic_round((y[2] - 2*y[1] + y[0])/2) # get a
b = logic_round(y[1] - y[0] - 3*a) # get b
c = logic_round(y[0]-a-b) # get c
return f"f(x) = {a}x² {b:+}x {c:+} ; f(1) = {y[0]}".replace('1x²','x²').replace('1x','x').replace(' +0x','').replace(' +0','')
If you try the code with multiple inputs such as 5.0 you will get 5.0x + 4 (example). To omit that try:
def logic_round(num):
splitted = str(num).split('.') # split decimal
if len(splitted)>1 and len(set(splitted[-1])) == 1 and splitted[-1].startswith('0'): return int(splitted[0]) # check if it is int.0 or similar
elif len(splitted)>1: return float(num) # else returns float
return int(num)
The above functions will work in any way provided that the y is a list where the domain is [1, ∞).
Hope this helps :) Also give cubic a try.

Why am I getting a type error when trying to join a list to a string?

I'm trying to build a linear equation calculator with Python. After gathering information by asking the user questions, I start calculating the equation. If the user says that they have 2 points that the line goes through, I use that info to create an equation. The different parts of the equation (e.g slope, y-intercept, operations, x and y) are stored in a list. After calculating the equation, I want to join that list into a single string; However, I get a type error. Here's part of the traceback:
File "/Users/matthewschell/PycharmProjects/Linear Equation Calculator/main.py", line 19, in slope_intercept
final_equation = solve_slopeint(**arg_dict)
File "/Users/matthewschell/PycharmProjects/Linear Equation Calculator/solve_functions.py", line 52, in solve_slopeint
final_equation = ''.join(equation)
TypeError: sequence item 0: expected str instance, int found
And here is the full code for the function to calculate the equation:
def solve_slopeint(**kwargs):
if kwargs['point1'] is not None and kwargs['point2'] is not None:
equation = [None, '= ']
point1 = kwargs['point1']
point2 = kwargs['point2']
slope = (point2[1] - point1[1]) / (point2[0] - point1[0])
slope = str(slope)
if slope[-2:] == ".0":
slope = str(int(float(slope)))
num = 0 # Variable that lets program know the type of num the slope is. 0 = whole num and 1 = fraction
else:
num = point2[1] - point1[1]
denom = point2[0] - point1[0]
common_divisor = gcd(num, denom)
numerator = num / common_divisor
denominator = denom / common_divisor
slope = [int(numerator), int(denominator)]
num = 1
equation.append(slope)
equation.append(None)
equation.append('+ ')
equation.append(0)
equation[0] = point1[1]
equation[3] = point1[0]
if num == 0:
check = slope * equation[3]
while check + equation[5] != equation[0]:
if check + equation[5] < equation[0]:
equation[5] += 1
elif check + equation[5] > equation[0]:
equation[5] -= 1
else:
check = (slope[0] * equation[3]) / slope[1]
while check + equation[5] != equation[0]:
if check + equation[5] < equation[0]:
equation[5] = equation[0] - (check + equation[5])
elif check + equation[5] > equation[0]:
equation[5] = (check + equation[5]) - equation[0]
for item in equation:
item = str(item)
print(item)
final_equation = ''.join(equation)
return final_equation
Does anyone know why I'm getting a type error?
In this part of the snippet:
for item in equation:
item = str(item)
print(item)
You are only str()ing the new items that exist in the loop, but not saving them in the equation
newequation = []
for item in equation:
newequation.append(str(item))
equation = newequation
There's probably a cleaner way to fix this, but I'm not very good

Check result using 4 operations based with Python

I'm struggling to make a Python program that can solve riddles such as:
get 23 using [1,2,3,4] and the 4 basic operations however you'd like.
I expect the program to output something such as
# 23 reached by 4*(2*3)-1
So far I've come up with the following approach as reduce input list by 1 item by checking every possible 2-combo that can be picked and every possible result you can get to.
With [1,2,3,4] you can pick:
[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]
With x and y you can get to:
(x+y),(x-y),(y-x),(x*y),(x/y),(y/x)
Then I'd store the operation computed so far in a variable, and run the 'reducing' function again onto every result it has returned, until the arrays are just 2 items long: then I can just run the x,y -> possible outcomes function.
My problem is this "recursive" approach isn't working at all, because my function ends as soon as I return an array.
If I input [1,2,3,4] I'd get
[(1+2),3,4] -> [3,3,4]
[(3+3),4] -> [6,4]
# [10,2,-2,24,1.5,0.6666666666666666]
My code so far:
from collections import Counter
def genOutputs(x,y,op=None):
results = []
if op == None:
op = str(y)
else:
op = "("+str(op)+")"
ops = ['+','-','*','/','rev/','rev-']
z = 0
#will do every operation to x and y now.
#op stores the last computated bit (of other functions)
while z < len(ops):
if z == 4:
try:
results.append(eval(str(y) + "/" + str(x)))
#yield eval(str(y) + "/" + str(x)), op + "/" + str(x)
except:
continue
elif z == 5:
results.append(eval(str(y) + "-" + str(x)))
#yield eval(str(y) + "-" + str(x)), op + "-" + str(x)
else:
try:
results.append(eval(str(x) + ops[z] + str(y)))
#yield eval(str(x) + ops[z] + str(y)), str(x) + ops[z] + op
except:
continue
z = z+1
return results
def pickTwo(array):
#returns an array with every 2-combo
#from input array
vomit = []
a,b = 0,1
while a < (len(array)-1):
choice = [array[a],array[b]]
vomit.append((choice,list((Counter(array) - Counter(choice)).elements())))
if b < (len(array)-1):
b = b+1
else:
b = a+2
a = a+1
return vomit
def reduceArray(array):
if len(array) == 2:
print("final",array)
return genOutputs(array[0],array[1])
else:
choices = pickTwo(array)
print(choices)
for choice in choices:
opsofchoices = genOutputs(choice[0][0],choice[0][1])
for each in opsofchoices:
newarray = list([each] + choice[1])
print(newarray)
return reduceArray(newarray)
reduceArray([1,2,3,4])
The largest issues when dealing with problems like this is handling operator precedence and parenthesis placement to produce every possible number from a given set. The easiest way to do this is to handle operations on a stack corresponding to the reverse polish notation of the infix notation. Once you do this, you can draw numbers and/or operations recursively until all n numbers and n-1 operations have been exhausted, and store the result. The below code generates all possible permutations of numbers (without replacement), operators (with replacement), and parentheses placement to generate every possible value. Note that this is highly inefficient since operators such as addition / multiplication commute so a + b equals b + a, so only one is necessary. Similarly by the associative property a + (b + c) equals (a + b) + c, but the below algorithm is meant to be a simple example, and as such does not make such optimizations.
def expr_perm(values, operations="+-*/", stack=[]):
solution = []
if len(stack) > 1:
for op in operations:
new_stack = list(stack)
new_stack.append("(" + new_stack.pop() + op + new_stack.pop() + ")")
solution += expr_perm(values, operations, new_stack)
if values:
for i, val in enumerate(values):
new_values = values[:i] + values[i+1:]
solution += expr_perm(new_values, operations, stack + [str(val)])
elif len(stack) == 1:
return stack
return solution
Usage:
result = expr_perm([4,5,6])
print("\n".join(result))

Alternating sums of a list [duplicate]

This question already has answers here:
Writing a function that alternates plus and minus signs between list indices
(7 answers)
Closed 2 years ago.
9.Write a program that accepts 9 integers from the user and stores them in a list. Next, compute the alternating sum of all of the elements in the list. For example, if the user enters
1 4 9 16 9 7 4 9 11
then it computes
1 – 4 + 9 – 16 + 9 – 7 + 4 – 9 + 11 = –2
myList = []
value = None
count = 0
while count != 9:
value = int(input("Please enter a number: "))
myList.append(value)
count = count + 1
if count == 9:
break
print(myList)
def newList(mylist):
return myList[0] - myList[1] + myList[2] - myList[3] + myList[4] - myList[5] + myList[6] - myList[7] + myList[8]
x = newList(myList)
print(x)
My code returns the correct answer, but I need it to print out the actual alternating sums as in the example. I have been stuck on this for a while. I am having a mental block on this and havent been able to find anything similar to this online.
I appreciate any help or tips.
Also, this is python 3.
Thank you.
a=[1, 4, 9, 16, 9, 7, 4, 9, 11]
start1=0
start2=1
sum1=0
first_list=[a[i] for i in range(start1,len(a),2)]
second_list=[a[i] for i in range(start2,len(a),2)]
string=''
for i,j in zip(first_list,second_list):
string+=str(i)+'-'+str(j)+'+'
string.rstrip('+')
print('{}={}'.format(string,str(sum(first_list)-sum(second_list))))
Output
1-4+9-16+9-7+4-9+=-2
Try doing this:
positives = myList[::2]
negatives = myList[1::2]
result = sum(positives) - sum(negatives)
print ("%s = %d" % (" + ".join(["%d - %d" % (p, n) for p, n in zip(positives, negatives)]), result))
I'll explain what I'm doing here. The first two lines are taking slices of your list. I take every other number in myList starting from 0 for positives and starting from 1 for negatives. From there, finding the result of the alternating sum is just a matter of taking the sum of positives and subtracting the sum of negatives from it.
The final line is somewhat busy. Here I zip positives and negatives together which produces a list of 2-tuples where of the form (positive, negative) and then I use string formatting to produce the p - n form. From there I use join to join these together with the plus sign, which produces p0 - n0 + p1 - n1 + p2 - n2.... Finally, I use string formatting again to get it in the form of p0 - n0 + p1 - n1 + p2 - n2 ... = result.
You can do as you did but place it in a print statement
print(myList[0] + " - " + myList[1] + " + " + myList[2] + " - " + myList[3] + " + " + myList[4] + " - " + myList[5] + " + " + myList[6] + " - " + myList[7] + " + " + myList[8] + " = " + x)
Its not perfectly clean, but it follows your logic, so your teacher won't know you got your solution from someone else.
Something along the lines of the following would work:
def sumList(theList):
value = 0
count = 0
steps = ""
for i in theList:
if count % 2 == 0:
value += i
steps += " + " + str(i)
else:
value -= i
steps += " - " + str(i)
count += 1
print(steps[3:])
return value
print(sumList(myList))
It alternates between + and - by keeping track of the place in the list and using the modulus operator. Then it calculates the value and appends to a string to show the steps which were taken.
You can also do something like below once your 9 or more numbers list is ready
st = ''
sum = 0
for i, v in enumerate(myList):
if i == 0:
st += str(v)
sum += v
elif i % 2 == 0:
st += "+" + str(v)
sum += v
else:
st += "-" + str(v)
sum -= v
print("%s=%d" % (st, sum))
It prints : 1-4+9-16+9-7+4-9+11=-2

How to draw this bow tie pattern using Python 2.7?

I need to draw the following pattern using Python While Loops.
I have spent quite a lot of time and came up with this code which prints it perfectly but this code is so much long and I feel like it is not one of those good codes.
If anybody here can help me out shrinking this code or suggesting a better way to output?
here is the code:
#Question 10, Alternate Approach
temp = 1
pattern = ""
innerSpace = 7
starCount = 1
while temp <= 5:
st = 1
while st <= starCount:
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
sp = 0
if temp == 5:
innerSpace = 1
while sp < innerSpace:
pattern = pattern + " "
sp = sp + 1
st = 1
while st <= starCount:
if temp == 5:
st = st + 1
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
temp = temp + 1
innerSpace = innerSpace - 2
pattern = pattern + "\n"
if temp % 2 == 0:
pattern = pattern + " "
else:
starCount = starCount + 1
starCount = 2
innerSpace = 1
while temp > 5 and temp <= 9:
st = 1
while st <= starCount:
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
sp = 0
while sp < innerSpace:
pattern = pattern + " "
sp = sp + 1
st = 1
while st <= starCount:
pattern = pattern + "*"
if st != starCount:
pattern = pattern + " "
st = st + 1
temp = temp + 1
innerSpace = innerSpace + 2
pattern = pattern + "\n"
if temp % 2 == 0:
starCount = starCount - 1
pattern = pattern + " "
print pattern
Since this looks like an assignment, I'll give you a hint how I would do it.
Take advantage of the symmetry of the bow. It is symmetrical about the horizontal and vertical axis. Therefore, you really only need to solve 1 corner, then copy/mirror the results to get the rest.
This code gives one way of looking at the problem, which is just shifting a initial string (the middle of the bow) to get the desired shape:
m = '*'
size = 4
n = 5 # must be odd
pad = ' ' * n
middle = (m + pad) * size
half = int(n / 2) + 1
print middle
print middle[half*1:]
print middle[half*2:]
print middle[half*3:]
print middle[half*4:]
print middle[half*5:]
print middle[half*6:]
Which yields this:
* * * *
* * *
* * *
* *
* *
*
*
Good luck!
I would use list comprehensions and strings and would exploit the symmetry of the figure.
Not a complete solution, but could be a part of a loop body
In [2]: a = '*' + ' '*8
In [3]: a
Out[3]: '* '
In [24]: result = ''
In [25]: result += a
In [26]: result
Out[26]: '* '
In [27]: result += a[-1::-1]
In [28]: result
Out[28]: '* *'
In [29]: result += '\n'
In [30]: a = ' '+'*' + ' '*7
In [31]: a
Out[31]: ' * '
In [32]: result += a
In [33]: result += a[-1::-1]
In [34]: result += '\n'
In [36]: print result
* *
* *
IMHO you use while loop much as if they where for loops.
I don't think that's what your teacher wants.
The idea behind while is to run until a certain condition is met, not
necessarily when the number of iterations exceed a certain limit.
The condition does not need to be included in the while statement, you can check it later and use the break command to escape the loop
Try for example this:
start = '*'
while True:
print start
if start[0] == '*':
start = ' ' + start
else:
start = '*' + start
if (start == '* * *'):
break
output is just a part of your assignment, think you should be able to work it out to the final, expected result!
Hopefully by this time HW is done. Since I solved this using dynamic programming, I thought I would list solution here.
Observations:
While looking at pattern its observed that bottom half is palindrome of top half. Hence we need to calculate only the top half.
Next we see that for every row count,we have pattern like,
row 1 = 1 , n
row 2 = 2 , n -1
row 3 = 1,3, n-2, n
row 4 = 2, 4 , n-3, n-1
.. and so on.
With iteration index as row count and n as input value we can dynamically calculate remaining values very efficiently.
Source-Code
def get_list(bound, alist):
tmp_list = []
for i in xrange(1,bound + 1):
tmp_list.append(star if i in alist else dot)
return tmp_list
star = "*"
dot = " "
n = 20 #How large of BowTie do you want?
m = (n * 2) - 1
#get top half list
th = []
for idx,k in enumerate(xrange(1,n+1)): #run through 1 - n
row = idx + 1
tmplst = []
if row % 2 != 0:
tmplst.append(i for i in xrange(1,row + 1) if i % 2 != 0)
tmplst.append(i for i in xrange(m, m-row, -1) if i % 2 != 0)
else:
tmplst.append(i for i in xrange(1,row + 1) if i % 2 == 0)
tmplst.append(i for i in xrange(m, m-row, -1) if i % 2 == 0)
#append each row value to top half list.
th.append(sorted(set([j for i in tmplst for j in i])))
#create palindrome of top half which is our bottom half
th = th + th[len(th) -2::-1]
#create list of * and blanks
final = [get_list(m, i) for i in th]
#Print BowTie
for i in final:
print ' '.join(i)
Using a stars and spacing and counting variable
counting=1
star_amount=1
space_amount=6
loop_var=7
while loop_var>0:
loop_var-=1
if space_amount==0:
counting*=-1
stars=" * "*star_amount
spaces=" "*space_amount
print(stars+spaces+stars)
star_amount+=counting
space_amount-= counting*2

Categories

Resources