<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://ideawaza.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=82.32.0.0%2F16</id>
	<title>IdeaWazaWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://ideawaza.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=82.32.0.0%2F16"/>
	<link rel="alternate" type="text/html" href="https://ideawaza.com/wiki/Special:Contributions/82.32.0.0/16"/>
	<updated>2026-09-29T18:09:34Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://ideawaza.com/index.php?title=Archive:Think_Python/Classes_and_functions&amp;diff=52249</id>
		<title>Archive:Think Python/Classes and functions</title>
		<link rel="alternate" type="text/html" href="https://ideawaza.com/index.php?title=Archive:Think_Python/Classes_and_functions&amp;diff=52249"/>
		<updated>2008-10-06T21:26:32Z</updated>

		<summary type="html">&lt;p&gt;82.32.51.70: /* Chapter&amp;amp;#XA0;16&amp;amp;#XA0;&amp;amp;#XA0;Classes and functions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Think Python/Page}}&lt;br /&gt;
&lt;br /&gt;
== Chapter 16 Classes and functions ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 16.1 Time ===&lt;br /&gt;
&lt;br /&gt;
As another example of a user-defined type, we&#039;ll define a class called&lt;br /&gt;
&amp;lt;TT&amp;gt;Time&amp;lt;/TT&amp;gt; that records the time of day. The class definition looks&lt;br /&gt;
like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;class Time(object):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;represents the time of day.&lt;br /&gt;
       attributes: hour, minute, second&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
We can create a new &amp;lt;TT&amp;gt;Time&amp;lt;/TT&amp;gt; object and assign&lt;br /&gt;
attributes for hours, minutes, and seconds:&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;time = Time()&lt;br /&gt;
time.hour = 11&lt;br /&gt;
time.minute = 59&lt;br /&gt;
time.second = 30&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
The state diagram for the &amp;lt;TT&amp;gt;Time&amp;lt;/TT&amp;gt; object looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;DIV CLASS=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;IMG SRC=&amp;quot;book025.png&amp;quot;&amp;gt;&amp;lt;/DIV&amp;gt;&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;1&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;&#039;&lt;br /&gt;
Write a function called &#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;print_time&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039; that takes a &lt;br /&gt;
Time object and prints it in the form &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;hour:minute:second&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039;.&lt;br /&gt;
Hint: the format sequence &#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;&#039;%.2d&#039;&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039; prints an integer using&lt;br /&gt;
at least two digits, including a leading zero if necessary.&lt;br /&gt;
&#039;&#039;&amp;lt;/DIV&amp;gt;&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;2&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&#039;&#039;&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Write a boolean function called &#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;is_after&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039; that&lt;br /&gt;
takes two Time objects, &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;t1&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; and &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;t2&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039;, and&lt;br /&gt;
returns &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;True&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; if &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;t1&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; follows &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;t2&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; chronologically and&lt;br /&gt;
&#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;False&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; otherwise. Challenge: don&amp;amp;#X2019;t use an &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;if&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; statement.&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&amp;lt;/DIV&amp;gt;=== 16.2&amp;amp;#XA0;&amp;amp;#XA0;Pure functions ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In the next few sections, we&amp;amp;#X2019;ll write two functions that add time&lt;br /&gt;
values. They demonstrate two kinds of functions: pure functions and&lt;br /&gt;
modifiers. They also demonstrate a development plan I&amp;amp;#X2019;ll call &#039;&#039;&#039;prototype and patch&#039;&#039;&#039;, which is a way of tackling a complex problem&lt;br /&gt;
by starting with a simple prototype and incrementally dealing with the&lt;br /&gt;
complications.&lt;br /&gt;
&lt;br /&gt;
Here is a simple prototype of &amp;lt;CODE&amp;gt;add_time&amp;lt;/CODE&amp;gt;:&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def add_time(t1, t2):&lt;br /&gt;
    sum = Time()&lt;br /&gt;
    sum.hour = t1.hour + t2.hour&lt;br /&gt;
    sum.minute = t1.minute + t2.minute&lt;br /&gt;
    sum.second = t1.second + t2.second&lt;br /&gt;
    return sum&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
The function creates a new &amp;lt;TT&amp;gt;Time&amp;lt;/TT&amp;gt; object, initializes its&lt;br /&gt;
attributes, and returns a reference to the new object. This is called&lt;br /&gt;
a &#039;&#039;&#039;pure function&#039;&#039;&#039; because it does not modify any of the objects&lt;br /&gt;
passed to it as arguments and it has no effect,&lt;br /&gt;
like displaying a value or getting user input, &lt;br /&gt;
other than returning a value.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
To test this function, I&amp;amp;#X2019;ll create two Time objects: &amp;lt;TT&amp;gt;start&amp;lt;/TT&amp;gt;&lt;br /&gt;
contains the start time of a movie, like &#039;&#039;Monty Python and the&lt;br /&gt;
Holy Grail&#039;&#039;, and &amp;lt;TT&amp;gt;duration&amp;lt;/TT&amp;gt; contains the run time of the movie,&lt;br /&gt;
which is one hour 35 minutes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;CODE&amp;gt;add_time&amp;lt;/CODE&amp;gt; figures out when the movie will be done.&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; start = Time()&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; start.hour = 9&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; start.minute = 45&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; start.second =  0&lt;br /&gt;
&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; duration = Time()&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; duration.hour = 1&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; duration.minute = 35&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; duration.second = 0&lt;br /&gt;
&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; done = add_time(start, duration)&lt;br /&gt;
&amp;amp;gt;&amp;amp;gt;&amp;amp;gt; print_time(done)&lt;br /&gt;
10:80:00&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
The result, &amp;lt;TT&amp;gt;10:80:00&amp;lt;/TT&amp;gt; might not be what you were hoping&lt;br /&gt;
for. The problem is that this function does not deal with cases where the&lt;br /&gt;
number of seconds or minutes adds up to more than sixty. When that&lt;br /&gt;
happens, we have to &amp;amp;#X201C;carry&amp;amp;#X201D; the extra seconds into the minute column&lt;br /&gt;
or the extra minutes into the hour column.&lt;br /&gt;
&lt;br /&gt;
Here&amp;amp;#X2019;s an improved version:&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def add_time(t1, t2):&lt;br /&gt;
    sum = Time()&lt;br /&gt;
    sum.hour = t1.hour + t2.hour&lt;br /&gt;
    sum.minute = t1.minute + t2.minute&lt;br /&gt;
    sum.second = t1.second + t2.second&lt;br /&gt;
&lt;br /&gt;
    if sum.second &amp;amp;gt;= 60:&lt;br /&gt;
        sum.second -= 60&lt;br /&gt;
        sum.minute += 1&lt;br /&gt;
&lt;br /&gt;
    if sum.minute &amp;amp;gt;= 60:&lt;br /&gt;
        sum.minute -= 60&lt;br /&gt;
        sum.hour += 1&lt;br /&gt;
&lt;br /&gt;
    return sum&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
Although this function is correct, it is starting to get big.&lt;br /&gt;
We will see a shorter alternative later.&lt;br /&gt;
=== 16.3&amp;amp;#XA0;&amp;amp;#XA0;Modifiers ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sometimes it is useful for a function to modify the objects it gets as&lt;br /&gt;
parameters. In that case, the changes are visible to the caller.&lt;br /&gt;
Functions that work this way are called &#039;&#039;&#039;modifiers&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;TT&amp;gt;increment&amp;lt;/TT&amp;gt;, which adds a given number of seconds to a &amp;lt;TT&amp;gt;Time&amp;lt;/TT&amp;gt;&lt;br /&gt;
object, can be written naturally as a&lt;br /&gt;
modifier. Here is a rough draft:&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def increment(time, seconds):&lt;br /&gt;
    time.second += seconds&lt;br /&gt;
&lt;br /&gt;
    if time.second &amp;amp;gt;= 60:&lt;br /&gt;
        time.second -= 60&lt;br /&gt;
        time.minute += 1&lt;br /&gt;
&lt;br /&gt;
    if time.minute &amp;amp;gt;= 60:&lt;br /&gt;
        time.minute -= 60&lt;br /&gt;
        time.hour += 1&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
The first line performs the basic operation; the remainder deals&lt;br /&gt;
with the special cases we saw before.&lt;br /&gt;
&lt;br /&gt;
Is this function correct? What happens if the parameter &amp;lt;TT&amp;gt;seconds&amp;lt;/TT&amp;gt;&lt;br /&gt;
is much greater than sixty? &lt;br /&gt;
&lt;br /&gt;
In that case, it is not enough to carry&lt;br /&gt;
once; we have to keep doing it until &amp;lt;TT&amp;gt;time.second&amp;lt;/TT&amp;gt; is less than sixty.&lt;br /&gt;
One solution is to replace the &amp;lt;TT&amp;gt;if&amp;lt;/TT&amp;gt; statements with &amp;lt;TT&amp;gt;while&amp;lt;/TT&amp;gt;&lt;br /&gt;
statements. That would make the function correct, but not&lt;br /&gt;
very efficient.&lt;br /&gt;
&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;3&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&#039;&#039;&lt;br /&gt;
Write a correct version of &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;increment&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; that&lt;br /&gt;
doesn&amp;amp;#X2019;t contain any loops.&lt;br /&gt;
&#039;&#039;&amp;lt;/DIV&amp;gt;&lt;br /&gt;
Anything that can be done with modifiers can also be done with pure&lt;br /&gt;
functions. In fact, some programming languages only allow pure&lt;br /&gt;
functions. There is some evidence that programs that use pure&lt;br /&gt;
functions are faster to develop and less error-prone than programs&lt;br /&gt;
that use modifiers. But modifiers are convenient at times,&lt;br /&gt;
and functional programs tend to be less efficient.&lt;br /&gt;
&lt;br /&gt;
In general, I recommend that you write pure functions whenever it is&lt;br /&gt;
reasonable and resort to modifiers only if there is a compelling&lt;br /&gt;
advantage. This approach might be called a &#039;&#039;&#039;functional&lt;br /&gt;
programming style&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;4&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&#039;&#039;&lt;br /&gt;
Write a &amp;amp;#X201C;pure&amp;amp;#X201D; version of &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;increment&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; that creates and returns&lt;br /&gt;
a new Time object rather than modifying the parameter.&lt;br /&gt;
&#039;&#039;&amp;lt;/DIV&amp;gt;=== 16.4&amp;amp;#XA0;&amp;amp;#XA0;Prototyping versus planning ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The development plan I am demonstrating is called &amp;amp;#X201C;prototype and&lt;br /&gt;
patch.&amp;amp;#X201D; For each function, I wrote a prototype that performed the&lt;br /&gt;
basic calculation and then tested it, patching errors along the&lt;br /&gt;
way.&lt;br /&gt;
&lt;br /&gt;
This approach can be effective, especially if you don&amp;amp;#X2019;t yet have a&lt;br /&gt;
deep understanding of the problem. But incremental corrections can&lt;br /&gt;
generate code that is unnecessarily complicated&amp;amp;#X2014;since it deals with&lt;br /&gt;
many special cases&amp;amp;#X2014;and unreliable&amp;amp;#X2014;since it is hard to know if you&lt;br /&gt;
have found all the errors.&lt;br /&gt;
&lt;br /&gt;
An alternative is &#039;&#039;&#039;planned development&#039;&#039;&#039;, in which high-level&lt;br /&gt;
insight into the problem can make the programming much easier. In&lt;br /&gt;
this case, the insight is that a Time object is really a three-digit&lt;br /&gt;
number in base 60 (see &amp;lt;TT&amp;gt;wikipedia.org/wiki/Sexagesimal&amp;lt;/TT&amp;gt;)! The&lt;br /&gt;
&amp;lt;TT&amp;gt;second&amp;lt;/TT&amp;gt; attribute is the &amp;amp;#X201C;ones column,&amp;amp;#X201D; the &amp;lt;TT&amp;gt;minute&amp;lt;/TT&amp;gt;&lt;br /&gt;
attribute is the &amp;amp;#X201C;sixties column,&amp;amp;#X201D; and the &amp;lt;TT&amp;gt;hour&amp;lt;/TT&amp;gt; attribute is&lt;br /&gt;
the &amp;amp;#X201C;thirty-six hundreds column.&amp;amp;#X201D;&lt;br /&gt;
&lt;br /&gt;
When we wrote &amp;lt;CODE&amp;gt;add_time&amp;lt;/CODE&amp;gt; and &amp;lt;TT&amp;gt;increment&amp;lt;/TT&amp;gt;, we were effectively&lt;br /&gt;
doing addition in base 60, which is why we had to carry from one&lt;br /&gt;
column to the next.&lt;br /&gt;
&lt;br /&gt;
This observation suggests another approach to the whole problem&amp;amp;#X2014;we&lt;br /&gt;
can convert Time objects to integers and take advantage of the fact&lt;br /&gt;
that the computer knows how to do integer arithmetic. &lt;br /&gt;
&lt;br /&gt;
Here is a function that converts Times to integers:&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def time_to_int(time):&lt;br /&gt;
    minutes = time.hour * 60 + time.minute&lt;br /&gt;
    seconds = minutes * 60 + time.second&lt;br /&gt;
    return seconds&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
And here is the function that converts integers to Times&lt;br /&gt;
(recall that &amp;lt;TT&amp;gt;divmod&amp;lt;/TT&amp;gt; divides the first argument by the second&lt;br /&gt;
and returns the quotient and remainder as a tuple).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def int_to_time(seconds):&lt;br /&gt;
    time = Time()&lt;br /&gt;
    minutes, time.second = divmod(seconds, 60)&lt;br /&gt;
    time.hour, time.minute = divmod(minutes, 60)&lt;br /&gt;
    return time&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
You might have to think a bit, and run some tests, to convince&lt;br /&gt;
yourself that these functions are correct. One way to test them is to&lt;br /&gt;
check that &amp;lt;CODE&amp;gt;time_to_int(int_to_time(x)) == x&amp;lt;/CODE&amp;gt; for many values of&lt;br /&gt;
&amp;lt;TT&amp;gt;x&amp;lt;/TT&amp;gt;. This is an example of a consistency check.&lt;br /&gt;
&lt;br /&gt;
Once you are convinced they are correct, you can use them to &lt;br /&gt;
rewrite &amp;lt;CODE&amp;gt;add_time&amp;lt;/CODE&amp;gt;:&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def add_time(t1, t2):&lt;br /&gt;
    seconds = time_to_int(t1) + time_to_int(t2)&lt;br /&gt;
    return int_to_time(seconds)&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
This version is shorter than the original, and easier to verify.&lt;br /&gt;
&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;5&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&#039;&#039;&lt;br /&gt;
Rewrite &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;increment&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; using &#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;time_to_int&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039; and &#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;int_to_time&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039;.&lt;br /&gt;
&#039;&#039;&amp;lt;/DIV&amp;gt;&lt;br /&gt;
In some ways, converting from base 60 to base 10 and back is harder&lt;br /&gt;
than just dealing with times. Base conversion is more abstract; our&lt;br /&gt;
intuition for dealing with time values is better.&lt;br /&gt;
&lt;br /&gt;
But if we have the insight to treat times as base 60 numbers and make&lt;br /&gt;
the investment of writing the conversion functions (&amp;lt;CODE&amp;gt;time_to_int&amp;lt;/CODE&amp;gt;&lt;br /&gt;
and &amp;lt;CODE&amp;gt;int_to_time&amp;lt;/CODE&amp;gt;), we get a program that is shorter, easier to&lt;br /&gt;
read and debug, and more reliable.&lt;br /&gt;
&lt;br /&gt;
It is also easier to add features later. For example, imagine&lt;br /&gt;
subtracting two Times to find the duration between them. The&lt;br /&gt;
na&amp;amp;#XEF;ve approach would be to implement subtraction with borrowing.&lt;br /&gt;
Using the conversion functions would be easier and more likely to be&lt;br /&gt;
correct.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Ironically, sometimes making a problem harder (or more general) makes it&lt;br /&gt;
easier (because there are fewer special cases and fewer opportunities&lt;br /&gt;
for error).&lt;br /&gt;
=== 16.5&amp;amp;#XA0;&amp;amp;#XA0;Debugging ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A Time object is well-formed if the values of &amp;lt;TT&amp;gt;minutes&amp;lt;/TT&amp;gt; and &amp;lt;TT&amp;gt;seconds&amp;lt;/TT&amp;gt; are between 0 and 60 (including 0 but not 60) and if &lt;br /&gt;
&amp;lt;TT&amp;gt;hours&amp;lt;/TT&amp;gt; is positive. &amp;lt;TT&amp;gt;hours&amp;lt;/TT&amp;gt; and &amp;lt;TT&amp;gt;minutes&amp;lt;/TT&amp;gt; should be&lt;br /&gt;
integral values, but we might allow &amp;lt;TT&amp;gt;seconds&amp;lt;/TT&amp;gt; to have a&lt;br /&gt;
fraction part.&lt;br /&gt;
&lt;br /&gt;
These kind of requirements are called &#039;&#039;&#039;invariants&#039;&#039;&#039; because&lt;br /&gt;
they should always be true. To put it a different way, if they&lt;br /&gt;
are not true, then something has gone wrong.&lt;br /&gt;
&lt;br /&gt;
Writing code to check your invariants can help you detect errors&lt;br /&gt;
and find their causes. For example, you might have a function&lt;br /&gt;
like &amp;lt;CODE&amp;gt;valid_time&amp;lt;/CODE&amp;gt; that takes a Time object and returns&lt;br /&gt;
&amp;lt;TT&amp;gt;False&amp;lt;/TT&amp;gt; if it violates an invariant:&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def valid_time(time):&lt;br /&gt;
    if time.hours &amp;amp;lt; 0 or time.minutes &amp;amp;lt; 0 or time.seconds &amp;amp;lt; 0:&lt;br /&gt;
        return False&lt;br /&gt;
    if time.minutes &amp;amp;gt;= 60 or time.seconds &amp;amp;gt;= 60:&lt;br /&gt;
        return False&lt;br /&gt;
    return True&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
Then at the beginning of each function you could check the&lt;br /&gt;
arguments to make sure they are valid:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def add_time(t1, t2):&lt;br /&gt;
    if not valid_time(t1) or not valid_time(t2):&lt;br /&gt;
        raise ValueError, &#039;invalid Time object in add_time&#039;&lt;br /&gt;
    seconds = time_to_int(t1) + time_to_int(t2)&lt;br /&gt;
    return int_to_time(seconds)&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
Or you could use an &amp;lt;TT&amp;gt;assert&amp;lt;/TT&amp;gt; statement, which checks a given invariant&lt;br /&gt;
and raises an exception if it fails:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;PRE CLASS=&amp;quot;verbatim&amp;quot;&amp;gt;def add_time(t1, t2):&lt;br /&gt;
    assert valid_time(t1) and valid_time(t2)&lt;br /&gt;
    seconds = time_to_int(t1) + time_to_int(t2)&lt;br /&gt;
    return int_to_time(seconds)&lt;br /&gt;
&amp;lt;/PRE&amp;gt;&lt;br /&gt;
&amp;lt;TT&amp;gt;assert&amp;lt;/TT&amp;gt; statements are useful because they distinguish&lt;br /&gt;
code that deals with normal conditions from code&lt;br /&gt;
that checks for errors.&lt;br /&gt;
=== 16.6&amp;amp;#XA0;&amp;amp;#XA0;Glossary ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;DL CLASS=&amp;quot;description&amp;quot;&amp;gt;&amp;lt;DT CLASS=&amp;quot;dt-description&amp;quot;&amp;gt;&#039;&#039;&#039;prototype and patch:&#039;&#039;&#039;&amp;lt;/DT&amp;gt;&amp;lt;DD CLASS=&amp;quot;dd-description&amp;quot;&amp;gt; A development plan that involves&lt;br /&gt;
writing a rough draft of a program, testing, and correcting errors as&lt;br /&gt;
they are found.&lt;br /&gt;
&amp;lt;/DD&amp;gt;&amp;lt;DT CLASS=&amp;quot;dt-description&amp;quot;&amp;gt;&#039;&#039;&#039;planned development:&#039;&#039;&#039;&amp;lt;/DT&amp;gt;&amp;lt;DD CLASS=&amp;quot;dd-description&amp;quot;&amp;gt; A development plan that involves&lt;br /&gt;
high-level insight into the problem and more planning than incremental&lt;br /&gt;
development or prototype development.&lt;br /&gt;
&amp;lt;/DD&amp;gt;&amp;lt;DT CLASS=&amp;quot;dt-description&amp;quot;&amp;gt;&#039;&#039;&#039;pure function:&#039;&#039;&#039;&amp;lt;/DT&amp;gt;&amp;lt;DD CLASS=&amp;quot;dd-description&amp;quot;&amp;gt; A function that does not modify any of the objects it&lt;br /&gt;
receives as arguments. Most pure functions are fruitful.&lt;br /&gt;
&amp;lt;/DD&amp;gt;&amp;lt;DT CLASS=&amp;quot;dt-description&amp;quot;&amp;gt;&#039;&#039;&#039;modifier:&#039;&#039;&#039;&amp;lt;/DT&amp;gt;&amp;lt;DD CLASS=&amp;quot;dd-description&amp;quot;&amp;gt; A function that changes one or more of the objects it&lt;br /&gt;
receives as arguments. Most modifiers are fruitless.&lt;br /&gt;
&amp;lt;/DD&amp;gt;&amp;lt;DT CLASS=&amp;quot;dt-description&amp;quot;&amp;gt;&#039;&#039;&#039;functional programming style:&#039;&#039;&#039;&amp;lt;/DT&amp;gt;&amp;lt;DD CLASS=&amp;quot;dd-description&amp;quot;&amp;gt; A style of program design in which the&lt;br /&gt;
majority of functions are pure.&lt;br /&gt;
&amp;lt;/DD&amp;gt;&amp;lt;DT CLASS=&amp;quot;dt-description&amp;quot;&amp;gt;&#039;&#039;&#039;invariant:&#039;&#039;&#039;&amp;lt;/DT&amp;gt;&amp;lt;DD CLASS=&amp;quot;dd-description&amp;quot;&amp;gt; A condition that should always be true during the&lt;br /&gt;
execution of a program.&lt;br /&gt;
&amp;lt;/DD&amp;gt;&amp;lt;/DL&amp;gt;=== 16.7&amp;amp;#XA0;&amp;amp;#XA0;Exercises ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;6&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&#039;&#039;&lt;br /&gt;
Write a function called &#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;mul_time&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039; that takes a Time object&lt;br /&gt;
and a number and returns a new Time object that contains&lt;br /&gt;
the product of the original Time and the number.&#039;&#039;&lt;br /&gt;
&#039;&#039;Then use &#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;mul_time&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039; to write a function that takes a Time&lt;br /&gt;
object that represents the finishing time in a race, and a number&lt;br /&gt;
that represents the distance, and returns a Time object that represents&lt;br /&gt;
the average pace (time per mile).&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/DIV&amp;gt;&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;7&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Write a class definition for a Date object that has attributes &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;day&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039;, &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;month&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; and &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;year&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039;. Write a function called&lt;br /&gt;
&#039;&#039;&amp;lt;CODE&amp;gt;&#039;&#039;increment_date&#039;&#039;&amp;lt;/CODE&amp;gt;&#039;&#039; that takes a Date object, &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;date&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; and an&lt;br /&gt;
integer, &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;n&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039;, and returns a new Date object that&lt;br /&gt;
represents the day &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;n&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; days after &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;date&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039;. Hint:&lt;br /&gt;
&amp;amp;#X201C;Thirty days hath September...&amp;amp;#X201D; Challenge: does your function&lt;br /&gt;
deal with leap years correctly? See &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;wikipedia.org/wiki/Leap_year&amp;lt;/TT&amp;gt;&#039;&#039;&lt;br /&gt;
&amp;lt;/DIV&amp;gt;&amp;lt;DIV CLASS=&amp;quot;theorem&amp;quot;&amp;gt;&#039;&#039;&#039;Exercise&amp;amp;#XA0;8&#039;&#039;&#039;&amp;amp;#XA0;&amp;amp;#XA0;&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;The &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;datetime&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; module provides &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;date&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; and &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;time&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; objects&lt;br /&gt;
that are similar to the Date and Time objects in this chapter, but&lt;br /&gt;
they provide a rich set of methods and operators. Read the&lt;br /&gt;
documentation at &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;docs.python.org/lib/datetime-date.html&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039;.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;Use the &#039;&#039;&#039;&#039;&amp;lt;TT&amp;gt;datetime&amp;lt;/TT&amp;gt;&#039;&#039;&#039;&#039; module to write a program that&lt;br /&gt;
gets the current date and prints the day of the week.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;Write a program that takes a birthday as input&lt;br /&gt;
and prints the user&amp;amp;#X2019;s age and the number of days, hours,&lt;br /&gt;
minutes and seconds until their next birthday.&lt;br /&gt;
&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/DIV&amp;gt;&amp;lt;HR&amp;gt;&lt;br /&gt;
&amp;lt;IMG SRC=&amp;quot;previous_motif.gif&amp;quot; ALT=&amp;quot;Previous&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;IMG SRC=&amp;quot;contents_motif.gif&amp;quot; ALT=&amp;quot;Up&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;IMG SRC=&amp;quot;next_motif.gif&amp;quot; ALT=&amp;quot;Next&amp;quot;&amp;gt;&lt;/div&gt;</summary>
		<author><name>82.32.51.70</name></author>
	</entry>
	<entry>
		<id>https://ideawaza.com/index.php?title=Template:OMIM&amp;diff=15729</id>
		<title>Template:OMIM</title>
		<link rel="alternate" type="text/html" href="https://ideawaza.com/index.php?title=Template:OMIM&amp;diff=15729"/>
		<updated>2006-12-05T01:45:09Z</updated>

		<summary type="html">&lt;p&gt;82.32.38.45: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Mendelian Inheritance in Man]] (OMIM) [http://www.ncbi.nlm.nih.gov/entrez/dispomim.cgi?id={{{1}}} {{{1}}}]&amp;lt;noinclude&amp;gt;[[Category:External link templates|OMIM]]&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Stop hand.svg|left|3000x3000px]]&lt;/div&gt;</summary>
		<author><name>82.32.38.45</name></author>
	</entry>
</feed>