MacBook, defective by design banner

Put the knife down and take a green herb, dude.


One feller's views on the state of everyday computer science & its application (and now, OTHER STUFF) who isn't rich enough to shell out for

Using 89% of the same design the blog had in 2001.

Back-up your data and, when you bike, always wear white.

MarkUpDown is the best Markdown editor for professionals on Windows 10.

It includes two-pane live preview, in-app uploads to imgur for image hosting, and MultiMarkdown table support.

Features you won't find anywhere else include...

You've wasted more than $15 of your time looking for a great Markdown editor.

Stop looking. MarkUpDown is the app you're looking for.

Learn more or head over to the 'Store now!

Saturday, March 24, 2018

TIL, Pokémon Edition:

I've been using Pokemon GO as an excuse to walk more (Apple Watch Pokemon GO app review: Don't.), and was wondering when should I evolve which of my eevees. You know, normal, grown up questions like...

  • Do I automatically evolve the one with highest CP? Or is the "sunset graph" more important?
  • What does the sunset graph mean? Are all eevees on the same scale, or do some have more "potential" than others? (That is, if I have five with "max sunset", how close would they be to being equal?)
  • Is there an advantage to powering it up before evolving? If so, how much?
  • Are the higher CP eevees I catch later going to max out higher in their new forms (see sunset question, above)?
  • Is there a CP threshold I should wait for before evolving an eevee?

That is, I didn't want to waste my candies on evolving the ones I have now if the next one I catch is likely going to be significantly stronger. But then what stops me from waiting forever?

And I don't want to evolve them too early if powering them up before evolution would increase their potential later. Etc etc. INACTION THROUGH INFORMATION DEFICIT!!!!1!

Aside: Didn't I mention I hate theorycrafting? This is theorycrafting.

Determining Pokémon Apititude

From a reddit manual about Pokémon GO:

There is NO DIFFERENCE in the end result of Powering Up then Evolving vs. Evolving then Powering Up, therefore the general recommendation is to always Evolve first to find out the move set. You can Power Up up to 1.5 levels above your Trainer level, at which point the white dot on the arc will be all the way to the right. Once you level up your Trainer, you can then Power Up again to the new maximum.

I think that suggests that you might as well evolve first, with the chance to cut your losses if you really dislike their attacks after evolution.

Quick run-down of aptitude from a Pokémon GO pokemon trading card's stats

Assessing the potential of each eevee is called appraisal. I'd seen this when I started playing, but had completely forgotten about it 18 months later.

Each Pokémon has 3 "Individual Values", or IVs - Attack, Defense, HP/Stamina. Each IV can individually range from 0-15, and they are randomly generated when the Pokémon spawns (Pokémon hatched from eggs are randomized from 10-15 instead). The appraisal feature gives you an idea of what that specific Pokémon's IVs are. Depending on what team you are on, your team leader has slightly different phrases they will use. The first phrase tells you what overall range the stats are in, out of a possible 45 total (15/15/15). The next phrase(s) tell you which of the three stats is the highest (or multiple if tied for highest). The final phrase tells you how good that high stat is.

There's great detail on what your appraisals mean here. Here's a taste for Blanche, the Team Mystic (ie, "Blue Team") leader:

Its stats exceed my calculations. It's incredible!Pokemon has perfect IVs in at least one base stat.
I am certainly impressed by its stats, I must say.Pokemon has IVs of 13 or 14 in at least one base stat.
Its stats are noticeably trending to the positive.Pokemon has IVs of 8 to 12 in at least one base stat.
Its stats are not out of the norm, in my estimation.Pokemon IVs are below 8 in every base stat.


It's apparently a lot easier to catch Pokémon if you can throw a half-way consistent curveball. From

Prior to this project, the Ball bonuses had already been discovered in a previous study:

Ball TypeBall Factor
Poke Ball1
Great Ball1.5
Ultra Ball2
The Curveball Bonus

Our analysis strongly suggests that the Curve factor is equal to 1.7.

So without any other bonuses, curving is equivalent to using 1.7 Poke Balls each turn. And since the Ultra Ball bonus is 2, a curved Ultra Ball is equivalent to using 1.7 * 2 = 3.4 Poke Balls each turn.

