Start and pause a process in python - python

I have a function that calculates the Fibonacci numbers. I am trying to add a feature that sends a signal indicating that I need to pause the function running. Once I get the signal, I store away all the numbers calculated thus far.
And when the user wants to resume the function, I can load back the files and start calculating from where we had stopped.
This is the code I have
MAX = 100000
fibo_series = [0] * MAX
import pickle
def fib(start_value=0, stop_value=1000, stop_signal=False):
if not stop_signal:
for i in range(start_value, stop_value):
if i == 0:
fibo_series[i] = 0
elif i == 1 or i == 2:
fibo_series[i] = 1
else:
fibo_series[i] = fibo_series[i-1] + fibo_series[i-2]
return fibo_series[i]
else:
with open('fibo_series.pkl', 'wb') as f:
pickle.dump(fibo_series, f)
def reload_fib():
with open('fibo_series.pkl', 'rb') as f:
fibo_series = pickle.load(f)
start_value = fibo_series[1:].index(0) + 1
stop_value = len(fibo_series)
return fib(start_value, stop_value, stop_signal=False)
The part that I am not able to figure out is how to use this stop_signal once the function has started running. Once the function has started the value stop_signal is locked. The only way I know to pause a function is by terminating it which is not what I am trying to do.
How do I achieve this?

I am not sure what are the stop and run conditions, but a simple work around is to use a global variable for these two functions. This is not better than using a lock of a thread library but if your work is simply to use one process and does not need complexity, then you may try.
import threading
import time
MAX = 100000
fibo_series = [0] * MAX
import pickle
stop_signal = False
def fib(start_value=0, stop_value=1000):
for i in range(start_value, stop_value):
if (not stop_signal):
print('here', i)
time.sleep(1)
if i == 0:
fibo_series[i] = 0
elif i == 1 or i == 2:
fibo_series[i] = 1
else:
fibo_series[i] = fibo_series[i-1] + fibo_series[i-2]
else:
break
return fibo_series[i]
print('exiting... stop_signal: ', stop_signal)
with open('fibo_series.pkl', 'wb') as f:
pickle.dump(fibo_series, f)
def reload_fib():
with open('fibo_series.pkl', 'rb') as f:
fibo_series = pickle.load(f)
start_value = fibo_series[1:].index(0) + 1
stop_value = len(fibo_series)
global stop_signal
stop_signal = False
return fib(start_value, stop_value)
x = threading.Thread(target=fib )
x.start()
time.sleep(10)
stop_signal = True
print('finished...')
Then, whenever the user wants to stop the execution, you can set the global variable stop_signal=True
and the output is:
here 0
here 1
here 2
here 3
here 4
here 5
here 6
here 7
here 8
here 9
finished...
I hope this helps.

Related

Recursive routine escape for backtracking routine

I was wondering if anyone could help me out with this recursive routine for a sudoku back-tracking problem. I was wanting to get out of the recursive routine when the a certain problem had been executing for a known quantity of time, in this case - 2 seconds. However, I am having some trouble getting this to work and believe there may be something wrong with my base case. Any help would be appreciated.
def solver(Domains,SudokuSolv):
start = time.time()
global global_length
global global_row_index
global global_column_index
global global_val_index
global global_number
if global_length == 0:
return True
else:
global_row_index+=3
global_column_index+=3
global_val_index+=3
print(global_row_index)
row = Domains[global_row_index]
col = Domains[global_column_index]
val = global_val_index
for i in Domains[val]:
end = time.time()
if end-start > 2:
global_length = 0
Checker = isValid(i,row,col,SudokuSolv)
if Checker == False:
SudokuSolv[row][col] = i
print(SudokuSolv)
global_length-= 1
if solver(Domains, SudokuSolv):
return True
global_length+=1
SudokuSolv[row][col] = 0
else:
print("Trying next value...")
global_row_index-=3
global_column_index-=3
global_val_index-=3
return False

Don't understand this timed while loop attribute error

