Revisión | 9c8455b2e3ab9742aa0dfa59ecc501a0e8b476b4 (tree) |
---|---|
Tiempo | 2017-10-21 04:16:33 |
Autor | Albert Mietus < albert AT mietus DOT nl > |
Commiter | Albert Mietus < albert AT mietus DOT nl > |
Added dPID python 'homework' exercise in DRAFT
@@ -4,7 +4,7 @@ | ||
4 | 4 | .. _dPID_exercise: |
5 | 5 | |
6 | 6 | ============== |
7 | -dPID: exercise | |
7 | +dPID: Exercise | |
8 | 8 | ============== |
9 | 9 | :status: pre-alpha |
10 | 10 |
@@ -23,19 +23,61 @@ | ||
23 | 23 | The :class:`dpid.dPID` class is discrete; it only calculates the :meth:`dpid.dPID.result` when requested. This implies the |
24 | 24 | (return) value of :meth:`dpid.dPID.result` will depend on when it is called (relative to the other methods). |
25 | 25 | |
26 | - * So, timing may be relavant in your (test)-code. One can use ``time.sleep`` to controll that. By using a floating-point | |
27 | - parameter, this is accurate in the milli-seconds range. | |
26 | + * So, timing may be relavant in your (test)-code. One can use ``time.sleep`` to controll that. Usa a floating-point | |
27 | + parameter for sub-second resolution. Typically, the function is accurate in the milli-seconds range. | |
28 | 28 | |
29 | - * By using a (small, relavant) MARGIN when comparing values, small derivations (in e.g. timing) can be compensated. | |
29 | + * Compare using a small *MARGIN*, to allow derivations due e.g. timing. See the :ref:`examples <dPID_test_examples>`. | |
30 | 30 | |
31 | 31 | .. seealso:: Convenient python functions |
32 | 32 | |
33 | 33 | * https://docs.python.org/3.5/library/time.html?highlight=sleep#time.sleep |
34 | 34 | * https://docs.python.org/3.5/library/functions.html?highlight=abs#abs |
35 | 35 | |
36 | +Instructions | |
37 | +~~~~~~~~~~~~ | |
38 | + | |
39 | +* Use the `pytest <https://pytest.readthedocs.io>`__ framework, to shorten tests-code. | |
40 | + | |
41 | + - :ref:`pytest_into` is a summary with everything you need for this exercise. | |
42 | + - You can use :ref:`dPID_test_examples` as *template* for your own files. | |
43 | + | |
44 | +* Start by running ``pytest`` as shown. | |
45 | + | |
46 | + - Reproduce the shown output first, before adding your own files. | |
47 | + - Remember; the output text will differ slightly; for paths, dates etc. | |
48 | + | |
49 | +* Add a (one) new file: ``test_<something>.py``. | |
50 | + | |
51 | + - Copy the start of the file (above the first function); update the copyright. | |
52 | + - Write a single test-function: | |
53 | + | |
54 | + * Create a :class:`dpid.dPID` instance with known, **simple** ``P``, ``I`` and ``D`` settings. | |
55 | + * Give it a :meth:`~dpid.dPID.setpoint` and :meth:`~dpid.dPID.measured` value. | |
56 | + * Request a :meth:`~dpid.dPID.result`. | |
57 | + * Assert the returned value is (almost) equal to the pre-computed number. | |
58 | + | |
59 | +* Run ``pytest`` again. | |
60 | + | |
61 | + - It should run both the existing example, and the new test-file. | |
62 | + - The test should fail! As the *empty* class always returns ``0``, that is easy. | |
63 | + - Watch for *syntax errors*, and errors but AssertionError. Improve your code when needed | |
64 | + | |
65 | +* Repeat, either by adding test-function to that file, or adding more test-files. | |
66 | + | |
67 | + - When needed, you can add auxiliary functions; just don’t use the *test*-phrase in there name. | |
68 | + - Or continue first with the implementation part. And add more test later (for other functions). | |
69 | + - Each test should be a little more complicated as the existing onces. | |
70 | + - Or better: start with the trivial once. Then the almost-trivial, etc. | |
71 | + | |
72 | + * Start testing a “*P-only*” PID-controller | |
73 | + * Then an “*I-only*”, then a “*D-only*”. After which you test a simple combination | |
74 | + * etc. | |
75 | + | |
36 | 76 | Code second |
37 | 77 | ----------- |
38 | 78 | |
79 | +When a part of the functionality is tested (or at least: there is test-code for), you can start implementing | |
80 | +the :class:`~dpid.dPID` class. Keep is simple. The only objective is to **make one failing test pass**. | |
39 | 81 | |
40 | 82 | And improve (refactor) |
41 | 83 | ---------------------- |
@@ -18,7 +18,7 @@ | ||
18 | 18 | ************* |
19 | 19 | |
20 | 20 | .. toctree:: |
21 | - | |
21 | + :maxdepth: 3 | |
22 | 22 | |
23 | 23 | class |
24 | 24 | exercise |