Home > Back-end >  Execeute command at specific timepoints based on timepoint input
Execeute command at specific timepoints based on timepoint input

Time:12-11

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()
  • Related