Book - 3.7) Algorithms - Iteration in BlockPy (Part 2)
Overview
We have seen how the Accumulate pattern can be used to produce quantitative measures of the values contained in a list. We have also seen that decisions can be used in the Accumulate pattern to decide which elements of the list to include in the quantitative measures especially when computing measures of ranges or thresholds. The next two patterns are distinctive in that they both involve the creation of a new list. Such a list can be used as the basis for further computation. In our examples, we will see how the newly created list can be used to create visualizations.
These two list creating patterns are:
- Filter - create a new list that includes only those elements of an existing list that satisfy some criteria,
- Transform - create a new list where each element is obtained by converting in some way the corresponding value of an existing list.
Lists generated algorithmically by the Filter and Transform patterns can be analyzed by computing a quantitative measure for the new list or by visualizing the new list.
Before examining these two patterns we will first see how to create a new list algorithmically. After examining the two patterns we will see how the generate visualizations for the lists.
Creating a New List
We have already seen two ways in which a list can be created. First, a list can be created "by hand" - that is, we can explicitly define the value of each element of the list. However, this method of creating a list is useful only when there are only a few elements in the list. Second, there are sources of data that provide a list. We have seen, for example, data blocks that return lists of values. This method of creating a list is useful when there are many items in the list. Lists of this form contain the values of a single property in a "real world" abstraction that we are analyzing.
The third way to create a list is algorithmically. That is, an algorithm that we write itself generates a new list based on an existing list. In general, the algorithm uses iteration to create a new list as follows:
initialize the <new list> to be empty
for each <element> of the <existing list>
do some computation using the <element> to create a <new value>
append to the <new list> the <new value>
Two new ideas are introduced here:
- initializing a list to be empty
- adding to a list a new element by an append operation
The initialization is needed because, like many properties that are used in an iteration, the list itself must have an initial value. The append operation allows a list to be created one element at a time. Each time the append operation is used it adds another value to the end of the list.
BlockPy provides blocks for each of these two list operations. Both of these blocks are in the List menu. We will see these blocks used in the examples that follow but, in brief they are:
- create empty list : this block is a value for an empty list that can be set as the value of a property
- to list <__> append item <__ > : this block has two slots denoted by <__ >; the first slot is for the list that will be appended to and the second slot is for the new value to be appended to that list
The best way to see the details of these blocks is in the context of their use in the Filter and Transform patterns.
Iteration: Filter ¶
In some cases only certain items in a data set (i.e., a list) are of interest. We can “filter” the data set by iterating through the list looking for the items of interest and ignoring those not of interest. The items of interest are used to create a new list that contains only the items of interest. For example, in the Weather data set the precipitation property records the amount of rainfall on each day. We may be interested only in those days when there is precipitation, ignoring the days when there is no rainfall. The BlockPy workspace below illustrates this example of the Filter pattern. The algorithm shown here creates a new list containing only precipitation values for days when there is measurable precipitation (i.e., the precipitation value is above zero).
Notice that this example has two lists. The "precipitation_list" is initialized from the data block that contains the amount of precipitation for each day that was recorded in the Location "Blacksburg, VA". The "rainy_day_list" is initialized to be an empty list (because we have not yet determined the precipitation amount for any rainy day). Iteration is used to examine, one a time, each "precipitation" in the "precipitation_list". Each "precipitation" value is tested in the decisions to determine if the value it greater than zero. If a given "precipitation" value is greater than zero that value is appended to the end of the list "rainy_day_lists". At the end of the iteration the "rainy_days_list" is printed so that we can see what has been created. Run the algorithm and observe that all of the elements of the list are greater than zero.
In this example the "filter condition" - the condition determining whether a value is of interest - is a simple one: testing if the value is greater than zero. However, the filter condition can be of any degree of complexity.
Iteration: Transform ¶
The transform pattern also produces a new list from an existing list. Each item of the existing list is changed in some way to generate a item that is appended to the new list being created. This pattern is illustrated in the BlockPy workspace below. In this example, each item in the existing list is a temperature on the Fahrenheit scale. What is needed is a list where each item is the same temperature but measured on the Celsius scale. The transform pattern can be used to produce the list of temperatures in Celsius from the list of temperatures in Fahrenheit.
The BlockPy algorithm uses the Weather data block to initialize the property “fahrenheit_temperature_list”. This list is printed. Each of the printed values will be a temperature in Fahrenheit. The algorithm also creates a new list named “celsius_temperature_list” to represent the list to be created. Notice that this list is initialized to be an empty list because it contains no items at the beginning.
The iteration produces the transformed list one element at a time. One each iteration:
- an item, denoted by “fahrenheit_temperature”, is selected from the "fahrenheit_temperature_list"
- the value of “celsius_temperature” is set to the result of converting “fahrenheit_temperature” to the equivalent temperature on the Celsius scale.
- the value of “celsius_temperature” is appended to the “celsius_temperature_list”
When the iteration is completed the “celsius_temperature_list” list is printed. You can run the program and see the correspondence between each item in the original data set in Fahrenheit and its transformed value in the new data set in Celsius.
Combining the Patterns ¶
The individual patterns of uniform, filter, accumulate, and transform can be combined. For example, might want to generate a data set whose items are only temperatures above 85 degrees Fahrenheit, the hot temperatures, and where the temperatures in the generated data set are in Celsius. The program to generate this data stream uses both a filter pattern and a transform pattern.
Visualizing Filtered or Transformed Data
The new list produced by the Filter or Transform pattern can be analyzed by creating a visualization of the data in the newly generated list. BlockPy provides blocks for creating line plot visualizations, scatter plot visualization, and histogram visualizations. Related blocks allow a title to be added to the visualization and for labels to be added to the horizontal and vertical axis of the visualization.
The following BlockPy example shows how the precipitation data produced by the Filter pattern example above can be visualized using a histogram.
In this example, the filter pattern is used to produce a list of days on which there was some amount (greater than zero) of reported precipitation. A histogram of this algorithmically generated list is then drawn, labelled, and displayed. Note the use of these blocks that are in the Output menu:
- plot histogram: draws a histogram for the provided list (in this example, the list "rainy_day_list")
- make plot's title: a string of characters can be used to create a descriptive label for the histogram. The title is centered at the top of the histogram.
- make plot's x-axis label: a string of characters can be used to create descriptive label for the horizontal axis. The label is centered below the horizontal axis.
- make plot's y-axis label: a string of characters can be used to create descriptive label for the vertical axis. The label is centered to the left of the vertical axis.
- show plot canvas: cause the labeled and titled visualization to be drawn in the Printer area. No parts of the visualization will appear until this block is executed.
Other kinds of visualization can also be produced using:
- plot line: draws a line plot for the provided list
- plot scatter: draws a scatter plot for the two provided lists
The same blocks for adding titles, labels, and showing the visualization can be used with these other forms of visualization.