一种用于计算随机化加班打卡次数并进行效果评估的Python方法

发布时间 2023-08-26 00:24:40作者: namiya

写着玩的。

import random

def get_random_bool(possbility):
    assert possbility <= 100 and possbility > 0
    return random.randint(0, 100) < possbility

def generate_dinner_days_list():
    dinner_days_list = set([])

    # Weekdays
    num_dinner_days_weekday = 3
    if get_random_bool(70):
        num_dinner_days_weekday = 3
    elif get_random_bool(20):
        num_dinner_days_weekday = 4
    else:
        num_dinner_days_weekday = 5
    
    while(len(dinner_days_list) != num_dinner_days_weekday):
        dinner_day_tmp = random.randint(1,5)
        dinner_days_list.add(dinner_day_tmp)
    
    # Weekends
    num_dinner_days_weekend = 1
    if get_random_bool(70):
        num_dinner_days_weekend = 1
    elif get_random_bool(30):
        num_dinner_days_weekend = 2
    else:
        num_dinner_days_weekend = 0


    while(len(dinner_days_list) != num_dinner_days_weekend + num_dinner_days_weekday):
        dinner_day_tmp = random.randint(6,7)
        dinner_days_list.add(dinner_day_tmp)
    
    return dinner_days_list

def get_random_index_in_list(*possbility_list):
    assert sum(possbility_list) == 100
    possbility_list = list(possbility_list)
    edges = []
    count = 0
    for i in possbility_list:
        edges.append(range(count, count+i))
        count += i
    t = random.randint(1, 100)
    for index, edge in enumerate(edges):
        if (t in edge):
            return index
    return len(edges) - 1

def generate_dinner_days_list2():
    dinner_days_list = set([])

    # Weekdays
    possible_num_dinner_days_weekday = [3, 4, 5]
    num_dinner_days_weekday = 3
    index = get_random_index_in_list(80, 15, 5)
    num_dinner_days_weekday = possible_num_dinner_days_weekday[index]
    
    while(len(dinner_days_list) != num_dinner_days_weekday):
        dinner_day_tmp = random.randint(1,5)
        dinner_days_list.add(dinner_day_tmp)
    
    # Weekend
    possible_num_dinner_days_weekend = [1, 2, 0]
    num_dinner_days_weekend = 1
    index = get_random_index_in_list(70, 20, 10)
    num_dinner_days_weekend = possible_num_dinner_days_weekend[index]


    while(len(dinner_days_list) != num_dinner_days_weekend + num_dinner_days_weekday):
        dinner_day_tmp = random.randint(6,7)
        dinner_days_list.add(dinner_day_tmp)
    
    return dinner_days_list, num_dinner_days_weekday, num_dinner_days_weekend



# print(generate_dinner_days_list())

TOTAL_WEEKS = 10000

stat = [-1, 0, 0, 0, 0, 0, 0, 0]
stat_weekday = [0, 0, 0, 0, 0, 0]
stat_weekend = [0, 0, 0]
total_dinner_days = 0
total_dinner_counts = 0
TOTAL_MONTH = TOTAL_WEEKS / 4
for _ in range(TOTAL_WEEKS):
    t, t_num_weekday, t_num_weekend = generate_dinner_days_list2()
    for day in t:
        stat[day] += 1
        total_dinner_days += 1
        total_dinner_counts += 1 if day in range(1,6) else 2
    stat_weekday[t_num_weekday] += 1
    stat_weekend[t_num_weekend] += 1
    if TOTAL_WEEKS <= 4:
        print(t)

print(f'''Result: In {TOTAL_WEEKS} weeks, {total_dinner_days}/{TOTAL_WEEKS*7} days ({total_dinner_days/(TOTAL_WEEKS*7)*100}%)
      Mon:{stat[1]}({stat[1]/total_dinner_days * 100}%)
      Tue:{stat[2]}({stat[2]/total_dinner_days * 100}%)
      Wed:{stat[3]}({stat[3]/total_dinner_days * 100}%)
      Thu:{stat[4]}({stat[4]/total_dinner_days * 100}%)
      Fri:{stat[5]}({stat[5]/total_dinner_days * 100}%)
      Sat:{stat[6]}({stat[6]/total_dinner_days * 100}%)
      Sun:{stat[7]}({stat[7]/total_dinner_days * 100}%)
total_dinner_counts = {total_dinner_counts}
average monthly total_dinner_counts = {total_dinner_counts/TOTAL_MONTH}
      ''')

for dinnerdays, count  in enumerate(stat_weekday):
    if count > 0:
        print(f"Weekday with {dinnerdays} dinner days: {count} weeks({round(count/TOTAL_WEEKS*100, 2)}%)")

for dinnerdays, count  in enumerate(stat_weekend):
    if count > 0:
        print(f"Weekend with {dinnerdays} dinner days: {count} weeks({round(count/TOTAL_WEEKS*100, 2)}%)")