Welcome to my first post on Big Mountain Analytics! The time has come to bid a warm good-bye to Data Shop Talk. I am very excited to be launching my own platform in collaboration with my friend and colleague Jacob Bennett. Check out his information in the About Us page. What a better way to kick off than with a little IronPython.
This week’s post follows up on two posts from last week on IronPython. The first post introduced a code snippet, discussed objects versus syntax, and explained how to modify the code. The second walked thru all of the API references used in the code. This post explains the IronPython code line by line. The intention is to help you better understand IronPython in order to learn to write original code. I am assuming you have read the other posts in the series. So, let’s go!
IronPython Code Snippet
Here is a copy of the code for reference. This code originated with a TIBCO Community post, and it will uncheck all of the checkboxes in a specified filter in the filter panel. If you follow the link, you’ll also find corresponding code to check all the boxes.
High-Level IronPython Code Summary
Now, I wrote the Line By Line explanation (below) first. Upon finishing, I realized it might help to have high-level context when starting. So, here is that high-level context.
Lines 1 – 5 are importing the necessary namespaces, classes, methods, etc that the code will call farther down.
Lines 7 – 13 create objects pinpointing the precise points of the application to be manipulated.
Line 15 specifies what should happen to (Empty) values in the checkbox.
Lines 17 – 19 perform the unchecking.
Next, we can look at the code in detail.
IronPython Line By Line
Line 1
Line 1 import Spotfire.Dxp.Application.Filters as filters
Line 1 imports the Spotfire.Dxp.Application.Filters namespace. As you can see in the API reference, this namespace is used when you need to work with filters and filtering schemes in the filter panel. That is exactly what we are doing – modifying a filter. Now, the developer could have written the code a little differently. He could have written…
Import Spotfire.Dxp.Application.Filters *
This would have imported all the classes, methods, etc from the Spotfire.Dxp.Application.Filters namespace, which would have included the classes he calls in lines 3 and 5. However, if he had done that, he wouldn’t be able to use the “as” keyword to create the “filters” object, which is used later on in the code. You can’t import all and still use “as”.
Lines 3-5
Line 3 import Spotfire.Dxp.Application.Filters.CheckBoxFilter
Line 5 from Spotfire.Dxp.Application.Filters import FilterTypeIdentifiers
Lines 3 – 5 might be confusing. Line 3 uses “import something”. Line 5 uses “from somewhere import something”. Why weren’t these three lines written the same? Well, these different methods of importing have different consequences for naming and referencing the API. Rather than reword it, I’ll just link to an article that explains it really well. Pause and read it.
Line 7
Line 7 myPanel = Document.ActivePageReference.FilterPanel
Line 7 creates an object called “myPanel” that gives the developer access to the filter panel. The Document class opens up the document. The ActivePageReference property will get or set the active page. Thus, ActivePageReference gets to the active page (as opposed to any other page). The FilterPanel property gets the filter panel for the page. As noted in the last post, the Document class is
Line 9
Line 9 myFilter = myPanel.TableGroups[4].GetFilter("BudgetNode")
Line 7 creates an object called “myFilter” which is directing Spotfire to the filter for the column of data that we are interested in. It uses the previously created object, “myPanel”, so we don’t have to type out “Document.ActivePageReference.FilterPanel” (like I just did). Then within the panel, it uses the TableGroup property to find the 5th table (index starts at 0). In order to access filters in the filter panel, you must use the TableGroup, even if there is only one table in your DXP. TableGroup is the path to the FilterHandle, which accesses the filter. Then, the code uses the GetFilter method to get the filter.
Now, you might be getting a bit confused about when to work with the different classes — Filter class, FilterPanel class, and FilterGroup class. Let’s use the API documentation to make it a little clearer. Here is the description for the FilterPanel class.
If you are in the API and click on the links, you’ll see the filters link takes you to the Filters class. The filter groups link takes you to the FilterGroups class, and the TableGroups link takes you to the TableGroups property in the FilterPanel class, explaining how to traverse among these pieces of the API.
Line 11
Line 11 myFilter.FilterReference.TypeId = FilterTypeIdentifiers.CheckBoxFilter
Line 11 uses the “myFilter” object, which is actually a combination of “myFilter” and “myPanel”. What this line of code is doing is making sure the filter in question is a checkbox filter. If it’s not, it changes it to a checkbox. We can test this by commenting out the code to line 11 and then running it. I changed my filter to an item filter and ran the code thru line 11. The code changed the filter from an item filter to a checkbox.
Line 13
Line 13 checkBoxFilter = myFilter.FilterReference.As[filters.CheckBoxFilter]()
Line 13 creates an object called “
Line 15
Line 15 checkBoxFilter.IncludeEmpty = False
This part of the code is here to deal with the (Empty) option in the checkbox. You may or may not have an Empty. Personally, I don’t know why you would want to check/uncheck all and not also check/uncheck Empty.
Line 17 – 19
Line 17 for value in checkBoxFilter.Values:
Line 19 checkBoxFilter.Uncheck(value)
In Line 17, the Values property gets a collection of checkbox values. Collectively, lines 17 and 19 specify what should happen to each value in that collection. Line 19 uses the Uncheck method to uncheck the boxes
I want to pause here and point out something important. Often in IronPython, you’ll see code using “for” and “in” keywords. What’s between the keywords is an object, not syntax. I’ve talked about that before. Generally speaking, that object is going to be whatever collection is accessed with a property. In this case, the Values property returns a collection of values. Thus, the code is specifying what should happen to each of those values, and it just makes sense to name the object in a corresponding manner.
And, it’s done!
Summary of API References
If you want to walk thru everything again, here is a summary of the namespaces, classes, properties, methods, and fields used in this code. (thanks to the new WordPress editor this list is incredibly long)
- Spotfire.Dxp.Application namespace
- Document class
- ActivePageReference property
- Page class
- FilterPanel property
- Document class
- Spotfire.Dxp.Application.Filters namespace
- CheckBoxFilter class
- IncludeEmpty property
- Values property
- Uncheck method
- Filter class
- TypeId property
- As method
- FilterGroup class
- GetFilter method
- FilterHandle class
- FilterReference property
- FilterPanel class
- TableGroups property
- FilterTypeIdentifiers class
- CheckBoxFilter field
- CheckBoxFilter class
Conclusion
There’s a whole lot I haven’t addressed yet. For example, what if you don’t know the difference between a namespace, property or class? Don’t worry, that’s coming in a future post. This learning process is a long game, and I’ll be at it for a while.
Lastly, please add a comment if you have a different way of explaining how this code works.
Spotfire Version
Content created with Spotfire 7.12.
Pingback: Inspect HTML to Find Spotfire CSS Classes » The Analytics Corner
Pingback: How To Make Type Curve Inputs More Efficient » The Analytics Corner
Pingback: Exporting to Excel with IronPython » The Analytics Corner
Thank you, Julie Sebby for this post.
I wanted to see, is there a way I can select multiple tables instead of just one in below line?
myFilter = myPanel.TableGroups[4].GetFilter(“BudgetNode”)
Integrated filtering across tables is possible out of the box with the filter panel, but I’ve never tried to use Integrated filtering with IronPython.