The Daily Parker

Politics, Weather, Photography, and the Dog

H is for Human Factors

Blogging A to ZThe Blogging A-to-Z challenge enters its second week with a note about you, the human.

Last week I discussed several topics that you probably thought were about computers. They weren't. They were about how you interact with computers.

Computers don't need programming languages. This is a perfectly runnable program for the 6502 microprocessor:

0600: a9 01 8d 00 02 a9 05 8d 01 02 a9 08 8d 02 02

The human-readable version looks like this:

$0600    a9 01     LDA #$01
$0602    8d 00 02  STA $0200
$0605    a9 05     LDA #$05
$0607    8d 01 02  STA $0201
$060a    a9 08     LDA #$08
$060c    8d 02 02  STA $0202

Imagine looking at that all day and trying to debug it. You'd go insane. I know, because back in the day, I wrote that kind of code for 6502 chips and, well, you have evidence about my sanity in these pages.

This is why we use high-level languages instead of low-level ones. We try to abstract away all the crap. Instead of writing for the machine to read, as you do with assembly language (and even there you have a thin abstraction layer), you write software for a human to read.

And the languages continuously improve. Here, below, is some of the first code I ever plagiarized wrote that lived in a production application. You might understand what it does from reading it:

day=VAL(MID$(dtee$,4,2))
month=VAL(LEFT$(dtee$,2))
year=VAL(RIGHT$(dtee$,4))
hour=VAL(LEFT$(ttee$,2))
minute=VAL(MID$(ttee$,4,2))

