Easy Eggs Benedict

Easy Eggs Benedict

There’s really not much to making this fabulous breakfast (or lunch or dinner) dish. This video shows how to make Eggs Benedict in about 10 minutes.

Actually, the video is only 9 minutes, because we cut out part of the egg poaching time.

But all you need to make Eggs Benedict is

  • 2 English muffins, split and toasted
  • 4 slices ham, sauteed in butter
  • 4 eggs to poach
  • 3 egg yolks
  • 1-2 Tb lemon juice
  • ¼ lb butter melted and still hot

Sauté the ham slices in butter for about a minute.

Toast the split English muffins and top each half with a ham slice.

The important part of making the Hollandaise in a blender is to melt the butter so it is hot and bubbly. In our microwave, this is about 75 seconds (1:15 minutes). Make sure the butter is quite hot, so it cooks the egg yolks a bit when you pour it into the blender with the yolks and lemon juice.

To poach the eggs, we use a 3-quart saucepan with water gently simmering. Add salt and about 2 Tb white vinegar to the water, and quickly slip the 4 eggs into the water. No need to stir or swirl. Set a timer for 3:00 minutes and then lift the eggs out and put them on the toasted English muffins with the hams slice. Pour on some hollandaise and serve right away. Decorate with a bit of parsley if you like.

This makes a festive breakfast in about 15 minutes, including the time to bring the water to a boil. Enjoy it!

Entering data in Python: console or GUI

Entering data in Python: console or GUI

Suppose you want the user to enter some data for a Python program to work on. For this, Python provides the input statement, which can print out a prompting string and wait for keyboard input. 

name = input("What is your name? ")
print("Hi "+name +" boy!")

This little program asks for your name and waits for you to type a string and press Enter. The input statement accepts keyboard input and returns a string. So, the resulting console results might look like this:

What is your name? Jim
Hi Jim boy!

Heinlein fans may recognize the reference.

You can paste that 2-line program into any development environment, such as Thonny, PyCharm or even Jupyter Notebook and see it work right away.

Adding two numbers

Of course, you can enter numbers as well, but you must be sure to convert the resulting strings into an int or a float. Here we use the more general float.

x = float(input("Enter x: "))
y = float(input("Enter y: "))
print("The sum is: ", x+y)

The resulting output is:

Enter x: 23.45|
Enter y: 41.46
The sum is:  64.91

Of course, this naïve program expects only legal input. If you enter, say, “qq” instead of 22, you will get a Python error:

File "C:\Users\James\PycharmProjects\input\inputdemo.py", line 7, in <module>    
y = float(input("Enter y: "))
ValueError: could not convert string to float: 'qq'

There are ways to check for this, of course, such as catching Exceptions, and we will explain those in the following example.

However, you will only find the input statement in rudimentary examples. Most programs that need user input get it from a windowing interface. We’ll show these same examples next using the tkinter GUI library.

Making a windowing example program

You can do much the same thing by using the Entry field in the tkinter GUI (graphical user interface). Here we repeat those examples in simple tkinter windows.  To use tkinter, you have to import that library into your program:

from tkinter import *
import tkinter as tk

You also create an abbreviation for tkinter, naming it just tk.

Then, most of the setup code creates the visual widgets and their arrangement. In the following example, we use an Entry field, a Button and two Labels. You start by getting the window system pointer tk.Tk() and use it to attach the widgets to. After you create this objects, you run the mainloop() function which displays the window and receives mouse and keyboard input. The window keeps running until you close it by clicking on the “X” in the upper right corner or selects some widget that causes the window to close.

Our first example above was one where you enter your name and it says Hello back, again giving homage to Heinlein in the process. The tkinter program does the same thing

The code for this program creates the two labels, the Entry field and the OK button:

def build(self):
    root = tk.Tk()
    # top label
    Label(root,
         text="""What is your name?""",
         justify=LEFT, fg='blue', pady=10, padx=20).pack()

    # create entry field
    self.nmEntry = Entry(root)
    self.nmEntry.pack()   # and put it into the window

    # OK button calls getName when clicked
    self.okButton = Button(root, text="OK",
                            command=self.getName )
    self.okButton.pack()

    # This is the label whose text changes
    self.cLabel = Label(root, text='name', fg='blue')
    self.cLabel.pack()
    mainloop()      #run loop until window closes

