They're just paid protesters

You're wrong, Donnie

In an effort to strip protesters of their legitimacy, Trump and Fox News claim that protesters are simply there because they’re paid by powerful oppositional interests. Never mind that Trump has no evidence for his claim; he has no evidence for practically anything that emerges from his loud mouth. What is more interesting to me is that if money delegitimizes authenticity then presumably we can use this effect to come to additional conclusions.

If, as Trump claims, money discredits and taints the political process, then:

  1. Trump’s own motives, as an extremely wealthy man, should be suspect.
  2. For that matter, wealthy family members, such as Ivanka Trump™ and Jared Kushner who have been appointed to high positions in the Administration but who have no political experience should be viewed with skepticism.
  3. The Republicans pushed the Citizens United decision allowing unlimited amounts of money in politics. If money is good for the political process, as they presumably believe, then the mythical existence of paid protest should give them no pause for concern. It’s just free market capitalism in action, right?
  4. Considering the degree to which the NRA, the brothers Koch and other deep-pocket interests fund the campaigns of GOP politicians, maybe we should just consider all Republican politicians paid protesters.

As Simon Maloy, points out in Salon:

The irony here is that there’s one person we know for sure has paid people to show up and voice a prefabricated political message: Donald Trump. In the summer of 2015, Trump arranged for actors to show up at Trump Tower and cheer and wave signs as he announced his candidacy for president, offering them $50 for their services. And, in typical Trump fashion, he tried to stiff the agency that set up his Potemkin campaign launch.


And, no; no one paid me to write this. All protest is my own.

marking time

marking time,
eyes glazed, pupils constricted
to the head of a pin
from facing the blue white sterile light
for too long
a zombie tribe
numbering in the millions
if not more

this throng, agitated
in a subdued anesthetized
crowns one of its own
a clown of sorts
knowing little of the past
less of the present
and practically nothing
of the future.
“why not? it could be worse.”

in a strange unreality
a vaudeville show becomes
its own rehearsal,
a dreamish state from which
only an atomic flash
can awaken a person.

13 Random thoughts about Canada after living here for a year.


On January 1, 2016 we packed up all our earthly goods and headed south to Canada. (Yes, it’s true. When you live in Minnesota, it’s possible to move south to Canada. Look at the map!) Having lived here for a little over a year, here are some thoughts about living here, in no particular order:

  1. “Sorry” is more of a greeting than just an apology.
  2. Canadians really are polite; but put them behind the wheel of a car and all bets are off.
  3. Universal healthcare works. Americans love to go on and on about socialized medicine; but I’m here to tell you: it works.
  4. Bumper stickers are rare here.
  5. People don’t really talk politics. Well, they talk about U.S. politics.
  6. Left turn arrows on traffic lights are rare. It makes for interesting moments when the light changes.
  7. The electric utility is called “hydro”, which given the Greek origin of the word makes little sense until you realize that it stands for “hydroelectric.”
  8. Youth music is well-supported - both through private and public funding.
  9. State-church separation is fuzzier. For example, the Catholic school system is tax-payer funded. But only the Catholic schools. It has something to do with the Canadian Charter (a.k.a Constitution.) It was apparently some sort of historical compromise in the 1800’s.
  10. Don’t order iced tea in Canada. It’s way too sweet.
  11. As a practical matter, you can’t be elected Prime Minister unless you speak both English and French fluently. This is a really good thing.[1]
  12. Speaking of politics, campaigns are time-limited to 6 weeks before an election. How cool is that?
  13. Poutine sounds horrible, but it’s actually pretty good.

  1. How many languages does Donald Trump speak fluently, for example?

Serious audio processing on the command line

I’ve written previously about extracting and processing mp3 files from web pages. The use case that I described, obtaining Russian word pronunciations for Anki cards is basically the same although I’m now obtaining many of my words from Forvo. However, Forvo doesn’t seem to apply any audio dynamic range processing or normalization to the audio files. While many of the pronunciation mp3’s are excellent as-is, some need post-processing chiefly because the amplitude is too low. However, being lazy by nature, I set out to find a way of improving the audio quality automatically before I insert the mp3 file into my new vocabulary cards.

