I am constructing a script to execute two commands at specific time points.
As an example, commands of print()
for x
and y
as highlighted below.
x = [10,15,25,40] #x timepoints
y = [18,23, 33,48] # y timepoints
# function to run at second: 10 (x)
delay(10)
print("x moved one increment") # x function
# fucntion to run at second: 15 (x)
delay(5)
print("x moved one increment") # x function
# function to run at second: 18 (y)
delay(3)
print("y moved one increment") # y function
...etc
Now, I am manually inputting every function separately, which I want to avoid.
I cannot for loop, because some of the times are overlapping between x
and y
. Thoughts?
Any assistance is appreciated.
CodePudding user response:
You're simulating time passing, so think about having a "master timer" that moves one unit at a time.
x = [10,15,25,40] #x timepoints
y = [18,23, 33,48] # y timepoints
i = 0
while x and y:
if x and x[0] == i:
x.pop(0)
print("x moved one increment at", i)
if y and y[0] == i:
y.pop(0)
print("y moved one increment at", i)
i = 1
Output:
x moved one increment at 10
x moved one increment at 15
y moved one increment at 18
y moved one increment at 23
x moved one increment at 25
y moved one increment at 33
x moved one increment at 40
CodePudding user response:
I think you can use merge sort to merge the two x
and y
list timepoints (z
in the code below) but also store the associated function with the timepoints (z_function
in code below) and iterate through the timepoints list, and execute the associated function as it goes
import time
x = [10,15,25,40] #x timepoints
y = [18,23, 33,48] # y timepoints
z = [] # containing both time points in x and y
z_function = [] # 'x' or 'y'
ix, iy = 0, 0 # index for iterating through x and y
# Merge sort with associated original list
while ix < len(x) and iy < len(y):
if x[ix] <= y[iy]:
z.append(x[ix])
z_function.append('x')
ix = 1
else:
z.append(y[iy])
z_function.append('y')
iy = 1
# copy the remaining elements in x to z, if any
while ix < len(x):
z.append(x[ix])
z_function.append('x')
ix = 1
# copy the remaining elements in y to z, if any
while iy < len(y):
z.append(y[iy])
z_function.append('y')
iy = 1
# z should now has [10, 15, 18, 23, 25, 33, 40, 48]
# z_function should now has [x, x, y, y, x, y, x, y]
# z_diff should now be [10, 5, 3, 5, 2, 8, 7, 8]
# z_diff is time wait for the next timepoint
z_diff = [z[0]] [y - x for x,y in zip(z,z[1:])]
for i in range(len(z_diff)):
time_wait = z_diff[i]
z_function_name = z_function[i]
time.sleep(time_wait)
if z_function_name == 'x':
# Execute x function
print("x moved one increment")
elif z_function_name == 'y':
# Execute y function
print("y moved one increment")
CodePudding user response:
The following will make sure each command is executed x seconds from when the program starts regardless of how long each job takes to complete. If that isn't important than use Tim's answer.
import time
x = [10,15,25,40] #x timepoints
y = [18,23,33,48] # y timepoints
jobs = {
id(x): (lambda: print("x moved one increment")),
id(y): (lambda: print("y moved one increment"))
}
start_time = time.time()
def run_next_job():
# assuming x and y are always sorted
# if they are not then you would need to sort them here
next_delay_list = min(filter(None, (x,y)))
delay = next_delay_list.pop(0)
job = jobs[id(next_delay_list)]
current_time = time.time()
time_to_sleep = start_time delay - current_time
if time_to_sleep > 0:
time.sleep(time_to_sleep/100)
job()
while x or y:
run_next_job()