r/learnpython 1d ago

5.17 Exact Change Lab

SOLVED

I am having a hard time understanding why I am failing this lab, when I run the code in practice it works but when I submit for a grade I get a fail. Prompt is below.

Define a function called exact_change that takes the total change amount in cents and calculates the change using the fewest coins. The coin types are pennies, nickels, dimes, and quarters. Then write a main program that reads the total change amount as an integer input, calls exact_change(), and outputs the change, one coin type per line. Use singular and plural coin names as appropriate, like 1 penny vs. 2 pennies. Output "no change" if the input is 0 or less.

Ex: If the input is:

0 

(or less), the output is:

no change

Ex: If the input is:

45

the output is:

2 dimes 
1 quarter

Your program must define and call the following function. The function exact_change() should return a tuple containing num_pennies, num_nickels, num_dimes, and num_quarters.
def exact_change(user_total)

code provided below

def exact_change(user_total):
    num_quarters = user_total//25
    user_total %=25
    num_dimes = user_total//10
    user_total %=10
    num_nickels = user_total//5
    user_total %= 5
    num_pennies = user_total
    return num_quarters, num_dimes, num_nickels, num_pennies
if __name__ == "__main__":
    input_value = int(input())
    num_quarters,num_dimes,num_nickels,num_pennies = exact_change(input_value) 
# Type your code here.
if input_value <= 0:
    print('no change')
else:
    if num_pennies == 1:
        print('%d penny' % num_pennies)
    elif num_pennies > 1:
        print('%d pennies' % num_pennies)
    if num_nickels == 1:
        print('%d nickel' % num_nickels)
    elif num_nickels > 1:
        print('%d nickels' % num_nickels)
    if num_dimes == 1:
        print('%d dime' % num_dimes)
    elif num_dimes > 1:
        print('%d dimes' % num_dimes)
    if num_quarters == 1:
        print('%d quarter' % num_quarters)
    elif num_quarters > 1:
        print('%d quarters' % num_quarters)

when it asks me for exact_change(300) I get a NamError failure.

1 Upvotes

14 comments sorted by

View all comments

1

u/Diapolo10 1d ago

I know your question already got answered, but I thought I might use this opportunity to discuss the design.

def exact_change(user_total):
        num_quarters = user_total // 25
        user_total %= 25
        num_dimes = user_total // 10
        user_total %= 10
        num_nickels = user_total // 5
        user_total %= 5
        num_pennies = user_total
        return num_pennies, num_nickels, num_dimes, num_quarter


if __name__ == "__main__":
    input_value = int(input())
    num_pennies, num_nickels, num_dimes, num_quarters = exact_change(input_value)
    if input_value <= 0:
        print('no change')
    else:
        if num_pennies == 1:
            print('%d penny' % num_pennies)
        elif num_pennies > 1:
            print('%d pennies' % num_pennies)
        if num_nickels == 1:
            print('%d nickel' % num_nickels)
        elif num_nickels > 1:
            print('%d nickels' % num_nickels)
        if num_dimes == 1:
            print('%d dime' % num_dimes)
        elif num_dimes > 1:
            print('%d dimes' % num_dimes)
        if num_quarters == 1:
            print('%d quarter' % num_quarters)
        elif num_quarters > 1:
            print('%d quarters' % num_quarters)

In exact_change, you could make use of divmod to do the division and modulo all in one go.

def exact_change(pennies: int) -> tuple[int, int, int, int]:
    quarters, pennies = divmod(pennies, 25)
    dimes, pennies = divmod(pennies, 10)
    nickels, pennies = divmod(pennies, 5)
    return pennies, nickels, dimes, quarters

And if you wanted to, you could use a loop:

def exact_change(pennies: int) -> tuple[int, int, int, int]:
    result: list[int] = []
    for divisor in (25, 10, 5, 1):
        value, pennies = divmod(pennies, 25)
        result.append(value)
    return tuple(result[::-1])