Related
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
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))
I'm fairly new to this but will try and be as clear as possible.
Essentially I have 5 different lists of lists. 4 are imported from txt files and the 5th is a merger of the 4. Each inner list contains a value at index position 3. My objective is to maximize the sum by picking appropriately.
I also have a couple constraints:
The sum of the values at index 6 position can't exceed 50000
I pick 2 items from set C, 3 from set W, 2 from set D, 1 from set G, and 1 from set U (the combined) and I can't pick the same item for each set. Ie. each pick in W has to be different.
My code is below. I'm having trouble in that the optimizer just spits out my initial list of picks. Looking at the data though, I know for sure there are better solutions. I read that the issue may be related to late binding but I'm not sure if that's right and if it is, not sure how to update to fix error either. Appreciate any help. Thanks!
Read: Scipy.optimize.minimize SLSQP with linear constraints fails
import numpy as np
from scipy.optimize import minimize
C = open('C.txt','r').read().splitlines()
W = open('W.txt','r').read().splitlines()
D = open('D.txt','r').read().splitlines()
G = open('G.txt','r').read().splitlines()
def splitdata(file):
for index,line in enumerate(file):
file[index] = line.split('\t')
return(file)
def objective(x, sign=-1.0):
x = list(map(int, x))
pos = 3
Cvalue = float(C[x[0]][pos]) + float(C[x[1]][pos])
Wvalue = float(W[x[2]][pos]) + float(W[x[3]][pos]) + float(W[x[4]][pos])
Dvalue = float(D[x[5]][pos]) + float(D[x[6]][pos])
Gvalue = float(G[x[7]][pos])
Uvalue = float(U[x[8]][pos])
grand_value = sign*(Cvalue + Wvalue + Dvalue + Gvalue + Uvalue)
#print(grand_value)
return grand_value
def constraint_cost(x):
x = list(map(int, x))
pos = 6
Ccost = int(C[x[0]][pos]) + int(C[x[1]][pos])
Wcost = int(W[x[2]][pos]) + int(W[x[3]][pos]) + int(W[x[4]][pos])
Dcost = int(D[x[5]][pos]) + int(D[x[6]][pos])
Gcost = int(G[x[7]][pos])
Ucost = int(U[x[8]][pos])
grand_cost = 50000 - (Ccost + Wcost + Dcost + Gcost + Ucost)
#print(grand_cost)
return grand_cost
def constraint_C(x):
if x[0] == x[1]:
return 0
else:
return 1
def constraint_W(x):
if x[2] == x[3] or x[2] == x[4] or x[3] == x[4]:
return 0
else:
return 1
def constraint_D(x):
if x[5] == init[6]:
return 0
else:
return 1
con1 = {'type':'ineq','fun':constraint_cost}
con2 = {'type':'ineq','fun':constraint_C}
con3 = {'type':'ineq','fun':constraint_W}
con4 = {'type':'ineq','fun':constraint_D}
con = [con1, con2, con3, con4]
c0 = [0,1]
w0 = [0,1,2]
d0 = [0,1]
g0 = [0]
u0 = [0]
init = c0+w0+d0+g0+u0
C = splitdata(C)
W = splitdata(W)
D = splitdata(D)
G = splitdata(G)
U = C + W + D + G
sol = minimize(objective, init, method='SLSQP',constraints=con)
print(sol)
I am writing a binary addition program but am unsure as to why when the inputs start with a zero the output is incorect.The output is also incorrect when the program has to add zeros to the start of one of the inputs to make them the same length.
a = input('Enter first binary number\t')
b = input('Enter second binary number\t')
carry = 0
answer = ""
length = (max(len(a),len(b))) - min(len(a),len(b))
if b > a:
a = length * '0' + a
elif a > b:
b = length * '0' + b
print(a)
print(b)
for i in range(len(a)-1, -1, -1):
x = carry
if a[i] == '1': x += 1
else: x = 0
if b[i] == '1': x += 1
else: x = 0
if x % 2 == 1: answer = '1' + answer
else: answer = '0' + answer
if x < 2: carry = 0
else: carry = 1
if carry == 1: answer = '1' + answer
print(answer)
What an excellent opportunity to explore some Boolean Logic.
Adding binary like this can be done with two "half adders" and an "or"
First of all the "Half Adder" which is a XOR to give you a summed output and an AND to give you a carry.
[EDIT as per comments: python does have an XOR implemented as ^ but not as a "word" like and not or. I am leaving the answer as is, due to the fact it is explaining the Boolean logic behind a binary add]
As python doesn't come with a XOR, we will have to code one.
XOR itself is two AND's (with reversed inputs) and an OR, as demonstrated by this:
This would result is a simple function, like this:
def xor(bit_a, bit_b):
A1 = bit_a and (not bit_b)
A2 = (not bit_a) and bit_b
return int(A1 or A2)
Others may want to write this as follows:
def xor(bit_a, bit_b):
return int(bit_a != bit_b)
which is very valid, but I am using the Boolean example here.
Then we code the "Half Adder" which has 2 inputs (bit_a, bit_b) and gives two outputs the XOR for sum and the AND for carry:
def half_adder(bit_a, bit_b):
return (xor(bit_a, bit_b), bit_a and bit_b)
so two "Half Adders" and an "OR" will make a "Full Adder" like this:
As you can see, it will have 3 inputs (bit_a, bit_b, carry) and two outputs (sum and carry). This will look like this in python:
def full_adder(bit_a, bit_b, carry=0):
sum1, carry1 = half_adder(bit_a, bit_b)
sum2, carry2 = half_adder(sum1, carry)
return (sum2, carry1 or carry2)
If you like to look at the Full Adder as one logic diagram, it would look like this:
Then we need to call this full adder, starting at the Least Significant Bit (LSB), with 0 as carry, and work our way to the Most Significant Bit (MSB) where we carry the carry as input to the next step, as indicated here for 4 bits:
This will result is something like this:
def binary_string_adder(bits_a, bits_b):
carry = 0
result = ''
for i in range(len(bits_a)-1 , -1, -1):
summ, carry = full_adder(int(bits_a[i]), int(bits_b[i]), carry)
result += str(summ)
result += str(carry)
return result[::-1]
As you see we need to reverse the result string, as we built it up "the wrong way".
Putting it all together as full working code:
# boolean binary string adder
def rjust_lenght(s1, s2, fill='0'):
l1, l2 = len(s1), len(s2)
if l1 > l2:
s2 = s2.rjust(l1, fill)
elif l2 > l1:
s1 = s1.rjust(l2, fill)
return (s1, s2)
def get_input():
bits_a = input('input your first binary string ')
bits_b = input('input your second binary string ')
return rjust_lenght(bits_a, bits_b)
def xor(bit_a, bit_b):
A1 = bit_a and (not bit_b)
A2 = (not bit_a) and bit_b
return int(A1 or A2)
def half_adder(bit_a, bit_b):
return (xor(bit_a, bit_b), bit_a and bit_b)
def full_adder(bit_a, bit_b, carry=0):
sum1, carry1 = half_adder(bit_a, bit_b)
sum2, carry2 = half_adder(sum1, carry)
return (sum2, carry1 or carry2)
def binary_string_adder(bits_a, bits_b):
carry = 0
result = ''
for i in range(len(bits_a)-1 , -1, -1):
summ, carry = full_adder(int(bits_a[i]), int(bits_b[i]), carry)
result += str(summ)
result += str(carry)
return result[::-1]
def main():
bits_a, bits_b = get_input()
print('1st string of bits is : {}, ({})'.format(bits_a, int(bits_a, 2)))
print('2nd string of bits is : {}, ({})'.format(bits_b, int(bits_b, 2)))
result = binary_string_adder(bits_a, bits_b)
print('summarized is : {}, ({})'.format(result, int(result, 2)))
if __name__ == '__main__':
main()
two internet sources used for the pictures:
https://www.electronics-tutorials.ws/combination/comb_7.html
https://www.allaboutcircuits.com/textbook/digital/chpt-7/the-exclusive-or-function-xor/
For fun, you can do this in three lines, of which two is actually getting the input:
bits_a = input('input your first binary string ')
bits_b = input('input your second binary string ')
print('{0:b}'.format(int(bits_a, 2) + int(bits_b, 2)))
And in your own code, you are throwing away a carry if on second/subsequent iteration one of the bits are 0, then you set x = 0 which contains the carry of the previous itteration.
this is how i managed to complete this, hope you find this useful.
#Binary multiplication program.
def binaryAddition(bin0, bin1):
c = 0
answer = ''
if len(bin0) > len(bin1):
bin1 = (len(bin0) - len(bin1))*"0" + bin1
elif len(bin1) > len(bin0):
bin0 = (len(bin1) - len(bin0))*"0" + bin0
#Goes through the binary strings and tells the computer what the anser should be.
for i in range(len(bin0)-1,-1,-1):
j = bin0[i]
k = bin1[i]
j, k = int(j), int(k)
if k + j + c == 0:
c = 0
answer = '0' + answer
elif k + j + c == 1:
c = 0
answer = '1' + answer
elif k + j + c == 2:
c = 1
answer = '0' + answer
elif k + j + c == 3:
c = 1
answer = '1' + answer
else:
print("There is something wrong. Make sure all the numbers are a '1' or a '0'. Try again.") #One of the numbers is not a 1 or a 0.
main()
return answer
def binaryMultiplication(bin0,bin1):
answer = '0'*8
if len(bin0) > len(bin1):
bin1 = (len(bin0) - len(bin1))*"0" + bin1
elif len(bin1) > len(bin0):
bin0 = (len(bin1) - len(bin0))*"0" + bin0
for i in range(len(bin0)-1,-1,-1):
if bin1[i] == '0':
num = '0'*len(answer)
elif bin1[i] == '1':
num = bin0 + '0'*((len(bin0)-1)-i)
answer = binaryAddition(num, answer)
print(answer)
def main():
try:
bin0, bin1 = input("Input both binary inputs separated by a space.\n").split(" ")
except:
print("Something went wrong. Perhaps there was not a space between you numbers.")
main()
binaryMultiplication(bin0,bin1)
choice = input("Do you want to go again?y/n\n").upper()
if choice == 'Y':
main()
else: input()
main()
The following adds integers i1 and i2 using bitwise logical operators (i1 and i2 are overwritten). It computes the bitwise sum by i1 xor i2 and the carry bit by (i1 & i2)<<1. It iterates until the shift register is empty. In general this will be a lot faster than bit-by-bit
while i2: # check shift register != 0
i1, i2 = i1^i2, (i1&i2) << 1 # update registers
My algorithm to find the HCF of two numbers, with displayed justification in the form r = a*aqr + b*bqr, is only partially working, even though I'm pretty sure that I have entered all the correct formulae - basically, it can and will find the HCF, but I am also trying to provide a demonstration of Bezout's Lemma, so I need to display the aforementioned displayed justification. The program:
# twonumbers.py
inp = 0
a = 0
b = 0
mul = 0
s = 1
r = 1
q = 0
res = 0
aqc = 1
bqc = 0
aqd = 0
bqd = 1
aqr = 0
bqr = 0
res = 0
temp = 0
fin_hcf = 0
fin_lcd = 0
seq = []
inp = input('Please enter the first number, "a":\n')
a = inp
inp = input('Please enter the second number, "b":\n')
b = inp
mul = a * b # Will come in handy later!
if a < b:
print 'As you have entered the first number as smaller than the second, the program will swap a and b before proceeding.'
temp = a
a = b
b = temp
else:
print 'As the inputted value a is larger than or equal to b, the program has not swapped the values a and b.'
print 'Thank you. The program will now compute the HCF and simultaneously demonstrate Bezout\'s Lemma.'
print `a`+' = ('+`aqc`+' x '+`a`+') + ('+`bqc`+' x '+`b`+').'
print `b`+' = ('+`aqd`+' x '+`a`+') + ('+`bqd`+' x '+`b`+').'
seq.append(a)
seq.append(b)
c = a
d = b
while r != 0:
if s != 1:
c = seq[s-1]
d = seq[s]
res = divmod(c,d)
q = res[0]
r = res[1]
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
print `r`+' = ('+`aqr`+' x '+`a`+') + ('+`bqr`+' x '+`b`+').'
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
s = s + 1
seq.append(r)
fin_hcf = seq[-2] # Finally, the HCF.
fin_lcd = mul / fin_hcf
print 'Using Euclid\'s Algorithm, we have now found the HCF of '+`a`+' and '+`b`+': it is '+`fin_hcf`+'.'
print 'We can now also find the LCD (LCM) of '+`a`+' and '+`b`+' using the following method:'
print `a`+' x '+`b`+' = '+`mul`+';'
print `mul`+' / '+`fin_hcf`+' (the HCF) = '+`fin_lcd`+'.'
print 'So, to conclude, the HCF of '+`a`+' and '+`b`+' is '+`fin_hcf`+' and the LCD (LCM) of '+`a`+' and '+`b`+' is '+`fin_lcd`+'.'
I would greatly appreciate it if you could help me to find out what is going wrong with this.
Hmm, your program is rather verbose and hence hard to read. For example, you don't need to initialise lots of those variables in the first few lines. And there is no need to assign to the inp variable and then copy that into a and then b. And you don't use the seq list or the s variable at all.
Anyway that's not the problem. There are two bugs. I think that if you had compared the printed intermediate answers to a hand-worked example you should have found the problems.
The first problem is that you have a typo in the second line here:
aqr = aqc - (q * aqd)#These two lines are the main part of the justification
bqr = bqc - (q * aqd)#-/
in the second line, aqd should be bqd
The second problem is that in this bit of code
aqd = aqr
bqd = bqr
aqc = aqd
bqc = bqd
you make aqd be aqr and then aqc be aqd. So aqc and aqd end up the same. Whereas you actually want the assignments in the other order:
aqc = aqd
bqc = bqd
aqd = aqr
bqd = bqr
Then the code works. But I would prefer to see it written more like this which is I think a lot clearer. I have left out the prints but I'm sure you can add them back:
a = input('Please enter the first number, "a":\n')
b = input('Please enter the second number, "b":\n')
if a < b:
a,b = b,a
r1,r2 = a,b
s1,s2 = 1,0
t1,t2 = 0,1
while r2 > 0:
q,r = divmod(r1,r2)
r1,r2 = r2,r
s1,s2 = s2,s1 - q * s2
t1,t2 = t2,t1 - q * t2
print r1,s1,t1
Finally, it might be worth looking at a recursive version which expresses the structure of the solution even more clearly, I think.
Hope this helps.
Here is a simple version of Bezout's identity; given a and b, it returns x, y, and g = gcd(a, b):
function bezout(a, b)
if b == 0
return 1, 0, a
else
q, r := divide(a, b)
x, y, g := bezout(b, r)
return y, x - q * y, g
The divide function returns both the quotient and remainder.
The python program that does what you want (please note that extended Euclid algorithm gives only one pair of Bezout coefficients) might be:
import sys
def egcd(a, b):
if a == 0:
return (b, 0, 1)
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def main():
if len(sys.argv) != 3:
's program caluclates LCF, LCM and Bezout identity of two integers
usage %s a b''' % (sys.argv[0], sys.argv[0])
sys.exit(1)
a = int(sys.argv[1])
b = int(sys.argv[2])
g, x, y = egcd(a, b)
print 'HCF =', g
print 'LCM =', a*b/g
print 'Bezout identity: %i * (%i) + %i * (%i) = %i' % (a, x, b, y, g)
main()