## 17. `trantest`: A small test driver

Here we present a small script that exercises the functions of the `homcoord` module. The output from the script is available online as `trantest.out`.

The script starts with a line to make it self-executing under Unix, followed by a comment that points back to this documentation.

trantest
```#!/usr/bin/env python
#================================================================
# trantest: Exercise the homcoord module.
#
# Do not edit this file.  It is extracted automatically from
# the documentation, here:
#   http://www.nmt.edu/~shipman/soft/homcoord/
#----------------------------------------------------------------
```

Imported modules include the standard `sys` module and the module under test. We'll also need the `numpy` module for the constant `pi` so we can work in radians.

trantest
```# - - - - -   I m p o r t s

import sys
import homcoord as hom
import numpy as num
```

Next comes the main.

trantest
```# - - - - -   m a i n

def main():
"""
"""
```

First, we will test the three basic transforms, and then the composition of two of those basic transforms. Here is a plot of the principal points:

 `P` The example point before transformation. `Pt` Translation of `P` by (-2, 3). `Ps` Scaling of `P` by (2.5, 2). `Pr` Rotation of P around the origin 90 degrees clockwise (π/2 radians). `Ptr` Composition of two transforms: translation by (-2, 3) followed by 90-degree clockwise rotation.
trantest
```    #--
# Demonstrate the three basic transforms and their
# composition.
#--
p = hom.Pt(4,1)

tt = hom.Xlate((-2,3))
tranTest ( p, tt, "Pt: translation by (-2, 3)" )

ts = hom.Xscale((2.5, 2))
tranTest ( p, ts, "Ps: scaling by (2.5, 2)" )

tr = hom.Xrotate(num.pi/2)
tranTest ( p, tr, "Pr: rotation 90 degrees CCW" )

tc = tt.compose(tr)
tranTest ( p, tc, "Ptr: translation + rotation those amounts" )
```

The second part of the test is for `Xrotaround`, showing the rotation of an entire triangle `ABC` around vertex `A`.

trantest
```    #--
# Rotation of triangle ABC around point A.
#--
a = hom.Pt(7, 1)
b = hom.Pt(8, 2)
c = hom.Pt(7, 5)
tra = hom.Xrotaround ( a, num.pi/2 )
tranTest ( a, tra, "Point A rotated +90 around A" )
tranTest ( b, tra, "Point B rotated +90 around A" )
tranTest ( c, tra, "Point C rotated +90 around A" )
```

The third part tests the functions of the `Line` class. We define three lines, `L1`, `L2`, and `L3`. The intersection of `L1` and `L2` should be at (1,4). An attempt to find the intersection of `L2` and `L3` should raise a `ValueError` exception, since those two lines are parallel.

trantest
```    #--
# Line tests
#--
L1 = hom.Line.pointBearing ( hom.Pt(3,2), 0.75*num.pi)
L2 = hom.Line.twoPoint ( hom.Pt(-1,0), hom.Pt(0,2) )
L3 = hom.Line.twoPoint ( hom.Pt(2,0), hom.Pt(3,2) )

print
print "=== Line L1 is", L1
print "=== Line L2 is", L2
print "=== Line L3 is", L3

p = L1.intersect(L2)
print "=== Intersection of L1 and L2 should be (1,4):", p

try:
print "*** Error: It says L2 an L3 intersect at %s!" % bad
except ValueError, details:
print "Correctly detected L2||L3:", details
```

The `tranTest` function takes three arguments: a point, a transform, and a text string identifying the transform. It shows the point after transformation and again after applying the inverse transformation to be sure we get back to the original point.

trantest
```# - - -   t r a n T e s t

def tranTest ( p, xf, text ):
'''Demonstrate transform xf on point p and then check the inverse.

[ (p is a Pt) and (xf is an Xform) and (text is a string) ->
sys.stdout  +:=  text + (report on transform xf applied to p) +
(report on inverse transform xf applied to the result
of xf applied to p) ]
'''
print "\n=== %s: point is %s." % (text, p)
px = xf(p)
check = xf.invert(px)
print ( "Forward transform %s; inverse transform %s." %
(px, check) )
```

The script ends with an epilogue that initiates execution of the main.

trantest
```# - - - - -   E p i l o g u e

if __name__ == "__main__":
main()
```