As before, the workflow depends heavily on Hazel to identify and process files coming out of Forvo. The download button on their website, sends the mp3 files to the Downloads directory. The first rule in the workflow just grabs downloaded mp3 files and moves them to ~/Documents/mp3 so that I can work on them directly there.


Another Hazel rule renames the verbosely-titled files to just the single Russian word being pronounced. It’s just neater that way.

rename 's/(pronunciation_ru_)(.*)/$2/' *.mp3

This uses the convenient rename command that you can obtain via Homebrew.

The final rule, grabs the newly-renamed mp3 file and performs a series of audio processing steps:

ffmpeg -i "$1" tmp.wav;
sox tmp.wav temp_out.wav norm gain compand 0.02,0.20 5:-60,-40,-10 -5 -90 0.1;
ffmpeg -i temp_out.wav -codec:a libmp3lame -qscale:a 2 tmp.mp3;
lame --mp3input -b 64 --resample 22.50 tmp.mp3 tmp;
mv tmp "$1";
rm tmp.mp3;
rm tmp.wav;
rm temp_out.wav

The first line ffmpeg -i "$1" tmp.wav; simply writes a temporary .wav file that we can process using sox. The second line invokes sox with a number of options that normalize and improve the dynamic range of the audio. Finally we use ffmpeg to convert the .wav file back to .mp3, compress the .mp3 file and then clean up.

Now I have excellent normalized audio for my cards, with no work for me!

See also:

Foreign language education in the U.S.: a neglected cure for xenophobia

Xenophobia has deep roots in the U.S. For all of its “global melting pot” rhetoric, the reality has been much more complex. It begins with the maltreatment of the native peoples of America with its attendant extinction of their language and culture. But even as recently as 1923, the U.S. Supreme Court ruled that persons from India were not eligible for U.S. citizenship because only “free white persons” were permitted. This case was one of the most egregious in the history of the United States and is a poignant example of how the Supreme Court reflects, rather than transcends, prevailing cultural values. In the United States v. Bhagat Singh Thind, 261 U.S. 204, the Supreme Court unanimously decided that an Indian Sikh man could not be granted citizenship because he was not white. Even today, the suspicion with which many English-speaking Americans view Spanish speakers undoubtedly contributes to their xenophobic calls to build a wall along the border with Mexico.

Language and culture are inextricably linked. We use spoken and written language to pass cultural values among one another and from one generation to another. Small wonder that imperialists throughout time have first sought to rid colonies of their native language. But perhaps it’s also true that by purposefully teaching languages, the U.S. will begin to see itself as a global participant rather than a global boss. The Latin origins of the word “educate” imply a process of leading out, drawing out, or leading away. Seen in this way, education isn’t a preparation solely to become part of an economic engine. It is to lead away from entrenched provincial ideas to a broader world view. Language education is a key component of this process.

Language education in the U.S.

Foreign language education in the U.S. is, to be blunt, deplorable. Owing to its fragmentary leadership structure, there are no national standards for education in the U.S. Local school districts, large and small are left to their own devices in writing curriculum standards. In many cases, individual states have specific standards to which local districts must adhere. But even those standards often derided by local politicians.

The effectiveness of a process can be judged by its outcomes. The desired outcome of foreign language education is fluency in the target language. In the U.S., less than 1% of Americans are fluent in a language that they studied in school.[1] According to Stephen Dubner of “Freakonomics” fame, the average U.S. student studies a foreign language for 2-3 years.[2] It’s hard to imagine anything more wasteful for children’s developing brains to spend hundreds of hours studying something they will never actually be able to apply in a meaningful way. Education budget cuts, lack of qualified teachers, and disjointed policy all contribute to poor foreign language acquisition by U.S. students. And that, in turn, heightens the perception that knowing English is sufficient to participate in the affairs of the world.