So I have been trying to make a while loop that will run for 10 minutes. But is keeps erroring out on the line with the while loop. It says 'str' object has no attribute 'time'.
I have discovered that if i remove the lines with now.strftime() in them that the code runs but I don't know why it runs without those lines or how to fix it.
I did also try to do something using the datetime module instead of importing the time module but this also fails.
import math
from datetime import datetime
import time
test_num = 1
largest_loop = 0
delay = 60 * 10
end_time = time.time() + delay
def even_number(value):
if value == 2:
return True
def divide_five(value):
if value == 5:
return True
def is_square(value):
if math.sqrt(value).is_integer():
return False
def multiple_of(value):
if value == 2:
return True
def is_happy():
global check
if check == 1:
return True
while time.time() <= end_time:
test_num += 1
check = test_num
now = datetime.now()
loop_counter = 0
record_loop = 6
date = now.strftime("%m/%d/%Y")
time = now.strftime("%H:%M:%S")
if even_number(test_num) == True:
if divide_five(test_num) == True:
if is_square(test_num) == True:
for _ in range(record_loop + 4):
loop_counter += 1
if is_happy() == True:
if multiple_of(test_num) == True:
#print(test_num)
record_loop = loop_counter
break
else:
pass
else:
pass
else:
pass
else:
pass
else:
pass
As #CoryKramer pointed out, you named a variable time, which is also the name of the module you are importing. All I really did was change the time variable to something like currTime. Try the code below (runs for me):
import math
from datetime import datetime
import time
test_num = 1
largest_loop = 0
delay = 60 * 10
end_time = time.time() + delay
def even_number(value):
if value == 2:
return True
def divide_five(value):
if value == 5:
return True
def is_square(value):
if math.sqrt(value).is_integer():
return False
def multiple_of(value):
if value == 2:
return True
def is_happy():
global check
if check == 1:
return True
while time.time() <= end_time:
test_num += 1
check = test_num
now = datetime.now()
loop_counter = 0
record_loop = 6
date = now.strftime("%m/%d/%Y")
currTime = now.strftime("%H:%M:%S")
if even_number(test_num) == True:
if divide_five(test_num) == True:
if is_square(test_num) == True:
for _ in range(record_loop + 4):
loop_counter += 1
if is_happy() == True:
if multiple_of(test_num) == True:
#print(test_num)
record_loop = loop_counter
break
else:
pass
else:
pass
else:
pass
else:
pass
else:
pass
Additionally, consider reading up on:
How to name a module without conflict with variable name?
https://en.wikipedia.org/wiki/Variable_shadowing
dont name your variable in your while loop time when you import the time library:
time = now.strftime("%H:%M:%S")
in your while loop you want to use the time function of the time library but as soon as you run the while loop once it will try to use time() on the string time you defined in the while loop.
I think the problem is here:
time = now.strftime("%H:%M:%S")
Thus, you converted time into a string variable. Name this variable in a different way!
Apart from this, running for 10 minutes at "full throttle" is a lot! Consider to introduce a "sleep" time at the end of the while loop (just suggesting)

Python: Failing to break out of while loop with "SyntaxError: 'break' outside loop"