When you click on the OK button, it calls the getName method, which fetches the text from the entry field and inserts it into the bottom label text.

# gets the entry field text
# places it on the cLabel text field
def getName(self):
   newName = self.nmEntry.get()
   self.cLabel.configure(text="Hi "+newName+" boy!")

Adding two numbers

And our second example rewritten from above reads two Entry fields, converts them to floats and puts the sum in the lower label.

 The code for this window is much the same, except that we fetch and add two numbers. Here is the function the OK button calls.

xval= float(self.xEntry.get())
yval = float(self.yEntry.get())
self.cLabel.configure(text="Sum = "+str(xval+yval))

Catching the error

However, if you enter some illegal non-numeric value, you can catch the exception and issue a error message:

try:
    xval= float(self.xEntry.get())
    yval = float(self.yEntry.get())
    self.cLabel.configure(text="Sum = "+str(xval+yval))
except:
    messagebox.showerror("Conversion error",
                              "Not numbers")

If you enter non-numeric strings, the program displays this message box:

And that’s all there is to creating a program with a simple graphical user interface.

Steak béarnaise using a blender

Steak béarnaise using a blender

Steak béarnaise is a simple dish. You cook a steak and pour some sauce béarnaise over it. You can cook the steak over a grill, in a cast iron pan, or even in the oven. Here is a classic description of cooking an (effing) steak.

But how to make béarnaise? It’s really very easy, and here we simplify it even more by using a blender and a microwave.

  • 1/3 to ½ cup dry white wine
  • 2 scallions, chopped
  • 2 tsp tarragon
  • 3 egg yolks
  • ¼ lb (1 stick) butter
  • Another 2 tsp tarragon
  • 1 steak (sirloin or ribeye works well)
  1. Put the wine in a small saucepan and add the scallions and tarragon.
  2. Boil the wine down to about 1-2 tablespoons. Do this slowly, so the pan doesn’t suddenly go dry.
  3. Strain the wine reduction into a small dish, pressing the scallions to squeeze out any remaining wine.
  4. Put the 3 egg yolks and the wine reduction in a blender and pulse briefly.
  5. Melt the butter in a microwave for about 1 minute. The butter should be hot and bubbly. If it isn’t, add another 15 seconds or so. You need the butter hot to cook the egg yolks.

  1. Slowly  pour the hot butter into the running blender. Add the remaining tarragon and turn off the  blender. Let it set while you prepare the steak.
  2. Cook the steak to about 120˚ F.  Let it rest for at least 5 minutes. Then cut it into serving strips.
  3. Pour the béarnaise over the steak and  serve it. If by any chance you want the béarnaise thicker, you can heat it briefly over low heat, with constant stirring.

Serve with baked potatoes and a veggie or salad (or both).

Ten products you can skip –as seen on TV

Ten products you can skip –as seen on TV

Cable news, even when its reporting is sound, is rife with advertising of products you never heard of. And for good reason, advertising is relatively cheap on cable news and anyone can flood the news with “wonderful new products” that probably aren’t that great.

Prevagen does not improve your memory, as explained in this Harvard Health blog. . You have probably seen Prevagen ads everywhere. Targeted particularly at seniors who may experience normal word finding difficulties, the claims may mention “studies,” but not “doctors,” because no doctor recommends. It. Allegedly extracted from jellyfish (apoaequorin) actual studies have shown no significant effect, although by rearranging their data (called p-hacking) Quincy Biosciences has claimed it does. The FDA does not agree as explained in this Science Based Medicine article. The Global Council on Brain Health concludes that  “there is no convincing evidence to recommend daily dietary supplements for brain health in healthy older adults.”

The ASPCA does not help your local animal shelter. Despite their tear-jerking ads, the ASPCA is a New York City organization, and is not an umbrella organization for your local SPCA. Give to your local animal shelter instead. Further the ASPCA has been criticized for euthanizing pets rather than saving them.

Zerowater is a water filtering pitcher which takes about six minutes to filter a quart of water. Consumer Reports rated it Very Good and the competing Britta filter Excellent. It takes only about 1:15 to filter a quart of water. However, the Zerowater seems to removes 98% more contaminants. Unless your tap water has an unpleasant taste or smell, these may not  be that valuable.