Language education worldwide

In contrast to the U.S. public education, the competent acquisition of a foreign language is required. Most European countries require the study of two foreign languages from an early age.[3]


In this study from the Pew Research Center, nearly three-quarters of European countries require the study of not just one foreign language, but two languages. Instead, the U.S. is a crazy-quilt of state and local foreign language requirements. Some states are even allowing students to substitute computer languages for foreign languages to meet this requirement. I’m sure this will help them enormously during their vacations in Computerland!

Another striking observation about language education in Europe is that it begins early, far earlier than the U.S. where most foreign language education takes place in high school. The delayed exposure to foreign languages for most U.S. students has two devastating effects. Drawing on what is known about the acquisition of musical ability, another aural skill, students who first encounter a foreign language late in their education are less likely to become fluent because certain features of brain plasticity decline. A more insidious effect of delayed foreign language study is that students become more and more rooted in their own cultures. Their world view becomes more and more fossilized. This, of course, is the start of a vicious cycle. Their poor foreign language experience means that they won’t support improvements for the next generation.


Foreign language acquisition is a must. Political rallies, calls to Make America Great Again™, walls, immigration bans and disparaging foreign nations won’t solve looming worldwide crises like climate change. But being able to understand and communicate with one another might.

  1. First, the U.S. needs to “prime the pump” by recruiting and developing qualified teachers who speak foreign languages competently. The U.S. already has an agency, the National Security Education Program (NSEP) a Federal initiative whose aim is to build the pool of U.S. citizens who fluently speak languages that are vital to its security interests.
  2. The U.S. Federal government should develop and promote a plan for compulsory foreign language education beginning in the early elementary years.
  3. The U.S. foreign language educational plan should develop a language prioritization based on the languages spoken by its own citizens and residents and on the languages spoken by both its adversaries and allies. The NSEP has developed just such a list of languages of strategic security importance.
  4. The U.S. should develop a plan for evaluating the effectiveness of foreign language education, holding school systems accountable for ensuring that each student is developing language fluency.

On a personal note, I was educated in the U.S. My first exposure to a language other than English was Latin which I studied for two years beginning in Grade 9. I went on to study French and Russian in high school with an amazing teacher Mme Collette Males to whom I’ve indescribably indebted. Had I not had this experience, I’m not quite sure where I would be.

  1. America's Lacking Language Skills, The Atlantic, May 10, 2015. Friedman, A. Link

  2. Is Learning a Foreign Language Really Worth It?, Freakonomics blog, March 5, 2014. Link

  3. Learning a foreign language a 'must' in Europe, not so in America, Devlin, K.,Pew Research Center, July 13, 2015, Link

Trump and the arts


I’ve long suspected that Trump regards the arts as an unnecessary nuisance for losers and suckers. High art for this hollow man is the vacuous reality television that made him famous. Now in his Federal budget, Trump offers proof. He proposes the elimination of the National Endowment for the Arts and the National Endowment for the Humanities.

This is a man with no soul.

But in the closing lines of her lyric poem “Renascence”, Edna St. Vincent Millay has a warning:

The world stands out on either side
No wider than the heart is wide;
Above the world is stretched the sky,—
No higher than the soul is high.
The heart can push the sea and land
Farther away on either hand;
The soul can split the sky in two,
And let the face of God shine through.
But East and West will pinch the heart
That can not keep them pushed apart;
And he whose soul is flat—the sky
Will cave in on him by and by.
- Edna St. Vincent Millay Renascence

If it’s not garish, gold, or glittering, it’s not worth our investment. Time for an artist’s march.

Using macOS NSSpeechSynthesizer to generate audio content for Anki cards

As I’ve written before, I use Anki for Russian language learning. One of the skills to master in learning a foreign language is to quickly speak and recognize numbers. With a little help from macOS, I’ve developed a way of rapidly creating audible content of spoken numbers for my Anki cards.

That’s the good news. The bad news is that as of right now, you’ll have to have Xcode and build the app yourself. Someday, I’ll deal with all the official certificate stuff again (I’ve not developed apps seriously for iOS or macOS for several years now.)

But, here it is anyway on Github: RussianNumberGenerator.

The operating principal is that it generates spoken numbers in a user-specified range. You can choose to generate numbers sequentially or randomly within a range. NSSpeechSynthesizer generates .aiff files, but to make the audio content more widely usable, the application converts these files to .mp3 using ffmpeg which, by the way, you will need to have installed.


There’s much more to do, but there’s the idea.

My month without news

“The unexamined life is not worth living.” - Socrates

This year I decided to take a different approach to making New Year’s resolutions. Although many people make resolutions, less than 10% regard themselves as successful at achieving them.

I decided to overhaul the idea of New Year’s resolutions. Rather than committing to an entire year of change, I set up a schedule of 12 mini-resolutions in the form of experiments. My first experiment for the month of January was to work out daily. My February experiment was to determine whether avoiding the news and time-boxing my social media interactions would make me happier.


For the entire month of February, I committed to avoiding browsing the news. Since the U.S. elections, I found myself unusually angry, anxious, and unhappy. I hypothesized that the constant stream of bad news about the America’s flirtation with authoritarian rule was seriously distorting my days.


First, I set limits on my social media use - no Twitter, and only 5 minutes Facebook time per day. I committed to avoiding the primary news sources both on the Internet and elsewhere.


For the month, I did not use Twitter. Setting a 5 minute timer, I limited my Facebook time considerably. By blocking news-heavy feeds, I rarely saw anything political. Throughout the month, I did read a handful of essays that treated the current socio-political session in a more analytical way; so I had a vague idea of what was going on in the U.S. For the most part I was successful in limiting my time on Facebook. Rarely if I was tired or felt in need of a distraction between tedious work, I did look at Facebook more than once during a day.

Over the course of the month, my emotions definitely changed. I felt less angry about the U.S. political affairs. Rather than being outraged, I felt like the process of focusing more on analysis slowed down the whole process for me in a way that made me much less anxious. My productivity was definitely higher by avoiding the distraction of the news.


Overall, this was a successful experiment, one that I’d like to continue. For news-junkies, this is anathema. The goings on in Washington, D.C. are, of course, important. But I’m limited in my responses. I can write or call representatives. But I’m registered to vote in Minnesota where all of my representatives and senators are Democrats anyway. The White House shut down its phone lines and I’m pretty sure the current occupants aren’t really interested in what I have to say anyway. And you can’t call Congressional leaders unless you happen to be in their district. I don’t live in the U.S. so I can’t easily march or protest. For me, it has been better to focus on my own circle of influence where I have a sense of agency.

If you’re feeling frustrated over the steady stream of bad news, I’d recommend this experiment.

Using rrdtool to chart Indigo data

Indigo currently shipping version 7 is a leading Mac home automation software package. One of it’s mostly widely-used features is its ability to execute user-provided Python scripts of AppleScripts. In my previous introduction to scripting Indigo with Python I showed how to use the Indigo plugin host to execute Python scripts. In this post, I’ll describe how I use a third-party charting package rrdtool to graph data from Indigo by taking advantage of Indigo’s ability to execute arbitrary Python scripts. This tutorial is focused on using Python as a bridge between Indigo 7 and rrdtool. If you are interested in a solution that takes advantage of AppleScript and bash scripts to do the samee thing, see this thread on the Indigo forums.

Installing rrdtool

I used Homebrew to install rrdtool. Homebrew is a package manager for macOS. If you already have Homebrew, then installing rrdtool is just: brew install rrdtool. Otherwise, you can easily install Homebrew. In the terminal, execute the following:

/usr/bin/ruby -e "$(curl -fsSL \"

After installing Homebrew, then you can easily install rrdtool as described above.

Installing Python bindings for rrdtool

