def generate_schedule(unityId, day_date, _student_record, buffer_time):
	past_deadline(_student_record)
	if not 'freeTime' in _student_record:
		# print("inside if")
		generate_free_time(_student_record, buffer_time, day_date)
		# Above query replaced by the following query.
		_student_record = db_scripts.db_retrieve(db_name, collection_name, unityId, username, password)

	tasks = _student_record['tasks']

	# Initially free_time is the same as the original. As tasks get added, free_time reduces.
	free_time = _student_record['freeTime']

	# The smallest quantum of time in which the student is willing to work
	window_size = 1
	# The schedule entry to be added to the student_record
	schedule = defaultdict(list)
	sorted_tasks = sorted(tasks, key=lambda task: (task['deadline'], task['duration']))

	for task in sorted_tasks:
		rem_time = float(task['duration'])

		for day in '1234567':
			if rem_time == 0:
				# Go to next task
				break

			if day_date[day] > task['deadline']:
				# abort task scheduler and tell the user that he has to finish it in the whatever time slice has been assigned
				# (i.e. if duration = 4 hrs but after assigning a time slice of 2 the deadline is crossed,
				# then tell them to do it in 2)
				print("Sorry! The task", task['name'], "cannot be scheduled completely. You will have to complete the task in",
				      task['duration']-rem_time, "hours instead of", task['duration'], "hours!")
				break

			idx = 0
			while idx < len(free_time[day]):
				if rem_time == 0:
					break
				start_time = free_time[day][idx]
				end_time = free_time[day][idx + 1]
				# Difference between two consecutive datetime objects (in seconds)
				avail = end_time - start_time
				time_avail = avail.seconds/3600
				# If the number of available hours for this window is more than the window_size
				# if diff.hours >= window_size:
				if time_avail >= window_size:
					if time_avail >= rem_time:
						# Add the duration of remaining time to the free_time
						# end_time (date) should be start_time (date) + rem_time (float)
						end_hours = start_time.hour + int(rem_time)
						extra_minutes = int((rem_time - int(rem_time))*60)
						end_minutes = start_time.minute + extra_minutes

						if end_minutes >= 60:
							end_minutes -= 60
							end_hours += 1

						end_time = datetime(start_time.year, start_time.month, start_time.day, end_hours, end_minutes)
						rem_time = 0
					# If the amount of time available is less than the total time required
					else:
						rem_time -= time_avail
					pos = idx + 1
					free_time[day].insert(pos, start_time)
					free_time[day].insert(pos + 1, end_time)
					schedule[day].append([start_time, end_time, task['name']])
				# pprint("In while")
				idx += 2

	# # Update tasks to the new_tasks (i.e. removing those which have been scheduled successfully)
	# db_scripts.db_update(db_name, collection_name, _student_record['uid'], 'tasks', new_tasks, username, password)

	pprint(schedule)
	if schedule:
		pass
		db_scripts.db_update(db_name, collection_name, _student_record['uid'], 'schedule', schedule, username, password)
		return schedule
	pprint(schedule)
	if schedule:
		pass
		db_scripts.db_update(db_name, collection_name, _student_record['uid'], 'schedule', schedule, username, password)
		return schedule
	# Suggestion: if we reach the deadline and the task is not getting completed, we can try scheduler again
	# by reducing the buffer to 15 mins/0 mins (this is optimization i guess. can be ignored for now)



db_name = 'mydb'
collection_name = 'student'
username = '******'
password = '******'

unityId = sys.argv[1]

day_date = ast.literal_eval(sys.argv[2])
buffer_time = int(sys.argv[3])

# unityId is the only parameter on which we query right now. Can be modified to have other parameters as well.
student_record = db_scripts.db_retrieve(db_name, collection_name, unityId, username, password)
print(student_record)

schedule = generate_schedule(unityId, day_date, student_record, buffer_time)

# print("Success!")
print(schedule)
sys.stdout.flush()