adpkg

A package containing Python mo...
Log | Files | Refs | README | LICENSE

finance.py (5125B)


      1 # This module contains an interest calculator
      2 # Formula used for compound interest: A = P * (1 + r / n) ** (n * t)
      3 
      4 def interest(prime_amount, time_duration_str, number_of_times_interest_will_compound_per_year, rate_of_interest) :
      5     """
      6     Calculates the compound interest.
      7 
      8     Args:
      9         prime_amount (float or int): The initial principal amount (P).
     10         time_duration_str (str): The duration for which the interest is calculated,
     11                                  **must be in specific short-hand formats**:
     12                                  - "XyYm" (e.g., "5y6m", "1y8m" for 1 year 8 months)
     13                                  - "Xm" (e.g., "15m", "6m" for 15 months, 6 months)
     14                                  - "Xy" (e.g., "5y", "1y" for 5 years, 1 year)
     15                                  Where X and Y are whole numbers.
     16         number_of_times_interest_will_compound_per_year (float or int):
     17             The number of times interest is compounded per year (n).
     18             (e.g., 2 for half-yearly, 4 for quarterly, 12 for monthly, 365 for daily).
     19         rate_of_interest (float or int): The annual nominal interest rate (as a percentage, e.g., 5 for 5%).
     20 
     21     Returns:
     22         float: The compound interest amount earned, rounded to 3 decimal places.
     23         None: If the input is not valid or any error occurs.
     24     """
     25 
     26     # Convert and validate numeric inputs (P, N, R)
     27     try:
     28         p = float(prime_amount)
     29         n = float(number_of_times_interest_will_compound_per_year)
     30         r = float(rate_of_interest)
     31     except ValueError:
     32         print('Error: Please enter valid numbers (integer or float) for Prime Amount, Compounding Frequency, and Rate of Interest.')
     33         return None
     34     except Exception as error:
     35         print(f'An unexpected error happened during initial input conversion: {error}')
     36         return None
     37 
     38     # Parse and validate 'time_duration_str' without 're' module
     39     total_time_in_years = 0.0
     40     # Normalize input string for consistent parsing
     41     time_str_normalized = str(time_duration_str).lower().strip()
     42 
     43     years = 0
     44     months = 0
     45     is_valid_format = False
     46 
     47     if 'y' in time_str_normalized and 'm' in time_str_normalized:
     48         # Potentially XyYm format
     49         y_index = time_str_normalized.find('y')
     50         m_index = time_str_normalized.find('m')
     51 
     52         if y_index != -1 and m_index != -1 and y_index < m_index:
     53             years_part = time_str_normalized[:y_index]
     54             months_part = time_str_normalized[y_index + 1 : m_index]
     55 
     56             if years_part.isdigit() and months_part.isdigit():
     57                 years = int(years_part)
     58                 months = int(months_part)
     59                 total_time_in_years = years + (months / 12.0)
     60                 is_valid_format = True
     61     
     62     if not is_valid_format: # If XyYm wasn't matched or was invalid, try other formats
     63         if time_str_normalized.endswith('m') and 'y' not in time_str_normalized:
     64             # Format: Xm
     65             months_part = time_str_normalized[:-1] # Remove 'm'
     66             if months_part.isdigit():
     67                 months = int(months_part)
     68                 total_time_in_years = months / 12.0
     69                 is_valid_format = True
     70         elif time_str_normalized.endswith('y') and 'm' not in time_str_normalized:
     71             # Format: Xy
     72             years_part = time_str_normalized[:-1] # Remove 'y'
     73             if years_part.isdigit():
     74                 years = int(years_part)
     75                 total_time_in_years = float(years)
     76                 is_valid_format = True
     77     
     78     if not is_valid_format:
     79         print(f"Error: Invalid time duration format: '{time_duration_str}'.")
     80         print("Please use formats like '5y6m', '15m', or '5y'.")
     81         return None
     82     
     83     # Final validation for parsed time
     84     if total_time_in_years <= 0:
     85         print('Error: Time duration must be a positive value.')
     86         return None
     87 
     88     # Validate other numeric data (after time parsing, before main logic)
     89     if p <= 0:
     90         print('Error: Prime amount should be greater than Zero.')
     91         return None
     92     if n <= 0:
     93         print('Error: The number of times the interest will compound per year should be greater than Zero.')
     94         return None
     95     if r <= 0:
     96         print('Error: Rate of Interest should be greater than Zero.')
     97         return None
     98 
     99     # Main calculation logic
    100     try :
    101         r_decimal = r / 100.0  # Change percentage to decimal (using 100.0 for float division)
    102 
    103         # Calculate the total amount after compounding with full precision
    104         total_amount_precise = p * (1 + r_decimal / n) ** (n * total_time_in_years)
    105 
    106         # Calculate the compound interest with full precision
    107         compound_interest_precise = total_amount_precise - p
    108 
    109         # Round the final interest amount to 3 decimal places before returning
    110         result = round(compound_interest_precise, 3)
    111 
    112         return result
    113 
    114     except Exception as error :
    115         print(f'An unexpected error happened during calculation: {error}')
    116         return None
© notamitgamer • Site Built: 2026-07-21 13:58:23 UTC • git-mirror commit: 1037f62 [view raw info]
Originally created with stagit • modified by notamitgamer
Forked from github.com/notamitgamer/git-mirror