python workout: exercise 3
run timing
problem
For this exercise, then, we’ll assume that you run 10 km each day as part of your exercise regime. You want to know how long, on average, that run takes.
Write a function (
run_timing) that asks how long it took for you to run 10 km. The function continues to ask how long (in minutes) it took for additional runs, until the user presses Enter. At that point, the function exits—but only after calculating and displaying the average time that the 10 km runs took.For example, here’s what the output would look like if the user entered three data points:
Enter 10 km run time: 15 Enter 10 km run time: 20 Enter 10 km run time: 10 Enter 10 km run time: <enter> Average of 15.0, over 3 runsNote that the numeric inputs and outputs should all be floating-point values.
attempts
Off the top of my head, I’d write something like:
def run_timing():
run_times, n_runs = 0.0, 0
while True:
try:
run_time = float(input("Enter 10km run time: "))
except ValueError:
break
else:
n_runs += 1
run_times += run_time
print(f"Average of {run_times/n_runs:.2f}, over {n_runs} runs")
We need the except block to handle the
<enter>.
Keep in mind this function will actually return on any input that can’t be cast
to float not just on <enter>. We could do this by adding a conditional on the input string
before casting to float but why not keep things as is
for now?
solution
The book’s implementation:
def run_timing():
"""
Asks the user repeatedly for numeric input. Prints the average time an
d number of runs.
"""
number_of_runs = 0
total_time = 0
while True:
one_run = input('Enter 10 km run time: ')
if not one_run:
break
number_of_runs += 1
total_time += float(one_run)
average_time = total_time / number_of_runs
print(f'Average of {average_time}, over {number_of_runs} runs')
beyond the exercise
before & after
-
problem
Write a function that takes a
floatand two integers (beforeandafter). The function should return afloatconsisting ofbeforedigits before the decimal point andafterdigits after. Thus, if we call the function with1234.5678,2and3, the return value should be34.567.
-
attempts
We can just convert the float to a string, split on the dot, and use string indexing:
def subfloat(n: float, before: int, after: int) -> float: before_digits, after_digits = str(n).split(".") return float(f"{before_digits[-before:]}.{after_digits[:after]}") print(subfloat(1234.5678, 2, 3))34.567
decimal class
-
problem
Explore the
Decimalclass (http://mng.bz/oPVr), which has an alternative floating-point representation that’s as accurate as any decimal number can be. Write a function that takes two strings from the user, turns them intodecimalinstances, and then prints the floating-point sum of the user’s two inputs. In other words, make it possible for the user to enter0.1and0.2, and for us to get0.3back.
-
attempts
I’ve played around with
Decimal== before - time to use it again!from decimal import Decimal def decimal_sum(n1: str, n2: str) -> float: return float(Decimal(n1)+Decimal(n2)) print(decimal_sum('0.1', '0.2'))0.3Job done!