【问题标题】:Generate some "random" start times for scripts to run based on a period of time in python根据python中的一段时间为脚本运行生成一些“随机”开始时间
【发布时间】:2016-03-30 02:09:05
【问题描述】:

我正在尝试生成一些随机播种时间来告诉我的脚本何时从主脚本中触发每个脚本。

我想设置一个时间范围:

START_TIME = "02:00"
END_TIME = "03:00"

到了开始时间,它需要看看我们要运行多少个脚本:

script1.do_proc()
script2.alter()
script3.noneex()

在这种情况下要运行 3 个,因此它需要生成 3 个随机时间来启动这些脚本,每个脚本之间的最小间隔为 5 分钟,但时间必须在设置的时间范围内在START_TIMEEND_TIME

但是,它还需要知道script1.main 总是第一个触发的脚本,其他脚本可以随机播放(随机)

所以我们可能让script1 在 01:43 运行,然后 script3 在 01:55 运行,然后 script2 可能在 02:59 运行

我们还可能让script1 在 01:35 运行,然后 script3 在 01:45 运行,然后 script2 可能在 01:45 运行,这也可以。

到目前为止,我的脚本可以在下面找到:

import random
import pytz
from time import sleep
from datetime import datetime

import script1
import script2
import script3

START_TIME = "01:21"
END_TIME = "03:00"

while 1:
    try:

        # Set current time & dates for GMT, London
        CURRENT_GMTTIME = datetime.now(pytz.timezone('Europe/London')).strftime("%H%M")
        CURRENT_GMTDAY = datetime.now(pytz.timezone('Europe/London')).strftime("%d%m%Y")
        sleep(5)

        # Grab old day for comparisons
        try:
            with open("DATECHECK.txt", 'rb') as DATECHECK:
                OLD_DAY = DATECHECK.read()
        except IOError:
             with open("DATECHECK.txt", 'wb') as DATECHECK:
                DATECHECK.write("0")
                OLD_DAY = 0

        # Check for new day, if it's a new day do more
        if int(CURRENT_GMTDAY) != int(OLD_DAY):
            print "New Day"

            # Check that we are in the correct period of time to start running
            if int(CURRENT_GMTTIME) <= int(START_TIME.replace(":", "")) and int(CURRENT_GMTTIME) >= int(END_TIME.replace(":", "")):
                print "Correct time, starting"

                # Unsure how to seed the start times for the scripts below

                script1.do_proc()
                script2.alter()
                script3.noneex()

                # Unsure how to seed the start times for above

                # Save the current day to prevent it from running again today.
                with open("DATECHECK.txt", 'wb') as DATECHECK:
                    DATECHECK.write(CURRENT_GMTDAY)

                print "Completed"

            else:
                pass
        else:
            pass

    except Exception:
        print "Error..."
        sleep(60)

编辑 2016 年 3 月 31 日

假设我添加以下内容

SCRIPTS = ["script1.test()", "script2.test()", "script3.test()"]
MAIN_SCRIPT = "script1.test()"
TIME_DIFFERENCE = datetime.strptime(END_TIME, "%H:%M") - datetime.strptime(START_TIME, "%H:%M")
TIME_DIFFERENCE = TIME_DIFFERENCE.seconds
  • 我们现在有了要运行的脚本数量
  • 我们有要运行的脚本列表。
  • 我们有主脚本的名称,是第一个运行的。
  • 我们有时间(以秒为单位)来显示我们总共有多少时间在其中运行所有脚本。

当然有一种方法可以让我们插入某种循环来完成这一切..

  • for i in range(len(SCRIPTS)),是3倍
  • 生成 3 颗种子,确保最短时间为 300,并且 3 颗种子加在一起不得超过 TIME_DIFFERENCE
  • 根据RUN_TIME = START_TIMERUN_TIME = RUN_TIME + SEED[i] 创建开始时间
  • 第一个循环将检查MAIN_SCRIPT 是否存在于SCRIPTS 中,如果存在则它将首先运行该脚本,从SCRIPTS 中删除自身,然后在下一个循环中,因为它在@987654342 中不存在@它会切换到随机调用其他脚本之一。

播种时代

以下似乎可行,但可能有更简单的方法。

CALCULATE_SEEDS = 0
NEW_SEED = 0
SEEDS_SUCESSS = False
SEEDS = []

while SEEDS_SUCESSS == False:
    # Generate a new seed number
    NEW_SEED = random.randrange(0, TIME_DIFFERENCE)

    # Make sure the seed is above the minimum number
    if NEW_SEED > 300:
        SEEDS.append(NEW_SEED)

    # Make sure we have the same amount of seeds as scripts before continuing.
    if len(SEEDS) == len(SCRIPTS):

        # Calculate all of the seeds together
        for SEED in SEEDS:
            CALCULATE_SEEDS += SEED
        # Make sure the calculated seeds added together is smaller than the total time difference
        if CALCULATE_SEEDS >= TIME_DIFFERENCE:
            # Reset and try again if it's not below the number
            SEEDS = []
        else:
            # Exit while loop if we have a correct amount of seeds with minimum times.
            SEEDS_SUCESSS = True

