Last active
October 24, 2025 18:12
-
-
Save seabbs/d0f61c5f39e53bf23ab2bbd9b6903a45 to your computer and use it in GitHub Desktop.
Grant application break-even analysis calculator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env julia | |
| # Grant Application Break-even Analysis (Funder/Community Perspective) | |
| # | |
| # Analyses whether a grant opportunity creates net value for the community. | |
| using Printf | |
| let | |
| function show_help() | |
| println(""" | |
| Grant Application Break-even Analysis | |
| Analyses whether grant opportunities create net value by comparing total funding | |
| awarded vs total applicant effort. | |
| USAGE: | |
| julia grant_breakeven.jl [OPTIONS] [GRANT_VALUE] | |
| ARGUMENTS: | |
| GRANT_VALUE Months of funding per grant (default: 48) | |
| OPTIONS: | |
| -h, --help Show this help message | |
| --rates RATES Comma-separated acceptance rates as percentages | |
| (default: 1,2,5,10,15,20,25,30,50) | |
| --costs COSTS Comma-separated application costs in months | |
| (default: 0.25,0.5,1,1.5,2,2.5,3,4,5,6) | |
| EXAMPLES: | |
| julia grant_breakeven.jl | |
| julia grant_breakeven.jl 60 | |
| julia grant_breakeven.jl --rates 5,10,20,30 48 | |
| julia grant_breakeven.jl --costs 1,2,3,4 --rates 10,20,30 72 | |
| ASSUMPTIONS: | |
| - Application effort (X) and acceptance rate (p) are constant regardless of N | |
| - Applicant pool is not constrained (can always attract N/p applications for N grants) | |
| - Under these assumptions, net value % = (1 - X/(p×V)) × 100 is independent of N | |
| EXAMPLE: | |
| With 48-month grants at 10% acceptance rate and 2-month application cost: | |
| - Per grant: 48 months value - 20 months effort (10 apps × 2mo) = 58% net | |
| - Scale to any N: percentage stays 58% (funding and effort scale proportionally) | |
| Formula: Net value % = (1 - X/(p×V)) × 100 | |
| where X = app cost, p = acceptance rate, V = grant value | |
| """) | |
| end; | |
| function parse_float_list(str::String) | |
| return [parse(Float64, strip(s)) for s in split(str, ',')] | |
| end; | |
| function main() | |
| # Default values | |
| grant_value = 48.0 | |
| acceptance_rates = [0.01, 0.02, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.50] | |
| application_costs = [0.25, 0.5, 1, 1.5, 2, 2.5, 3, 4, 5, 6] | |
| # Parse command-line arguments | |
| i = 1 | |
| while i <= length(ARGS) | |
| arg = ARGS[i] | |
| if arg in ["-h", "--help"] | |
| show_help() | |
| return | |
| elseif arg == "--rates" | |
| i += 1 | |
| if i <= length(ARGS) | |
| # Parse as percentages, convert to decimals | |
| acceptance_rates = parse_float_list(ARGS[i]) ./ 100.0 | |
| else | |
| println("Error: --rates requires a value") | |
| return | |
| end | |
| elseif arg == "--costs" | |
| i += 1 | |
| if i <= length(ARGS) | |
| application_costs = parse_float_list(ARGS[i]) | |
| else | |
| println("Error: --costs requires a value") | |
| return | |
| end | |
| elseif !startswith(arg, "-") | |
| grant_value = parse(Float64, arg) | |
| else | |
| println("Error: Unknown option: $arg") | |
| println("Use --help for usage information") | |
| return | |
| end | |
| i += 1 | |
| end | |
| # Sort for better display | |
| sort!(acceptance_rates) | |
| sort!(application_costs) | |
| # Break-even rate: p = X/V | |
| function breakeven_rate(application_cost, grant_value) | |
| return application_cost / grant_value | |
| end; | |
| # Net value percentage: 1 - X/(p*V) | |
| function net_value_percentage(application_cost, acceptance_rate, grant_value) | |
| return (1.0 - application_cost / (acceptance_rate * grant_value)) * 100 | |
| end; | |
| println("=" ^ 100) | |
| println("GRANT APPLICATION BREAK-EVEN ANALYSIS") | |
| println("=" ^ 100) | |
| println("\nGrant value: $grant_value months per grant") | |
| println("Acceptance rate = grants awarded / applications received") | |
| println("\nASSUMPTION: Application effort (X months) and acceptance rate (p) are constant") | |
| println(" regardless of N grants awarded (i.e., no constraint on applicant pool).") | |
| println(" Under this assumption, funding and effort scale proportionally with N,") | |
| println(" so net value % is independent of N.\n") | |
| # Main analysis table | |
| println("=" ^ 100) | |
| println("NET COMMUNITY VALUE (% of Total Funding)") | |
| println("=" ^ 100) | |
| println("\nShows what percentage of grant funding remains as net value after accounting for") | |
| println("all applicant effort. Rightmost column shows break-even acceptance rate.\n") | |
| # Print header with column label | |
| col_width = 12 * length(acceptance_rates) | |
| @printf("%-15s", "") | |
| print(lpad("Acceptance Rate", col_width ÷ 2 + 7)) | |
| println() | |
| @printf("%-15s", "App Cost") | |
| for rate in acceptance_rates | |
| @printf("%-12s", @sprintf("%.0f%%", rate * 100)) | |
| end | |
| @printf("%-12s\n", "Break-even") | |
| println("-" ^ 100) | |
| # Print rows | |
| for cost in application_costs | |
| @printf("%-15s", @sprintf("%.2f mo", cost)) | |
| be_rate = breakeven_rate(cost, grant_value) | |
| for rate in acceptance_rates | |
| percentage = net_value_percentage(cost, rate, grant_value) | |
| if percentage >= 0 | |
| @printf("%-12s", @sprintf("%.0f%% ✓", percentage)) | |
| else | |
| @printf("%-12s", @sprintf("%.0f%% ✗", percentage)) | |
| end | |
| end | |
| @printf("%-12s\n", @sprintf("%.1f%%", be_rate * 100)) | |
| end | |
| println("-" ^ 100) | |
| println("\n✓ = positive net value (grant benefits community)") | |
| println("✗ = negative net value (applicants waste more time than grant provides)") | |
| println("Break-even = minimum acceptance rate for positive net value") | |
| end; | |
| main() | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Grant Application Break-even Analysis
Analyses whether grant opportunities create net value for the community by comparing total funding awarded vs total applicant effort.
Key Insight
Net value percentage is independent of the number of grants awarded (under the assumption that application effort (X) and acceptance rate (p) are constant regardless of N).
Whether you award 1 grant or 100 grants, the percentage of funding that remains as net community value stays the same because both funding and applicant effort scale proportionally with N (assuming no constraint on applicant pool).
Formula: Net value % = (1 - X/(p×V)) × 100
Installation
Option 1: Download once and use locally
Option 2: Run directly from URL
Useful for quick one-off analyses:
Usage Examples
Once downloaded locally:
Example Output
Default settings (48-month grants):
Interpretation
✓ marks positive net value (grant benefits community)
✗ marks negative net value (applicants waste more time than grant provides)
For example, with 48-month grants:
This analysis helps funders understand when grant opportunities help vs harm the community.
Features
--helpto see detailed explanation with worked example and formulaOptions
-h, --help: Show detailed help with worked example and formula--rates RATES: Comma-separated acceptance rates as percentages (e.g.,--rates 5,10,20,30)--costs COSTS: Comma-separated application costs in months (e.g.,--costs 1,2,3,4)GRANT_VALUE: Positional argument for months per grant (e.g.,60)Default rates: 1,2,5,10,15,20,25,30,50%
Default costs: 0.25,0.5,1,1.5,2,2.5,3,4,5,6 months
Default grant value: 48 months