Reputation: 3
hey guys i was trying to create a code that generate dates in given range but i faced some problems the code is as follows:
import datetime
import random
import os
from random import randrange
year_b = 2019
month_b = 1
day_b = 1
year_e = 2020
month_e = 1
day_e = 1
def date_range(start, end, step: datetime.timedelta):
while start < end:
yield start
start += step
rand_list=[5,8,6,9,10]
for d in date_range(
start=datetime.datetime(year_b, month_b, day_b),
end=datetime.datetime(year_e, month_e, day_e),
step=datetime.timedelta(days=rand.choice(rand_list)),
):
print(d)
os.system("pause")
output:
2019-01-01 00:00:00
2019-01-09 00:00:00
2019-01-17 00:00:00
2019-01-25 00:00:00
2019-02-02 00:00:00
Press any key to continue . . .
first problem that the code only select one random value from the list and add it to the date but i need it to select random value for each date generated
second problem is that code the time it not been generated randomly
any ideas to solve those problems???!!
Upvotes: 0
Views: 1027
Reputation: 3
now not all the months are showing:
from datetime import datetime, timedelta
import random
samples = 10
start = datetime(2018, 1, 1)
end = datetime(2020, 1, 1)
def items(start, end, samples):
total_sec = int((end - start).total_seconds())
deltas = random.sample(range(total_sec), samples) # xrange if py2k!
return (start + timedelta(seconds=delta) for delta in sorted(deltas))
for _ in list(items(start, end, samples)):
print(_)
output:
2018-02-01 18:25:48
2018-02-20 20:24:23
2018-06-07 22:03:48
2018-07-20 07:15:37
2018-08-22 07:04:06
2018-08-28 18:02:07
2018-10-09 03:40:58
2019-01-04 15:11:40
2019-03-22 12:16:58
2019-07-22 14:44:00
Upvotes: 0
Reputation: 4427
"Random" is often poorly defined. Why not select a specific number of samples uniformly from the distribution?
from datetime import datetime, timedelta
def items(start, end, samples):
total_sec = int((end - start).total_seconds())
deltas = random.sample(range(total_sec), samples) # xrange if py2k!
return (start + timedelta(seconds=delta) for delta in sorted(deltas))
Then you have
samples = 10
start = datetime(2019, 1, 1)
end = datetime(2020, 1, 1)
print(list(items(start, end, samples)))
giving, e.g.:
[datetime.datetime(2019, 1, 12, 16, 40, 53),
datetime.datetime(2019, 2, 1, 1, 41, 45),
datetime.datetime(2019, 2, 25, 10, 29, 51),
datetime.datetime(2019, 3, 10, 10, 24, 48),
datetime.datetime(2019, 4, 3, 12, 46, 14),
datetime.datetime(2019, 8, 12, 18, 30, 57),
datetime.datetime(2019, 9, 11, 3, 59, 6),
datetime.datetime(2019, 9, 27, 3, 9, 36),
datetime.datetime(2019, 10, 13, 14, 23, 37),
datetime.datetime(2019, 12, 14, 12, 23, 5)]
From this base you can easily modify to various other distributions, or use days or microseconds, or allow duplicates.
After reading your question more closely, I'm not entirely convinced this answer is what you're looking for, but I'll leave it up in case it is helpful.
Upvotes: 1
Reputation: 7210
The problem is because randrange(10)
evaluates as soon as it is called. You can instead make date_range
take a callable
that returns a "random" time delta (or a variable delta, or whatever you'd like).
def adjustable_date_range(start, end, random_delta_maker):
while start < end:
yield start
start += random_delta_maker
And use it like so in your example by passing a callable that makes a random time delta on [0-10)
days:
for d in adjustable_date_range(
start=datetime.datetime(year_b, month_b, day_b),
end=datetime.datetime(year_e, month_e, day_e),
step=lambda: datetime.timedelta(days=randrange(10)),
):
print(d)
Upvotes: 0