I am developing a breadth-first-search algorithm for a factorization problem and am running into an interesting/confusing bug when attempting to break out of a while loop. If you run the code below, it will fail inside the "construct_path" method, stating :
File "main.py", line 96
break
SyntaxError: 'break' outside loop
but I am inside of a while loop! If anyone could give me some advice on this issue, I would really appreciate it. Thanks in advance.
from numpy import random
import itertools
import Queue
#Finding multiples, BFS problem
#Given input of list with unique integers 0 - 9 and n = range(0,1000000), calculate smallest multiple of n and unique combination of values in the list
#Example : Input : list = {0,1,2} , n = 3,
# output = 12
# Input : list = {0,1,2} , n = 50
# Output = 200
class Problem:
def __init__(self):
self.n = random.randint(0,10000000)
listSize = random.randint(1,9)
mainSet = set()
self.mainList = []
while True:
toAdd = random.randint(0,9)
if(toAdd not in self.mainList):
self.mainList.append(toAdd)
if(len(self.mainList) == listSize):
break
def get_start_state(self):
s = ''.join(map(str, self.mainList))
return int(s)
def is_goal(self, state):
return True
def get_sucessors(self):
print "Getting successors"
def breadth_first_search(problem):
# a FIFO open_set
open_set = Queue.Queue()
# an empty set to maintain visited nodes
closed_set = set()
# a dictionary to maintain meta information (used for path formation)
meta = dict() # key -> (parent state, action to reach child)
# initialize
start = problem.get_start_state()
meta[start] = (None, None)
open_set.put(start)
while not open_set.empty():
parent_state = open_set.get()
print "{} {}".format("parent_state is ", parent_state)
if problem.is_goal(parent_state):
return construct_path(parent_state, meta)
for (child_state, action) in problem.get_successors(parent_state):
if child_state in closed_set:
continue
if child_state not in open_set:
meta[child_state] = (parent_state, action)
open_set.put(child_state)
closed_set.add(parent_state)
#collect path to desired answer
def construct_path(state, meta):
action_list = list()
while True:
row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
return action_list.reverse()
x = Problem()
breadth_first_search(x)
Could be that you have a mix of tabs and spaces so that the break in line 96 looks like it is indented to be below action_list.append(action) but effectively it is below the while. That would explain the error at least.
It is just a guess. But it could be like this, using a visible tabwidth of 4 in the editor:
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
To the Python interpreter this looks like this (because it assumes a tabwidth of 8):
→ while True:
→ → row = meta[state]
if (len(row) == 2):
state = row[0]
action = row[1]
action_list.append(action)
else:
break
This is still valid but obviously means a different thing and would put your break outside of the while loop.

My state machine in Python runs into infinite loop

I am new to python. My code runs into infinite loop, keeps adding & printing numberCycles. My logic in C++ works fine.
Would you please help to identify why?
The first line of input is the number of simulations.
The next line is the number of minutes for a single reproductive cycle.
The next line is the number of rows (x), followed by a single space, and followed by number of columns (y).
The next group of y lines will have x number of characters, with a single period (.) representing a blank space and a single capitol B representing a starting Bunny tries to reproduce to up, right, down, left direction. If there is a existing bunny, then it goes to sleep.
Input.txt
2 # 2 simulations
5 # 5 minutes/cycle
3 3 # 3*3 map
...
.B.
...
1
4 4
B.BB
..B.
...
B.B
Spot.py
#!/usr/bin/env python
class Spot(object):
isBunny = bool()
nextCycle = 0
UP = 0
RIGHT = 1
DOWN = 2
LEFT = 3
SLEEP = 4
def __init__(self, newIsBunny):
self.isBunny = newIsBunny
self.nextCycle = self.UP
def setNextCycle(self):
if (self.nextCycle != self.SLEEP):
self.nextCycle += 1
def getNextCycle(self):
return self.nextCycle
def getIsBunny(self):
return self.isBunny
def makeBunny(self):
if not self.isBunny:
self.nextCycle = self.UP
self.isBunny = True
Bunny.py
#!/usr/bin/env python
from Spot import Spot
import os
class Bunny(object):
#classmethod
def main(cls, args):
with open(os.path.expanduser('~/Desktop/input.txt')) as f:
numSims = int(f.readline())
myMap = []
print numSims
minPerCycle= int(f.readline())
print minPerCycle
for k in xrange(numSims):
xyLine= f.readline()
row = int(xyLine.split()[0])
col = int(xyLine.split()[1])
print row,col
for i in range(0,row):
myLine = f.readline()
myMap.append([])
for j in range(0,col):
myMap[i].append(Spot(myLine[j] == 'B'))
numCycles = 1
if cls.isFilled(row,col,myMap):
numCycles = 0
while not cls.isFilled(row,col,myMap):
numCycles += 1
print numCycles
for m in range(0,row):
for n in range(0,col):
if myMap[m][n].getIsBunny():
if myMap[m][n].getNextCycle() == Spot.UP:
if m>0:
myMap[m-1][n].makeBunny()
break
elif myMap[m][n].getNextCycle() == Spot.RIGHT:
if n<col-1:
myMap[m][n+1].makeBunny()
break
elif myMap[m][n].getNextCycle() == Spot.DOWN:
if m<row-1:
myMap[m+ 1][n].makeBunny()
break
elif myMap[m][n].getNextCycle() == Spot.SLEEP:
if n>0:
myMap[m][n- 1].makeBunny()
break
myMap[m][n].setNextCycle()
time = numCycles * minPerCycle
print "It took " , time , " minutes for the bunnies to take over the world!\n"
del myMap[:]
f.close()
#classmethod
def isFilled(cls,row,col,myMap):
for a in range(0,row):
for b in range(0,col):
if not myMap[a][b].getIsBunny():
return False
return True
if __name__ == '__main__':
import sys
Bunny.main(sys.argv)
It never goes to the left. Also, you set a break for the inner loop, so, myMap[m][n].setNextCycle() is never called. I just saw your C++ code and you translated it to Python with errors (using Spot.SLEEP instead of Spot.LEFT).
The break statement makes sense in C++ because you want to break the switch. Here, you are using if..else.
It should be something like:
while not cls.isFilled(row, col, myMap):
numCycles += 1
print numCycles
for m in range(0,row):
for n in range(0,col):
if myMap[m][n].getIsBunny():
if myMap[m][n].getNextCycle() == Spot.UP:
if m>0:
myMap[m-1][n].makeBunny()
elif myMap[m][n].getNextCycle() == Spot.RIGHT:
if n<col-1:
myMap[m][n+1].makeBunny()
elif myMap[m][n].getNextCycle() == Spot.DOWN:
if m<row-1:
myMap[m+ 1][n].makeBunny()
elif myMap[m][n].getNextCycle() == Spot.LEFT:
if n>0:
myMap[m][n-1].makeBunny()
myMap[m][n].setNextCycle()

