How to remove the list index out of range? - index-error

The code runs perfectly with the custom input but while running in competetive programming platform, it shows runtime error.
I have searched about this but couldn't resolve it.
def GCD(num1, num2):
if num1 < num2:
small = num1
else:
small = num2
for i in range(1, small + 1):
if (num1 % i == 0) and (num2 % i == 0):
gcd = i
return gcd
arr = [int(i) for i in input().split(' ')]
print(GCD(arr[0], arr[1]))
Runtime Error
Traceback (most recent call last): File Main.py , line 10, in print(GCD(arr[0], arr[1])) IndexError: list index out of range

In the last line you are printing the GCD of the first and the second element of the array which are of the index 0 and 1. But if user only enters a single number then index 1 is out of range. So you can just check if the size of array is less than two then simply print the element at the index 0.
if len(arr) is 1:
print(arr[0])
else:
print(GCD(arr[0], arr[1]))
Furthermore, if you are trying to find the GCD of the array then the algorithm is wrong. You will have to iterate over the array and find the GCD.
if len(arr) is 1:
print(arr[0])
else:
answer = arr[0];
for i in range(len(arr)):
answer = GCD(answer,arr[i])
print(answer)

Related

How would I print the sum of my range for my code?

Code for printing a range where odd numbers are negative and even numbers are positive. Need help with adding the sum of the range.
def evenoddsequence(i):
for i in range(i):
if i%2 != 0:
i = i*-1
print(i, end=" ")
elif i == None:
return i
else:
print(i, end=" ")
print()
result = evenoddsequence(7)
print("Sum of terms in the sequence:", result)
I think you are overcomplicating things. What you want to do is to change the sign for every other element in the sequence:
x->(-1)**(x%2)*x
i.e. 0->0, 1->-1, 2->2, 3->-3. So you can just apply this function to every element in the sequence and get a new sequence:
[(-1)**(x%2)*x for x in range(7)] -> [0, -1, 2, -3, 4, -5, 6]
Given that your function is named evenoddsequence I would suggest returning that and do the sum outside:
def evenoddsequence(i):
return [(-1)**(x%2)*x for x in range(i)]
print(sum(evenoddsequence(7)))
or rename it to say sum_of_evenoddsequence:
def sum_of_evenoddsequence(i):
return sum([(-1)**(x%2)*x for x in range(i)])
print(sum_of_evenoddsequence(7))
FWIW, you may notice that you add -1 to the sum for every other element:
0-1, 2-3, 4-5, ...
if there are an odd number of elems the sum will be positive, otherwise negative. The absolute value of the sum will therefor be half the length of the sequence:
(len(range(i))//2)*(-1)**len(range(i-1))
A less cryptic version:
def g(i):
if i%2==0:
return -1*(i//2)
else:
return i//2

Binary-search without an explicit array

I want to perform a binary-search using e.g. np.searchsorted, however, I do not want to create an explicit array containing values. Instead, I want to define a function giving the value to be expected at the desired position of the array, e.g. p(i) = i, where i denotes the position within the array.
Generating an array of values regarding the function would, in my case, be neither efficient nor elegant. Is there any way to achieve this?
What about something like:
import collections
class GeneratorSequence(collections.Sequence):
def __init__(self, func, size):
self._func = func
self._len = size
def __len__(self):
return self._len
def __getitem__(self, i):
if 0 <= i < self._len:
return self._func(i)
else:
raise IndexError
def __iter__(self):
for i in range(self._len):
yield self[i]
This would work with np.searchsorted(), e.g.:
import numpy as np
gen_seq = GeneratorSequence(lambda x: x ** 2, 100)
np.searchsorted(gen_seq, 9)
# 3
You could also write your own binary search function, you do not really need NumPy in this case, and it can actually be beneficial:
def bin_search(seq, item):
first = 0
last = len(seq) - 1
found = False
while first <= last and not found:
midpoint = (first + last) // 2
if seq[midpoint] == item:
first = midpoint
found = True
else:
if item < seq[midpoint]:
last = midpoint - 1
else:
first = midpoint + 1
return first
Which gives identical results:
all(bin_search(gen_seq, i) == np.searchsorted(gen_seq, i) for i in range(100))
# True
Incidentally, this is also WAY faster:
gen_seq = GeneratorSequence(lambda x: x ** 2, 1000000)
%timeit np.searchsorted(gen_seq, 10000)
# 1 loop, best of 3: 1.23 s per loop
%timeit bin_search(gen_seq, 10000)
# 100000 loops, best of 3: 16.1 µs per loop
Inspired by #norok2 comment, I think you can use something like this:
def f(i):
return i*2 # Just an example
class MySeq(Sequence):
def __init__(self, f, maxi):
self.maxi = maxi
self.f = f
def __getitem__(self, x):
if x < 0 or x > self.maxi:
raise IndexError()
return self.f(x)
def __len__(self):
return self.maxi + 1
In this case f is your function while maxi is the maximum index. This of course only works if the function f return values in sorted order.
At this point you can use an object of type MySeq inside np.searchsorted.

ValueError: invalid literal for int() with base 10: 'O'

I am relatively new to python, and as such I don't always understand why I get errors. I keep getting this error:
Traceback (most recent call last):
File "python", line 43, in <module>
ValueError: invalid literal for int() with base 10: 'O'
This is the line it's referring to:
np.insert(arr, [i,num], "O")
I'm trying to change a value in a numpy array.
Some code around this line for context:
hOne = [one,two,three]
hTwo = [four,five,six]
hThree = [seven, eight, nine]
arr = np.array([hOne, hTwo, hThree])
test = "O"
while a != Answer :
Answer = input("Please Enter Ready to Start")
if a == Answer:
while win == 0:
for lists in arr:
print(lists)
place = int(input("Choose a number(Use arabic numerals 1,5 etc.)"))
for i in range(0,len(arr)):
for num in range(0, len(arr[i])):
print(arr[i,num], "test")
print(arr)
if place == arr[i,num]:
if arr[i,num]:
np.delete(arr, [i,num])
np.insert(arr, [i,num], "O")
aiTurn = 1
else:
print(space_taken)
The number variables in the lists just hold the int version of themselves, so one = 1, two = 2 three = 3, etc
I've also tried holding "O" as a variable and changing it that way as well.
Can anyone tell me why I'm getting this error?

TypeError: unhashable type: 'numpy.ndarray' - How to get data from data frame by querying radius from ball tree?

How to get data by querying radius from ball tree? For example
from sklearn.neighbors import BallTree
import pandas as pd
bt = BallTree(df[['lat','lng']], metric="haversine")
for idx, row in df.iterrow():
res = df[bt.query_radius(row[['lat','lng']],r=1)]
I want to get those rows in df that are in radius r=1. But it throws type error
TypeError: unhashable type: 'numpy.ndarray'
Following the first answer I got index out of range when iterating over the rows
5183
(5219, 25)
5205
(5219, 25)
5205
(5219, 25)
5221
(5219, 25)
Traceback (most recent call last):
File "/Users/Chu/Documents/dssg2018/sa4.py", line 45, in <module>
df.loc[idx,word]=len(df.iloc[indices[idx]][df[word]==1])/\
IndexError: index 5221 is out of bounds for axis 0 with size 5219
And the code is
bag_of_words = ['beautiful','love','fun','sunrise','sunset','waterfall','relax']
for idx,row in df.iterrows():
for word in bag_of_words:
if word in row['caption']:
df.loc[idx, word] = 1
else:
df.loc[idx, word] = 0
bt = BallTree(df[['lat','lng']], metric="haversine")
indices = bt.query_radius(df[['lat','lng']],r=(float(10)/40000)*360)
for idx,row in df.iterrows():
for word in bag_of_words:
if word in row['caption']:
print(idx)
print(df.shape)
df.loc[idx,word]=len(df.iloc[indices[idx]][df[word]==1])/\
np.max([1,len(df.iloc[indices[idx]][df[word]!=1])])
The error is not in the BallTree, but the indices returned by it are not used properly for putting it into index.
Do it this way:
for idx, row in df.iterrows():
indices = bt.query_radius(row[['lat','lng']].values.reshape(1,-1), r=1)
res = df.iloc[[x for b in indices for x in b]]
# Do what you want to do with res
This will also do (since we are sending only a single point each time):
res = df.iloc[indices[0]]
Explanation:
I'm using scikit 0.20. So the code you wrote above:
df[bt.query_radius(row[['lat','lng']],r=1)]
did not work for me. I needed to make it a 2-d array by using reshape().
Now bt.query_radius() returns array of array of indices within the radius r specified as mentioned in the documentation:
ind : array of objects, shape = X.shape[:-1]
each element is a numpy integer array listing the indices of neighbors of the corresponding point. Note that unlike the results of
a k-neighbors query, the returned neighbors are not sorted by distance
by default.
So we needed to iterate two arrays to reach the actual indices of the data.
Now once we got the indices, in a pandas Dataframe, iloc is the way to access data with indices.
Update:
You dont need to query the bt each time for individual points. You can send all the df at once to return a 2-d array containing the indices of points within the radius to the point specified that index.
indices = bt.query_radius(df, r=1)
for idx, row in df.iterrows():
nearest_points_index = indices[idx]
res = df.iloc[nearest_points_index]
# Do what you want to do with res

PyOmo/Ipopt fails with "can't evaluate pow"

I am using PyOmo to generate a nonlinear model which will ultimately be solved with Ipopt. The model is as follows:
from pyomo.environ import *
from pyomo.dae import *
m = ConcreteModel()
m.t = ContinuousSet(bounds=(0,100))
m.T = Param(default=100,mutable=True)
m.a = Param(default=0.1)
m.kP = Param(default=20)
m.P = Var(m.t, bounds=(0,None))
m.S = Var(m.t, bounds=(0,None))
m.u = Var(m.t, bounds=(0,1), initialize=0.5)
m.Pdot = DerivativeVar(m.P)
m.Sdot = DerivativeVar(m.S)
m.obj = Objective(expr=m.S[100],sense=maximize)
def _Pdot(M,i):
if i == 0:
return Constraint.Skip
return M.Pdot[i] == (1-M.u[i])*(M.P[i]**0.75)
def _Sdot(M,i):
if i == 0:
return Constraint.Skip
return M.Sdot[i] == M.u[i]*0.2*(M.P[i]**0.75)
def _init(M):
yield M.P[0] == 2
yield M.S[0] == 0
yield ConstraintList.End
m.Pdotcon = Constraint(m.t, rule=_Pdot)
m.Sdotcon = Constraint(m.t, rule=_Sdot)
m.init_conditions = ConstraintList(rule=_init)
discretizer = TransformationFactory('dae.collocation')
discretizer.apply_to(m,nfe=100,ncp=3,scheme='LAGRANGE-RADAU')
discretizer.reduce_collocation_points(m,var=m.u,ncp=1,contset=m.t)
solver = SolverFactory('ipopt')
results = solver.solve(m,tee=False)
Running the model results in the following error:
Error evaluating constraint 1: can't evaluate pow'(0,0.75).
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.5/dist-packages/pyomo/opt/base/solvers.py", line 577, in solve
"Solver (%s) did not exit normally" % self.name)
pyutilib.common._exceptions.ApplicationError: Solver (asl) did not exit normally
The first part of the error comes from Ipopt whereas the second part comes from PyOmo. Evidently the issue has something ot do with the term M.P[i]**0.75 in the constraints, but changing the power does not resolve the issue (though 2.0 did work).
How can I resolve this?
The error message states that pow'(0,0.75) cannot be evaluated. The ' character in this function indicates the first derivative ('' would indiate the second derivative). The message is effectively saying that the first derivative does not exist or results in an infinity at zero.
Resolving the issue is easy: bound your variables to a non-zero value as follows:
m.P = Var(m.t, bounds=(1e-20,None))
m.S = Var(m.t, bounds=(1e-20,None))
I would add to Richard's answer:
you might also need to update the initial value of your variable as ipopt assumes 0 if not specified, so it will evaluate the variable at 0 for the first iteration.
hence:
m.P = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
m.S = Var(m.t, bounds=(1e-20,None), initialize=1e-20)
instead of 1e-20 as initialize you might use a value more relevant to your problem