I have this list that I want to sort based on bubble sort, and there is a function in code (Swap()) is refusing to work. I don't know why. there is the code
score = [92,95,7,5,85,55,789,47,125,3265,88,965,655,3,15,448,0,255,455]
size = len(score)
x = 0
COMPS = size - 1
def swap():
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
# The Sort Array Function
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
#This function not working.
swap()
x += 1
y += 1
#Display Array Function
def displayArray():
x = 0
while x < size:
print(score[x])
x += 1
SortArray()
displayArray()
but inserting the swap() code, thus the code under the swap() and replacing it underneath the SortArray(), below the if condition; just like this:
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
#This Works
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
x += 1
y += 1
then it works, so I want to know why the swap() function doesn't get called under the SortArray()
I want to know why the swap() function doesn't get called under the SortArray()
Actually, it IS called - which you can check by yourself adding a couple print() calls within or using the step debugger - but it doesn't do what you think it should do, because you're confusing local and global variables.
In SortArray() you define a local variable named x (it's defined as local because you assign it in the function), and this is obviously the one you expect swap() to use. But in your swap function, you use a variable x which is neither an argument of the function nor assigned within the function (both of which would make it a local variable), so it's resolved as the global x declared above.
IOW, swap uses the global x why you'd expect it to use the one which is local to SortArray(). This is also why the second version works, since this time it uses the proper variable.
The solution is to remove the global x and explicitely pass the correct value to swap(), ie:
def swap(x):
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
def SortArray():
y = 0
while y < COMPS:
x = 0
while x < COMPS:
if score[x] > score[x + 1]:
swap(x)
x += 1
y += 1
And while you're at it, you should also to the same with score - actually, you should avoid globals as much as possible (and believe me, you can write a lot of code without using globals):
def swap(score, x):
temp = score[x + 1]
score[x + 1] = score[x]
score[x] = temp
def SortArray(score):
comps = len(score) - 1
y = 0
while y < comps:
x = 0
while x < comps:
if score[x] > score[x + 1]:
swap(score, x)
x += 1
y += 1
def displayArray(score):
x = 0
while x < len(score):
print(score[x])
x += 1
if __name__ == "__main__":
score = [92,95,7,5,85,55,789,47,125,3265,88,965,655,3,15,448,0,255,455]
SortArray(score)
displayArray(score)
And now your functions can be used with any list or sequence. They are still totally unpythonic but that's obviously not the point here (python has one of the most optimized sort algorithm builtin anyway).
Related
I know there are better ways to do this, and I found some of them online too, but I want to know why this simple logic doesn't work.
p =[0,1,2,3,4]
q = p
U = 1
for i,elt in enumerate(p):
print(p[i])
if i + U > len(p)-1:
p[(i+U)-len(p)] = q[i]
else:
p[i+U] = q[i]
print(p)
The output for this is:
0
0
0
0
0
[0, 0, 0, 0, 0]
in the above code every time you are assigning the value present in the 0th index so in every loop from 0 to n-1 you keep on changing the original value with the 0th index value.
so instead of doing that do :
p =[5,6,7,8,9,10]
q = p.copy()
U = 1
for i,elt in enumerate(p):
print(p[i])
if i + U > len(p)-1:
p[(i+U)-len(p)] = q[i]
else:
p[i+U] = q[i]
print(p)
OR YOU CAN USE :
p =[5,6,7,8,9,10]
n = len(p)
temp = [None] * (n * 2)
for i in range(n):
temp[i] = temp[n+i] = p[i]
n2 = len(temp)
U = 1
arr = []
for i in range(n-U,n2-U):
arr.append(temp[i])
print(arr)
The problem with the code is that q and p are the same array, if you change one the other reflects those changes. Try changing the sencond line to this:
q = p.copy()
As on the line:
p[i+U] = q[i]
The every element is changed to the previous element, thus, all of them are now zero (the first element).
This is the code I wrote and seems like it's working but when I checked on the Hackerrank for testing with the huge test cases - it's giving me a runtime error.
How can I optimize this code?
def dynamicArray(n, queries):
lastAnswer = 0
seq = []
result = []
for k in range(0, n):
seq.append([])
for i in queries:
N_querytype = i[0] #it can be either 1 or 2
x = i[1]
y = i[2]
index = (x ^ lastAnswer) % n
if(N_querytype == 1):
seq[index].append(y)
elif(N_querytype == 2):
lastAnswer = seq[index][y]
result.append(lastAnswer)
return result
This is the test-case for which it is not running. Is there something I am missing?
Your answer was close but you misunderstood what to do in query 2
Find the value of element y % size in seq (where size is the size of seq) and assign it to
So using index you get the sequence which will be a list, but you are then asked to find the value in the list whic his indexed at position y % size where size = len(seq[index])
def dynamicArray(n, queries):
lastAnswer = 0
seq = []
result = []
for k in range(0, n):
seq.append([])
for i in queries:
N_querytype = i[0] #it can be either 1 or 2
x = i[1]
y = i[2]
index = (x ^ lastAnswer) % n
print("#", index, y)
if(N_querytype == 1):
seq[index].append(y)
elif(N_querytype == 2):
size = len(seq[index]) #Calculate the size of the sequnce at this index
lastAnswer = seq[index][y % size] #look up the value in this sequence at index y % size
result.append(lastAnswer)
return result
I want to write a Fibonacci sequence code where it takes a number as input and prints that many Fibonacci numbers.
def fibonacci(x):
a = []
a[0] = 0
a[1] = 1
for i in range(2, x + 1):
a[i] = a[i - 1] + a[i - 2]
a += a[i]
return a
a = [] creates an empty array named a. a[0] cannot be instanced because it doesn't exist yet, it raises a out of range error
x = []
x[0] = 0 # <- error
What you need to append it like append() or a+=[] :
def fibonacci(x):
a = []
a.append(0)
a.append(1)
for i in range(2, x + 1):
a.append(a[i - 1] + a[i - 2])
#a +=[a[i - 1] + a[i - 2]]
return a
I need to compare each number in a list back to back, subtract, and add the outcome to a new list.
so
list1[1]-[0] = list2 [0]
list1[2]-[1] = list2 [1]
etc.
But I can't get it to do this.
Here is my block
change = []
index = 0
popyear_up = 1
popyear_low = 0
while index < len(data_numbers):
#for i in range, len(data_numbers:
difference = data_numbers[popyear_up] - data_numbers[popyear_low]
change.append(difference)
popyear_up += 1
popyear_low += 1
index += 1
The uncommented "while" line right now returns
difference = data_numbers[popyear_up] - data_numbers[popyear_low]
IndexError: list index out of range
The commented line only does [1]-[0] and [2]-[1], but does them correctly and appends them to change[]
I have no idea why it only does those 2. But for the first one I feel it has something to do with the length of my main list of data and the length of the list I'm asking it to create.
So two different issues, and I can't for the life of me figure out what I'm missing.
Full code if necessary
file = input('File to open: ')
infile = open(file, 'r')
source_file = infile.readlines()
infile.close()
index = 0
while index < len(source_file):
source_file[index] = source_file[index].rstrip('\n')
index += 1
data_numbers = [int(i) for i in source_file]
change = []
index = 0
popyear_up = 1
popyear_low = 0
while index < len(data_numbers):
#for i in range, len(data_numbers:
difference = data_numbers[popyear_up] - data_numbers[popyear_low]
change.append(difference)
popyear_up += 1
popyear_low += 1
index += 1
#start_year = 1950
#change_sum = float(sum(change))
#change_average = change_sum / len(change)
#max_change = start_year + change.index(max(n)) + 1
#min _change = start_year + change.index(min(n)) + 1
#print('Average Change in Population:',change_average)
#print ('Year with most population increas:',max_change)
#print ('Year with lease population increas:',min_change)
Since your lists are of the same length and one of the indices (popyear_up) is one ahead, it will break. Instead, only go up to index < len(data_numbers) - 1.
Also, just do this:
change = []
popyear_up = 1
popyear_low = 0
for popyear_low in range(len(data_numbers) - 1):
difference = data_numbers[popyear_low + 1] - data_numbers[popyear_low]
change.append(difference)
Also, just do this:
change = [data_numbers[i + 1] - data_numbers[i] for i in range(len(data_numbers) - 1)]
Or if you want (though this is slightly less readable):
change = [y - x for x, y in zip(data_numbers, data_numbers[1:])]
I need to find a way to write cos(1) in python using a while loop. But i cant use any math functions. Can someone help me out?
for example I also had to write the value of exp(1) and I was able to do it by writing:
count = 1
term = 1
expTotal = 0
xx = 1
while abs(term) > 1e-20:
print("%1d %22.17e" % (count, term))
expTotal = expTotal + term
term=term * xx/(count)
count+=1
I amm completely lost as for how to do this with the cos and sin values though.
Just change your expression to compute the term to:
term = term * (-1 * x * x)/( (2*count) * ((2*count)-1) )
Multiplying the count by 2 could be changed to increment the count by 2, so here is your copypasta:
import math
def cos(x):
cosTotal = 1
count = 2
term = 1
x=float(x)
while abs(term) > 1e-20:
term *= (-x * x)/( count * (count-1) )
cosTotal += term
count += 2
print("%1d %22.17e" % (count, term))
return cosTotal
print( cos(1) )
print( math.cos(1) )
You can calculate cos(1) by using the Taylor expansion of this function:
You can find more details on Wikipedia, see an implementation below:
import math
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)
def cos(order):
a = 0
for i in range(0, order):
a += ((-1)**i)/(factorial(2*i)*1.0)
return a
print cos(10)
print math.cos(1)
This gives as output:
0.540302305868
0.540302305868
EDIT: Apparently the cosine is implemented in hardware using the CORDIC algorithm that uses a lookup table to calculate atan. See below a Python implementation of the CORDIS algorithm based on this Google group question:
#atans = [math.atan(2.0**(-i)) for i in range(0,40)]
atans =[0.7853981633974483, 0.4636476090008061, 0.24497866312686414, 0.12435499454676144, 0.06241880999595735, 0.031239833430268277, 0.015623728620476831, 0.007812341060101111, 0.0039062301319669718, 0.0019531225164788188, 0.0009765621895593195, 0.0004882812111948983, 0.00024414062014936177, 0.00012207031189367021, 6.103515617420877e-05, 3.0517578115526096e-05, 1.5258789061315762e-05, 7.62939453110197e-06, 3.814697265606496e-06, 1.907348632810187e-06, 9.536743164059608e-07, 4.7683715820308884e-07, 2.3841857910155797e-07, 1.1920928955078068e-07, 5.960464477539055e-08, 2.9802322387695303e-08, 1.4901161193847655e-08, 7.450580596923828e-09, 3.725290298461914e-09, 1.862645149230957e-09, 9.313225746154785e-10, 4.656612873077393e-10, 2.3283064365386963e-10, 1.1641532182693481e-10, 5.820766091346741e-11, 2.9103830456733704e-11, 1.4551915228366852e-11, 7.275957614183426e-12, 3.637978807091713e-12, 1.8189894035458565e-12]
def cosine_sine_cordic(beta,N=40):
# in hardware, put this in a table.
def K_vals(n):
K = []
acc = 1.0
for i in range(0, n):
acc = acc * (1.0/(1 + 2.0**(-2*i))**0.5)
K.append(acc)
return K
#K = K_vals(N)
K = 0.6072529350088812561694
x = 1
y = 0
for i in range(0,N):
d = 1.0
if beta < 0:
d = -1.0
(x,y) = (x - (d*(2.0**(-i))*y), (d*(2.0**(-i))*x) + y)
# in hardware put the atan values in a table
beta = beta - (d*atans[i])
return (K*x, K*y)
if __name__ == '__main__':
beta = 1
cos_val, sin_val = cosine_sine_cordic(beta)
print "Actual cos: " + str(math.cos(beta))
print "Cordic cos: " + str(cos_val)
This gives as output:
Actual cos: 0.540302305868
Cordic cos: 0.540302305869