]> git.friedersdorff.com Git - max/python_unittesting.git/commitdiff
Add README that outlines unittesting master
authorMaximilian Friedersdorff <max@friedersdorff.com>
Wed, 13 Mar 2019 20:11:35 +0000 (20:11 +0000)
committerMaximilian Friedersdorff <max@friedersdorff.com>
Wed, 13 Mar 2019 20:11:35 +0000 (20:11 +0000)
README.pdf [new file with mode: 0644]
README.rst [new file with mode: 0644]

diff --git a/README.pdf b/README.pdf
new file mode 100644 (file)
index 0000000..e59d404
--- /dev/null
@@ -0,0 +1,727 @@
+%PDF-1.4
+%\93\8c\8b\9e ReportLab Generated PDF document http://www.reportlab.com
+1 0 obj
+<<
+/F1 2 0 R /F2 3 0 R /F3 4 0 R /F4 5 0 R /F5 6 0 R /F6 9 0 R
+>>
+endobj
+2 0 obj
+<<
+/BaseFont /Helvetica /Encoding /WinAnsiEncoding /Name /F1 /Subtype /Type1 /Type /Font
+>>
+endobj
+3 0 obj
+<<
+/BaseFont /Helvetica-Bold /Encoding /WinAnsiEncoding /Name /F2 /Subtype /Type1 /Type /Font
+>>
+endobj
+4 0 obj
+<<
+/BaseFont /Courier-Bold /Encoding /WinAnsiEncoding /Name /F3 /Subtype /Type1 /Type /Font
+>>
+endobj
+5 0 obj
+<<
+/BaseFont /Courier /Encoding /WinAnsiEncoding /Name /F4 /Subtype /Type1 /Type /Font
+>>
+endobj
+6 0 obj
+<<
+/BaseFont /Courier-Oblique /Encoding /WinAnsiEncoding /Name /F5 /Subtype /Type1 /Type /Font
+>>
+endobj
+7 0 obj
+<<
+/Contents 19 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources <<
+/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
+>> /Rotate 0 /Trans <<
+
+>> 
+  /Type /Page
+>>
+endobj
+8 0 obj
+<<
+/A <<
+/S /URI /Type /Action /URI (https://projecteuler.net/project/resources/p102_triangles.txt)
+>> /Border [ 0 0 0 ] /Rect [ 62.69291 717.0236 209.4129 729.0236 ] /Subtype /Link /Type /Annot
+>>
+endobj
+9 0 obj
+<<
+/BaseFont /Helvetica-Oblique /Encoding /WinAnsiEncoding /Name /F6 /Subtype /Type1 /Type /Font
+>>
+endobj
+10 0 obj
+<<
+/Annots [ 8 0 R ] /Contents 20 0 R /MediaBox [ 0 0 595.2756 841.8898 ] /Parent 18 0 R /Resources <<
+/Font 1 0 R /ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ]
+>> /Rotate 0 
+  /Trans <<
+
+>> /Type /Page
+>>
+endobj
+11 0 obj
+<<
+/Outlines 13 0 R /PageLabels 21 0 R /PageMode /UseNone /Pages 18 0 R /Type /Catalog
+>>
+endobj
+12 0 obj
+<<
+/Author () /CreationDate (D:20190313201115+00'00') /Creator (\(unspecified\)) /Keywords () /ModDate (D:20190313201115+00'00') /Producer (ReportLab PDF Library - www.reportlab.com) 
+  /Subject (\(unspecified\)) /Title (Unit testing) /Trapped /False
+>>
+endobj
+13 0 obj
+<<
+/Count 4 /First 14 0 R /Last 17 0 R /Type /Outlines
+>>
+endobj
+14 0 obj
+<<
+/Dest [ 7 0 R /XYZ 62.69291 439.8236 0 ] /Next 15 0 R /Parent 13 0 R /Title (Why)
+>>
+endobj
+15 0 obj
+<<
+/Dest [ 7 0 R /XYZ 62.69291 292.8236 0 ] /Next 16 0 R /Parent 13 0 R /Prev 14 0 R /Title (How)
+>>
+endobj
+16 0 obj
+<<
+/Dest [ 7 0 R /XYZ 62.69291 187.8236 0 ] /Next 17 0 R /Parent 13 0 R /Prev 15 0 R /Title (What)
+>>
+endobj
+17 0 obj
+<<
+/Dest [ 10 0 R /XYZ 62.69291 705.0236 0 ] /Parent 13 0 R /Prev 16 0 R /Title (Test driven development)
+>>
+endobj
+18 0 obj
+<<
+/Count 2 /Kids [ 7 0 R 10 0 R ] /Type /Pages
+>>
+endobj
+19 0 obj
+<<
+/Length 10422
+>>
+stream
+1 0 0 1 0 0 cm  BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 741.0236 cm
+q
+BT 1 0 0 1 0 4 Tm 179.9449 0 Td 24 TL /F2 20 Tf 0 0 0 rg (Unit testing) Tj T* -179.9449 0 Td ET
+Q
+Q
+q
+1 0 0 1 62.69291 695.0236 cm
+q
+BT 1 0 0 1 0 26 Tm 3.17248 Tw 12 TL /F1 10 Tf 0 0 0 rg (Unit testing means testing small portions \(individual functions, modules, classes\) of your program,) Tj T* 0 Tw .411654 Tw (independently of the rest, in an automated fashion. The tests usually consist of a set of functions that are) Tj T* 0 Tw (distributed along with the rest of the source code.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 641.0236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL 2.051654 Tw (Each test will call part of the main source code, usually with some dummy data, and verify that the) Tj T* 0 Tw -0.101512 Tw (behaviour of the code is as expected. It is typical to test a few edge cases and boundary conditions in such) Tj T* 0 Tw .848735 Tw (a way. A primitive attempt to test a python function, that implements a mathematical function might look) Tj T* 0 Tw (like this:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 451.8236 cm
+q
+q
+1 0 0 1 0 0 cm
+q
+1 0 0 1 6.6 6.6 cm
+q
+.662745 .662745 .662745 RG
+.5 w
+.960784 .960784 .862745 rg
+n -6 -6 468.6898 180 re B*
+Q
+q
+.960784 .960784 .862745 rg
+n 0 156 18 12 re f*
+.960784 .960784 .862745 rg
+n 24 156 72 12 re f*
+.960784 .960784 .862745 rg
+n 96 156 6 12 re f*
+.960784 .960784 .862745 rg
+n 102 156 6 12 re f*
+.960784 .960784 .862745 rg
+n 108 156 12 12 re f*
+.960784 .960784 .862745 rg
+n 18 144 432 12 re f*
+.960784 .960784 .862745 rg
+n 0 132 306 12 re f*
+.960784 .960784 .862745 rg
+n 18 120 24 12 re f*
+.960784 .960784 .862745 rg
+n 48 120 24 12 re f*
+.960784 .960784 .862745 rg
+n 78 120 36 12 re f*
+.960784 .960784 .862745 rg
+n 120 120 12 12 re f*
+.960784 .960784 .862745 rg
+n 132 120 6 12 re f*
+.960784 .960784 .862745 rg
+n 138 120 18 12 re f*
+.960784 .960784 .862745 rg
+n 18 108 36 12 re f*
+.960784 .960784 .862745 rg
+n 60 108 18 12 re f*
+.960784 .960784 .862745 rg
+n 78 108 6 12 re f*
+.960784 .960784 .862745 rg
+n 84 108 6 12 re f*
+.960784 .960784 .862745 rg
+n 90 108 6 12 re f*
+.960784 .960784 .862745 rg
+n 96 108 6 12 re f*
+.960784 .960784 .862745 rg
+n 102 108 12 12 re f*
+.960784 .960784 .862745 rg
+n 114 108 6 12 re f*
+.960784 .960784 .862745 rg
+n 120 108 18 12 re f*
+.960784 .960784 .862745 rg
+n 138 108 12 12 re f*
+.960784 .960784 .862745 rg
+n 0 84 18 12 re f*
+.960784 .960784 .862745 rg
+n 24 84 96 12 re f*
+.960784 .960784 .862745 rg
+n 120 84 18 12 re f*
+.960784 .960784 .862745 rg
+n 18 72 36 12 re f*
+.960784 .960784 .862745 rg
+n 60 72 72 12 re f*
+.960784 .960784 .862745 rg
+n 132 72 6 12 re f*
+.960784 .960784 .862745 rg
+n 138 72 12 12 re f*
+.960784 .960784 .862745 rg
+n 150 72 6 12 re f*
+.960784 .960784 .862745 rg
+n 162 72 12 12 re f*
+.960784 .960784 .862745 rg
+n 180 72 6 12 re f*
+.960784 .960784 .862745 rg
+n 0 48 18 12 re f*
+.960784 .960784 .862745 rg
+n 24 48 90 12 re f*
+.960784 .960784 .862745 rg
+n 114 48 18 12 re f*
+.960784 .960784 .862745 rg
+n 18 36 36 12 re f*
+.960784 .960784 .862745 rg
+n 60 36 72 12 re f*
+.960784 .960784 .862745 rg
+n 132 36 6 12 re f*
+.960784 .960784 .862745 rg
+n 138 36 6 12 re f*
+.960784 .960784 .862745 rg
+n 144 36 6 12 re f*
+.960784 .960784 .862745 rg
+n 156 36 12 12 re f*
+.960784 .960784 .862745 rg
+n 174 36 6 12 re f*
+.960784 .960784 .862745 rg
+n 0 12 18 12 re f*
+.960784 .960784 .862745 rg
+n 24 12 150 12 re f*
+.960784 .960784 .862745 rg
+n 174 12 18 12 re f*
+.960784 .960784 .862745 rg
+n 18 0 36 12 re f*
+.960784 .960784 .862745 rg
+n 60 0 72 12 re f*
+.960784 .960784 .862745 rg
+n 132 0 6 12 re f*
+.960784 .960784 .862745 rg
+n 138 0 18 12 re f*
+.960784 .960784 .862745 rg
+n 156 0 6 12 re f*
+.960784 .960784 .862745 rg
+n 168 0 12 12 re f*
+.960784 .960784 .862745 rg
+n 186 0 6 12 re f*
+.960784 .960784 .862745 rg
+n 198 0 6 12 re f*
+.960784 .960784 .862745 rg
+n 204 0 6 12 re f*
+.960784 .960784 .862745 rg
+n 216 0 72 12 re f*
+.960784 .960784 .862745 rg
+n 288 0 6 12 re f*
+.960784 .960784 .862745 rg
+n 294 0 18 12 re f*
+.960784 .960784 .862745 rg
+n 312 0 6 12 re f*
+.960784 .960784 .862745 rg
+n 324 0 12 12 re f*
+.960784 .960784 .862745 rg
+n 342 0 6 12 re f*
+BT 1 0 0 1 0 158 Tm 12 TL /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (calc_deg_sin) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj 0 0 0 rg (\):) Tj 0 0 0 rg  T* (   ) Tj /F5 10 Tf .729412 .129412 .129412 rg ("""This is an elaborate python function that calculates the mathematical) Tj T* (   function f\(x\)=sin\(x\), where x is in degrees. """) Tj /F4 10 Tf 0 0 0 rg  T* (   ) Tj /F3 10 Tf 0 .501961 0 rg (from) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf 0 0 1 rg (math) Tj /F4 10 Tf 0 0 0 rg ( ) Tj /F3 10 Tf 0 .501961 0 rg (import) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (pi) Tj 0 0 0 rg (,) Tj 0 0 0 rg (sin) Tj 0 0 0 rg  T* (   ) Tj /F3 10 Tf 0 .501961 0 rg (return) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (sin) Tj 0 0 0 rg (\() Tj 0 0 0 rg (x) Tj .4 .4 .4 rg (*) Tj 0 0 0 rg (\() Tj 0 0 0 rg (pi) Tj .4 .4 .4 rg (/) Tj .4 .4 .4 rg (189) Tj 0 0 0 rg (\)\)) Tj 0 0 0 rg  T*  T* /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (test_sin_90_is_1) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg  T* (   ) Tj /F3 10 Tf 0 .501961 0 rg (assert) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (calc_deg_sin) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (90) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (1) Tj 0 0 0 rg  T*  T* /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (test_sin_0_is_0) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg  T* (   ) Tj /F3 10 Tf 0 .501961 0 rg (assert) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (calc_deg_sin) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (0) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg  T*  T* /F3 10 Tf 0 .501961 0 rg (def) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 1 rg (test_sin_180_and_360_is_0) Tj 0 0 0 rg (\(\):) Tj 0 0 0 rg  T* (   ) Tj /F3 10 Tf 0 .501961 0 rg (assert) Tj /F4 10 Tf 0 0 0 rg ( ) Tj 0 0 0 rg (calc_deg_sin) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (180) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (&) Tj (&) Tj 0 0 0 rg ( ) Tj 0 0 0 rg (calc_deg_sin) Tj 0 0 0 rg (\() Tj .4 .4 .4 rg (360) Tj 0 0 0 rg (\)) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (==) Tj 0 0 0 rg ( ) Tj .4 .4 .4 rg (0) Tj T* ET
+Q
+Q
+Q
+Q
+Q
+q
+1 0 0 1 62.69291 418.8236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Why) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 400.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Unit testing is a useful thing to do for a number of reasons, including \(in no particular order\):) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 394.8236 cm
+Q
+q
+1 0 0 1 62.69291 394.8236 cm
+Q
+q
+1 0 0 1 62.69291 382.8236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Unit tests document the expected behaviour of your program.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 376.8236 cm
+Q
+q
+1 0 0 1 62.69291 352.8236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.40528 Tw (Unit tests allow you to verify that you did not make unintended changes to the behaviour of your) Tj T* 0 Tw (program when you add features, or change the implementation.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 346.8236 cm
+Q
+q
+1 0 0 1 62.69291 322.8236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL .753516 Tw (Unit tests catch many bugs before your program runs for real \(before you submit the job that takes) Tj T* 0 Tw (multiple days, but crashes right before it prints out the result\).) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 316.8236 cm
+Q
+q
+1 0 0 1 62.69291 304.8236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Unit tests allow you to conveniently play with unfamiliar libraries/apis/modules language features.) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 304.8236 cm
+Q
+q
+1 0 0 1 62.69291 271.8236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (How) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 229.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 26 Tm /F1 10 Tf 12 TL -0.135662 Tw (Use a test runner. A test runner will find all functions in a file or module that are defined to be tests, and run) Tj T* 0 Tw .754431 Tw (them. It will also give you a convenient output of the result, and some basic statistics. Test runners vary) Tj T* 0 Tw (greatly in their ease of use, flexibility and the usefulness of their output.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 199.8236 cm
+q
+BT 1 0 0 1 0 14 Tm .386488 Tw 12 TL /F1 10 Tf 0 0 0 rg (In this case I am using ) Tj /F4 10 Tf 0 0 0 rg (pytest) Tj /F1 10 Tf 0 0 0 rg (. ) Tj /F4 10 Tf 0 0 0 rg (pytest) Tj /F1 10 Tf 0 0 0 rg ( will execute all top level functions in a file that start with ) Tj /F4 10 Tf 0 0 0 rg (test_) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* 0 Tw (You run the tests in a file with ) Tj /F4 10 Tf 0 0 0 rg (pytest) Tj ( ) Tj (FILE) Tj ( ) Tj ([FILE]) Tj ( ) Tj ([FILE]...) Tj /F1 10 Tf 0 0 0 rg (.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 166.8236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (What) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 148.8236 cm
+q
+BT 1 0 0 1 0 2 Tm 12 TL /F1 10 Tf 0 0 0 rg (Look at the examples in this directory. The files staring with ) Tj /F4 10 Tf 0 0 0 rg (<) Tj (somenumber) Tj (>) Tj (_) Tj /F1 10 Tf 0 0 0 rg ( contain tests.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 130.8236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (The first file contains some basic tests. Some will fail, some will pass.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 88.82362 cm
+q
+BT 1 0 0 1 0 26 Tm 1.282126 Tw 12 TL /F1 10 Tf 0 0 0 rg (The second file contains tests that check if a function called ) Tj /F4 10 Tf 0 0 0 rg (incorrect_ackermann) Tj /F1 10 Tf 0 0 0 rg ( will produce the) Tj T* 0 Tw 2.160542 Tw (expected values for a number of different inputs \(hint: it won't\). Fix any problems that turn up \( the) Tj T* 0 Tw (definition of the ackermann function is at the very bottom of the file that implements it\).) Tj T* ET
+Q
+Q
+endstream
+endobj
+20 0 obj
+<<
+/Length 4562
+>>
+stream
+1 0 0 1 0 0 cm  BT /F1 12 Tf 14.4 TL ET
+q
+1 0 0 1 62.69291 717.0236 cm
+q
+BT 1 0 0 1 0 38 Tm .472126 Tw 12 TL /F1 10 Tf 0 0 0 rg (The third file contains tests for two functions, ) Tj /F4 10 Tf 0 0 0 rg (collatz) Tj /F1 10 Tf 0 0 0 rg ( and ) Tj /F4 10 Tf 0 0 0 rg (longest_collatz) Tj /F1 10 Tf 0 0 0 rg (. These return the length) Tj T* 0 Tw .959986 Tw (of the collatz sequence for a particular integer, and the integer with the longest collatz sequence that is) Tj T* 0 Tw .25832 Tw (smaller than the input integer. Implement these functions so that they pass the tests. This is based on the) Tj T* 0 Tw 0 0 .501961 rg (Euler Project problem number 14) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 684.0236 cm
+q
+BT 1 0 0 1 0 3.5 Tm 21 TL /F2 17.5 Tf 0 0 0 rg (Test driven development) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 630.0236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 38 Tm /F1 10 Tf 12 TL 1.961235 Tw (Test driven development is a practice, whereby one first writes the tests that fully describe a certain) Tj T* 0 Tw 1.87881 Tw (feature \(or test for a particular bug\). These tests should all initially fail. Then one writes the simplest) Tj T* 0 Tw .537045 Tw (implementation that will make these tests pass. Doing things in this order forces one to be very thorough) Tj T* 0 Tw (with writing tests. It is a lot of work however.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 588.0236 cm
+q
+BT 1 0 0 1 0 26 Tm .04881 Tw 12 TL /F1 10 Tf 0 0 0 rg (Pick your favourite algorithm \(ideally one ) Tj /F6 10 Tf (you) Tj /F1 10 Tf ( can implement in python\). Write some tests for a function \(or) Tj T* 0 Tw 1.864983 Tw (functions\) that implements that algorithm, then implement that algorithm to pass the tests that you've) Tj T* 0 Tw (written.) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 570.0236 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Some good algorithms to tests with might be:) Tj T* ET
+Q
+Q
+q
+1 0 0 1 62.69291 564.0236 cm
+Q
+q
+1 0 0 1 62.69291 564.0236 cm
+Q
+q
+1 0 0 1 62.69291 552.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Binary search) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 546.0236 cm
+Q
+q
+1 0 0 1 62.69291 534.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Your favourite sorting algorithm) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 528.0236 cm
+Q
+q
+1 0 0 1 62.69291 516.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (DFS/BFS) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 510.0236 cm
+Q
+q
+1 0 0 1 62.69291 498.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Calculating the edit distance between two strings) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 492.0236 cm
+Q
+q
+1 0 0 1 62.69291 480.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Kernel convolution) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 474.0236 cm
+Q
+q
+1 0 0 1 62.69291 462.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Maximum parsimony) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 456.0236 cm
+Q
+q
+1 0 0 1 62.69291 444.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL (Calculate the Levenshtein or edit distance between two strings) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 438.0236 cm
+Q
+q
+1 0 0 1 62.69291 414.0236 cm
+0 0 0 rg
+BT /F1 10 Tf 12 TL ET
+q
+1 0 0 1 6 9 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 2 Tm /F1 10 Tf 12 TL 10.5 0 Td (\177) Tj T* -10.5 0 Td ET
+Q
+Q
+q
+1 0 0 1 23 -3 cm
+q
+0 0 0 rg
+BT 1 0 0 1 0 14 Tm /F1 10 Tf 12 TL 1.266098 Tw (Calculating the value of the fibonacci sequence, the sum of integers up to n, the first n primes or) Tj T* 0 Tw (some other such mathematical function) Tj T* ET
+Q
+Q
+q
+Q
+Q
+q
+1 0 0 1 62.69291 414.0236 cm
+Q
+endstream
+endobj
+21 0 obj
+<<
+/Nums [ 0 22 0 R 1 23 0 R ]
+>>
+endobj
+22 0 obj
+<<
+/S /D /St 1
+>>
+endobj
+23 0 obj
+<<
+/S /D /St 2
+>>
+endobj
+xref
+0 24
+0000000000 65535 f 
+0000000073 00000 n 
+0000000154 00000 n 
+0000000261 00000 n 
+0000000373 00000 n 
+0000000483 00000 n 
+0000000588 00000 n 
+0000000701 00000 n 
+0000000906 00000 n 
+0000001119 00000 n 
+0000001234 00000 n 
+0000001458 00000 n 
+0000001564 00000 n 
+0000001834 00000 n 
+0000001908 00000 n 
+0000002012 00000 n 
+0000002129 00000 n 
+0000002247 00000 n 
+0000002372 00000 n 
+0000002439 00000 n 
+0000012914 00000 n 
+0000017528 00000 n 
+0000017578 00000 n 
+0000017612 00000 n 
+trailer
+<<
+/ID 
+[<0e78adeec461ba0fa6ed6f6f883a9461><0e78adeec461ba0fa6ed6f6f883a9461>]
+% ReportLab generated PDF document -- digest (http://www.reportlab.com)
+
+/Info 12 0 R
+/Root 11 0 R
+/Size 24
+>>
+startxref
+17646
+%%EOF
diff --git a/README.rst b/README.rst
new file mode 100644 (file)
index 0000000..5c5c8ea
--- /dev/null
@@ -0,0 +1,111 @@
+Unit testing
+============
+
+Unit testing means testing small portions (individual functions, modules, 
+classes) of your program, independently of the rest, in an automated fashion.  
+The tests usually consist of a set of functions that are distributed along with
+the rest of the source code.  
+
+Each test will call part of the main source code, usually with some dummy data, 
+and verify that the behaviour of the code is as expected.  It is typical to test
+a few edge cases and boundary conditions in such a way.  A primitive attempt
+to test a python function, that implements a mathematical function might look
+like this:
+
+.. code-block:: python
+   
+   def calc_deg_sin(x):
+      """This is an elaborate python function that calculates the mathematical
+      function f(x)=sin(x), where x is in degrees. """
+      from math import pi,sin
+      return sin(x*(pi/189))
+
+   def test_sin_90_is_1():
+      assert calc_deg_sin(90) == 1
+
+   def test_sin_0_is_0():
+      assert calc_deg_sin(0) == 0
+
+   def test_sin_180_and_360_is_0():
+      assert calc_deg_sin(180) == 0 && calc_deg_sin(360) == 0
+
+Why
+---
+
+Unit testing is a useful thing to do for a number of reasons, including (in no
+particular order):
+
+- Unit tests document the expected behaviour of your program.
+- Unit tests allow you to verify that you did not make unintended changes to the 
+  behaviour of your program when you add features, or change the implementation.
+- Unit tests catch many bugs before your program runs for real (before you submit
+  the job that takes multiple days, but crashes right before it prints out the 
+  result).
+- Unit tests allow you to conveniently play with unfamiliar libraries/apis/modules
+  language features.
+
+How
+---
+
+Use a test runner.  A test runner will find all functions in a file or module 
+that are defined to be tests, and run them.  It will also give you a convenient
+output of the result, and some basic statistics.  Test runners vary greatly in 
+their ease of use, flexibility and the usefulness of their output.
+
+In this case I am using ``pytest``.  ``pytest`` will execute all top level 
+functions in a file that start with ``test_``.  You run the tests in a file with
+``pytest FILE [FILE] [FILE]...``.
+
+What
+----
+Look at the examples in this directory.  The files staring with 
+``<somenumber>_`` contain tests.  
+
+The first file contains some basic tests.  
+Some will fail, some will pass.  
+
+The second file contains tests that check if
+a function called ``incorrect_ackermann`` will produce the expected values for
+a number of different inputs (hint: it won't).  Fix any problems that turn up (
+the definition of the ackermann function is at the very bottom of the file that
+implements it).
+
+The third file contains tests for two functions, ``collatz`` and ``longest_collatz``.
+These return the length of the collatz sequence for a particular integer, and the
+integer with the longest collatz sequence that is smaller than the input integer.
+Implement these functions so that they pass the tests.  This is based on the 
+`Euler Project problem number 14`_
+
+Test driven development
+-----------------------
+
+Test driven development is a practice, whereby one first writes the tests that 
+fully describe a certain feature (or test for a particular bug).  These tests
+should all initially fail.  Then one writes the simplest implementation that will
+make these tests pass.  Doing things in this order forces one to be very thorough
+with writing tests.  It is a lot of work however.
+
+Pick your favourite algorithm (ideally one *you* can implement in python).  Write
+some tests for a function (or functions) that implements that algorithm, then 
+implement that algorithm to pass the tests that you've written.
+
+Some good algorithms to tests with might be:
+
+- Binary search
+- Your favourite sorting algorithm
+- DFS/BFS
+- Calculating the edit distance between two strings
+- Kernel convolution
+- Maximum parsimony
+- Calculate the Levenshtein or edit distance between two strings
+- Calculating the value of the fibonacci sequence, the sum of integers up to n,
+  the first n primes or some other such mathematical function
+
+
+
+
+
+
+
+
+.. _Euler Project problem number 14: https://projecteuler.net/project/resources/p102_triangles.txt