Mr Clean Magic Eraser.  These products look like a good idea and have positive reviews, although it is not clear how they improve on a damp paper towel and some SoftScrub.  According to reviews at The Spruce, “Because the eraser works by scrubbing at the surface with tiny but extremely hard threads, you should not use on highly glossy or satin finishes….it is not appropriate for paneling or wood finished surfaces. It will strip away the surface and create damage and the sponge does begin to break down after [several] uses.

Tac Shaver by Bell and Howell. The reviews of this shaver are mixed, but according to this review apparently it didn’t last long and the beard trimmer didn’t do much. The Bell and Howell company you may remember from years back essentially got out of the technology business in the 2000’s and is now just a name owned by Westview Capital Partners.

COQ10 with Turmeric – If you are taking statins, a COQ10 supplement won’t do much of anything more. And turmeric is mostly good in curries.

Flex Seal is one of those As Seen on TV pitches you probably are skeptical of. You should be. It works for some things, but has a cumulative review of 1.5 out of 5 stars.

Yoshi Copper Grill MatIt “sort of works” but can’t be placed over an open flame. You could use it on a gas grill with covered burners, though.

Spin Power – is a multi-outlet charging station for your cordless devices. It does not include any spot for phones that can be charged by induction. It has mixed reviews on Amazon as you might expect from anything from ASOTV.

WATCHMAN – is an implant from Boston Scientific for stroke prevention. It is FDA approved and in wide use, But it was criticized in a handful of studies cited by Dr David Becker from Chestnut Hill Temple Cardiology and by Dr John Mandrola of Baptist Medical Associates of Louisville. If you are a candidate for this implant, discuss these objection with your cardiologist. The product has been generally  successful.

Spurtles – I never heard the word outside of the commercials from Lucinda’s Kitchen. They seem to be a set of wooden kitchen utensils made of acacia wood. Lucinda claims these exactly fit pans and jars and are more useful than what you have now. (I seriously doubt that.) You must hand wash them rather than tossing them in the dishwasher. This review calls them low-quality, not durable and having delayed delivery.

Comparing Python Tkinter and PyQt5

Comparing Python Tkinter and PyQt5

TkInter is the well-known GUi system based on the Tk toolkit and interfaced to Python so that it has become the preferential GUI interface system. PyQt5 is an analogous user interface developed and support by Riverbank Computing, and is essentially a set of bindings for the QT platform developed by the Qt company. PyQT5 is available under a GNU GPL v3 license, or as a commercial license. This essentially means that you can use PyQt5 freely, but you must distribute your source code with any product you build using PyQt5. Or, you can buy a commercial license.

GUI using Tkinter

GUI using PyQt5

The two figures above show the same interface developed in Tkinter and PyQt5. They show that you can build pretty much the same kind of GUI with either system.  I spent a week learning PyQt5 and building the new interface to match the one I had already built in Tkinter. Each system has different advantages and disadvantages, and we’ll summarize them in the article that follows.

The tkinter version is fully integrated with the database, but I only bother to connect the right hand searchbox and listbox to the database in PyQt5. The rest are just hardcoded,

But basically, the systems do about the same things and are about equally easy (or hard) to use, and you can’t go wrong using either of them. There was no clear winner of this experiment: once you have climbed the learning curve you can build nice-looking systems either way.

I built the Tkinter version of this interface as part of a larger development project to interface our opera company’s data to a new MySQL database, where building a UI gave us the ability to view the information in more flexible ways. This screen represents a way to create a cast list for the current and previous shows and generate spreadsheets of those casts for the Board , the cast and the directors to work with. The left-hand table is the final cast, sorted by role-type and sex, which amounts to one simple database query.

It allows you to select any person in our database and assign them a role in the current or an older production.

I learned how to use PyQt5 from the on-line PyQT5 reference guide as well as from this short tutorial by Michael Herrman. He has also written a book on PyQt and there is a link to it at the bottom of the tutorial.  The Zetcode tutorial was also helpful. There is also a video tutorial at learnpyqt.com.

If you want to build a GUI using listboxes, buttons and checkboxes, you won’t have any trouble with PyQt. In fact, since the listbox automatically includes a slider, you will find it a bit easier.  It is also worth noting that all PyQt widgets have Tooltips: helpful phrases that can explain what a widget is for.

I already noted that the QRadioButtons work better if you derive a class that holds the button index or title, using a Mediator pattern.

Layout managers

Tkinter has two major layout managers, pack() and grid(). Pack arranges the objects in the frame you provide. Grid allows you set up an n x n  grid and place the objects in one or more grid cells.

PyQt5 has three layout managers: QHBoxLayout, QVBoxLayout and QGridLayout. You can add widgets to the box layouts and they will line up horizontally or vertically. The QGridLayout is similar to, but not the same as, the tkinter grid. The biggest single difference is that if you place a widget in a grid cell, it expands to fill the entire cell. In order to put a button in a grid and not have it stretched to fill the cell, you have to add a QHBoxLayout inside the cell and then perform a hbox.addStretch(1) before and after the button to center it. These are essentially spacers that grow to fill the space on either side of the widget.

QtDesigner

PyQt5 provides the QtDesigner app which allows you create layouts visually. It actually includes layouts, and you can at least look at what code it generates. However, the resulting file is of type .ui and you have to run the pyuic5.exe program to convert the .ui file to a Python file. Once you have done this and edited the Python file, you can never go back to the designer.

Events in Qt5 are referred to as signals and slots, where the event is a signal and the callback function is a slot.  You can easily write analogous programs in PyQt5 to handle events much as you do in tkinter. You can also do this in the QtDesigner, but the event interface in the designer is a lot of trouble to use. Writing the code yourself is easier, and you probably would want to modify the code anyway. And, again, once you change the code, you can’t do back to the designer.

PyQt5 Style Sheets

While PyQt5 widgets have a plethora of useful methods, the designers left out such things as changing colors and borders. For this you have to resort to CSS (Cascading Style Sheets).  You can find a whole web page of Qt5 CSS examples here.

For example, suppose you want a label to be blue instead of black. In tkinter, you would write:

lb1 = Label(cFrame, text="Character", foreground='blue')

But in PyQt5, you would have to write.

lb1 = QLabel("Character")
lb1.setStyleSheet("QLabel { color : blue; }")

This sets the style for all instances of QLabel, but you can specify an individual label as well.

A more difficult case was setting the border of the GroupBox (which is the same as a tkinter LabelFrame). I also changed the color of the text label here too.

self.app.setStyleSheet("""QGroupBox {border:1px solid black;
    margin-top: 10ex;  padding: 15 3 px; }""")
self.setStyleSheet("QGroupBox::title {"
                     "color: blue;"
                    "background-color: transparent;"
                    "padding-top: -50px;"
                    "padding-left: 8px;} ");

Setting these style sheets can be tricky because you do not get any errors if you leave something out, like that terminal semicolon.

Listboxes and Model-View-Controller

PyQt5 has a list box, a table widget and a separate Treeview widget. While each of them can be used as stand-alone widgets, they also can be used in the Model-View-Controller system, where the data is the Model, the widget is the View and the Controller is the user or some external event. Essentially this is useful when the data changes frequently and this will cause your table to be refreshed automatically. I haven’t tried this out yet, as it takes quite a bit of programming. However, there are list and table widgets you can use without getting into using MVC.

I found the table display troublesome, because while you could remove the gridlines and left hand column numbers, the lines were quite widely separated.  After consulting the informants on Stackoverflow, I found that you could code the line spacing a line at a time. It turns out that the height of each row is calculated from the top of the table, so for each row, you have to calculate it as follows:

self.castTable.setRowHeight(row, (row + 2) * 7)

It turned out, however, that the spacing in the Treeview looks a lot better, and I am switching to that.

Conclusions

Tkinter is better documented and may a bit easier to work with. But there are more widgets in the PyQt5 library, including date editors, a progress bar, a slider, a font picker, a toolbar, and a multiline text entry field. It also supports the MVC pattern and includes Tooltips, which might be helpful for new users. While Herrman felt there was a difference in the clarity of the widgets, I didn’t notice it.

PyQt Radio Buttons and the Mediator Pattern

PyQt Radio Buttons and the Mediator Pattern

In our previous article, we showed how to derive a new class from QRadioButton that keeps the index value of that button and keeps the click event callback right in the class itself.

In this simple article we are going to look at an easy program that fills an entry field with a text string based on which radio button you select. We also introduce you to the Mediator Design Pattern to help communication between widgets.

We came up with this little trick while writing a program to create a cast list for our operetta company. Leads play named roles, but for chorus member we just store their voice part. The radio buttons are labeled S, A, T and B, and when you click on one of them, the entry field is filled with the full name of that voice part: Soprano, Alto, Tenor and Bass. Since the entry field is editable, you can add more text like “2nd Tenor” where this might be useful, and that name is stored as part of the last list. 

Using a Mediator

When you click on any of the RadioButtons, the long name is copied into the entry field. The question is, how does it get there?  In effect, each of the four button instances need to communicate with the entry field. And, while that is not difficult to achieve, it doesn’t scale very well as your program grows to include more visual widgets. To simplify this problem, you use the Mediator Design Pattern and the Mediator class.

Rather than the various controls all sending information to each other, the Mediator class becomes the traffic cop that receives the various button clicks and other widget actions. Then, it knows about the other controls you might want to communicate with and passes the click information on to them. So, when we create instances of the derived vcRadioButton, you pass it the label it displays, the long name it is to send on to the entry field and a reference to the Mediator class:

You first create the Mediator and give it a reference to the entry field  (which is called QLineEdit in PyQt5):

# create the entry field
self.entry = QLineEdit()
grid.addWidget(self.entry,0,0)

# Create Mediator and
# pass it the entry reference
self.med = Mediator()
self.med.setEntry(self.entry)
# Create a GroupBox for the four radio buttons
self.voiceBox = QGroupBox("Voice part")
vcGrid = QGridLayout()

Then you create the buttons and pass each of them a reference to the Mediator

# create the four radio buttons and labels
vs = VcRadioButton("S", "Soprano", self.med)
va = VcRadioButton("A", "Alto", self.med)
vt = VcRadioButton("T", "Tenor", self.med)
vb = VcRadioButton("B", "Bass", self.med)


# and add them to the 2 x 2 grid
vcGrid.addWidget(vs, 0, 0)
vcGrid.addWidget(va, 0, 1)
vcGrid.addWidget(vt, 1, 0)
vcGrid.addWidget(vb, 1, 1)

Then we add the vcGrid to the voiceBox layout, and the voiceBox to the outer grid.

self.voiceBox.setLayout(vcGrid)
grid.addWidget(self.voiceBox, 1, 0)
self.setLayout(grid)

The VcRadioButton class

Our actual VcRadioButton class is even simpler than the one we wrote for the six radio button example, because we don’t have to store anything in a class variable: we just tell the Mediator that the button has been clicked.

class VcRadioButton(QRadioButton):
    def __init__(self, label, title, med):
        super().__init__(label)
        self.title = title  #save the title
        self.med = med      # and copy the Mediator reference
        # connect the button clicks to the comd method                                                   
        self.toggled.connect(self.comd)

    # returns title stored in this class instance
    def getTitle(self):
        return self.title
    # gets the title and puts it in the character entry field
    # using the Mediator
    def comd(self):
        radio = self.sender()   #get the button you clicked
        if radio.isChecked():   # if checked copy the title
            self.med.setVoice(radio.getTitle())

Note that the VcRadioButton connects the click event (called toggled in Qt5) to the comd method right there in the same class. And that comd method tells the Mediator to set the voice part into the entry field.

Then finally our Mediator is simple, since we are only mediating connections between radio buttons and the entry field. When the radio button is clicked, it calls the setVoice method in the Mediator, which copies the text into the entry field.

# The Mediator saves a reference to the entry field
# and copies text into the field when setVoice is called

class Mediator():
    # save the entry field reference
    def setEntry(self, entry):
        self.entry = entry
    # copy the text into the entry field
    def setVoice(self, text):
        self.entry.clear()
        self.entry.insert(text)
 

This may seem like a lot of running around to copy text into an entry field, but the Mediator quickly becomes quite important when your program needs to handle interactions among a number of widgets, such as list boxes, push buttons and check boxes. It is probably the most useful and significant of the 23 Design Patterns when you are writing user interfaces.

Improving the Radiobuttons in Python Qt5

Improving the Radiobuttons in Python Qt5

PyQt5 is an alternative GUI interface for Python that you can use instead of Tkinter. Both systems provide ways to create buttons, listboxes, tables, checkboxes and radiobuttons. PyQt5 has a number of advantages, though, including built-in Tooltips. Coding for PyQt is in general as easy or easier than for tkinter, but there are some quirks.

One place where you might find it more troublesome is in the way that it handles Radiobuttons. So, in this article, we show you how to make the QRadioButton class a little friendlier.

Now, the idea of a Radiobutton is that you can only select one button, just like old car radios. This interface is now displayed on some screen in your car, rather than by actual push buttons. But the idea is that if you pick one, any other selected button is unselected.

If you have more than one group of Radiobuttons on a page, you want to find a way to group them so that clicking on a member of one group doesn’t affect the other group. In Tkinter, you do this by associating all the members of one group with a single external variable. Then, whatever button you click changes the value of that variable. So, if you have three buttons, the variable might take on the value 0, 1 or 2.

In Qt5, you group the variables by putting them inside a frame or Groupbox. And how do you find out which on was clicked? You have to run through them all to look for which one’s isChecked() status is true. Now, if there are only two buttons this is simple: you only need to check one button. If its status is false, then the other one must be true. 

But what if you have six or more buttons like in this interface for storing cast members in an operetta?

Figure 1: Six radio buttons used in generating a cast table.

In the tkinter approach, you just take the value of that external variable. In PyQt5, you would have to run through them individually or put them in an array (or List) and run through that.

But here is where we have a cooler solution. The QRadioButton is a first class object and you can create derived classes from it really easily. So, all we need to do, is create a RlRadioButton derived from QRadiobutton which contains an index value for each instance of the button. So, we could write

Lead = RlRadioButton(“Lead”, 0)
MinorLead = RlRadioButton(“Minor lead”, 1)

And so forth.  We can then keep the index of the each button in an instance variable: self.index.

class RlRadioButton(QRadioButton):|
    clickIndex = 0    # key of last button selected stored here

    def __init__(self, label, index):
        super().__init__(label)
        self.index= index

Note that the variable clickIndex is a class-level variable There is only one copy of this variable, shared by all six instances of the RlRadioButton class. But how does this variable get set?

It gets set when you click on that RadioButton. We connect the click event for each button to the same method within the button class.

self.toggled.connect(self.onClicked) #connect click to onClicked

The toggled event occurs whenever you click on a button. The event occurs on the button you click on AND on the button which becomes deselected. So, you must check to see whether the button is selected. If it is selected, this method copies the index of that button in that instance into the class variable clickIndex.

#store index of selected button in class variable
def onClicked(self):
    radio = self.sender()
    if radio.isChecked():   #if it is checked, store that index
       
RlRadioButton.clickIndex = radio.getIndex()

So, what is happening is that there are six instances of RlRadiobutton, one for each button. Each instance has a different index number, and if the button for that instance is clicked, it copies its index into the class variable clickIndex they all hold in common. Then, to find out which was selected you simply check the variable RlRadioButton.clickIndex from anywhere in the program.

We illustrate these instances of the RlRadioButton in Figure 2 below, where button 1 was selected.

Figure 2: Three instances of the RlRadioBtton class, showing that they all have access to the same clickIndex class variable.

This shows that while there are three instances of RlRadioButton with three different indexes, there is only one copy of clickIndex that all instances of the RlRadioButton class share.

In Figure 1, you can click on the Status button to see which Radiobutton was selected. The program then fetches that value from RlRadioButton.clickIndex and displays it in a message box using this somewhat verbose message box code:

msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText("Role index: "
        + str(RlRadioButton.clickIndex))
msg.setWindowTitle("Status")
msg.setStandardButtons(QMessageBox.Ok )
retval = msg.exec_()

and displays the result in that message box.

Figure 3: The status message box.

So, to conclude, the best way to query a large list of QRadioButtons is by deriving a class which can save the current index and asking the class for the index of the last selected button.

Is that poison ivy?

Is that poison ivy?

Yes, the above picture is definitely of poison ivy. In this late spring/early summer season, the question “is that poison ivy?” comes up really often on-line and in real conversations with actual people. The slogan “leaves of three, let them be” is a little too general to be helpful and even then people still seem to be confused and hesitant.

The pictures here are of real poison ivy taken in June in southern Connecticut.

Note carefully from the photo– poison ivy has three leaves: the center one is symmetrical and the outer two are asymmetrical, with jagged edges along the outside. Just as important, the stems of the outer two leaves do not run through the center of the leaf, but are located closer to the inner side of the leaf. This is a distinguishing feature you can look for when you can’t decide whether or not you are looking at poison ivy.

