Who was Herman Wasserman?

Probably relatively well-known in music circles in his day, Herman Wasserman seems to only pop up today in conversation associated with George Gershwin. It seems like he was also a teacher to Ferde GrofĂ©, who orchestrated Gershwin’s Rhapsody in Blue.

If you search library catalogs, he turns up as having edited George Gershwin’s Song-Book as well as having arranged a simplified piano solo version of Rhapsody in Blue.

In the foreword of that version of Rhapsody in Blue, it claims:

(more…)

QListView not accepting drag and drop

Python + Qt (in the form of PyQt5 or PySide2) is a weird mash-up of the famously slow interpreted dynamic language plus a heavyweight C++ GUI library. It certainly has its advantages over writing in C++, but I’m really wondering if there aren’t better ways to write cross-platform desktop apps.

Anyways, in Qt, you’re supposed to be able to accept drag-and-drop in a widget by doing something like:

myWidget.setAcceptDrops(True)
# install some event handlers
myWidget.dragMoveEvent = ...
myWidget.dropEvent = ...

If you use a QListView to present an explorer-style view of some items, this mysteriously doesn’t work. Why? Qt is object-oriented from top to bottom, and you think you’re using a QListView but it’s actually a QAbstractItemView which is actually a QAbstractScrollArea. But a QAbstractScrollArea is very different conceptually from a QListView.

It turns out that when you drop something onto the QListView, it’s not the QListView that gets the drop events. Instead, its internal viewport (the scroll area) gets the event.

And if you’ve setAcceptDrops(True) on myWidget, that’s not what you actually want. The viewport is its own QWidget with its own acceptDrops flag that isn’t True.

class MyWidget(QListView):
    def __init__(self):
        ...
        # NOT self.setAcceptDrops(True)
        self.viewport().setAcceptDrops(True)
        self.viewport().installEventFilter(self)

    def eventFilter(self, obj, event):
        # grab any drag and drop events that the viewport receives...

Is this a bug? It certainly seems like poor API design, because if doing a setAcceptDrops(True) on a QListView doesn’t also setAcceptDrops(True) on its internal viewport, then what does it accomplish?

Technically, this behavior seems to be mentioned in this old Qt 4.6 page: https://doc.qt.io/archives/4.6/model-view-dnd.html

But this kind of requirement that I cobble together bits and pieces of Qt 4, C++, PyQt*, and StackOverflow documentation to figure out what to do in PySide2 is apparently the state of using Qt with Python. Excuse me while I go back to complaining about JavaScript…

Fixing only left/right channels working on Logitech headsets

I have a Logitech G430 headset. It’s one of a series of Logitech headsets that offer fake surround sound as a marketing ploy. (I will write up something someday about why surround sound headphones are 95% marketing B.S.)

Using it on Windows, at some point all audio from channels other than left and right disappeared. I.e. 6 of the 8 channels were just completely inaudible.

Toggling the surround sound effect in Logitech Gaming Software didn’t work. I looked around and there were similar complaints from people with other Logitech headsets.

Here’s what did work, and how to test it:

(more…)

100% Unbreakable Encryption is Achievable!

There were two common cryptography misconceptions that we unlearned in school, and this post is about the first one we learned about. (And Cryptonomicon helped with this one too.)

We hear a lot about how “strong” encryption is. That our files would take bazillion years to decrypt via brute force or that our Bitcoin account would take the fastest supercomputer a gajillion years to break into. But what about an encryption scheme that an adversary could never, ever brute force? Sounds pretty useful, doesn’t it?

You may be surprised to learn that yes, we can do it! And we’ve been doing perfectly unbreakable encryption in the military since before WWII.

Let’s say we have a plain-text message:

A T T A C K A T O N E O C L O C K

And we encrypted it with a random key that’s the same length as the message, where each character of the key is just added to the corresponding plain-text letter of the English alphabet (A = 0, so B + C = D, Y + B = Z and so on…).

(more…)

Reverse-Engineered Dumpling Sauce Recipe

