33import numpy as np
44
55import pytest
6+ from inline_snapshot import snapshot
67
78from project_selection import select_proposals_to_fund
89
@@ -112,40 +113,38 @@ def test_select_proposals_more_than_funds(capfd):
112113 # Reset output.
113114 capfd .readouterr ()
114115
115- expected_result = {'B' , 'C' , 'D' , 'F' , 'G' , 'H' }
116- expected_captured = (
117- "Inputs:\n "
118- "Budget: $5\n "
119- "Per-project funding limit: $2\n "
120- "Proposals in the drawing:\n "
121- '"A" requests $2 and is proposed by a project that has previously received $0 this year.\n '
122- '"B" requests $1 and is proposed by a project that has previously received $0 this year.\n '
123- '"C" requests $1 and is proposed by a project that has previously received $0 this year.\n '
124- '"D" requests $0.5 and is proposed by a project that has previously received $0 this year.\n '
125- '"E" requests $1.5 and is proposed by a project that has previously received $0 this year.\n '
126- '"F" requests $0.25 and is proposed by a project that has previously received $0 this year.\n '
127- '"G" requests $1.9 and is proposed by a project that has previously received $0 this year.\n '
128- '"H" requests $0.7 and is proposed by a project that has previously received $0 this year.\n '
129- "\n "
130- "Random Outputs:\n "
131- 'Allocated: $5.35 ($0.35 over budget)\n '
132- '6 proposals funded out of 8 total proposals in the drawing\n \n '
133- 'Funded the following projects\n '
134- 'Fund "B" for $1 bringing its project\' s annual total to $1.\n '
135- 'Fund "C" for $1 bringing its project\' s annual total to $1.\n '
136- 'Fund "D" for $0.5 bringing its project\' s annual total to $0.5.\n '
137- 'Fund "F" for $0.25 bringing its project\' s annual total to $0.25.\n '
138- 'Fund "G" for $1.9 bringing its project\' s annual total to $1.9.\n '
139- 'Fund "H" for $0.7 bringing its project\' s annual total to $0.7.\n '
140- )
141116 result = select_proposals_to_fund (budget ,
142117 funding_limit ,
143118 proposals ,
144119 seed = 2025 )
145120 captured = capfd .readouterr ()
146121
147- assert set (result ) == expected_result
148- assert captured .out == expected_captured
122+ assert set (result ) == snapshot ({'D' ,'E' ,'F' ,'G' ,'H' })
123+ assert captured .out == snapshot ("""\
124+ Inputs:
125+ Budget: $5
126+ Per-project funding limit: $2
127+ Proposals in the drawing:
128+ "A" requests $2 and is proposed by a project that has previously received $0 this year.
129+ "B" requests $1 and is proposed by a project that has previously received $0 this year.
130+ "C" requests $1 and is proposed by a project that has previously received $0 this year.
131+ "D" requests $0.5 and is proposed by a project that has previously received $0 this year.
132+ "E" requests $1.5 and is proposed by a project that has previously received $0 this year.
133+ "F" requests $0.25 and is proposed by a project that has previously received $0 this year.
134+ "G" requests $1.9 and is proposed by a project that has previously received $0 this year.
135+ "H" requests $0.7 and is proposed by a project that has previously received $0 this year.
136+
137+ Random Outputs:
138+ Allocated: $4.85 ($0.15 under budget)
139+ 5 proposals funded out of 8 total proposals in the drawing
140+
141+ Funded the following projects
142+ Fund "D" for $0.5 bringing its project's annual total to $0.5.
143+ Fund "E" for $1.5 bringing its project's annual total to $1.5.
144+ Fund "F" for $0.25 bringing its project's annual total to $0.25.
145+ Fund "G" for $1.9 bringing its project's annual total to $1.9.
146+ Fund "H" for $0.7 bringing its project's annual total to $0.7.
147+ """ )
149148
150149
151150def test_select_proposals_more_than_funds_under (capfd ):
@@ -166,39 +165,38 @@ def test_select_proposals_more_than_funds_under(capfd):
166165 # Reset output.
167166 capfd .readouterr ()
168167
169- expected_result = {'C' , 'D' , 'E' , 'F' , 'H' }
170- expected_captured = (
171- "Inputs:\n "
172- "Budget: $4.1\n "
173- "Per-project funding limit: $2\n "
174- "Proposals in the drawing:\n "
175- '"A" requests $2 and is proposed by a project that has previously received $0 this year.\n '
176- '"B" requests $1 and is proposed by a project that has previously received $0 this year.\n '
177- '"C" requests $1 and is proposed by a project that has previously received $0 this year.\n '
178- '"D" requests $0.5 and is proposed by a project that has previously received $0 this year.\n '
179- '"E" requests $1.5 and is proposed by a project that has previously received $0 this year.\n '
180- '"F" requests $0.25 and is proposed by a project that has previously received $0 this year.\n '
181- '"G" requests $1.9 and is proposed by a project that has previously received $0 this year.\n '
182- '"H" requests $0.7 and is proposed by a project that has previously received $0 this year.\n '
183- "\n "
184- "Random Outputs:\n "
185- 'Allocated: $3.95 ($0.15 under budget)\n '
186- '5 proposals funded out of 8 total proposals in the drawing\n \n '
187- 'Funded the following projects\n '
188- 'Fund "C" for $1 bringing its project\' s annual total to $1.\n '
189- 'Fund "D" for $0.5 bringing its project\' s annual total to $0.5.\n '
190- 'Fund "E" for $1.5 bringing its project\' s annual total to $1.5.\n '
191- 'Fund "F" for $0.25 bringing its project\' s annual total to $0.25.\n '
192- 'Fund "H" for $0.7 bringing its project\' s annual total to $0.7.\n '
193- )
194168 result = select_proposals_to_fund (budget ,
195169 funding_limit ,
196170 proposals ,
197171 seed = 2026 )
198172 captured = capfd .readouterr ()
199173
200- assert set (result ) == expected_result
201- assert captured .out == expected_captured
174+ assert set (result ) == snapshot ({'B' ,'C' ,'D' ,'E' ,'F' })
175+ assert captured .out == snapshot ("""\
176+ Inputs:
177+ Budget: $4.1
178+ Per-project funding limit: $2
179+ Proposals in the drawing:
180+ "A" requests $2 and is proposed by a project that has previously received $0 this year.
181+ "B" requests $1 and is proposed by a project that has previously received $0 this year.
182+ "C" requests $1 and is proposed by a project that has previously received $0 this year.
183+ "D" requests $0.5 and is proposed by a project that has previously received $0 this year.
184+ "E" requests $1.5 and is proposed by a project that has previously received $0 this year.
185+ "F" requests $0.25 and is proposed by a project that has previously received $0 this year.
186+ "G" requests $1.9 and is proposed by a project that has previously received $0 this year.
187+ "H" requests $0.7 and is proposed by a project that has previously received $0 this year.
188+
189+ Random Outputs:
190+ Allocated: $4.25 ($0.15 over budget)
191+ 5 proposals funded out of 8 total proposals in the drawing
192+
193+ Funded the following projects
194+ Fund "B" for $1 bringing its project's annual total to $1.
195+ Fund "C" for $1 bringing its project's annual total to $1.
196+ Fund "D" for $0.5 bringing its project's annual total to $0.5.
197+ Fund "E" for $1.5 bringing its project's annual total to $1.5.
198+ Fund "F" for $0.25 bringing its project's annual total to $0.25.
199+ """ )
202200
203201
204202def test_select_proposals_more_than_funds_eqweight_zero (capfd ):
@@ -219,40 +217,39 @@ def test_select_proposals_more_than_funds_eqweight_zero(capfd):
219217 # Reset output.
220218 capfd .readouterr ()
221219
222- expected_result = {'A' , 'C' , 'D' , 'F' , 'G' , 'H' }
223- expected_captured = (
224- "Inputs:\n "
225- "Budget: $6\n "
226- "Per-project funding limit: $2\n "
227- "Proposals in the drawing:\n "
228- '"A" requests $1 and is proposed by a project that has previously received $0 this year.\n '
229- '"B" requests $1 and is proposed by a project that has previously received $0 this year.\n '
230- '"C" requests $1 and is proposed by a project that has previously received $0 this year.\n '
231- '"D" requests $1 and is proposed by a project that has previously received $0 this year.\n '
232- '"E" requests $1 and is proposed by a project that has previously received $0 this year.\n '
233- '"F" requests $1 and is proposed by a project that has previously received $0 this year.\n '
234- '"G" requests $1 and is proposed by a project that has previously received $0 this year.\n '
235- '"H" requests $1 and is proposed by a project that has previously received $0 this year.\n '
236- "\n "
237- "Random Outputs:\n "
238- "Allocated: $6 ($0 under budget)\n "
239- "6 proposals funded out of 8 total proposals in the drawing\n \n "
240- "Funded the following projects\n "
241- 'Fund "A" for $1 bringing its project\' s annual total to $1.\n '
242- 'Fund "C" for $1 bringing its project\' s annual total to $1.\n '
243- 'Fund "D" for $1 bringing its project\' s annual total to $1.\n '
244- 'Fund "F" for $1 bringing its project\' s annual total to $1.\n '
245- 'Fund "G" for $1 bringing its project\' s annual total to $1.\n '
246- 'Fund "H" for $1 bringing its project\' s annual total to $1.\n '
247- )
248220 result = select_proposals_to_fund (budget ,
249221 funding_limit ,
250222 proposals ,
251223 seed = 2025 )
252224 captured = capfd .readouterr ()
253225
254- assert set (result ) == expected_result
255- assert captured .out == expected_captured
226+ assert set (result ) == snapshot ({'A' ,'C' ,'E' ,'F' ,'G' ,'H' })
227+ assert captured .out == snapshot ("""\
228+ Inputs:
229+ Budget: $6
230+ Per-project funding limit: $2
231+ Proposals in the drawing:
232+ "A" requests $1 and is proposed by a project that has previously received $0 this year.
233+ "B" requests $1 and is proposed by a project that has previously received $0 this year.
234+ "C" requests $1 and is proposed by a project that has previously received $0 this year.
235+ "D" requests $1 and is proposed by a project that has previously received $0 this year.
236+ "E" requests $1 and is proposed by a project that has previously received $0 this year.
237+ "F" requests $1 and is proposed by a project that has previously received $0 this year.
238+ "G" requests $1 and is proposed by a project that has previously received $0 this year.
239+ "H" requests $1 and is proposed by a project that has previously received $0 this year.
240+
241+ Random Outputs:
242+ Allocated: $6 ($0 under budget)
243+ 6 proposals funded out of 8 total proposals in the drawing
244+
245+ Funded the following projects
246+ Fund "A" for $1 bringing its project's annual total to $1.
247+ Fund "C" for $1 bringing its project's annual total to $1.
248+ Fund "E" for $1 bringing its project's annual total to $1.
249+ Fund "F" for $1 bringing its project's annual total to $1.
250+ Fund "G" for $1 bringing its project's annual total to $1.
251+ Fund "H" for $1 bringing its project's annual total to $1.
252+ """ )
256253
257254
258255def test_select_proposals_more_than_funds_eqweight_under (capfd ):
@@ -273,39 +270,38 @@ def test_select_proposals_more_than_funds_eqweight_under(capfd):
273270 # Reset output.
274271 capfd .readouterr ()
275272
276- expected_result = {'A' , 'C' , 'D' , 'G' , 'H' }
277- expected_captured = (
278- "Inputs:\n "
279- "Budget: $5.4\n "
280- "Per-project funding limit: $2\n "
281- "Proposals in the drawing:\n "
282- '"A" requests $1 and is proposed by a project that has previously received $0 this year.\n '
283- '"B" requests $1 and is proposed by a project that has previously received $0 this year.\n '
284- '"C" requests $1 and is proposed by a project that has previously received $0 this year.\n '
285- '"D" requests $1 and is proposed by a project that has previously received $0 this year.\n '
286- '"E" requests $1 and is proposed by a project that has previously received $0 this year.\n '
287- '"F" requests $1 and is proposed by a project that has previously received $0 this year.\n '
288- '"G" requests $1 and is proposed by a project that has previously received $0 this year.\n '
289- '"H" requests $1 and is proposed by a project that has previously received $0 this year.\n '
290- "\n "
291- "Random Outputs:\n "
292- "Allocated: $5.0 ($0.4 under budget)\n "
293- "5 proposals funded out of 8 total proposals in the drawing\n \n "
294- "Funded the following projects\n "
295- 'Fund "A" for $1 bringing its project\' s annual total to $1.\n '
296- 'Fund "C" for $1 bringing its project\' s annual total to $1.\n '
297- 'Fund "D" for $1 bringing its project\' s annual total to $1.\n '
298- 'Fund "G" for $1 bringing its project\' s annual total to $1.\n '
299- 'Fund "H" for $1 bringing its project\' s annual total to $1.\n '
300- )
301273 result = select_proposals_to_fund (budget ,
302274 funding_limit ,
303275 proposals ,
304276 seed = 2025 )
305277 captured = capfd .readouterr ()
306278
307- assert set (result ) == expected_result
308- assert captured .out == expected_captured
279+ assert set (result ) == snapshot ({'C' ,'E' ,'F' ,'G' ,'H' })
280+ assert captured .out == snapshot ("""\
281+ Inputs:
282+ Budget: $5.4
283+ Per-project funding limit: $2
284+ Proposals in the drawing:
285+ "A" requests $1 and is proposed by a project that has previously received $0 this year.
286+ "B" requests $1 and is proposed by a project that has previously received $0 this year.
287+ "C" requests $1 and is proposed by a project that has previously received $0 this year.
288+ "D" requests $1 and is proposed by a project that has previously received $0 this year.
289+ "E" requests $1 and is proposed by a project that has previously received $0 this year.
290+ "F" requests $1 and is proposed by a project that has previously received $0 this year.
291+ "G" requests $1 and is proposed by a project that has previously received $0 this year.
292+ "H" requests $1 and is proposed by a project that has previously received $0 this year.
293+
294+ Random Outputs:
295+ Allocated: $5.0 ($0.4 under budget)
296+ 5 proposals funded out of 8 total proposals in the drawing
297+
298+ Funded the following projects
299+ Fund "C" for $1 bringing its project's annual total to $1.
300+ Fund "E" for $1 bringing its project's annual total to $1.
301+ Fund "F" for $1 bringing its project's annual total to $1.
302+ Fund "G" for $1 bringing its project's annual total to $1.
303+ Fund "H" for $1 bringing its project's annual total to $1.
304+ """ )
309305
310306
311307def test_select_proposals_more_than_funds_eqweight_over (capfd ):
@@ -322,38 +318,37 @@ def test_select_proposals_more_than_funds_eqweight_over(capfd):
322318 ("H" , 1 , 0 ),
323319 ]
324320
325- expected_result = {"A" , "B" , "C" , "D" , "F" , "H" , "G" }
326- expected_captured = (
327- "Inputs:\n "
328- "Budget: $6.6\n "
329- "Per-project funding limit: $2\n "
330- "Proposals in the drawing:\n "
331- '"A" requests $1 and is proposed by a project that has previously received $0 this year.\n '
332- '"B" requests $1 and is proposed by a project that has previously received $0 this year.\n '
333- '"C" requests $1 and is proposed by a project that has previously received $0 this year.\n '
334- '"D" requests $1 and is proposed by a project that has previously received $0 this year.\n '
335- '"E" requests $1 and is proposed by a project that has previously received $0 this year.\n '
336- '"F" requests $1 and is proposed by a project that has previously received $0 this year.\n '
337- '"G" requests $1 and is proposed by a project that has previously received $0 this year.\n '
338- '"H" requests $1 and is proposed by a project that has previously received $0 this year.\n '
339- "\n "
340- "Random Outputs:\n "
341- "Allocated: $7.0 ($0.4 over budget)\n "
342- "7 proposals funded out of 8 total proposals in the drawing\n \n "
343- "Funded the following projects\n "
344- 'Fund "A" for $1 bringing its project\' s annual total to $1.\n '
345- 'Fund "B" for $1 bringing its project\' s annual total to $1.\n '
346- 'Fund "C" for $1 bringing its project\' s annual total to $1.\n '
347- 'Fund "D" for $1 bringing its project\' s annual total to $1.\n '
348- 'Fund "F" for $1 bringing its project\' s annual total to $1.\n '
349- 'Fund "G" for $1 bringing its project\' s annual total to $1.\n '
350- 'Fund "H" for $1 bringing its project\' s annual total to $1.\n '
351- )
352321 result = select_proposals_to_fund (budget ,
353322 funding_limit ,
354323 proposals ,
355324 seed = 2025 )
356325 captured = capfd .readouterr ()
357326
358- assert set (result ) == expected_result
359- assert captured .out == expected_captured
327+ assert set (result ) == snapshot ({'A' ,'B' ,'C' ,'E' ,'F' ,'G' ,'H' })
328+ assert captured .out == snapshot ("""\
329+ Inputs:
330+ Budget: $6.6
331+ Per-project funding limit: $2
332+ Proposals in the drawing:
333+ "A" requests $1 and is proposed by a project that has previously received $0 this year.
334+ "B" requests $1 and is proposed by a project that has previously received $0 this year.
335+ "C" requests $1 and is proposed by a project that has previously received $0 this year.
336+ "D" requests $1 and is proposed by a project that has previously received $0 this year.
337+ "E" requests $1 and is proposed by a project that has previously received $0 this year.
338+ "F" requests $1 and is proposed by a project that has previously received $0 this year.
339+ "G" requests $1 and is proposed by a project that has previously received $0 this year.
340+ "H" requests $1 and is proposed by a project that has previously received $0 this year.
341+
342+ Random Outputs:
343+ Allocated: $7.0 ($0.4 over budget)
344+ 7 proposals funded out of 8 total proposals in the drawing
345+
346+ Funded the following projects
347+ Fund "A" for $1 bringing its project's annual total to $1.
348+ Fund "B" for $1 bringing its project's annual total to $1.
349+ Fund "C" for $1 bringing its project's annual total to $1.
350+ Fund "E" for $1 bringing its project's annual total to $1.
351+ Fund "F" for $1 bringing its project's annual total to $1.
352+ Fund "G" for $1 bringing its project's annual total to $1.
353+ Fund "H" for $1 bringing its project's annual total to $1.
354+ """ )
0 commit comments