12.07.2015 Views

Think Python - Denison University

Think Python - Denison University

Think Python - Denison University

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

156 Chapter 16. Classesand functions16.4 Prototypingversus planningThe development plan I am demonstrating is called “prototype and patch.” For each function, Iwrote a prototype that performed the basic calculation and then tested it, patching errors along theway.Thisapproachcanbeeffective,especiallyifyoudon’tyethaveadeepunderstandingoftheproblem.Butincrementalcorrectionscangeneratecodethatisunnecessarilycomplicated—sinceitdealswithmany special cases—and unreliable—since it ishardtoknow ifyou have found allthe errors.An alternative is planned development, in which high-level insight into the problem can make theprogrammingmucheasier. Inthiscase,theinsightisthataTimeobjectisreallyathree-digitnumberinbase60(seewikipedia.org/wiki/Sexagesimal.)! Thesecondattributeisthe“onescolumn,”the minute attribute is the “sixties column,” and the hour attribute is the “thirty-six hundreds column.”When we wroteadd_timeandincrement,we were effectively doing addition in base 60, which iswhy we had tocarryfrom one column tothenext.This observation suggests another approach to the whole problem—we can convert Time objects tointegers and take advantage of the fact that thecomputer knows how todo integer arithmetic.Here isafunction that converts Times tointegers:def time_to_int(time):minutes = time.hour * 60 + time.minuteseconds = minutes * 60 + time.secondreturn secondsAndhereisthefunctionthatconvertsintegerstoTimes(recallthatdivmoddividesthefirstargumentby thesecond and returns thequotient and remainder as atuple).def int_to_time(seconds):time = Time()minutes, time.second = divmod(seconds, 60)time.hour, time.minute = divmod(minutes, 60)return timeYou might have to think a bit, and run some tests, to convince yourself that these functions arecorrect. One way to test them is to check that time_to_int(int_to_time(x)) == x for manyvalues ofx. Thisis anexample of aconsistency check.Once you areconvinced they are correct, you can use them torewriteadd_time:def add_time(t1, t2):seconds = time_to_int(t1) + time_to_int(t2)return int_to_time(seconds)This version isshorter than theoriginal, and easier toverify.Exercise 16.5 Rewriteincrementusingtime_to_intandint_to_time.In some ways, converting from base 60 to base 10 and back is harder than just dealing with times.Base conversion ismoreabstract; our intuitionfordealing withtimevalues isbetter.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!