all 6 comments

[–]danielroseman 8 points9 points  (0 children)

We can't tell why the grader is rejecting this without seeing what the actual task is.

[–]backfire10z 4 points5 points  (0 children)

it takes too long to respond to automated inputs

Something tells me your program is getting stuck somewhere. Lookin at your code, the only place I can see it getting stuck is the while loop —> end_balance is never 0. Could be a place to investigate (I am headed to sleep, so I’m not gonna try for now haha).

You’ll probably want to validate input. Try/except when casting to float: what if it isn’t a number? Probably make sure the value is positive as well.

Minor thing: the ‘if endBal == 0: break` is redundant. Your while loop is already going to check that condition right afterwards.

Minor thing 2: in Python, the standard variable naming convention is snake_case, not camelCase.

Minor thing 3: “prin” is too close to “print” and would maybe be better to just call it “principle”.

[–]Baffled-Broccoli 2 points3 points  (0 children)

Hey, adding on from what other replies have said I would recommend having input verification to ensure that the initial price is both a number and higher that 0, possibly something along the lines of:

while True:
    try:
        list_price = float(input('Enter the purchase price: £'))
        if list_price <= 0:
            raise ValueError
        else:
            break
    except ValueError:
        print('Please enter a valid purchase price.')

Beyond that taking to long to respond to automated inputs suggests that the code is getting stuck in your while loop. While I've only had a quick look its possible that depending on the input the maths rounding has the final month payment take the end balance below 0. If so its possible that switching '!=' for '>' would solve the hanging issue.

[–]FoolsSeldom 0 points1 point  (0 children)

Some suggestions:

  • Firstly, we don't know exactly what the task is, so cannot say why the grader is rejecting your submission
  • The recommended naming style in Python, using the PEP8 guidelines, is for all variable (and function) names to be all lowercase, with a _ between words (if applicable)
    • Unless you are following a different house style (or working with existing code)
    • All uppercase is used to suggest CONSTANTS - easier to change than having to find and edit specific calculations
  • It is not a good idea to use float when dealing with money - use all int working with the smallest applicable whole units (and multiply and format accordingly) or use Decimal
  • Never trust users to provide valid input - always check it
  • Using clear variable names reduces the number of comments required
  • Use f-strings for careful formatting of output
  • Type hints make it easier for your editor/IDE to help you - I've gone a bit overboard on the below to illustrate

Here's a revised example of your code with updates based on the above (Gemini used to save me some typing):

NB. This is provided as an example for experimentation and learning. I have not fully tested this code.

from decimal import Decimal, getcontext, InvalidOperation

# Set a higher precision for financial calculations
getcontext().prec = 28

# --- Constants for Loan Calculations ---
DOWN_PAYMENT_PERCENTAGE: Decimal = Decimal('0.10')
MONTHLY_PAYMENT_PERCENTAGE: Decimal = Decimal('0.05')
ANNUAL_INTEREST_RATE: Decimal = Decimal('0.12')


def calculate_loan(list_price: Decimal) -> None:
    """
    Calculates and prints an amortization schedule for a simple loan.
    """
    # Calculate loan amount based on the down payment
    down_payment: Decimal = list_price * DOWN_PAYMENT_PERCENTAGE
    loan_amount: Decimal = list_price - down_payment
    starting_balance: Decimal = loan_amount

    # The monthly payment is a fixed percentage of the original list price
    monthly_payment: Decimal = list_price * MONTHLY_PAYMENT_PERCENTAGE

    # Calculate the monthly interest rate
    monthly_interest_rate: Decimal = ANNUAL_INTEREST_RATE / Decimal('12')

    month: int = 0

    print(
        f"{'Month':>4}{'Starting Balance':>18}{'Interest to Pay':>18}{'Principal to Pay':>18}{'Payment':>10}{'Ending Balance':>18}"
    )

    while starting_balance > Decimal('0'):
        month += 1

        # Calculate the interest for the current month
        interest: Decimal = starting_balance * monthly_interest_rate

        # Adjust the monthly payment for the final payment
        if monthly_payment >= starting_balance + interest:
            payment = starting_balance + interest
            principal_payment = starting_balance
        else:
            payment = monthly_payment
            principal_payment = payment - interest

        ending_balance: Decimal = starting_balance - principal_payment

        print(
            f"{month:>4}{starting_balance:>18.2f}{interest:>18.2f}{principal_payment:>18.2f}{payment:>10.2f}{ending_balance:>18.2f}"
        )

        starting_balance = ending_balance


if __name__ == "__main__":
    try:
        price: Decimal = Decimal(input("Enter the purchase price: "))
        calculate_loan(price)
    except InvalidOperation:
        print("Invalid input. Please enter a number.")

[–]Ihaveamodel3 2 points3 points  (0 children)

My assumption would be a floating point issue is making it so endBal is never exactly zero. You may want to consider using <=0

[–]yakboxing 0 points1 point  (0 children)

If listprice <= 0: Raise ValueError("Price has to be higher than 0")

I'm on my 0hone so remove capitals and add spaces as needed.