Skip to content
Snippets Groups Projects
Commit a4ed3c8d authored by Martin Lange's avatar Martin Lange
Browse files

test code of components chapter

parent 423e8d55
No related branches found
No related tags found
1 merge request!127Doc-tests
This commit is part of merge request !127. Comments created here will be created in the context of that merge request.
...@@ -31,7 +31,7 @@ which is called from downstream to request data. ...@@ -31,7 +31,7 @@ which is called from downstream to request data.
File ``src/scale.py``: File ``src/scale.py``:
.. code-block:: Python .. testcode:: scale-adapter
import finam as fm import finam as fm
...@@ -45,6 +45,11 @@ File ``src/scale.py``: ...@@ -45,6 +45,11 @@ File ``src/scale.py``:
d = self.pull_data(time) d = self.pull_data(time)
return d * self.scale return d * self.scale
.. testcode:: scale-adapter
:hide:
adapter = Scale(0.5)
In :meth:`.Adapter._get_data`, we: In :meth:`.Adapter._get_data`, we:
1. Pull the input for the requested ``time`` 1. Pull the input for the requested ``time``
...@@ -129,6 +134,10 @@ In :meth:`.Adapter._source_updated`, we need to store incoming data: ...@@ -129,6 +134,10 @@ In :meth:`.Adapter._source_updated`, we need to store incoming data:
self.old_data = None self.old_data = None
self.new_data = None self.new_data = None
@property
def needs_push(self):
return True
def _source_updated(self, time): def _source_updated(self, time):
self.old_data = self.new_data self.old_data = self.new_data
self.new_data = (time, fm.data.strip_data(self.pull_data(time))) self.new_data = (time, fm.data.strip_data(self.pull_data(time)))
...@@ -141,7 +150,7 @@ As the output time will differ from the input time, we need to strip the time of ...@@ -141,7 +150,7 @@ As the output time will differ from the input time, we need to strip the time of
In :meth:`.Adapter._get_data`, we can now do the interpolation whenever data is requested from upstream. In :meth:`.Adapter._get_data`, we can now do the interpolation whenever data is requested from upstream.
.. code-block:: Python .. testcode:: time-adapter
import finam as fm import finam as fm
...@@ -152,6 +161,10 @@ In :meth:`.Adapter._get_data`, we can now do the interpolation whenever data is ...@@ -152,6 +161,10 @@ In :meth:`.Adapter._get_data`, we can now do the interpolation whenever data is
self.old_data = None self.old_data = None
self.new_data = None self.new_data = None
@property
def needs_push(self):
return True
def _source_updated(self, time): def _source_updated(self, time):
self.old_data = self.new_data self.old_data = self.new_data
self.new_data = (time, fm.data.strip_data(self.pull_data(time))) self.new_data = (time, fm.data.strip_data(self.pull_data(time)))
...@@ -167,6 +180,11 @@ In :meth:`.Adapter._get_data`, we can now do the interpolation whenever data is ...@@ -167,6 +180,11 @@ In :meth:`.Adapter._get_data`, we can now do the interpolation whenever data is
return o + dt * (n - o) return o + dt * (n - o)
.. testcode:: time-adapter
:hide:
adapter = TimeInterpolation()
In :meth:`.Adapter._get_data`, the following happens: In :meth:`.Adapter._get_data`, the following happens:
1. If only one data entry was received so far, we can't interpolate and simply return the available data. Otherwise... 1. If only one data entry was received so far, we can't interpolate and simply return the available data. Otherwise...
......
...@@ -145,9 +145,9 @@ It is called internally by the :meth:`.TimeComponent.initialize` method. ...@@ -145,9 +145,9 @@ It is called internally by the :meth:`.TimeComponent.initialize` method.
# ... # ...
def _initialize(self): # <-- def _initialize(self): # <--
self.inputs.add(name="A", grid=fm.NoGrid()) # <-- self.inputs.add(name="A", time=self.time, grid=fm.NoGrid()) # <--
self.inputs.add(name="B", grid=fm.NoGrid()) # <-- self.inputs.add(name="B", time=self.time, grid=fm.NoGrid()) # <--
self.outputs.add(name="Sum", grid=fm.NoGrid()) # <-- self.outputs.add(name="Sum", time=self.time, grid=fm.NoGrid()) # <--
self.create_connector() # <-- self.create_connector() # <--
...@@ -196,7 +196,7 @@ After this connection phase, models can validate their state in :meth:`.TimeComp ...@@ -196,7 +196,7 @@ After this connection phase, models can validate their state in :meth:`.TimeComp
# ... # ...
def _connect(self): # <-- def _connect(self): # <--
self.try_connect(time=self.time, push_data={"Sum": 0}) # <-- self.try_connect(push_data={"Sum": 0}) # <--
def _validate(self): # <-- def _validate(self): # <--
pass # <-- pass # <--
...@@ -227,7 +227,7 @@ For the tests, we need to set up a real coupling from here on, as the component' ...@@ -227,7 +227,7 @@ For the tests, we need to set up a real coupling from here on, as the component'
# a component to consume output, details not important # a component to consume output, details not important
consumer = fm.modules.debug.DebugConsumer( consumer = fm.modules.debug.DebugConsumer(
inputs={"Sum": fm.Info(grid=fm.NoGrid())}, inputs={"Sum": fm.Info(time=None, grid=fm.NoGrid())},
start=datetime(2000, 1, 1), start=datetime(2000, 1, 1),
step=timedelta(days=7) step=timedelta(days=7)
) )
...@@ -338,7 +338,7 @@ Final code ...@@ -338,7 +338,7 @@ Final code
Here is the final code of the completed component. Here is the final code of the completed component.
.. code-block:: Python .. testcode::
import unittest import unittest
from datetime import datetime, timedelta from datetime import datetime, timedelta
...@@ -347,22 +347,22 @@ Here is the final code of the completed component. ...@@ -347,22 +347,22 @@ Here is the final code of the completed component.
class DummyModel(fm.TimeComponent): class DummyModel(fm.TimeComponent):
def __init__(self, start, step): # <-- def __init__(self, start, step):
super().__init__() super().__init__()
self._step = step # <-- self._step = step
self.time = start self.time = start
def _initialize(self): # <-- def _initialize(self):
self.inputs.add(name="A", grid=fm.NoGrid()) # <-- self.inputs.add(name="A", time=self.time, grid=fm.NoGrid())
self.inputs.add(name="B", grid=fm.NoGrid()) # <-- self.inputs.add(name="B", time=self.time, grid=fm.NoGrid())
self.outputs.add(name="Sum", grid=fm.NoGrid()) # <-- self.outputs.add(name="Sum", time=self.time, grid=fm.NoGrid())
self.create_connector() # <-- self.create_connector()
def _connect(self): # <-- def _connect(self):
self.try_connect(time=self.time, push_data={"Sum": 0}) # <-- self.try_connect(push_data={"Sum": 0})
def _validate(self): # <-- def _validate(self):
pass pass
def _update(self): def _update(self):
...@@ -395,7 +395,7 @@ Here is the final code of the completed component. ...@@ -395,7 +395,7 @@ Here is the final code of the completed component.
step=timedelta(days=7), step=timedelta(days=7),
) )
consumer = fm.modules.debug.DebugConsumer( consumer = fm.modules.debug.DebugConsumer(
inputs={"Sum": fm.Info(grid=fm.NoGrid())}, inputs={"Sum": fm.Info(time=None, grid=fm.NoGrid())},
start=datetime(2000, 1, 1), start=datetime(2000, 1, 1),
step=timedelta(days=7), step=timedelta(days=7),
) )
...@@ -412,3 +412,9 @@ Here is the final code of the completed component. ...@@ -412,3 +412,9 @@ Here is the final code of the completed component.
self.assertEqual(consumer.data, {"Sum": 0}) self.assertEqual(consumer.data, {"Sum": 0})
composition.run(t_max=datetime(2000, 12, 31)) composition.run(t_max=datetime(2000, 12, 31))
TestDummy().test_dummy_model() #doctest: +ELLIPSIS
.. testoutput::
...
...@@ -153,12 +153,13 @@ FINAM provides a comprehensive logging framework built on Pythons standard :mod: ...@@ -153,12 +153,13 @@ FINAM provides a comprehensive logging framework built on Pythons standard :mod:
You can configure the base logger when creating the :class:`.Composition` as shown above: You can configure the base logger when creating the :class:`.Composition` as shown above:
.. code-block:: Python .. testcode:: composition
import finam as fm
import logging import logging
comp = Composition( comp = fm.Composition(
modules, [],
logger_name="FINAM", logger_name="FINAM",
print_log=True, print_log=True,
log_file=True, log_file=True,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment