Error Output Using Timer Object in Python - python

I've got several functions that I need to evaluate the performance of using the timeit module.
For starters, I'm attempting to use a Timer object to evaluate a sequential search function run on a list of random integers which should return the time to execute in seconds. The function returns a value of False for -1 (since it will never find -1) but gives me the following error along with it. Here is the complete output:
False
Traceback (most recent call last):
File "D:/.../search-test.py", line 37, in <module>
main()
File "D:/.../search-test.py", line 33, in main
print(t1.timeit(number=100))
File "C:\...\Anaconda2\lib\timeit.py", line 202, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
TypeError: sequential_search() takes exactly 2 arguments (0 given)
This is my program:
from timeit import Timer
import random
def sequential_search(a_list, item):
pos = 0
found = False
while pos < len(a_list) and not found:
if a_list[pos] == item:
found = True
else:
pos = pos+1
return found
def num_gen(value):
myrandom = random.sample(xrange(0, value), value)
return myrandom
def main():
new_list = num_gen(100)
print(sequential_search(new_list, -1))
t1 = (Timer("sequential_search()", "from __main__ import sequential_search"))
print(t1.timeit(number=100))
if __name__ == '__main__':
main()
I'm a noob to programming and can honestly say that I'm struggling. This error doesn't make any sense to me. I don't understand why it's asking for the sequential_search function arguments when they're already passed in main(). Plugging the arguments in to the Timer statement doesn't solve the problem.
Please help me understand what I've screwed up. Thank you!

This is how you make a timer object -
t1 = (Timer("sequential_search(new_list, -1)", setup="from __main__ import sequential_search, num_gen;new_list=num_gen(100);"))
print(t1.timeit(number=100))
Output -
False
0.0014021396637
It didn't work just because you were simply not passing the arguments. So just initialize the variables in setup(not necessarily though) and you are good to go.

Related

TypeError: cannot unpack non-iterable int object, Plus Minus problem in HackerRank

I am stuck on what to do on this problem, tried to execute it on vscode and the hackerrank IDE, both are giving errors even though all solutions on web are same as mine
import math
import os
import random
import re
import sys
#
# Complete the 'plusMinus' function below.
#
# The function accepts INTEGER_ARRAY arr as parameter.
#
def plusMinus(arr):
# Write your code here
neg,pos,zero=0
for i in range(0,len(arr)):
if(arr[i]<0):
neg+=0
elif(arr[i]>0):
pos+=0
else:
zero+=0
print(pos/len(arr))
print(neg/len(arr))
print(zero/len(arr))
return 0
if __name__ == '__main__':
n = int(input().strip())
arr = list(map(int, input().rstrip().split()))
plusMinus(arr)
Traceback (most recent call last):
File "/tmp/submission/20211128/06/29/hackerrank-a7793862d075fcff390bb368bc113c47/code/Solution.py", line 35, in <module>
plusMinus(arr)
File "/tmp/submission/20211128/06/29/hackerrank-a7793862d075fcff390bb368bc113c47/code/Solution.py", line 17, in plusMinus
neg,pos,zero=0
TypeError: cannot unpack non-iterable int object
Reading the traceback reveals the cause of the error you're getting:
Traceback (most recent call last):
File "/tmp/submission/20211128/06/29/hackerrank-a7793862d075fcff390bb368bc113c47/code/Solution.py", line 35, in <module>
plusMinus(arr)
File "/tmp/submission/20211128/06/29/hackerrank-a7793862d075fcff390bb368bc113c47/code/Solution.py", line 17, in plusMinus
neg,pos,zero=0
TypeError: cannot unpack non-iterable int object
The correct syntax would be either
# map the elements of the iterable on the right-hand side to the
# declared variable names
neg, pos, zero = 0, 0, 0
or
# assign the same value to all declared variables
neg = pos = zero = 0
As-written, it's trying to unpack the integer 0 into three separate values neg, pos, zero. Since 0 is not an iterable object like a tuple (as, for example, 0, 0, 0 is), and thus cannot be unpacked into multiple values, python throws an error.

Python: calling inner() from outer()

