Created
November 29, 2024 04:48
-
-
Save Jon-dog/c6e1165c055040a7cd9b2a5a6e731019 to your computer and use it in GitHub Desktop.
Annual vs monthly cost calculator
This file contains 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
def calc_rate_offset(monthly_cost, annual_cost, tolerance=1e-8): | |
""" | |
Find the monthly interest rate needed to offset the cost difference | |
between monthly and annual plans. | |
""" | |
total_monthly = 12 * monthly_cost | |
diff = total_monthly - annual_cost # Extra cost to offset | |
# If there's no meaningful difference, no interest rate is needed | |
if diff <= 0: | |
print("Monthly plan is cheaper or equal to the annual plan.") | |
return 0.0 | |
# Binary search bounds | |
lower_rate = 0.0 | |
upper_rate = 1.0 | |
best_rate = None | |
min_diff = float("inf") | |
iteration = 0 # Track iterations for debugging | |
def debug_output(iteration, lower, upper, mid, balance, interest_earned): | |
"""Optional: Print debug information for each iteration.""" | |
print(f"Iteration {iteration}:") | |
print( | |
f" Lower Rate: {lower:.6f}, Upper Rate: {upper:.6f}, Mid Rate: {mid:.6f}" | |
) | |
print( | |
f" Final Balance: {balance:.2f}, Total Interest Earned: {interest_earned:.2f}, Target: {diff:.2f}" | |
) | |
# Binary search loop | |
while upper_rate - lower_rate > tolerance: | |
mid_rate = (lower_rate + upper_rate) / 2 | |
balance = total_monthly | |
total_interest = 0.0 | |
# Simulate monthly accrual and deductions | |
for month in range(12): | |
interest = balance * mid_rate | |
total_interest += interest | |
balance += interest - monthly_cost | |
# Check if this rate is the closest to the target difference | |
current_diff = abs(total_interest - diff) | |
if current_diff < min_diff: | |
min_diff = current_diff | |
best_rate = mid_rate | |
# Debugging: Report balance and rate bounds | |
debug_output( | |
iteration, lower_rate, upper_rate, mid_rate, balance, total_interest | |
) | |
# Adjust rate bounds based on final balance | |
if total_interest > diff: | |
upper_rate = mid_rate | |
else: | |
lower_rate = mid_rate | |
iteration += 1 | |
monthly_after_interest = total_monthly - total_interest | |
# Summary | |
print("\nSummary:") | |
print(f" Total Interest Earned: {total_interest:.2f}") | |
print(f" Total Monthly Cost After Interest Offset: {monthly_after_interest:.2f}") | |
print(f" Cost Difference: {diff:.2f}") | |
print(f" Annual Cost: {annual_cost:.2f}") | |
print(f"\nSearch completed in {iteration} iterations.") | |
return best_rate | |
try: | |
monthly_cost = float(input("Enter the monthly subscription cost: ")) | |
annual_cost = float(input("Enter the annual subscription cost: ")) | |
required_interest_rate = calc_rate_offset(monthly_cost, annual_cost) | |
if required_interest_rate is not None: | |
annual_interest_rate = (1 + required_interest_rate) ** 12 - 1 | |
print(f"Annual Interest Rate: {annual_interest_rate * 100:.3f}%") | |
print(f"Monthly Interest Rate: {required_interest_rate * 100:.4f}%") | |
else: | |
print("No valid interest rate found.") | |
except ValueError: | |
print("Invalid input. Please enter numeric values.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment