There’s a cool feature of pytest called parametrization.
It’s totally one of the superpowers of pytest.
It’s actually a handful of features, and there are a few ways to approach it.
Parametrization is the ability to take one test, and send lots of different input datasets into the code under test, and maybe even have different output checks, all within the same test that you developed in the simple test case.
Super powerful, but something since there’s a few approaches to it, a tad tricky to get the hang of.
- PyCharm Professional: Try PyCharm Pro for 4 months. Offer good through June 10. Try out Pro features like integrated coverage and profiling, and extended support for Django, Flask, Pyramid, Cython, and more. Promo Code: TESTNCODE2019
- pytest changelog
- pytest deprecations and removals
- Python Testing with pytest — Test function parametrization is in chapter 2. Fixture parametrization is in chapter 3.
- Parametrizing test functions — pytest documentation
- pytest fixtures — pytest documentation
<p>There's a cool feature of pytest called parametrization.<br> It's totally one of the superpowers of pytest.</p> <p>It's actually a handful of features, and there are a few ways to approach it.<br> Parametrization is the ability to take one test, and send lots of different input datasets into the code under test, and maybe even have different output checks, all within the same test that you developed in the simple test case.</p> <p>Super powerful, but something since there's a few approaches to it, a tad tricky to get the hang of.</p><p>Sponsored By:</p><ul><li><a href=”https://testandcode.com/pycharm” rel=”nofollow”>PyCharm Professional</a>: <a href=”https://testandcode.com/pycharm” rel=”nofollow”>Try PyCharm Pro for 4 months. Offer good through June 10. Try out Pro features like integrated coverage and profiling, and extended support for Django, Flask, Pyramid, Cython, and more.</a> Promo Code: TESTNCODE2019</li></ul><p><a href=”https://www.patreon.com/testpodcast” rel=”payment”>Support Test & Code – Python Testing & Development</a></p><p>Links:</p><ul><li><a href=”https://docs.pytest.org/en/latest/changelog.html” title=”pytest changelog” rel=”nofollow”>pytest changelog</a></li><li><a href=”https://docs.pytest.org/en/latest/deprecations.html#deprecations” title=”pytest deprecations and removals” rel=”nofollow”>pytest deprecations and removals</a></li><li><a href=”https://pragprog.com/book/bopytest/python-testing-with-pytest” title=”Python Testing with pytest” rel=”nofollow”>Python Testing with pytest</a> — Test function parametrization is in chapter 2. Fixture parametrization is in chapter 3.</li><li><a href=”https://docs.pytest.org/en/latest/parametrize.html” title=”Parametrizing test functions — pytest documentation” rel=”nofollow”>Parametrizing test functions — pytest documentation</a></li><li><a href=”https://docs.pytest.org/en/latest/fixture.html#fixture-parametrize” title=”pytest fixtures — pytest documentation” rel=”nofollow”>pytest fixtures — pytest documentation</a></li></ul>
There’s a common idea out there that I want to refute. It’s this: when measuring coverage, you should omit your tests from measurement. Searching GitHub shows that lots of people do this.
This is a bad idea. Your tests are real code, and the whole point of coverage is to give you information about your code. Why wouldn’t you want that information about your tests?
You might say, “but all my tests run all their code, so it’s useless information.” Consider this scenario: you have three tests written, and you need a fourth, similar to the third. You copy/paste the third test, tweak the details, and now you have four tests. Except oops, you forgot to change the name of the test.
Tests are weird: you have to name them, but the names don’t matter. Nothing calls the name directly. It’s really easy to end up with two same-named tests. Which means you only have one test, because the new one overwrites the old. Coverage would alert you to the problem.
Also, if your test suite is large, you likely have helper code in there as well as straight-up tests. Are you sure you need all that helper code? If you run coverage on the tests (and the helpers), you’d know about some weird clause in there that is never used. That’s odd, why is that? It’s probably useful to know. Maybe it’s a case you no longer need to consider. Maybe your tests aren’t exercising everything you thought.
The only argument against running coverage on tests is that it “artificially” inflates the results. True, it’s much easier to get 100% coverage on a test file than a product file. But so what? Your coverage goal was chosen arbitrarily anyway. Instead of aiming for 90% coverage, you should include your tests and aim for 95% coverage. 90% doesn’t have a magical meaning.
What’s the downside of including tests in coverage? “People will write more tests as a way to get the easy coverage.” Sounds good to me. If your developers are trying to game the stats, they’ll find a way, and you have bigger problems.
True, it makes the reports larger, but if your tests are 100% covered, you can exclude those files from the report with [report] skip_covered setting.
Your tests are important. You’ve put significant work into them. You want to know everything you can about them. Coverage can help. Don’t omit tests from coverage.
Qt Designer is a great tool for designing PyQt5 GUIs, allowing you to use the entire range of Qt5 widgets and layouts to construct your apps. As your applications get more complex however you may find yourself creating custom widgets, or using PyQt5 libraries such as PyQtGraph, who’s widgets are not available within Designer.
Helpfully, Qt Designer supports a mechanism for using placeholder widgets to represent your custom or external widgets in your design. This tutorial will walk you through the process of using placeholders to include a PyQtGraph plot in your app from within Qt Designer.
The principle of using placeholders in Qt Designer is quite straightforward —
- Create a UI as normal in Qt Designer.
- Add a placeholder widget to represent the custom widget you’re adding.
- Tell Qt to replace your placeholder with your actual widget when building the UI.
In Qt this final step is referred to as promoting (as in promoting a base class).
If the custom widget you are adding is a subclass of an existing Qt widget, you may want to use the base class as your placeholder to promote from. For example, if you have a custom
MyAwesomeButton button widget subclassed from
QPushButton as the placeholder and promote it to
MyAwesomeButton. This gives you access to the base class properties, events and actions from within Qt Designer.
If you don’t have an obvious base class to use, then you can use
QWidget, the common base class of all Qt widgets.
Data science is one of the post popular uses of Python, and building dashboards and analysis tools is a common use case of PyQt5. For all of these being able to add plots to your UI is very useful — and being able to do this from Qt Designer even more so.
There are a number of plotting libraries available in Python, with matplotlib being the most popular and offering some basic support for PyQt5. PyQtGraph is an popular alternative which uses Qt’s native
QGraphicsScene to provide fast zooming, scaling, drag-drop behaviour that feels a natural part of your application.
Whether you’re using PyQtGraph or maplotlib for your plotting needs, the plot canvas widgets are not available from within Qt Designer. In this tutorial I’ll walk you through the process of using these custom widgets in your apps.
If you don’t have PyQtGraph installed already, you can install it using:
pip install pyqtgraph
The instructions below aren't specific to PyQtGraph, and you can use the same process to add matplotlib or any other custom widgets to your app.
We will be using Qt Designer to create a simple UI design, and adding a placeholder for our PyQtGraph widget. First open Qt Designer and create a new
QMainWindow as normal.
We next need to add the placeholder widget. As there is no suitable baseclass for the PyQtGraph plot widget, we’ll use the basic
QWidget as our placeholder. Select the Widget from the left sidebar and place it in the centre of your window.
Give the widget a name, “graphWidget” will do. This is just a tag to reference the element in code.
Right click on the widget and select Promote to from the widget’s context menu.
QWidget indicates that it should be replaced with the specified subclass, in our case the PyQtGraph plot widget.
A promoted widget can be reverted back to its base class by right-clicking and choosing Demote to from the widget's context menu.
You will be presented with a dialog to specify the custom widget class the placeholder widget will become.
The header file is the name of the Python module used to import the class, which is
PlotWidget as the class name of the widget to replace it with.
The name you use for the file doesn't matter, but it's usually a good idea to name it after the class you're going to create with it.
Voila! The widget is now promoted to a canvas to plot. But you won’t be able to see any changes within Qt Designer. Save the window as
mainwindow.ui in the same directory as your PyQt app.
Loading the .ui file
We now have the
mainwindow.ui file containing our UI definition. We can load this from Python to show the window and our custom widget.
Let’s start from a basic app template.
from PyQt5 import QtWidgets, uic import pyqtgraph as pg import sys class MainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) #Load the UI Page uic.loadUi('mainwindow.ui', self) def main(): app = QtWidgets.QApplication(sys.argv) main = MainWindow() main.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
Save the code above in the same folder as your
mainwindow.ui file, and run it as normal.
You should see a window with your widget transformed into a PyQtGraph plotting widget.
Let’s now create a function to make a simple plot of
from PyQt5 import QtWidgets, uic from pyqtgraph import PlotWidget, plot import pyqtgraph as pg import sys # We need sys so that we can pass argv to QApplication import os class MainWindow(QtWidgets.QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) #Load the UI Page uic.loadUi('mainwindow.ui', self) self.plot([1,2,3,4,5,6,7,8,9,10], [30,32,34,32,33,31,29,32,35,45]) def plot(self, hour, temperature): self.graphWidget.plot(hour, temperature) def main(): app = QtWidgets.QApplication(sys.argv) main = MainWindow() main.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
So we added the
plot() method which accepts two arrays,
temp Temperature and
hour Hour, then plots the data using the graph widget
Run the code, you should see the following.
That’s it! You have just embedded your first plot with PyQtGraph.
The default PyQtGraph plot isn’t very pretty, however can play around with the
.plot() call to change the data shown.
We’ll cover more complex PyQtGraph plots and plot customization, including line colours, styles and alternative types of plots in an upcoming tutorial.
I’ve been doing marketing at InterWorks for eight years. Truth be told, I’ve had Impostor Syndrome the entire time. I didn’t come from fancy schools. I don’t have a marketing degree. I am fortunate to be one of the first college graduates in my family at all. Our partners and competitors are often way bigger than us—we are small giants after all. But it’s easy to feel intimidated.
After all these years, I am still learning every day about the art of marketing; the connection of marketing. The truest, most authentic ways that marketing can make great things happen in the world.
Impact and Trust
InterWorks is a place that brings people and technology together for great experiences and empowerment—and for eight years, I’ve gotten to watch that happen over and over with our customers. But InterWorks, from my view in marketing, is a brand. Brands are meant to be marketed—no, they are meant to have an impact on the audiences they serve. Recently, I have been exploring what it means to be a brand that people can trust. I took some time to ask our marketing team about their favorite brands, as well as brands they have left.
I have an endless fascination with people, their insights and what I can learn from them to become a better human and a better marketing manager. This collection of responses has been a great learning experience.
P.S. This is also a great topic to discuss with friends. Brands can be a true reflection of people’s interests and values once you dig into the details.
Brands That Resonate with Us
Here are some snippets/trends from the team when talking about their favorite brands. I intentionally left out all brand names in an effort to remain focused on the feedback. There are a lot of examples, but each one provides different perspectives that I believe are important:
- “I have a good history with this brand; they change things up all the time and provide new products in an interesting way but keep the quality high. I also personally know some of the owners, and they’re good people. They are interested in new and different products for their audience, but they remain consistent in the delivery and creativity.”
- “I ordered products from this brand online, and the entire experience was really good. Their package design is really strong yet simple. They do things that fuel customer success, like offer online resources and emails on the products I bought that give me tips on usage. They have a dreamy lifestyle presence on Instagram that inspires me. They aren’t overselling to me; I like them because I get the feeling they care about my success versus caring about selling me more things. Honestly, I will probably go back and buy more from them because of this. They seem genuinely interested in the products they provide to their customers.”
- “There is a brand I got interested in because their CEO decided to use her wealth and influence in a good way to start a company she felt passionate about. I order their products, and it’s a great brand experience for me; I have ordered from them several times, and each time, I am excited to see how the products are delivered. They also did some email follow-up with me that seemed very streamlined and not abrasive at all.”
- “There’s a shop here in town I visit often. I could easily get the products online, but the people in the shop have been so helpful, even when I didn’t spend a lot of money with them initially. They seem very invested in the success of their customers, and to me, that means they take pride in their work.”
- “I worked for a company for several years, and while I like their product, working for them helped me realize how they train their teams in the art of customer care. Every detail has been considered. Even when you put the product in the bag and send it home with the customer, you do it in a way that they feel is cared for and important.”
- “There are several brands I love and am heavily invested in. When I compared them all, I found that I am interested in brands that keep things fresh and relevant to me as their customer. They stay true to their values. Some of these companies have mastered the art of staying the same, while also providing new products that they seem to know I will want before even I know that! They have great consistency in their brand and seem relatable even when they have a massive customer base. These brands have a healthy evolution over time: some of them have an edgy quality to them, which keeps me intrigued. Some brands seem to really recognize their success and come back to it and build on it often, so their customers stay comfortable. There are a lot of brands that are also masters of simplicity with their design. With my favorite brands, I am willing to pay more for their products because I know it’s going to be great.”
- “There is one brand I really love because their product really fits me as a consumer, but the ironic thing is that their social media presence isn’t that great, but that doesn’t bother me. I actually kind of like it because it seems like they’re invested more in their product than their social presence. This makes me think that the brand is straightforward and honest, the quality is high and more substantial than their competitors. They have all of these high standards but make it seem effortless and genuine.”
- “Recently, I discovered a brand through a friend and was impressed by the website experience—resources and new products, plus it’s well designed. It’s cool, it’s effortless and it’s comprehensive. They aren’t trying to insert more into the industry than they have to because they know their product is solid and timeless.”
- “Quality products and they are ahead of the other technology in the market. They always seem to be trying to improve. Often, they offer things that I didn’t even know I needed but now cannot live without. They seem to be there at every turn with me as a customer. They have guided me through some of the unknowns. and I just love them for that.”
Above: My notes from team interviews about brands
Brands We’ve Decided to Leave
Now, let’s look at what our marketing team said about some of the brands they left:
- “I used to be really excited about this place and what a different vibe they had. I was really invested, and the quality was really high, then things started to change as they got popular. They developed a pretty pretentious attitude that I couldn’t ignore. They became something different from what I originally thought that they valued—their purpose had shifted. I haven’t been back in a while and from what I see on social media and have heard from friends, things haven’t really gotten better or gone back to where they were in the beginning.”
- “I left a certain brand because I felt like I outgrew them. I’m not sure if the quality of the product went down or maybe my standards got higher. Seems like the products I bought had a short shelf life, and I was wasting my money. Their goal was to appeal to lofty trends that weren’t really timeless. There was another brand that changed their logo, but their previous logo design was timeless, and I really don’t know why they changed it, and now I hate it. The previous logo was iconic and just seeing that branding made me trust the brand, and now I don’t know how to feel.”
- “I used to spend a ton of money with this one brand; the product was known for being really good. They had wholesome branding, and I was really attached to it and would pay extra for it, no questions asked. Then they had a really nasty PR incident that left their audience in turmoil. They did their best to address it, but I don’t think they actually fixed it or clarified their stance. I lost trust in them after that, and I don’t think it can be recovered.”
- “There are a few brands that have great products, but their prices are really high, and I think that has more to do with profits than quality of the product. Quickly, I learned that a little bit of research shows me brands out there where their product is great and the values align with me—their purpose and the care they show not only to their customers but also to their employees makes me feel very trustworthy, and I want to give those companies my money. I don’t think I care for companies or leaders of companies who are interested only in their own personal gains and success.”
- “I bought some products online from this brand, and I should have known better. Their website experience was pretty terrible, but they offered the product with a fast turnaround, which was what I needed; plus, they had decent/cheap prices. They totally messed up my order, and when I reached out, they were slow to respond. When they finally did respond, they didn’t want to fix the issue. I wanted my money back, and all they could offer was a discount of future products from them. Why would I order more and put myself through this again? I’m not going to do that, even if it’s discounted. Bad customer service made me leave.”
Above: If you see me in the office, I’m probably wearing denim and asking lots of questions that I hope help people get to know each other better.
And maybe we’ll learn something new.
Here’s what I learned from this exercise: you love brands when you feel that they love you. There is an emotional response somewhere to brands that understand you. These brands seem to be there for you at the right times. Brands you love aren’t just trying to sell you something; they care about your success. If anything, branding and marketing should mimic the human nature of connection—you want to be seen and heard … and valued. Brands that do it right do that with their audience at a wide scale. Marketing is human connection at scale.
We hope our customers know that behind the technology and our brand, there are really nice, fun people that want to help. We hope our customers feel seen and taken care of, and our marketing should reflect that.
Brands that you leave, you leave because of a bad experience. Needs are not met. Relevance with you is lost. Values no longer align. Trust is broken. The team spent way more time talking about brands they love and really didn’t want to talk much about the brands they left. Over it.
Creating a Meaningful Connection with a Brand
When I reflect on these insights with the marketing team, I challenge them to approach our marketing and brand representation with these feelings in mind. To take the collective inspiration of the incredible teams that represent InterWorks, get inspired by our customers and then take the inspiration you feel about brands that you love and charge your work energy with that.
In an age of facades with social media and technology, people want to believe in brands that represent something true and are authentic. We hope our customers know that behind the technology and our brand, there are really nice, fun people that want to help. We hope our customers feel seen and taken care of, and our marketing should reflect that.
I still don’t know if we are doing marketing right, and I’m not sure the Impostor Syndrome ever goes away (read more on that in a recent blog from one of my colleagues). But times like this make it seem like this could be the path to good marketing or something like it.
The post Learning from Brands You Love and Brands You Leave appeared first on InterWorks.