I have looked around on SO and surprisingly not found an answer to this question. I assume this is because normally inner/nested functions are used for something in particular (eg. maintaining an environment variable, factories) as opposed to something trivial like I'm trying to use them for. In any case, I can't seem to find any information on how to properly call an inner function from an outer function without having to declare inner() above outer() in the file. The problem is from this problem on HackerRank (https://www.hackerrank.com/challenges/circular-array-rotation/problem).
def circularArrayRotation(a, k, queries):
def rotateArrayRightCircular(arr: list, iterations: int) -> list:
"""
Perform a 'right circular rotation' on an array for number of iterations.
Note: function actually moves last 'iterations' elements of array to front of array.
>>>rotateArrayRightCircular([0,1,2], 1)
[2,0,1]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
[3,4,5,0,1,2]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
[0,1,2,3,4,5]
"""
return arr[-1 * iterations:] + arr[0:-1 * iterations]
k = k % len(a)
a = rotateArrayRightCircular(a, k)
res = []
for n in queries:
res.append(a[n])
return res
The code above does what I want it to, but it's somehow inelegant to me that I have to put the inner function call after the inner function definition. Various errors with different attempts:
# trying 'self.inner()'
Traceback (most recent call last):
File "solution.py", line 52, in <module>
result = circularArrayRotation(a, k, queries)
File "solution.py", line 13, in circularArrayRotation
a = self.rotateArrayRightCircular(a, k)
NameError: name 'self' is not defined
# Removing 'self' and leaving the definition of inner() after the call to inner()
Traceback (most recent call last):
File "solution.py", line 52, in <module>
result = circularArrayRotation(a, k, queries)
File "solution.py", line 13, in circularArrayRotation
a = rotateArrayRightCircular(a, k)
UnboundLocalError: local variable 'rotateArrayRightCircular' referenced before assignment
Any idea how I could include def inner() after the call to inner() without throwing an error?
As a function is executed from top to bottom, and a function is put into existence as the function is processed, what you want is just not possible.
You could put the function before the outer one, making it outer itself, possibly adding some parameters (not necessary here). (BTW, it looks so generic that other parts of the code might want to use it as well, so why not outer?)
But otherwise, you are stuck. It is essetially the same situation as in
def f():
print(a) # a doesn't exist yet, so this is an error
a = 4
Well, you could do it this way:
def circularArrayRotation(a, k, queries):
def inner_code():
k = k % len(a)
a = rotateArrayRightCircular(a, k)
# BTW, instead of the following, you could just do
# return [a[n] for n in queries]
res = []
for n in queries:
res.append(a[n])
return res
def rotateArrayRightCircular(arr: list, iterations: int) -> list:
"""
Perform a 'right circular rotation' on an array for number of iterations.
Note: function actually moves last 'iterations' elements of array to front of array.
>>>rotateArrayRightCircular([0,1,2], 1)
[2,0,1]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 3)
[3,4,5,0,1,2]
>>>rotateArrayRightCircular([0,1,2,3,4,5], 6)
[0,1,2,3,4,5]
"""
return arr[-1 * iterations:] + arr[0:-1 * iterations]
return inner_code()
but I don't see that you gain anything from it.
This is not possible in Python, but is possible in other languages like Javascript and PHP. It is called function hoisting.

Python multiprocessing pool doesn't take an iterable as an argument

I've read many posts here about multiprocessing.pool, but I still don't understand where the problem in my code is.
I want to parallelize a function using multiprocessing pool in python. The function takes one argument and returns two values. I want this one argument to be an integer and want to iterate over this integer. I've tried the examples I've seen here, but it doesn't work for me (apparently I do something wrong, but what?)
My code:
import multiprocessing
from multiprocessing import Pool
def function(num):
res1 = num ** 2 # calculate someting
res2 = num + num # calculate someting
return res1, res2
if __name__ == '__main__':
num = 10
pool = multiprocessing.Pool(processes=4)
# next line works, but with [something,something,...] as an argument
result = pool.map(function, [1, 100, 10000])
# next line doesn't work and I have no idea why!
result2 = pool.map(function, range(num))
pool.close()
pool.join()
print(result2)
I get TypeError: 'float' object is not subscriptable when I calculate result2.
Would be grateful for help!

Running multiprocessing on two different functions in Python 2.7

I have 2 different functions that I want to use multiprocessing for: makeFakeTransactions and elasticIndexing. The function makeFakeTransactions returns a list of dictionaries, which is then added to the async_results list. So essentially, async_results is a list of lists. I want to use this list of lists as input for the elasticIndexing function, but I must wait for the first p.apply_async to finish first before I use the list of lists. How do I ensure that the first batch of multiprocessing is finished before I initiate the next one?
Also, when I run the program as is, it skips the second p.apply_async and just terminates. Do I have to declare a separate multiprocessing.Pool variable to do another multiprocessing operation?
store_num = 1
process_number = 6
num_transactions = 10
p = multiprocessing.Pool(process_number)
async_results = [p.apply_async(makeFakeTransactions, args = (store_num, num_transactions,)) for store_num in xrange(1, 10, 5)]
results = [ar.get() for ar in async_results]
async_results = [p.apply_async(elasticIndexing, args = (result_list,)) for result_list in results]
EDIT:
I tried using p.join() after async_results, but it gives this error:
Traceback (most recent call last):
File "C:\Users\workspace\Proj\test.py", line 210, in <module>
p.join()
File "C:\Python27\lib\multiprocessing\pool.py", line 460, in join
assert self._state in (CLOSE, TERMINATE)
AssertionError

Yet another python scoping issue

I've read bunch of scoping posts but I haven't found answer to mine. I use python 2.7.6.
Here's the code:
def play(A, B):
state = START_STATE
#player = None
while state[1] < goal and state[2] < goal:
if state[0]:
player = B
else:
player = A
state = resolve_state(state, player(state))
return player
This raises UnboundLocalError. Uncommenting line 3 effects in always returning None variable, yet I am sure that the player variable is always either A or B. Making player a global variable solves the problem. Can anyone explain this behaviour? From what I've read while and if statements don't create their scopes so the function should be the scope for variables declared in while/if block.
Error says: "UnboundLocalError: local variable 'player' referenced before assignment"
I am sure that the loop executes because START_STATE = (0, 0, 0, 0) + I double checked it with printing + making player global solves the problem and it doesn't affect the loop entrance conditions
#jonathan -> it stayed from older version
You code is not going through the loop - here's a simplified code that demonstrate it:
# noloop.py
def loop(A, B, x):
#player = None
while x:
if True:
player = B
else:
player = A
x = False
return player
and the calls and results:
>>> import noloop
>>> noloop.loop("A", "B", True)
'B'
>>> noloop.loop("A", "B", False)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "noloop.py", line 12, in loop
return player
UnboundLocalError: local variable 'player' referenced before assignment
>>>
So your assertions are wrong, point cleared. Note that your code relies on two global variables, START_STATE and goal, which makes debugging harder. First rewrite your function to get rid of all globals (hint : pass START_STATE and goal as arguments), then add some debugging code (like a few print statements before, within and after the loop), and you'll probably find out by yourself what went wrong.

Categories