This was reverse-engineered from Wei-Chuan brand dumpling sauce. It’s not an exact replica but should provide a similar taste profile.

Makes approximately 200 mL.

Ingredients

(more…)

`git add -p` has made me a better programmer

If you don’t know about this already, then file it under your collection of “One Simple Trick articles”…

git add -p (AKA git add --patch) will interactively show you each change in your repo and ask you if you want to stage it.

Do you ever use git commit --all? Have you ever accidentally committed more than you meant to?

By using git add -p, you get a chance to review each change. That helps you catch mistakes, like leaving in debugging printlns that you don’t need anymore, or other temporary hacks. Since git add -p will present each change separately, you can even include some changes and exclude others within the same file.

And, it’s not uncommon for me to fix small, unrelated issues while working on a major feature. I’d like for those fixes to go into a separate commit, and git add -p gives me a chance to catch those fixes if I haven’t committed them already.

The other major benefit is that it gives you a refresher on what all you changed before you need to write your commit message. If I work on a big changeset, sometimes it’s hard for me to remember all the important changes that I should write about in my commit message. Quickly running through the changes interactively means that, instead of writing “Add feature X”, I can write more detailed commit messages that list the major areas that have been touched.

Overall, it’s made my commits cleaner and me a more thoughtful programmer.

Don’t blindly commit files. Try git add -p.

P.S. Even though I now mostly use VS Code, I still prefer to review changes in the built-in terminal instead of the Source Control pane. Since git add‘s interactive mode uses single-character commands, I can quickly step through the changes without fiddling with the mouse.

Things Japanese people say about English

There’s a large and thriving community of English speakers learning Japanese, in which they swap tips and trivia amongst themselves as they seek to improve their Japanese skills.

The corollary is that there’s a large and thriving community of Japanese speakers swapping tips and trivia about English, and I’ve found a bunch on Twitter. So, what are they talking about?

There’s practical advice on what they teach you in school vs. the real world:

(more…)

The cheapest way to run Minecraft on AWS

Summary: By taking advantage of AWS spot instances and only running when you need to, you can have a powerful Minecraft server for as little as a couple dollars per month.

I’m happy to share a set of tools we’ve created to run a cheap, personal Minecraft server on AWS! It works like this:

  • When you want to play, go to the server status webpage and launch the server.
  • Wait for it to start up.
  • Connect to the server from Minecraft.
  • After you disconnect, the server will automatically shut down after a period of inactivity.

This way, you only pay for the time you play (along with storage costs for your world data). How cheap is it? Based on prices as I’m writing this:

(more…)

Things even veteran developers do

It can feel overwhelming to be a new software engineer, but many “noob” things are actually “everybody” things. If any of these things happen to you, know that you’re in good company!

Forget basic syntax and need to Google it

Here’s what my recent search history looks like…

(more…)

Fun networking stories: finding the “fast lane”

I went to a boarding school for part of high school. (It was actually a public boarding school—weird, huh?) We lived in an old college dorm that had four floors. I lived on the 4th floor and one particular friend lived on the 1st floor.

Our Internet connection on the 4th floor (and actually most of the building) was pretty bad. We’d usually get around 110 KB/s and sometimes during busy hours it could drop to 30 KB/s with some bad jitter.

My 1st-floor friend, though, consistently got 4 MB/s down and would be playing low-latency Urban Terror while the rest of us upstairs were cursing the school’s IT department. Rumor is that part of the first floor flooded a few years back causing a lot of the wiring and networking to be replaced.

However, a little bit of experimenting showed something promising: I could connect to my friend’s computer downstairs at high speeds, even though at the same time I would have trouble watching YouTube. So, we did what any normal high schoolers would do: we set up OpenVPN, using one of the school-issue laptops as the server downstairs in my friend’s room, and installing the OpenVPN client on my own laptop upstairs. All of a sudden, I could stream videos at 4 MB/s while my next-door neighbors were stuck at 100 KB/s or worse. The only downside was increasing my friend’s latency while he was gaming.

We never did figure out the networking topology of the building, but I doubt it’s gotten much better since.