Loop to Store Test Results in Python - python

In short, I need to test some functions by creating 100 random integer lists of each specified length (500, 1000, 10000) and store the results. Eventually, I need to be able to calculate an average execution time for each test but I've yet to get that far with the code.
I assumed the following was the best way to approach this:
Create a dictionary to store the required list length values.
For each value in that dictionary, generate a new list of random integers (list_tests).
Create another dictionary for storing the results of each function test (test_results).
Use a while loop to create 100 lists of each length.
Run the tests by calling each function in the while loop and storing each result in the results dictionary.
The program appears to run but I have a couple problems:
It never reaches the other list_tests values; never proceeds beyond 500.
It's overwriting the values for the test_results dictionary
I don't quite understand where I've gone wrong with the loop in main(). Is my process to test these functions feasible? If so, I'm lost as to how I can fix this looping problem. Thank you in advance for any assistance you can offer!
Here is my program:
import time
import random
def sequential_search(a_list, item):
start = time.time()
pos = 0
found = False
while pos < len(a_list) and not found:
if a_list[pos] == item:
found = True
else:
pos = pos+1
end = time.time()
return found, end-start
def ordered_sequential_search(a_list, item):
start = time.time()
pos = 0
found = False
stop = False
while pos < len(a_list) and not found and not stop:
if a_list[pos] == item:
found == True
else:
if a_list[pos] > item:
stop = True
else:
pos = pos+1
end = time.time()
return found, end-start
def num_gen(value):
myrandom = random.sample(xrange(0, value), value)
return myrandom
def main():
#new_list = num_gen(10000)
#print(sequential_search(new_list, -1))
list_tests = {'t500': 500, 't1000': 1000, 't10000': 10000}
for i in list_tests.values():
new_list = num_gen(i)
count = 0
test_results = {'seq': 0, 'ordseq': 0}
while count < 100:
test_results['seq'] += sequential_search(new_list, -1)[1]
test_results['ordseq'] += ordered_sequential_search(new_list, -1)[1]
count += 1
if __name__ == '__main__':
main()

I think you meant
found = True
Instead of
found == True
On line 47
Also a for loop is much cleaner try this, it should be what your looking for:
def ordered_sequential_search(a_list, item):
start = time.time()
found = False
stop = False
for i in range(len(a_list)):
if a_list[i] == item:
found = True
else:
if a_list[i] > item:
stop = True
if found: break
if stop: break
end = time.time()
return found, end-start

It is overwriting values in the dictionary because you have specified the key to overwrite values. You are not appending to the dictionary which you should have done.
Your while loop might not be breaking, that why your for loop cannot iterate to another value.

Related

define a function to check if a list of elements is palindrome and returns a list