While it’s possible to run rrdtool from ApplesScripts that are executed inside of Indigo, it may be preferrable to use Python. I’ve found Python much easier to work with and more reliable than AppleScript. If you use Python, then the bindings to rrdtool make the work much easier than setting up shell scripts to execute. To install the Python bindings, I used sudo easy_install rrdtool. That should take care of all the prerequisites and install the rrdtool Python module.

Briefly introducing rrdtool

This tutorial isn’t meant to be an exhaustive introduction to rrdtool, but I’ll briefly describe the principles of operation. As its name implies, rrdtool uses a round robin database format which is a time series storage format implemented as a circular list. This format allows us to look closely at short-term trends while losing precision over the longer term. It’s ideal and compact for examining short-term data trends. rrdtool then is a set of tools that manage and graph data from a round robin database.

Creating a round robin database

To get started using rrdtool you need to create a database that will hold the data that Indigo 7 provides from your sensors. In my first use case, I was interested in charting temperature and humidity levels in a part of my basement. I set up the database as follows:

rrdtool create /usr/local/share/obasement.rrd
--step 90 \
DS:temperature:GAUGE:2000:32:80 \
DS:humidity:GAUGE:2000:20:80 \
RRA:AVERAGE:0.5:1:350400 \
RRA:AVERAGE:0.5:96:3650 \
RRA:MIN:0.5:96:3650 \

This asks rrdtool to create a new database as the specified location with the name obasement.rrd. The parameter descriptions are beyond the scope of this tutorial but briefly, the DS parameter has the following format: DS:variable_name:DST:heartbeat:min:max. The DST is the Data Source Type which can be any of: COUNTER, DERIVE, ABSOLUTE, GAUGE. Here, the GAUGE value for DST just means that no rate of change is saved - only the primary data point. The next parameter of DS is the heartbeat. To simplify, you can look at the heartbeat as the interval seconds between expected data points. Finally we have the expected minimum and maximum values for the data.

The RRA parameters specify a round robin archive and describes the behaviour of the consolidation algorithm. A round robin database has to compress older data to maintain its circular compact list and the RRA parameters describe how that should work. Here we’re using an AVERAGE function to consolidate old data.

I’d recommend reading through this thorough introduction to the rrd format parameters before creating your own databases.

Obtaining data from sensors via Indigo

In this example case, I want to chart temperature and humidity levels from a Aeotec MultiSensor 6. Grabbing the values from this device via Python is easy:

import rrdtool

# "Original basement temperature sensor"
temp = indigo.devices[401767099].sensorValue
# "Original basement humidity"
hum = indigo.devices[1437240536].sensorValue

# update our round robin database

In line 9, we update the round robin database with the incoming data. This script can be launched from and Indigo schedule that corresponds to the heartbeat we specified.

Graphing our data

Generating graphs of the data is straightforward now that we have the database functioning. Here’s the code that generates my graphs:

ret = rrdtool.graph("/Users/alan/Desktop/obasement.png",
"--start", "-2days", "-w 600",
'LINE1:Temperature#ff0000:Temperature (°F)',
'LINE1:Humidity#0000ff:Humidity (%)'

The full update-and-graph script is here:

Here you have a few choices, you can schedule the update and graph generation as a scheduled task in Indigo, or you can schedule it in the OS. I chose the latter and used the application LaunchControl to launch the job as a User Agent at the interval specified by the heartbeat parameter. The program to run in LaunchControl is: "/Library/Application Support/Perceptive Automation/Indigo 7/" -x /Users/alan/Documents/dev/scripts+tools/ or "path-to-indigo-plugin-host -x path-to-my-script"

The result

The result of all of this is a graph of the temperature and humidity in my basement which I can incorporate in control pages or display anywhere else of my choosing.


Of course, to use the graph in your Indigo control pages, you’ll need to change the path in the above code to “/Library/Application Support/Perceptive Automation/Indigo 7/IndigoWebServer/images”.


The inspiration to write this implementation came from users cullenfluffyjennings and webdeck in this thread on the Indigo forums.

See also