Younger leaves may be reddish and shiny, but more mature leaves are just green. And the amount of the irritant urushiol is the same on plants of any age.

creeper-2

Now let’s look at the above picture of Virginia creeper, a 5-leaved plant that doesn’t look anything like poison ivy. The problem is that Virginia creeper frequently grows right alongside or among poison ivy plants, and though it is not an irritant itself, you can regard it as a warning that poison ivy may be nearby. You can see that in the next two photos.

You will also see poison ivy climbing trees. What you may not see at first is the huge hairy rope-like stem the leaves grow from. The whole root also contains the same urushiol oil and if you grab that rope to steady yourself while gardening, you need to go wash your hands and arms right away. Even in the winter, these “ropes” still can spread the urushiol irritant.

Jewel weed

impatiens_capensis_photo2_lgIf you have jewel weed (a wild impatiens variety) growing wild nearby, many people report that the juice from the stem will help remove the urushiol and reduce skin inflammation. This was supposedly a Native American remedy and has at least some utility if you can get to hot soapy water right away. However, it does not seem to have been studied. If you develop a rash, lotions like Calamine will help reduce the itching.

In your garden

Poison ivy has the annoying habit of showing up in your gardens from time to time.

in pachysandra

This happens more every year as the carbon dioxide level in the atmosphere increases, and poison ivy loves it. You could put on heavy gloves and a heavy shirt and pull out the plants, but this usually leaves some roots behind which will eventually regrow. You can definitely kill poison ivy with Roundup, but in the garden it might kill valuable plants as well. A better choice is one of the commercial poison ivy killers: they all seem to contain triclopyr. This will kill broad leaved woody plants like poison ivy but leave grasses and the like alone.

Be careful in handling poison ivy debris: it all contains urushiol. Put the waste in a trash bag, never in the compost pile. And never burn it, since the smoke itself could still contain urushiol

Poison Oak and Poison Sumac

There are two other plants that secrete urushiol: poison oak and poison sumac. Poison oak has groups of 3 leaves that look rather oak like. Poison sumac is best recognized by the bright red stems. The Eastern variety has a rather short habit, while on the west coast, the bushes grow much taller. WebMD has very good pictures of all three plants. You will usually find poison sumac in or adjacent to swaps and wetlands, so unless you trudge through swamps you are less likely to see it.

Pacific poison oak is found mostly along the U.S. west coast, and eastern poison oak is mostly found in the southern U.S. It is somewhat similar to poison ivy and sometimes mistaken for it.

We try donuts made with Greek yogurt

We try donuts made with Greek yogurt

Bon Appetit recently published a delicious recipe for cake donuts made with Greek yogurt, which they called “yonuts.” The yogurt gives them just a little tang, and they are quite simple to make. You can probably have warm donuts for breakfast in about half an hour.

So, their recipe is

  • 2 ½ tsp baking powder
  • 2 cups flour
  • 1 tsp kosher salt
  • 2 large egg yolks
  • 1 cup Greek yogurt
  • ½ cup granulated sugar
  • 2 Tb melted unsalted butter, cooled
  • 1 tsp vanilla extract
  • 5-6 cups vegetable oil for frying (peanut or canola)
  • 1 cup confectioners’ sugar
  • Pinch of salt
  • Zest from ¼ lemon
  • ¼ cup water (or less)
  1. Mix the dry ingredients in one bowl
  2. Mix the egg yolks, yogurt, melted butter together with a whisk
  3. Mix in the granulated sugar and vanilla extract.
  4. Slowly add the flower mixture and mix with a whisk, or eventually a wooden spoon. The batter will be a bit stiff.
  5. Roll out the batter on a flour board or floured parchment. You may need to flour the top side, too.
  1. Cut out the donuts using a donut cutter, or a circular cookie cutter. In the latter case, we found you could dig out the donut hole with a cookie scoop. Dust off any excess flour before frying.
  2. Heat the oil to 350˚ F (use a thermometer) and cook the donuts 3-4 at a time. BA suggests 2 minutes per side, but we found that a bit too long. We recommend 1 to 1 ½ minutes per side. Turn them when they are brown.
  3. Drain the donuts on a wire rack until cool.
  4. Meanwhile, mix the powdered sugar with water until it is thin enough to dip the donuts in, but don’t overdo it. Mix in some zest from ¼ lemon.

