Generating multiple objects with random start and end dates which NEVER overlap?

Viewed 38

I'm creating 20 random objects for my fixtures like this:

EVENT_TYPE = [
    'A',
    'B',
    'C',
]


for _ in range(20):
        start_date = get_random_date(date(date.today().year, 1, 1), now())

        Event.objects.create(
            category=random.choice(EVENT_TYPE),
            start=start_date,
            end=get_random_date(start_date, start_date + timedelta(days=180)),
        )

What I want to do: having 20 objects with "unique" date ranges. For example Object1 starts at 01.01.2019 and ends at 10.01.2019 and has an EVENT_TYPE of "A". So no other object created should have a date range between those two dates with the same EVENT_TYPE. They can have a start date at 10.01.2019 or an end date at 01.01.2019, but never something between those dates.

BUT as you can see my objects also have categories, which split them, so if obj1 and obj2 have the same date range, but a different EVENT_TYPE thats totally okay.

Right now my code does that totally random. I tried to figure out a way to achieve that, but just couldn't come up with a smart idea. Does someone know a clever solution to this problem? How could I check if one object is in between the date range of another and let say just change its date to the beginning or end of that object so that it will definitely not overlap?

Thanks for any answer! :)

1 Answers

Create a dictionary holding current dates like:

current_dates = {
    'A': date(2019, 3, 5)
    'B': date(2019, 1, 1)
    'C': date(2019, 5, 4)
}

Pick your start date for a type from current_dates. After randomly picked end date, put it as the start date for the type and update current_dates dictionary.

for _ in range(20):
    category = random.choice(EVENT_TYPE)
    start_date = current_dates[category]
    end_date = get_random_date(start_date, start_date + timedelta(days=180))
    Event.objects.create(
        category=category,
        start=start_date,
        end=end_date,
    )
    current_dates[category] = end_date
Related