Skip to content

Commit a263618

Browse files
committed
refactor: assign less than min threshold students to previous center
Abstracts the center allocation to a separate function Assigns the remaining students to previous center if the remainder is less than minimum threshold
1 parent 607f3db commit a263618

File tree

1 file changed

+48
-25
lines changed

1 file changed

+48
-25
lines changed

school_center.py

Lines changed: 48 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,52 @@ def is_allocated(scode1: str, scode2:str) -> bool:
143143
else:
144144
return False
145145

146+
def allocate_to_centers(centers: List[Dict[str, str]], school: Dict[str, str], to_allot: int, remaining_cap: Dict[str, int], stretch: bool=False):
147+
allocated_centers = {}
148+
per_center = calc_per_center(to_allot)
149+
150+
for center in centers:
151+
school_code = school['scode']
152+
center_code = center['cscode']
153+
writer.writerow([
154+
school_code,
155+
school['count'],
156+
school['name-address'],
157+
school['lat'],
158+
school['long'],
159+
center_code,
160+
center['name'],
161+
center['address'],
162+
center['capacity'],
163+
center['distance_km']
164+
])
165+
166+
if is_allocated(center_code, school_code):
167+
continue
168+
169+
centers_cap_left = remaining_cap[center_code]
170+
171+
if stretch:
172+
stretched_capacity = math.floor(int(center['capacity']) * STRETCH_CAPACITY_FACTOR + centers_cap_left)
173+
next_allot = min(to_allot, max(stretched_capacity, MIN_STUDENT_IN_CENTER))
174+
centers_cap_left = stretched_capacity
175+
else:
176+
next_allot = min(to_allot, per_center, max(centers_cap_left, MIN_STUDENT_IN_CENTER))
177+
178+
if to_allot > 0 and next_allot > 0 and centers_cap_left >= next_allot:
179+
if next_allot < MIN_STUDENT_IN_CENTER and len(allocated_centers) > 0:
180+
# get the first center code
181+
allocate_center_code = centers[0]['cscode']
182+
else:
183+
allocate_center_code = center_code
184+
allocated_centers[allocate_center_code] = center
185+
186+
allocate(school_code, allocate_center_code, next_allot)
187+
to_allot -= next_allot
188+
remaining_cap[center_code] -= next_allot
189+
190+
return to_allot, allocated_centers
191+
146192
parser = argparse.ArgumentParser(
147193
prog='center randomizer',
148194
description='Assigns centers to exam centers to students')
@@ -172,36 +218,13 @@ def is_allocated(scode1: str, scode2:str) -> bool:
172218
for s in schools:
173219
centers_for_school = centers_within_distance(s, centers, PREF_DISTANCE_THRESHOLD)
174220
to_allot = int(s['count'])
175-
per_center = calc_per_center(to_allot)
176-
177-
allocated_centers = {}
178221

179222
# per_center = math.ceil(to_allot / min(calc_num_centers(to_allot), len(centers_for_school)))
180-
for c in centers_for_school:
181-
writer.writerow([s['scode'], s['count'], s['name-address'], s['lat'], s['long'], c['cscode'], c['name'], c['address'], c['capacity'], c['distance_km'] ])
182-
if is_allocated(c['cscode'], s['scode']):
183-
continue
184-
next_allot = min(to_allot, per_center, max(centers_remaining_cap[c['cscode']], MIN_STUDENT_IN_CENTER))
185-
if to_allot > 0 and next_allot > 0 and centers_remaining_cap[c['cscode']] >= next_allot:
186-
allocated_centers[c['cscode']] = c
187-
allocate(s['scode'], c['cscode'], next_allot)
188-
# allocation.writerow([s['scode'], s['name-address'], c['cscode'], c['name'], c['address'], next_allot, c['distance_km']])
189-
to_allot -= next_allot
190-
centers_remaining_cap[c['cscode']] -= next_allot
223+
to_allot, allocated_centers = allocate_to_centers(centers_for_school, s, to_allot, centers_remaining_cap)
191224

192225
if to_allot > 0: # try again with relaxed constraints and more capacity at centers
193226
expanded_centers = centers_within_distance(s, centers, ABS_DISTANCE_THRESHOLD)
194-
for c in expanded_centers:
195-
if is_allocated(c['cscode'], s['scode']):
196-
continue
197-
stretched_capacity = math.floor(int(c['capacity']) * STRETCH_CAPACITY_FACTOR + centers_remaining_cap[c['cscode']])
198-
next_allot = min(to_allot, max(stretched_capacity, MIN_STUDENT_IN_CENTER))
199-
if to_allot > 0 and next_allot > 0 and stretched_capacity >= next_allot:
200-
allocated_centers[c['cscode']] = c
201-
allocate(s['scode'], c['cscode'], next_allot)
202-
# allocation.writerow([s['scode'], s['name-address'], c['cscode'], c['name'], c['address'], next_allot, c['distance_km']])
203-
to_allot -= next_allot
204-
centers_remaining_cap[c['cscode']] -= next_allot
227+
to_allot, allocated_centers = allocate_to_centers(expanded_centers, s, to_allot, centers_remaining_cap, stretch_capacity=True)
205228

206229
for c in allocated_centers.values():
207230
allocation_file.writerow([s['scode'], s['name-address'], c['cscode'], c['name'], c['address'], allocations[s['scode']][c['cscode']], c['distance_km']])

0 commit comments

Comments
 (0)