[Tutor] How to refactor a simple, straightforward script into a "proper" program?

boB Stepp robertvstepp at gmail.com
Wed Jan 1 13:30:13 EST 2020


In a November thread I started, "How to type annotate complex
dictionary containing lambdas?"
(https://mail.python.org/pipermail/tutor/2019-November/115726.html), I
justifiably received multiple critiques on what an awful dictionary I
had created.  Eventually I responded that the program that that
dictionary was from (and other dictionaries like it) came from using
what originally was a very simple script which over time became rather
complex and gnarly from using it to try out different things I was
learning about over time.  At the time I started the aforementioned
thread my learning topic of the day was type annotations, and, of
course, I used my go to "simple" (Hah!) script to play around with
that concept.  So perhaps in line with D. L. Neil's "Friday Finking"
series on the main Python list, I would like to start a discussion on
how to properly transform a simple Python script into a
battle-hardened program suitable for release to the general public.

Below is my best reconstruction of what I probably originally wrote
once upon a time:

<version1.py => A simple throwaway script>
============================================================================
#!/usr/bin/env python3
"""Calculate the number of pages per day needed to read a book by a
given date."""

from datetime import date

COUNT_TODAY = 1

num_pages_in_book = int(input("How many pages are there in your book?  "))
num_pages_read = int(input("How many pages have you read?  "))
today_date = date.today()
goal_date = date.fromisoformat(
    input("What is your date to finish the book (yyyy-mm-dd)?  ")
)

days_to_goal = (goal_date - today_date).days
pages_per_day = (num_pages_in_book - num_pages_read) / (days_to_goal +
COUNT_TODAY)
print(
    "\nYou must read",
    pages_per_day,
    "pages each day (starting today) to reach your goal.",
)
============================================================================

As this script is I believe it to be easy to read and understand by an
outside reader.  For my original purposes it quickly gave me what I
wanted out of it.  But if I wanted to "give it away" to the general
public there are some things that bother me:

1)  There is no error checking.  If someone deliberately or mistakenly
enters incorrect input the program will terminate with a ValueError
exception.
2)  There are no checks for logic errors.  For instance, a person
could enter a goal date that is prior to today or enter a date in the
future that falls well beyond any human's possible lifespan (with
current technology).
3)  There is no formatting of output.  It is possible to generate
float output with many decimal places, something most users would not
want to see.  And does it make any sense to have non-integral numbers
of pages anyway?
4)  There are duplicated patterns of input in the code as is.  Surely
that duplication could be removed?
5)  A minor, but bothersome quibble:  If the reader need only read one
page per day, the program would display an annoying "... 1.0 pages
...", which is grammatically incorrect.
6)  There are no tests, which makes it more difficult to grow/maintain
the program in the future.
7)  The user must restart the program each time he/she wishes to try
out different goal dates.
8)  [Optional] There are no type annotations.

So I am curious as to how you pros would approach the refactoring
process.  I think that such a demonstration would surely be
educational for myself, and hopefully others.  But I do realize that
everyone does their thing voluntarily and my thoughts might not align
with yours.  So I am *hoping* a few experts go along with this, but,
regardless, in typical boB fashion I will plow away and post my future
efforts to transform version1.py into something more robust.  Then
those that wish to can critique version2.py leading ultimately to
version-who-knows-what.py ...

Anyway, it seems like a useful New Year's exercise that might actually
be helpful.

HAPPY NEW YEAR TO YOU AND YOURS!!!

-- 
boB


More information about the Tutor mailing list