【问题讨论】:

  • 是脚本变化的数量,我的意思不是3或4,但可以更多?
  • @minhhn2910 是的,确实如此。有没有办法可以将函数放入数组中以计算出我需要多少种子并改组脚本(script1 除外)
  • 您使用的是哪个操作系统?
  • 我的最后一个问题(问了很多问题,因为不够清楚):在START_TIMEEND_TIME 之间,您需要运行所有脚本还是其中一些?我认为很难像你想要的那样生成可以容纳所有脚本的随机时间。 (因为没有设置最大间隔,而最小是5分钟)
  • @minhhn2910 在START_TIMEEND TIME 之间的时间内,所有脚本都需要运行,但每个脚本只需要运行一次。

标签: python python-2.7 datetime random random-seed


【解决方案1】:

使用datetime.timedelta 计算时间差。此代码假定所有三个进程在同一天运行

from datetime import datetime, timedelta
from random import randint

YR, MO, DY = 2016, 3, 30
START_TIME = datetime( YR, MO, DY, 1, 21, 00 )   # "01:21"
END_TIME = datetime( YR, MO, DY, 3, 0, 0 )       # "3:00"
duration_all = (END_TIME - START_TIME).seconds
d1 = ( duration_all - 600 ) // 3          
#       
rnd1 = randint(0,d1)
rnd2 = rnd1 + 300 + randint(0,d1)
rnd3 = rnd2 + 300 + randint(0,d1)
#      
time1 = START_TIME + timedelta(seconds=rnd1)
time2 = START_TIME + timedelta(seconds=rnd2)
time3 = START_TIME + timedelta(seconds=rnd3)
#
print (time1)
print (time2)
print (time3)

rnd1rnd2rnd3 的值至少相隔 5 分钟(300 秒)。

rnd3 的值不能大于总时间间隔 (3 * d1 + 600)。所以所有三个时间都发生在区间内。

NB 您没有指定每个脚本运行的时间。这就是为什么我没有使用time.sleep。一个可能的选项是threading.Timer(参见 python 文档)。

【讨论】:

  • 每个脚本每天只运行一次,您发布的代码有些混乱。即使有你的解释,我实际上也无法弄清楚它是如何工作的。
  • 这更有意义,也更容易阅读。
【解决方案2】:

假设您将所有 method.func() 存储在一个数组中,并且如您所述,后续脚本必须在 script1 之后至少 5 分钟。它们可以随机执行,因此我们可以启动多个进程并让它们休眠一段时间,然后它们才能自动启动。 (时间以秒为单位)

from multiprocessing import Process
import os
import random
import time
#store all scripts you want to execute here
eval_scripts = ["script1.test()","script2.test()", "script3.test()"]

#run job on different processes. non-blocking
def run_job(eval_string,time_sleep):
    #print out script + time to test
    print eval_string + " " + str(time_sleep)
    time.sleep(time_sleep) #wait to be executed
    #time to start
    eval(eval_string)


def do_my_jobs():
    start_time = []
    #assume the duration between start_time and end_time is 60 mins, leave some time for other jobs after the first job (5-10 mins). This is just to be careful in case random.randrange returns the largest number
    #adjust this according to the duration between start_time and end_time since calculating (end_time - star_time) is trivial.
    proc1_start_time = random.randrange(60*60 - 10*60)
    start_time.append(proc1_start_time)
    #randomize timing for other procs != first script
    for i in range(len(eval_scripts)-1):
            #randomize time from (proc1_start_time + 5 mins) to (end_time - star_time)
            start_time.append(random.randint(proc1_start_time+5*60, 60*60))

    for i in range(len(eval_scripts)):
            p_t = Process(target = run_job, args = (eval_scripts[i],start_time[i],))
            p_t.start()
            p_t.join()

现在您只需在每天 START_TIME 调用一次 do_my_jobs()。

【讨论】:

  • 虽然可行,但这并不是我想要的。我已经编辑了主帖,也许你对我的编辑有建议。我很确定它可以完成,只是无法正确解决。
  • 所以现在你的问题是“如何首先运行 MAIN_SCRIPT 并迭代其他脚本的排列”或“有没有更好的种子方法?”。另一件事是 5 分钟是脚本之间的最小间隔,但是您的脚本将运行多长时间?我不知道多久,所以我建议使用多进程。它将确保触发每个脚本之间的最小时间间隔。
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 2011-04-04
  • 2013-12-21
  • 1970-01-01
  • 2020-10-28
  • 1970-01-01
  • 2019-12-30
  • 1970-01-01
相关资源
最近更新 更多