MDYTOJULIAN:
   julian!=INT(365.2422# * year + 30.44 * (month-1) + day + 1)
   t1=month - 2 - 12 * (month<3)
   t2=year + (month<3)
   t3=INT(t2/100)
   t2=t2-100*t3
   weekday!=INT(2.61*t1-.2) + day + t2 + INT(t2/4)
   weekday! = (weekday! + INT(t3/4) - t3 - t3 + 77) MOD 7 + 1
   t4=julian! - 7 * INT(julian!/7)
   julian!=julian!-t4+weekday!+7*(t4<weekday!-1)+1721060#
   day$=dow$(weekday!)+","+STR$(day)+" "+month$(month)+STR$(year)
   h=hour-12
   IF h<0 THEN julian!=julian!-1:_
      h=h+24
   ju#=CDBL(julian!)
   ju#=ju#+(h/24)+(minute/1440)

That language is called QuickBASIC, which Microsoft published from 1985 until 1991, when Visual BASIC took over. It's a subroutine that converts a date into its Julian day number. I developed it because in QuickBASIC there was no way to do simple date calculations, but in astronomy, there was.

Here's the C# version:

public static double ToJulianDayNumber(this DateTimeOffset date)
{
   return date.ToOADate() + 2415018.5;
}

Forget that this is a naïve implementation, as there are a ton of special cases before the 19th century; and also forget that it uses a magic number that depends on understanding a bit of .NET and Windows internals (like, for example, that JD 2415018.5 is 30 December 1899, which is the epoch date for OLE automation).

The point is, I can abstract away all the calculations and create an extension method which allows me to get any Julian day number just by calling that method on any date-time struct:

var julian = DateTimeOffset.UtcNow.ToJulianDayNumber();

As a human, I'd bet you find that a lot easier to read and understand than the MDYTOJULIAN subroutine above.

But C# makes it even easier to calculate the difference between two dates, obviating the Julian day entirely, unless you're writing software specifically for astronomers:

var otherDay = new DateTimeOffset(2017, 01, 20, 17, 0, 0, TimeSpan.Zero)
var days = DateTimeOffset.Now.Subtract(otherDay).TotalDays;

Because really, you're trying to get the total days between two dates. The Julian day is a required abstraction when you don't have date arithmetic built in. But when you can just do date.Subtract(otherDate) to get a TimeSpan object, the code is a lot easier for humans to read.

Let the compiler worry about the machine. You worry about other humans.

Further reading:

G is for Generics

Blogging A to ZFor day 7 of the Blogging A-to-Z challenge, I'm going totally generic.

A generic in C# allows your code to "defer the specification of one or more types until the class or method is declared and instantiated by client code." In other words, you can declare a class that takes a type to be named later.

Imagine you have a program that represents a house. Your house has rooms, and the rooms have windows, doors, and in some cases, fireplaces. They also have furniture. And sometimes headless corpses. (Don't ask.)

If you were using C# 1.0, you'd need to design structures to hold all of these things, and you'd probably wind up using arrays, like this:

#region Copyright ©2002 Inner Drive Technology

using System.Collections;

#endregion

namespace InnerDrive.DailyParkerAtoZ.WeekOne
{
	public class Window
	{
		public void Close() { }
		public void Open() { }
	}


	public class RoomV1
	{
		public void Add(Window window)
		{
			_windows.Add(window);
		}

		public IEnumerable Windows
		{
			get
			{
				return new ArrayList(_windows);
			}
		}

		private readonly ArrayList _windows = new ArrayList();
	}
}

The only problem is...you don't really know for sure whether the things going into or coming out of the _windows array list are actually windows. That's because the System.Collections.ArrayList class only stores objects, not specific kinds of objects.

Generics allow you to impose type safety on the collection of windows through the use of a type parameter. Now you can do this:

public class Room
{
	public void Add(Window window)
	{
		_windows.Add(window);
	}

	public IEnumerable<Window> Windows => new List<Window>(_windows);

	private readonly List<Window> _windows = new	List<Window>();
}

(Notice also the nifty shorthand on line 8 that eliminates the get method.)

This works because the List<T> class takes any object type for T, leaving it up to the compiler to work out what type it should contain. The prototype for the class looks something like this:

public class List<T>
{
	public void Add(T input) { }
}

The type parameter T can be anything. (You can restrict what T can contain, which I will leave as an exercise for the reader.)

Generics simplify a lot of programming tasks. But just wait until Tuesday when I show you how to make object-oriented designs really fly in C#.

Housekeeping note: The A-to-Z Challenge takes Sundays off. The next post in this series will be on Monday. Enjoy your weekend!

F is for F#

Blogging A to ZWe're up to day 6 of Blogging A-to-Z challenge, FFS.

The last few days I've written about the two main object-oriented languages that come with Visual Studio and .NET: C# and VB.NET. Today I want to diverge just a little into Microsoft's functional language, F#.

At first glance, F# looks a lot like C#. It is, in fact, a flavor of C#; and as it runs on the .NET CLR, it uses .NET constructs. But as Microsoft says, "F# is a programming language that provides support for functional programming in addition to traditional object-oriented and imperative (procedural) programming." Part of this support is the ability to express functions as first-class values. That means you can pass functions around as variables, and do things with them, in ways you can't with C# or other object-oriented languages (sort of—C# can do this too as of 4.7).

Here's an example:

let celsius (f: float) : float = (f - 32.0) * (5.0 / 9.0)

[<EntryPoint>]
let main argv =
    let c = 68.0
    printfn "%f Fahrenheit is %f Celsius" c (celsius c)
    0;;

This is just one step up from "Hello World," in that it actually does something. Two interesting bits: (a) You don't actually need to run this using the EntryPoint identifier; you can run it interactively; and (b) More importantly, celsius is just a variable.

I would love to spend another hour on this post, but I can't do the topic justice. Scott Wlaschin, on the other hand, will show you how to use F# for fun and profit. I recommend his site if you want to learn more.

But here's the sad truth: it's not very practical yet. And C# allows you to pass functions as parameters, even anonymously, so F# no longer has a monopoly on functional programming.

Remember, these A-to-Z posts aren't meant to exhaustively describe the topics. I'm only hoping to outline them and provide some follow-up reading links. And with F#, after a 45 minutes on one post, that's about all I'm up for today.

Construction complication in Dunning

No, not the Dunning of Kruger fame; Dunning, the community area on the far northwest side of Chicago.

Workers building a new school in the neighborhood discovered that not only was it the former site of a poor house, but also that 38,000 people may be buried there:

“There can be and there have been bodies found all over the place,” said Barry Fleig, a genealogist and cemetery researcher who began investigating the site in 1989. “It’s a spooky, scary place.”

Workers have until April 27 to excavate and clear the site, remediate the soil and relocate an existing sewer line. The school is scheduled to open in time for the 2019-20 academic year, though a spokesperson for Chicago Public Schools would not say what type of school it will be.

Fleig said he’s “nearly certain” there are no intact caskets buried underneath the proposed school grounds — bodies were primarily buried in two formal cemeteries, though scattered human remains have been discovered during previous construction projects near the campus.

In 1854, the county opened a poorhouse and farm and gradually added an insane asylum, infirmary and tuberculosis hospital to the property. At its peak, a thousand people were buried on the grounds each year.

The state took over in 1912 and changed the official name to Chicago State Hospital. Buildings were shuttered in 1970 and operations moved west of Oak Park Avenue to what is now Chicago-Read Mental Health Center. 

In 1854, the site would have been a few hours' ride from the city. So I'm glad to see that the American tradition of dumping the poor in places where they can't possible thrive was as strong then as now. I'm a little shocked that a pauper's cemetery acquired so many corpses in sixty years, though.

Not that this is news

In addition to crapping on the norms of office that have kept our Republic functioning for centuries, the Trump Administration has lowered the bar for standard written English in politics:

Amid all the chaos in the White House — including West Wing personnel drama, the Stormy Daniels scandal and Mueller’s Russia investigation — some wayward spellings and inaccurate honorifics might seem minor. But the constant small mistakes — which have dogged the Trump White House since the president’s official Inauguration Day poster boasted that “no challenge is to great” — have become, critics say, symbolic of the larger problems with Trump’s management style, in particular his lack of attention to detail and the carelessness with which he makes policy decisions.

On Monday, for example, the White House rolled out an executive order from Trump aimed at cutting off U.S. investment in Venezuela’s digital currency as a way to pinch strongman Nicolás Maduro’s regime. But in the headline on the public news release, the White House wrote that Trump was taking action to “address the situation in America.”

“Freudian slip????” wondered Rosiland Jordan, a reporter for Al Jazeera.

Liz Allen, who served as White House deputy communications director under President Barack Obama, said in an interview that the press office under the 44th president sought to be as rigorous as possible. Releases typically were proofread for accuracy and content by at least four or five people. Announcements that dealt with domestic policy issues and foreign affairs were vetted by experts at federal agencies and the National Security Council, she said.

“We felt a burden and responsibility to get it right,” Allen said. “We were acutely aware of the integrity of our platform. We took it seriously. No one should meet a higher bar than the White House. They are the ultimate voice.”

Read through to the punchline.

But Allen makes the main point, I think. The Administration's written communications reflect a deeper antipathy to "getting it right." They just don't care. And our allies and adversaries alike have noticed.

What really was the Cuban sonic weapon?

About a year ago, a number of American diplomats and their families in Cuba were injured by what our military speculated might be a sonic weapon. A sonic weapon directs sonic energy at a target to disable, but not necessarily permanently damage, the person. Over a few months, people reported "blaring, grinding noise," hearing loss, speech problems, nausea, disequilibrium...exactly what a sonic weapon could cause.

Via Bruce Schneier, a team at the University of Michigan working in association with the IEEE has published a paper speculating on the variety of weapon how it might have worked:

On the face of it, it seems impossible. For one thing, ultrasonic frequencies—20 kilohertz or higher—are inaudible to humans, and yet the sounds heard by the diplomats were obviously audible. What’s more, those frequencies don’t propagate well through air and aren’t known to cause direct harm to people except under rarefied conditions. Acoustic experts dismissed the idea that ultrasound could be at fault.

Then, about six months ago, an editor from The Conversation sent us a link to a video from the Associated Press, reportedly recorded in Cuba during one of the attacks.

To make the problem tractable, we began by assuming that the source of the audible sounds in Cuba was indeed ultrasonic. Reviewing the OSHA guidance, Fu theorized that the sound came from the audible subharmonics of inaudible ultrasound. In contrast to harmonics, which are produced at integer multiples of a sound’s fundamental frequency, subharmonics are produced at integer divisors (or submultiples) of the fundamental frequency, such as 1/2 or 1/3. For instance, the second subharmonic of an ultrasonic 20-kHz tone is a clearly audible 10 kHz. Subharmonics didn’t quite explain the AP video, though: In the video, the spectral plot indicates tones evenly spaced every 180 Hz, whereas subharmonics would have appeared at progressively smaller fractions of the original frequency. Such a plot would not have the constant 180-Hz spacing.

Of course, to this day, no one knows exactly why the attacks occurred, and even to say "attacks" makes a reasonable but not certain assumption.

We're #11?

Crain's reported yesterday on the latest business-school rankings from US News and World Report. University of Chicago tied with Harvard at the top spot and Northwestern landed at #6:

The magazine labels its ranking a year in advance, so this is the 2019 list. While it started the rankings in 1990, it has historical data reaching back only to 1994, but it was confident this was the first No. 1 showing for Booth.

“The University of Chicago’s Booth School of Business tied for No. 1 this year due to its strong placement data, meaning it had the highest percentage of employed students at graduation and, among the very top ranked schools, the highest percentage of graduates employed three months after graduation,” Robert Morse, the magazine’s chief data strategist, said in a statement. “The mean starting salary and bonus of Booth graduates was one of the highest among top schools.”

Duke dropped to #11 in the full-time rankings, but stayed at #5 in the Executive MBA list.

I expect they care more about this in Durham than I do here in Chicago.

Tuesday link round-up

Late afternoon on Tuesday, with so much to do before the end of the week, I can only hope actually to read these articles that have passed through my inbox today:

And now for something completely different tonight: Improv and Arias. Which is why I wonder whether I'll actually get to read all of the articles I just posted about.

Blogging A-to-Z Challenge Topic 2018

Blogging A to ZAs I mentioned a couple of weeks ago, The Daily Parker will participate in this year's Blogging A-to-Z Challenge. Today's the official Theme Reveal day. My topic will be: Programming Concepts using Microsoft C# .NET.

My topics will include:

  • Compilers vs Interpreters
  • Generics
  • Human factors (and errors)
  • LINQ
  • Polymorphism

...and will finish with a real-world practical example on April 30th.

I will also keep up my annoying political and Parker posts through April. And, full disclosure, many of the 26 A-to-Z posts will be technical and more involved than just linking to a Washington Post article. Because of that, and because I want a consistent publication cadence, I'm going to write them ahead of time, even if it's just the night before.

A-to-Z posts will start at noon UTC (7am Chicago time) on April 1st and continue through the 30th, with Sundays off. You can find them directly through their A-to-Z Tag. Enjoy!

Lying down with dogs

The New York Times last week suggested that people who sleep with their dogs sleep just as well as those whose dogs sleep elsewhere:

The dogs wore a device called a Fitbark, an activity tracker that attaches to the collar and records whether an animal is at rest and sleeping or active and at play. The people wore an Actiwatch 2, an activity monitor that records people’s movements and whether they are sleeping soundly or not. Both monitors were set to sample movement every minute, while the humans also kept a sleep diary.

Over seven days of testing, the researchers found that with a dog in the bedroom, both the humans and the dogs slept reasonably well. Humans had a mean sleep efficiency, or the percentage of time spent asleep while in bed, of 81 percent, while dogs had a sleep efficiency of 85 percent. Levels over 80 percent are generally considered satisfactory. People slept slightly better when the dog was off the bed; dogs slept the same whether they were on the bed or in another location in the bedroom.

Dr. Carlo Siracusa, a veterinarian and the director of animal behavioral science at Penn Vet in Philadelphia, added that a dog sleeping in the same room or bed with humans won’t make Sparky think he’s top dog. “Dogs can distinguish between the relationship with its human fellows and other dogs, and the way in which they regulate their interactions with humans in the house is not trying to establish a hierarchy,” he said.

First, don't think for a moment that I haven't considered getting a Fitbark for Parker. I've always been curious what he does at day camp; I suspect he sleeps about 90% of the time.

Second, no matter how well Parker sleeps, there are sometimes days like last Thursday when he woke up with an urgent matter that he immediately discussed with the bedroom floor, even though I could have gotten him outside in seconds had he asked.

Dogs.