I have to do the following:
Define a function called isSymmetricalVec that takes a list of elements, checks if each element in a list is palindrome, then returns their results in a list. For example, given ["1441", "Apple", "radar", "232", "plane"] the function returns [TRUE, FALSE, TRUE, TRUE, FALSE].
I wrote the following code but I'm stuck at the point where I cannot return the result in a list.
def isSymmetricalVec(myList):
for myString in myList:
myList = []
mid = (len(myString)-1)//2
start = 0
last = len(myString)-1
flag = 0
while(start<mid):
if (myString[start]== myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
print(bool(1))
else:
print(bool(0))
# Enter a list of strings to check whether it is symmetrical or not
myList = ["12321", "12345", "madam", "modem"]
isSymmetricalVec(myList)
My function returns the following but the result is not in a list format:
True
False
True
False
How can I modify my code to return a result in a list format?
You function should return value instead of printing it.
Created an empty list new_list and appended result to it.
def isSymmetricalVec(myList):
new_lst = []
for myString in myList:
mid = (len(myString) - 1) // 2
start = 0
last = len(myString) - 1
flag = 0
while (start < mid):
if (myString[start] == myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
new_lst.append(True)
else:
new_lst.append(False)
return new_lst
# Enter a list of strings to check whether it is symmetrical or not
Your function is actually not returning anything. What you see are only being printed and not returned.
You would want to keep each answer in a list like this.
def isSymmetricalVec(myList):
list_of_answers = []
for myString in myList:
...
while(start<mid):
...
if flag == 0:
print(bool(1))
list_of_answers.append(True)
else:
print(bool(0))
list_of_answers.append(False)
return list_of_answers
This way your answers are printed and returned.
Finally, you would need a variable to hold the returned list.
# Enter a list of strings to check whether it is symmetrical or not
myList = ["12321", "12345", "madam", "modem"]
list_of_answers = isSymmetricalVec(myList)
def isSymmetricalVec(myString):
mid = (len(myString)-1)//2
start = 0
last = len(myString)-1
flag = 0
while(start<mid):
if (myString[start]== myString[last]):
start += 1
last -= 1
else:
flag = 1
break;
if flag == 0:
return True
else:
return False
test = ["1221", "madam", "hello world"]
final = [isSymmetricalVec(i) for i in test]
print(final)
I rewrote the code a bit and this would be my solution. It retains the original functionality and is stylish as well as efficient. It also makes the original function more flexible and makes it easily migratable.
Your function doesn't return anything, just printing values.
There is a good way to shorten your algorithm with python slices. Also this function returns list of boolean objects.
from math import ceil, floor
def isSymmetricalVec(myList):
list_of_answers = []
for string in myList:
strLength = len(string)
#There is a string palindrome check
if string[:floor(strLength//2)] == string[ceil(strLength/2):][::-1]:
toAppend = True
else:
toAppend = False
list_of_answers.append(toAppend)
return list_of_answers
It is worth adding that it's better to use True and False instead of bool(1) and bool(0).
An example:
>>> isSymmetricalVec(['11211', 'AbbA', '12f23'])
>>> [True, True, False]

looping over a nested list with multiple rows and columns

I wanted to replace the items from listoflist = [[None, None, None]] with the output from
def _execute():
user_input = input("type in: ")
return user_input
without creating a new list
def insertdata(data): is doing that. its start with the first value and continues till the last value
def insertdata(data):
data_added = False
n = len(listoflist[0])
index = 0
while not data_added and index != n:
if listoflist[0][index] is None:
listoflist[0][index] = data
data_added = True
else:
index += 1
if index == n:
print("\n The list is full, No more elements will be added \n")
while True:
insertdata(_execute())
print(listoflist)
I want to extend the function to loop over a nested list with multiple rows.
what condition should the if statment have so it starts at the first row and execute the inner loop `?
def double_loop(data):
data_added_outer = False
index_outer = 0
n_out = len(listoflist)
# outer loop
while not data_added_outer and index_outer < n_out:
if: # what condition ?
#### inner loop ###############
data_added_inner = False
n_inner = len(listoflist[index_outer])
index_inner = 0
while not data_added_inner and index_inner != n_inner:
if listoflist[index_outer][index_inner] is None:
listoflist[index_outer][index_inner] = data
data_added = True
else:
index_inner += 1
if index_inner == n_inner:
print("\n The list is full, No more elements will be added \n")
####### inner ############################################################
else:
index_outer += 1
if index_outer == n_out:
print("\n The list is full, No more elements will be added \n")
Instead of replacing the data, the elegant approach in Python is to create new data, using comprehensions:
def with_nones_replaced(grid, replacement):
return [
[
replacement if value is None else value
for value in row
]
for row in grid
]
As far as I have understood, the job of your function is simply to replace the None objects in a 2D-List with the data parameter passed to the function. I find a for-loop approach much more cleaner, and pythonic in this case.
def changedata(arr, data):
for item in arr:
for x in range(len(item)):
if item[x] is None:
item[x] = data
You can also use the map function to simplify the code:
def changedata(arr, data):
for i in range(len(arr)):
arr[i] = list(map(lambda x: data if x is None else x, arr[i]))
If the data is coming from a function, you can still use this paradigm by calling
_execute() once, storing it in a variable, and then passing it to changedata()
data = _execute()
changedata(listoflist, data)
print(listoflist)

How to reset Yield and stop iteration

I am facing some problems regarding a generator. I have a list of 1000 elements. I want to read single item one by one and do some operation. The operation is something like comparing with some specific value. If I able to find that value from the list I want to stop iteration and reset the yield again.
I looking for the funtionality how to reset __next__ pointer in generator. Also I have to make 100 object in runtime FN_SOVLS.
class FN_SOV1S:
def __init__(self,elementlist,idxNo):
self._elementlist = elementlist
self._idxNo =idxNo
setup()
process()
def setup(self):
try:
self.df = pd.read_excel(r'D:\OPCUA\Working_VF1.xls', sheet_name='Valve1S')
for tag,col in self.readcmd():
if col==4:
self.cmd = tag
if col == 5:
self.openFB = tag
if col == 6:
self.clsFB = tag
if col == 7:
self.delaytime = tag
except Exception as e:
log_exception(e)
def process(self):
for tagname,tagvalue in self.searchValueBytag():
if tagname == self.cmd:
if tagvalue == 1:
sleep(self.delaytime)
gen.writegeneral.writenodevalue(self.openFB,1)
gen.writegeneral.writenodevalue(self.clsFB,0)
else:
gen.writegeneral.writenodevalue(self.openFB, 0)
gen.writegeneral.writenodevalue(self.clsFB, 1)
def searchValueBytag(self):
n = 0
while n < len(self._elementlist):
tagname, tagvalue = self._elementlist[n]
yield tagname, tagvalue
n =+ 1
The condition is to reset Generator function is:
for tagname,tagvalue in self.searchValueBytag():
if tagname == self.cmd:
You cannot "reset" a running generator.
What you can do is break out of the for-loop that uses the generator.
Later you can then create the generator anew by calling searchValueBytag again.
I don't completely understand your question, but hopefully, this can help. This uses a flag that will continue restarting the generator until the self.cmd value is no longer found.
Obviously, this is not identical to your code and more is needed for it to work perfectly, but you can easily use this flag to reset the generator
def generator():
# arbitrary length
length = 100
n = 0
while n < length:
yield n
n += 1
# create a complete flag that is only true when the end of the iteration is reached
complete = False
# keep trying until complete is true
while not complete:
# restarts the generator by making a new one
g = generator()
# keeps going until 'break'
while True:
# try/catch because next returns error when the end of the generator is reached
# when the end is reached we know that to turn complete to true
try:
# get the next val in the iterator
value = next(g)
# if value is the reset flag, then break out of while loop and restart generator
if value == RESET_FLAG:
break
except:
# StopIteration exeption received, job finished
complete = True
break
def generator():
length = 100
n = 0
while n < length:
yield n
n += 1

Python Wrong Input when working with Lists

I am working with this problem (https://open.kattis.com/problems/whowantstoliveforever). As the problem states, my program has to determine if the universe lives or dies based on the input 0s and 1s.
to determine the next value of the i-th bit, look at the current value of the bits at positions i−1 and i+1 (if they exist; otherwise assume them to be 0). If you see exactly one 1, then the next value of the i-th bit is 1, otherwise it is 0. All the bits change at once, so the new values in the next state depend only on the values in the previous state. We consider the universe dead if it contains only zeros.
My current solution works on the example input file, however it fails when submitting it to Kattis. (Wrong Answer)
Below is my code.
import sys
def get_bit(bits, i):
if 0 <= i < len(bits):
return int(bits[i])
else:
return 0
def get_new_state(old_state):
new_state = []
for index in range(len(old_state)):
if (get_bit(old_state, index-1) == 0 and get_bit(old_state, index+1) == 0) or (get_bit(old_state, index-1) == 1 and get_bit(old_state, index+1) == 1):
new_state.append(0)
elif(get_bit(old_state, index-1) == 0 and get_bit(old_state, index+1) == 1) or (get_bit(old_state, index-1) == 1 and get_bit(old_state, index+1) == 0):
new_state.append(1)
return new_state
def is_dead(state):
if len(set(state)) == 1:
return True
else:
return False
def foresee_fate(state):
seen = []
while True:
if is_dead(state):
return False
if state in seen:
return True
seen.append(state)
state = get_new_state(state)
def print_result(boolean):
print("LIVES" if boolean else "DIES")
num_cases = int(sys.stdin.readline().strip())
for i in range(num_cases):
cur_state = []
case = sys.stdin.readline().strip()
for char in case:
cur_state.append(char)
print_result(foresee_fate(cur_state))
Please let me know what I can do to improve this program.
As suggested, I have added the following to my code and IT works now. However, I ran into a new problem. now I'm getting "Time Limit Exceeded" > 3.00 s.
def is_dead(state):
if set(state).pop() == 1:
return False
elif len(set(state)) == 1:
return True
else:
return False
Please let me know if there is any suggestion on getting around this problem

python (passing parameters to functions)

I'm not really new to python but I came across this problem that has just puzzled me.
So I was solving the maze runner problem, using A* and then was finding the hardest possible maze for a given dimension. For this purpose, I created a function called generateHardMaze() that is called from the main function and takes an attribute newMaze.
Now here is where things get weird, when I change the value of newMaze in the if condition within the while loop the hardMaze value changes without the code entering the second if condition. I'm not really sure why this happening was hoping someone could help me.
I'm using pycharm as my IDE and python3.6.* if that makes any difference.
I'm sure this isn't how oops works but I'm thinking this is a python thing. Has anyone ever come across anything like this? If yes please sympathize.
Thanks in advance.
def solveMazeAManH(newMaze,rows,cols):
startTime = time.time()
backTrackPriority = []
setup_cells(rows, cols)
# start and end points of the maze
start = (0, 0)
end = (rows - 1, cols - 1)
current = start
print("The path to be take is: ")
print(current)
frinLength = 0
# traversing the neighbours
while current != end:
unvisited.remove(current)
neighboursDFSandA(newMaze, current, rows, cols)
heuristic = calManhattanDis(current, end) # finding the heuristic for every traversal
try:
if not currentNeighbours:
if not backTrackPriority:
print("No path available!")
return 0
else:
while not currentNeighbours:
current = nextPopMan(backTrackPriority, end)
backTrackPriority.remove(current)
neighboursDFSandA(newMaze, current, rows, cols)
neighbor = leastPathChildMan(heuristic, current, end)
backTrackPriority.append(current)
current = neighbor
print(current)
frinLength += 1
except:
print("No path Found!")
return 0
return frinLength
endTime = time.time()
print("The time taken to solve the maze using A* with manhattan distance: ")
print(startTime - endTime)
def generateHardMaze(newMazes):
rows = len(newMazes)
cols = len(newMazes[0])
hardMaze = newMaze
print("Solving the original maze!")
fringLength = solveMazeAManH(newMazes, rows, cols)
print("Creating new harder Maze:")
pFlag = True
pCout = 0
while pFlag:
count = 0
flag = True
while flag:
point = choice(setup_cells(rows, cols))
if (newMazes[point[0]][point[1]] == 1):
newMazes[point[0]][point[1]] = 0
else:
newMazes[point[0]][point[1]] = 1
if (fringLength < solveMazeAManH(newMazes, rows, cols)):
print("Harder Maze--------------------")
hardMaze = newMaze
fringLength = solveMazeAManH(newMazes, rows, cols)
count = 0
else:
count += 1
if count >= 10:
flag = False
print("one")
newMazes = creatMaze(rows)
pCout += 1
if pCout >= 100:
pFlag = False
print(hardMaze)

Categories

Resources