frosting

  1. Dip both sides of each donut in the icing and let them dry briefly.  Eat at once.

We ate them as soon as we could. This recipe makes 9-10 donuts. They are still pretty good the second day. You should probably rewarm them in the microwave for 15 seconds or so.

Meal kits: we try out “Gobble”

Meal kits: we try out “Gobble”

Previously we have written about Freshly, a meal delivery service that provides completely prepared, microwavable meals, and we weren’t all that thrilled. This article is about meal kits, which send you the ingredients and simple preparation instructions.

There are an awful lot of meal services out there trying to get you to subscribe, and one of the better rated ones is strangely named “Gobble.” Their slogan is “Make dinner in 15 minutes,” and this seems to be about right. We ordered three meal kits for two, for $73.93, or $24.64 each. They come delivered iced, but not frozen and so well sealed, they lasted nearly a week in the refrigerator until we’d tried all three. You will probably need a couple of cooking pans, a bowl or two, and perhaps a knife to chop up salad ingredients.

Spring Pot Roast

The first one we tried was “Spring Pot Roast,” with fava beans and asparagus. The meal kits come in several little sealed packages, one for the beef, one for the legumes. The asparagus was loosely packaged, but fresh, and the other envelopes were a red wine demi-glace, a shallot-garlic confit (which seemed to have little flavor), lemon gremolata and fried garlic bits.

Putting this one together was pretty simple. You put the beef cubes, red wine glace and some water in a covered pan and cook for five minutes.  Meanwhile, you cut the asparagus into short “batons.” You saute the beans as asparagus in a little oil and then add the garlic confit.

You put half of the beans-asparagus mixture on each place, divide the beef mixture over them and garnish with the lemon gremolata and fried garlic.

I found it pretty good, although my wife didn’t agree. Each portion was nominally 560 calories, and it left us feeling hungry. Of the three dinners, we liked this one the least.

Fortunately, the overall package came with two cookie dough puck that you could bake into cookies in 14 minutes, and we did.

Miso Glazed Pulled Pork Sandwich

pork plated

Our second meal was the miso glazed pulled pork sandwich with Gochujang aioli. It was really simple to put together. First you toast the brioche bins in a pan for a few minutes and set them aside. You heat the shredded pork, add the miso glaze and heat 2-3 minutes more. You chop up the lettuce, slice the Persian cucumber and mix with the shredded carrots to make a bit of a salad that you dress with Nuoc Cham (fish sauce). This salad was also to contain the cilantro which we decided to omit.

Then you put the supplied mayonnaise in a small bowl and add the gochujang paste, a mild Korean fermented red pepper paste. To assemble, you put half the salad on each plate, the buns on top, spread the mayo over the buns and distribute the pork among them. You can put a little salad on top as well, but there is so much pork it doesn’t all fit.

We thought these sandwiches were outstanding, and at 1120 calories each, were plenty filling.

Chicken Fettuccine Alfredo

chickn plated 2

This pasta dish also came with spinach and broccoli, and that same shallot-garlic confit the first meal also utilized. For this dinner, you brown a couple of small chicken breasts in a pan, and then roast them in the oven along with the broccoli at 450˚ F for six minutes. Then, you take out the chicken, simmer the broccoli with some water while covered, and then plate the broccoli while keeping the chicken warm. Oh, and that pan that was in the oven is going have a really hot handle, and burning your hand when you put the lid on is not improbable. And I’ve been cooking for 50 years! I think it might be better to steam the broccoli in a small saucepan instead.

Then, you boil the fettuccine, drain it and put it in the pan and add the spinach leaves and the alfredo sauce, along with that garlic confit. Finally, you plate the pasta and sauce and add the slice chicken breasts on top. You sprinkle with sone grated cheese, and most important, add the packet of chili flakes to keep the dish from being bland. We thought is was very good, and at 1050 calories it should have been more filling that it turned out.

Probably, my only real criticism with Gobble is that they are a weekly meal kit delivery service, but the deadline to make changes or skip a week is a whole week before. So, I ended up with another set of meals we hadn’t planned on arriving this evening, including one with a diminutive piece of salmon that looked like it wasn’t even enough for one. It says it weighs 10 oz.

Overall, we think Gobble is a very good meal kit service, and we will probably order more in the future.