Straight Throw11.52
Curve Ball1.72.553.4

That means a curveball with a Poke Ball has a better chance of catching a Pokémon than a straight throw with a Great Ball. Good to know.

How to do this? From

To do this, press and hold on the Pokéball to make the circle appear, and then throw it when you're ready with a swipe. Remember, the closer you get to the centre, the better the throw type - it goes from Nice for most of the circle, Great for around half, and Excellent when it's close to the middle.

Also, here's an excellent YouTube on how to throw curveballs.

Here endeth the lesson.

Labels: , ,

posted by ruffin at 3/24/2018 11:55:00 AM
Thursday, March 08, 2018


I’m not quite sure whether iTunes LP was a bad idea or simply one that neither Apple (aside from Steve Jobs?) nor the music producers actually had much interest in. 

I think this signals less "whether iTunes LP was a bad idea" (though the skeuomorphism Jobs loved is slowly dying our from the `OSes) than "someone's paying attention to scaling down iTunes". I think they're slowly moving towards killing music sales, no matter what Sellers at AWT thinks. ;^D

I tried to think of why this is happening now, and believe it falls in with a general deprecation of non-Apple Music (qua the streaming service) features in iTunes. Here are a few data points...

  • Cesium's author points out that playing music on your own phone is increasingly difficult via Apple Music in iOS 11.
    • That is, where Apple Music API used to be an easy way to access files and streams, it's now neither. A change is coming.
  • HomePod is an obvious push towards subscriptions.
    • The only music you can play that doesn't require at least an Apple Match subscription is stuff you bought directly from Apple.
    • In a sense, those files are delivered via streaming too... the only twist is that you sometimes save the bytes.
  • This useless Android Apple Music app, which can't even play what you've purchased from Apple. It's only streaming.
  • As Michael Tsai remarked recently (and I mighta mentioned), Amazon recently ended its song hosting.
  • Microsoft stopped its streaming service and replaced it with Spotify.
  • And Microsoft stopped selling online music completely.

The writing's on the wall. Heck, Apple Music on iTunes has a whole second UI...

After cashing in a $100 for $85 Apple Music gift card (<<< I'm not an affiliate, but it looks like it was legit), iTunes asked me if I'd like to put that towards an Apple Music subscription.

Snake oil

No, no I wouldn't. But I did drop into the Apple Music UI side of iTunes, which is obviously different than the normal iTunes Music Store. I bet there's some crossover with the Android app. After looking around the posh store of which I wasn't a member, I slunk out, knowing there's a new side to iTunes I don't get to experience.

Follow the money

I don't blame Apple, much. Streaming revenue continues to grow like mad, and 36 million x $100 or so is lots more than $600 million in digital sales.

The number will continue going lower. And subtract from that number the cost to support the mammoth mess that is iTunes and the iTunes Music Store. Microsoft's Groove is a small-scale test of the economics of supporting music sales. There are better places to spend that development time.

The Apple Music side of iTunes will eat the iTunes Music Store. We're getting rid of the cruft of the Store now. In a year or two, the iTMS will be a clear second fiddle to Music. Then we'll get a warning, like I did on Groove, to download all my purchases by a certain date, or they'll be unavailable.

And finally, acceptance

After years of hang-wringing, I find that by now I don't really mind that online track sales is dying. I have a good collection.

And I'm lucky enough to have a local record store. Here's what they wrote to all of their newsletter subscribers when Best Buy said it was closing down CD sales...

From Monster Music:

The whole point of all of this isn't to slam Best Buy...  But what invariably happens when the media reports an item like this is that the general public totally misconstrues what's going on.


What's going on, as it affects you, is... well, not much.


Except for this - not only are we going to continue to sell CDs, we're actually adding to our CD inventory.

I don't see vinyl getting less hipster. And, as they say later in their letter, "Three, there will be a CD resurgence one day, you know there will. It might not be as drastic and fantastic as the vinyl resurgence, but I'll bet it'll be stronger than the cassette revival." That's probably a good call too.

After the iTunes Music Store closes its doors, I'll still have music to buy. And rip. And mix. And burn.

Rip. Mix. Burn. iMac.

Labels: , , , , , ,

posted by ruffin at 3/08/2018 11:14:00 AM
Thursday, March 01, 2018

Oh google. Your raw source makes me something something.

Sad source

Why is this in the page itself? Why do you need so much source to display your page? What ever happened to humans writing html code?

I know I sound like an assembly programmer in the land of OO, but it still makes me sad. ;^)

Labels: , , , , ,

posted by ruffin at 3/01/2018 07:39:00 PM
Monday, February 19, 2018

If your architect hasn't written a tutorial -- not a cursory howto, but a tutorial -- you don't have an architect.

What does a tutorial look like? The canonical example for C# web apps, though now a bit long in the tooth, is NerdDinner:

NerdDinner Tutorial

The best way to learn a new framework is to build something with it. This tutorial walks through how to build a small, but complete, application using ASP.NET MVC, and introduces some of the core concepts behind it.

The application we are going to build is called "NerdDinner". NerdDinner provides an easy way for people to find and organize dinners online...

There's not only a nicely written walkthrough, but documented code and a live, running example.

If your architect hasn't taken the time to articulate their vision thoroughly, in plain, if expert-specific, [language of your locale], there's not much hope for your coders. Your codebase will necessarily be an unmaintainable cyborg (a topic I'm [not] surprised to find I've been ranting about since 2002).

The best job security is none. You've set your stage so well any competent programmer could come in and take over, getting up to speed incredibly quickly.

Those coders who work to ensure they're the most easily replaced are absolutely irreplaceable.

Labels: , , ,

posted by ruffin at 2/19/2018 10:02:00 AM
Wednesday, February 14, 2018

I've been setting up a new greenfield project, and wanted to use not exactly a new stack, per se, so much as an "all-star" stack that'd capture the lessons I've learned coding recently. For me, that means it needs to be pretty straightforward, minimal dependencies, and minimal compilation. The fewer libraries and snowflake server requirements, the better.

On first take, after bypassing Node, which really is the winner,1 my guess was that my all-star stack would be...

  1. ASP.NET Core
    • C# with no OS limits.
    • Deploy inexpensively to Linode, eg, if you want.
  2. Web API on ASP.NET
    • No Razor templates (not that I hate Razor; just one less tech to maintain)
    • No direct interaction between server and views/html/client.
    • Keeps concerns separated perfectly, exchanging only JSON between tiers.
  3. Statically served html (with JavaScript packages, natch)
  4. jQuery 3.x slim
    • Slim means no ajax; it's more efficient to roll your own.
    • Every time I've used $.ajax, we've wrapped that with our own error handling, etc, anyhow.
    • Learn to spell XmlHttpRequest. ;^)
  5. Bootstrap
    • The cheapest mobile client is a responsive web client.
    • I realize native is better. But responsive is, give or take, free.
    • Also gives a decent basic theme.
  6. VueJS
    • This was probably the most difficult to decide on ahead of time
    • Will discuss more below.
  7. PostgreSQL or MySQL

VueJS was difficult to pick. I've used React, and almost solely React, for the last year. I like it. But I believe it contributes to monolithic source that's not necessarily factored well. The more interdependencies your code has, the more maintenance is an issue. And doing good React essentially requires, at this point, using Babel, and as soon as you're transpiling, well, the surrounding tooling and library dependencies skyrocket. Not to mention that debugging transpiled code either means you're wading into transpiler-generated muck, or you've got to maintain yet more tooling to step through things in something that's not the browser.

I was originally going to use Handlebars, which I've liked for years for its exceptional thinness & the way it encourages minimal business logic on the client, but caught Shawn Wildermuth on Jesse Liberty's Yet Another Podcast, and heard him talk about VueJS. VueJS is essentially Handlebars with, afaict, a few more recent lessons baked in. The syntax is actually very similar to Handlebars in many ways.

Here's what eventually won me over:

Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.

It looks like we've got good room to grow using VueJS' conventions if we want to do a full SPA in the future.

I also debated not using Bootstrap, but I don't think it's worth the time to roll your own responsiveness when Bootstrap does it so well. It's over 200 KB total, but if you have it cached, that's a one-time hit that's smaller than most images. You're fine.

jQuery was also debatable, since you can handle DOM manipulation fairly well by wrapping vanilla JS with some convenience wrappers to check for DOM existence, but at 69 KB? Come on. It's well known, rock solid, and has good industry support. Use jQuery.

This looked nice. Simple, API-only and REST convention compliant server. No licensing fees. No JavaScript transpilation required, which will pay for itself in spades when you're debugging. Thin client. Clean separation of concerns.

I was going to go through my headaches setting everything up here, but I'll split that into a new post later. The quick version? Because of a wack nuget configuration I didn't realize was an issue (command line nugget didn't pick the "right" nugget server; I had a local one set up in VS2017 as well), I'm using SQL Server for now, though I will probably give PostgreSQL another look before I settle on a dbms.

1 If you want the cleanest stack, there's nothing more advantageous than using the same language on the server and the client. Node lets you do that. There's some overhead (learning & setup tedium) standing up a web server -- do you just use Express everywhere, or serve from Nginx? -- but nodejs is The Right Answer, imo. But I'm a C# guy "professionally", and there still seem to be more opening for C# devs than node, so I think there's an argument that a C# server-side should be easier for a customer to have maintained going forward.

Labels: , , , ,

posted by ruffin at 2/14/2018 11:10:00 AM
Thursday, February 08, 2018


YouTube was recently caught displaying ads that covertly leach off visitors' CPUs and electricity to generate digital currency on behalf of anonymous attackers, it was widely reported.

Word of the abusive ads started no later than Tuesday, as people took to social media sites to complain their antivirus programs were detecting cryptocurrency mining code when they visited YouTube. The warnings came even when people changed the browser they were using, and the warnings seemed to be limited to times when users were on YouTube.

That's clever.

And I do mean to resonate with Darwinism there.

Labels: , ,

posted by ruffin at 2/08/2018 11:56:00 AM
Monday, February 05, 2018

Have you ever opened frozen concentrated juice and had it look less juicy and more syrupy? I have.

Refrozen juice

After looking at it strangely for a few minutes, and remembering that it'd been in the fridge for months on months, though still well within its due date, did you remember that someone'd left the freezer door open overnight not that long ago? Boy, I did.

And that's probably what happened, confirmed by New York State's Department of Agriculture:

Can Thawed Food Be Refrozen?

Guide to Safely Refreezing Thawed Food

Frozen Uncooked Foods
Thawed - but Cold
45 Degrees or Lower
Thawed - Warm
(Above 45 Degrees)
Fruit Yes Probably safe - but may have fermented
Fruit Juice Concentrate Yes - but flavor may be poor and reconstituted juice [may] separate No - may have fermented
[emph mine -mfn]

Thanks, yankees!

(Ok, yes, I'm mixing it in a growler. Unlike the Yankees, I couldn't find any pitchers.)

Labels: ,

posted by ruffin at 2/05/2018 09:54:00 AM

Support freedom
All posts can be accessed here:

Just the last year o' posts:

URLs I want to remember:
* Atari 2600 programming on your Mac
* joel on software (tip pt)
* Professional links: resume, github, paltry StackOverflow * Regular Expression Introduction (copy)
* The hex editor whose name I forget
* JSONLint to pretty-ify JSON
* Using CommonDialog in VB 6 * Free zip utils
* git repo mapped drive setup * Regex Tester
* Read the bits about the zone * Find column in sql server db by name
* Giant ASCII Textifier in Stick Figures (in Ivrit) * Quick intro to Javascript
* Don't [over-]sweat "micro-optimization" * Parsing str's in VB6
* .ToString("yyyy-MM-dd HH:mm:ss.fff", CultureInfo.InvariantCulture); (src) * Break on a Lenovo T430: Fn+Alt+B
email if ya gotta, RSS if ya wanna RSS, (◔_◔), ¢, & Δ if you're keypadless

Powered by Blogger Curmudgeon Gamer badge
The postings on this site are [usually] my own and do not necessarily reflect the views of any employer, past or present, or other entity.