I have been looking at this function for hours and I can't seem to figure out why it is not giving me the result I am expecting. I have a test that generates a datetime start and datetime end. I want to calculate how many 'mondays' or any given day occur between that time range.
def day_count(week_day, start, end):
if week_day == 1:
day = 6
else:
day = week_day - 2
num_weekdays, remainder = divmod((end - start).days, 7)
if (day - start.weekday()) % 7 <= remainder:
return num_weekdays + 1
else:
return num_weekdays
to replicate, this is the data that I give it:
end: 2020-08-22 00:00:00+02:00
start: 2020-08-20 22:15:55.371646+00:00
weekday: 6
I expect to give back num_weekdays = 1
but I get num_weekdays = 0
I have no clue how I can possibly fix this, num_weekdays
and remainder
are 0 when I debug as well.
This is how i am calling the function:
total_day_count = day_count(params['dt_start__week_day'], params['dt_start__gte'], params['dt_end__lte'])
and this is how i get the params:
params = {}
if self.request.GET.get('day') == 'Today':
params['dt_start__week_day'] = (timezone.now().weekday() + 1) % 7 + 1
elif is_valid_queryparam(self.request.GET.get('day')):
day_of_the_week = self.request.GET.get('day')
params['dt_start__week_day'] = (int(day_of_the_week) + 1) % 7 + 1
else:
params['dt_start__week_day'] = (timezone.now().weekday() + 1) % 7 + 1
if is_valid_queryparam(self.request.GET.get('date_start')):
unaware = datetime.strptime(self.request.GET.get('date_start'), '%Y-%m-%d')
params['dt_start__gte'] = unaware.replace(tzinfo=local_tz)
else:
dt = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
first_job = Job.objects.earliest('dt_start')
params['dt_start__gte'] = first_job.dt_start
if is_valid_queryparam(self.request.GET.get('date_end')):
unaware = datetime.strptime(self.request.GET.get('date_end'), '%Y-%m-%d')
params['dt_end__lte'] = unaware.replace(tzinfo=local_tz) + timedelta(days=1)
else:
dt = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
dt_aware = local_tz.localize(dt)
params['dt_end__lte'] = dt_aware + timedelta(days=1)
I dont know i fthis is helpful, but this is the test:
class MachineDurationViewTestCase(CustomAPITestCase):
"""This testcase contains tests for the API endpoint MachineDurationView """
# todo once views and some of its variables were renamed, also apply these name changes here
fake = Faker()
def setUp(self) -> None:
self.fake.seed()
super(MachineDurationViewTestCase, self).setUp()
def test_a_single_job_that_occurs_in_the_space_of_one_hour(self):
"""
In this test a single job of 30 minutes is created occuring on the first hour on the current date. This means
that we should expect the endpoint to return an array of 24 value where the first item in the array has a value
of 0.5 (Because the first hour only occurs 1 time, and job lasts 30 minutes, machine occupancy is 50%)
"""
dt = timezone.localtime()
dt_start = dt.replace(hour=0, minute=15)
dt_end = dt.replace(hour=0, minute=45)
# dt_end = timezone.datetime(d.year, d.month, d.day, hour=0, minute=45)
# dt_start = timezone.make_aware(timezone.datetime.now().replace(hour=0, minute=0, second=0, microsecond=0))
print(dt_start)
print(dt_end)
job = JobFactory(dt_start=dt_start, dt_end=dt_end)
print(job.dt_start)
# Query the dbase to ensure the job is created
self.assertEqual(Job.objects.all().count(), 1)
# Force create/login a user to access the http mocking client
# (I don't care about authentication or permissions in this test)
self.client.force_login(user=UserFactory(is_superuser=True))
response = self.client.get(reverse('data_app:machine_avg'))
self.assertEqual(response.status_code, 200)
print(response.data['machines'])
self.assertNotEqual(response.data['machines'][0], 0.0, "Since we create a job on the first hour, we expect the"
"first item of the array not to be zero.")
self.assertEqual(response.data['machines'][0], 0.5, "Since we create a single job of 30 minutes that occurs on "
"the current date, the value on the given hour should be"
"0.5 (50% occupancy)")
# job = JobFactory(dt_start=)
I believe there's a problem with your input data. This seems to work for me:
from datetime import date
start = date(2020, 8, 20)
end = date(2020, 8, 22)
day_count(6, start, end)
This returns desired output of 1. The type of my dates is: <class 'datetime.date'>