Is this python code thread-safe?

I am trying to make my chunk of code non-thread-safe, in order to toy with some exceptions that I want to add on later.
This is my python code:
from time import sleep
from decimal import *
from threading import Lock
import random
def inc_gen(c):
"""
Increment generator
"""
while True:
#getting sleep period
timing_rand = random.randrange(0,1000)
print "INC: Sleeping for " + str(Decimal(timing_rand)/Decimal(1000))
sleep(Decimal(timing_rand)/Decimal(1000))
c.inc()
yield c
def dec_gen(c):
"""
decrement generator
"""
while True:
#getting sleep period
timing_rand = random.randrange(0,1000)
print "DEC: Sleeping for " + str(Decimal(timing_rand)/Decimal(1000))
sleep(Decimal(timing_rand)/Decimal(1000))
c.dec()
yield c
class something():
"""
We use an obj instead of an atomic variable c, we can have "threads"
simulating shared resources, instead of a single variable, to avoid
atomic instructions. (which is thread-safe in python thanks to GIL)
"""
def __init__(self):
self.c = 0
def inc(self):
self.c += 1
def dec(self):
self.c -= 1
def value(self):
return self.c
def main():
"""
main() function
"""
obj = something()
counters = [inc_gen(obj),dec_gen(obj)]
#we only want inc_gen 10 times, and dec_gen 10 times.
inc = 0 #number of times inc_gen is added
dec = 0 #number of times dec_gen is added
while True:
#choosing the next counter
if inc < 10 and dec < 10:
counter_rand = random.randrange(0,2)
if counter_rand == 0:
inc += 1
else: dec += 1
elif inc < 10 and dec == 10:
inc += 1
counter_rand = 0
elif dec < 10 and inc == 10:
dec += 1
counter_rand = 1
else: break
counters[counter_rand].next()
#print for testing
print "Final value of c: " + str(obj.value())
if __name__ == "__main__":
main()
What I want it to do is to have the code possibly result in a final value which is not 0.
Is it thread-safe? If not, how can I make it such that it is not thread-safe?
You have a Read-Modify-Write operation basically. If you want to ensure things go haywire, the best is to intruduce delay between the read and the write.
def inc(self):
v = self.c
time.sleep(random.random()) # Should probably limit it to a few hundred ms
self.c = v + 1
def dec(self):
v = self.c
time.sleep(random.random()) # Should probably limit it to a few hundred ms
self.c = v - 1

Categories

Resources