[currency-exchange] task 3 duck typing vs strict type

I’m struggling with the proper Pythonic guidance to give to my first mentee in the currency-exchange exercise.

My mentee asked about their solution to Task 6 and use of a type conversion in a calculation that is different from the exemplar solution, but still sufficient. I thought guiding them towards the exemplar solution would address their type concerns - as the exemplar use of get_number_of_bills should result in an int - as well as emphasize code reuse. They repeated concern about returning an int which caused me to look closer at the task and both of our solutions.

Current tests for get_number_of_bills use only ints for input. For floor division (//) in get_number_of_bills, this will always result in an int. The exemplar solution performs a type conversion on the amount to enforce this, as the denomination is assumed to be an int as well. Regardless, the test will succeed regardless of type as long as the value is correct, as it does not test type and Python will compare values between float and int. I noticed my and my mentee’s solution for get_number_of_bills (amount // denomination) pass tests but return a float.

I’m trying to understand the Pythonic response to this to educate myself. Should the tests validate the return type is int per the intent in docstring? Or does the principle of duck typing mean that a float-type is okay, as long as the calculated result (with the understanding of how int conversion or floor division works with floats) equals the specified integer value?

Given that the tests embody the requirements (and changing that test is liable to break a bunch of working solutions), I would suggest that returning an int is nice but certainly not required.

If this were production code, I would personally be using type annotations. That would require that either (1) the inputs are explicitly typed as ints, and would catch any place it’s called with a float, or (2) that the return value be typed explicitly as a float.