Friday, December 20, 2024

The Thaumaturge

Play The Thaumaturge. I swear, I'm a low stakes Comissioner Pelevin. Waiting for Wiktor.

Monday, July 31, 2017

Hacking about on AWS Alexa

First AWS Summit.
First Alexa skill.
First Node.js app.

That's a lot of first all at once. In any event, Jeff Blankenburg's workshop inspired me, and Memo Doring's workshop got things moving.

Then I hit the typical 'how the hell do I debug this pile of slag?' roadblock. Thankfully, Nathan Grice already wrote all that down. (the post is a bit out of date at this point, almost a full year after the publication date, but it's a minor bit of mental version translation)

Step-through in VSCode for Alexa Lambda functions. Now it's time to get this thing working!

Frankly, this same general setup probably works for any AWS Lambda function with the right packages; Alexa is just the use case that made me search for the environment setup. And, yes, this post is simply to remind me where to find the instructions later. Here's hoping the link-rot stays away for a while.

SF

According to Neil Gaiman Science Fiction should be call Speculative Fiction.
After listening to the TED Radio Hour 'Spoken and Unspoken' episode I think perhaps Subjunctive Fiction fits better and (with Phuc Tran's talk as background context) evokes more of the power of the genre. SF can express ideas that could not be explored at all without the background fictional conceits used.

Though that also probably sounds too professorial for ordinary use.

Saturday, July 15, 2017

I've been asked for a list of my podcasts

Sadly I don't get to listen to as many as I'd like and most of the episodes go un-heard. If you're curious, I use an Android app called Beyondpod to manage subscriptions and the playlist (the Smartplay feature is extremely useful). The names below are whatever is listed in Beyondpod's feed list and may not be exactly the same as what you might find while searching. It'll be close enough to get you there though. It's also important to note that I don't groom this list very often. I'm pretty sure that some of what I'm subscribed to has gone defunct, but I frankly can't be bothered to prune the list.

Without further preamble here they are in no particular order.


  • NPR Hourly News Summary
  • Planet Money
  • StarTalk Radio
  • Science Friday Audio Podcast
  • APM: Marketplace
  • Up First
  • APM: Marketplace Tech
  • TED Radio Hour
  • Snap Judgement
  • Hanselminutes
  • On Being
  • Freakonomics Radio
  • Note to Self
  • LeVar Burton Reads
  • Hidden Brain
  • The Infinite Monkey Cage
  • Wait Wait... Don't Tell Me!
  • The Skeptic's Guide to the Universe
  • CodeNewbie
  • Skepticality
  • American Museum of Natural History Podcast
  • Intelligence Squared U.S. Debates
  • Undiscovered
  • Astronomy Cast
  • Only Human
  • The Adaptors



These are some new ones I've added but haven't formed an opinion on. I reserve the right to can them later, but they looked worth investigating.

  • The Titanium Physicists Podcast
  • Ask a Spaceman!
  • KQED Science News
  • Hubblecast HD
  • Physics World Science Podcast

Sunday, July 19, 2015

4Clojure: For the Win

(for [x (range 40)
    :when (= 1 (rem x 4))]
    x)

x is assigned the range of integer values from 0-39. x is finite so the for stops evaluating when x is fully consumed.
On each iteration the remainder of x/4 is compared to 1 and if they are equal the body is evaluated (which is just x).

(for [x (iterate #(+ 4 %) 0)
    :let [z (inc x)]
    :while (< z 40)]
    z)

x is assigned a lazy sequence of all the multiples of 4 (iterate from 0 applying +4 at each step using an anonymous function). x is infinite so the for is terminated with :while
Each iteration of the for symbol z is assigned x+1.
While z is less than 40 the body is evaluated (which is just z) and the for loop terminates when z >= 40.

(for [[x y] (partition 2 (range 20))]
    (+ x y))

The range from 0-20 is split into segments of 2 numbers. One segment deconstructed into x and y per iteration of the for. The sequence is finite so the for terminates when the full sequence is consumed.
x and y are added as the body of the for.

Each of these results in the same output (a list of each multiple of 4 incremented by 1 up to 37) just by a different mechanism. For my money the first option is probably the best combination of concise and obvious.

Clojure for macro keywords

These docs weren't incredibly helpful in figuring out the difference between :when and :while.
The examples
(for [x [1 2 3]
  y [1 2 3]
  :while (<= x y)
  z [1 2 3]]
  [x y z])
and

(for [x [1 2 3]
  y [1 2 3]
  z [1 2 3]
  :while (<= x y)]
  [x y z])

come close to exposing the difference, but what should really be stated explicitly somewhere is that :while stops attempting to evaluate at the first false result whereas (almost said while there >.> ) :when continues to try to evaluate after the false.

(for [x [1 2 3]
  y [1 2 3]
  :while (= x y)
  z [1 2 3]]
  [x y z])
;;([1 1 1] [1 1 2] [1 1 3])
(for [x [1 2 3]
  y [1 2 3]
  :when (= x y)
  z [1 2 3]]
  [x y z])
;;([1 1 1] [1 1 2] [1 1 3] [2 2 1] [2 2 2] [2 2 3] [3 3 1] [3 3 2] [3 3 3])

Perhaps I'm dense but this wasn't immediately obvious to me.

Edit: Or perhaps I should have actually read. Example 8 is pretty explicit. >.<

Saturday, June 6, 2015

Fuck Microsoft and their little dog too

I just wasted 3 hours trying to get a dev environment past the 3rd setup step. Why? Because VT-x was FUBARed by Hyper-V. 3 fucking hours googling and getting a headache trying to figure out why the Intel(R) Processor Identification Utility tool was saying my hot-shit Surface Pro 3 Core i7 processor didn't support 'Intel(effingR) Virtualization Technology' or Intel (shockingly not Red) VT-x with Extended Page Tables. All the while wondering if my CPU is weirdly broken and going to need an RMA after 6 months of settling into it. As it happens I tried deleting Hyper-V entirely after trying a good half dozen tools and workarounds, looking at the (honetly braindead) Surface BIOS UEFI, and I can't remember what all else. All I needed was to open PowerShell as admin and
Disable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All

aka KILLITWITHFIRE

The HabitRPG dev environment uses Vagrant and VirtualBox, which was complaining that VT-x wasn't available and dieing horribly (presumably because it's a 64bit guest). But apparently Hyper-V EATS that part of your CPU so nobody else can use it. Or something. Whatever, don't bore me with the technical details, I just wish someone somewhere had thought to mention the critically important bit that HYPER-V WANTS TO MONOPOLIZE THE PLAYGROUND EQUIPMENT. Anyway. Learned my lesson (I might even remember it next time) and won't be touching Hyper-V ever. Unless by some perverse chance I opt to write something for Windows Phone. Which is incredibly unlikely knowing the debugging will require Hyper-V and thus explicitly ban me from doing a hundred other things. You can pretty much forget about that.
Now the vagrant guest is coming up and, with any luck, the VM I had decided was going to need to be wiped might actually be usable again. GAH, I was just starting to think MS gave a shit about computing in general, what with Community VS and free (sorta) Windows 10 upgrades.

Wednesday, April 1, 2015

Cancer

Cancer (n) - the phenomenon resulting from a cell making its division function recursive and forgetting a proper stopping criterion. The function will recurse until it crashes the system or is halted externally.

Friday, March 20, 2015

The right to be...

In response to http://intelligencesquaredus.org/debates/past-debates/item/1252-the-u-s-should-adopt-the-right-to-be-forgotten-online

There is no right to be forgotten. That's a misapprehension of the root point. There is instead a right to be understood.
Every story discussed in support of the motion points to the every-human wanting to be understood as what they are, not what they were or what someone else believes them to be.
Every story posed against the motion points equally to a public need to understand who someone is now. The stifling of negative information about public figures being prominent.

So I propose that the motion is simply broken. We should instead be discussing a right to be understood and processes that can express and reinforce that right. Frankly, I don't believe any government is the proper party for that. Law is not, cannot reasonably be, flexible enough for that and so it must come to the individual's interaction with the world that expresses the right. Perhaps sadly there are many individuals with greater leverage in their interactions that don't seem interested in understanding anyone outside their circles.

Tuesday, January 27, 2015

Problem analysis

Response to
http://discourse.codenewbie.org/t/coding-exercise-problem-breakdown/618


  1. Check front door lock.
    1. If locked, unlock.
  2. Open front door.
  3. Until distance to car door = 0, walk toward car door (I'm deliberately ignoring pathing concerns, my car door is basically straight outside my front door)
  4. Check car door.
    1. If locked, unlock
  5. Open car door.
  6. Sit down in driver seat sideways.
  7. Juggle lunch, backpack, etc into passenger seat (this sort of crap is why robots tend to look so clumsy, just try and create an algorithm for how your arms move doing that, never mind controlling your balance through it all, your brain really is amazing)
  8. Pull feet into car.
  9. Close car door.
  10. Insert key into ignition.
  11. Turn key.

There are a few minor steps left out and there's some assumed knowledge like the car not having keyless ignition (mine does so this algorithm couldn't be applied naively to my case). It also assumes that you're able to carry whatever you're carrying without juggling anything around, and you don't have to find the right key on your key ring or look for your car in an apartment parking lot. And it still took 11 procedural steps.

Oh. And we never closed and re-locked the front door. That wasn't in the requirements. Of course in my case my wife does that in the morning so I suppose you could call me a good example of why you should follow the requirements doc once it's been reviewed and accepted by all parties.

Tuesday, January 13, 2015

Code Combet + Firefox = win

Wow. This runs so much better in Firefox. Go figure.
It's nearly unplayable in Chrome (which surprised me), it's a lot better in IE (which floored me), but it's smooth as silk in FF. Well, aside from slowing down a bit as the thang count increases.

Also, in IE my solution to one of the levels locks up every time I submit it even though it runs fine in the 'debug environment'. In FF? Works like a charm. Go figure. >.> FF just earned a spot back on my computer.

Sunday, January 11, 2015

Certainty

There is one thing about which I hold myself certain. One thing I consider inviolable truth. It is that certainty is poison to the human spirit. The more certain you are of something the less human you become. Witness fundamentalism everywhere.

If you are certain of something then that is something that you must do your utmost to inject doubt into. Examine under the light of many worlds, consider it as the ancient Persian would both drunk and sober, include as many more altered states as your lifestyle allows, consider whether you would believe the same if your moral basis were built upon something else. Perform experiments, physical or social as necessary, to test your understanding and the veracity of your certainty and keep notes. Make it impossible for yourself to ignore the edges of your certainty where logic or fact tells you otherwise. Because once you refuse to allow yourself to see one small facet of reality you begin to blind yourself to all of it. And thence, by all measures of psychiatry, lies madness.

I have yet to find evidence that certainty in any thing does more good than harm. However while there are truths that lack contrary evidence there are no truths that merit certainty. I accept even my initial statement in this post as a poison, it poisons my ability to make statements unambiguously and it poisons my ability to trust in the things that people say. Frankly, that may be a good thing in some cases. I accept that one poison regardless but no further. No other certainty will I knowingly accept into my self.

Smart methods can make a developer look stupid.

So I'm playing through Code Combat (works a lot better generally using Python and in IE though it still has a lot of head-on-desk problems) and I reach a section where I'm supposed to blow up ogres but not villagers. Thing is I only have access to findnearestenemy() in order to identify them. Now it's a pretty explicit method name but I'm much more used to dealing with very simple functions. I'm expecting this to give me whatever the nearest actor is and make me decide whether it's something I want to attack or not. Indeed, a method that does that is generally more useful. So I'm bonking my head for 5 minutes or so because the example code which you're forced to use doesn't account for villagers.

Well apparently findnearestenemy() only returns hostiles. Duh. But. As a method that makes it painfully specific. I'd much rather have a method that gives me the nearest actor and lets me decide whether it's one I care about or not. Maybe that method comes later.

Saturday, January 10, 2015

CodeCombat take 2

So, it works much better in IE. To my great disappointment. It looks like Coffeescript is rather better/more fully implemented. Since they say it's mostly written in Coffeescript that stands to reason. What doesn't stand to reason is that even the CS implementation has bugs, or at least one level/possibly game, breaking bug. You can't attack in a loop. Though to be complete I don't think I tried attacking and something else in the same loop, but the level startup script contained a comment that attacking in a loop was currently broken. Anyway. That worked in Python, but it seems a bit silly to expect someone to work an entirely different syntax just to winkle their way past a few levels here and there.

Oh, and they're looking to hire a level designer which for a 'game' like this would be a very particular set of skills. Suggests that they're doing pretty well too. Though, having a good handful of languages implemented (mostly and partially) is generally pretty good.

Having escaped the dungeon it's time to explore the countryside. Onward!

Edit: Correction. There are a ton of bugs in IE as well. For an extremely frustrating example the second level in the forest area requires the leather boots. Only I couldn't buy them because the price was 'undefined.' Which may only be a minor data error but it stymied my progress until I decided to try buying the next upgrade of boots (reinforced or something) which I thankfully already had the gems for. Equally thankfully the game only checks that you have the required methods available on your equipped gear (in this case the moveXY method) rather than checking the gear itself. So that was at least thoughtfully implemented.
And then, of course, I don't know how many times I'd gone in and out of the level in the forest before it the second level stayed unlocked without a refresh. Here's the scenario: Enter level 2. Fiddle with it some and get frustrated at the bugs. Close IE to try it in Chrome. Get sick of it there, and go back to IE. Level 2 is closed. ?!? Hit refresh. Level 2 is back. !?!
Maybe the page is cache-enabled when it shouldn't be? But Chrome didn't have that particular problem. It has different problems. Cumulatively it's getting to be enough to put me right off the game.

Oh, and apparently you can put @attack in a loop in Coffeescript as long as there's some other statement with it. So... yeah.

Monday, January 5, 2015

It's the end of the year as we know it

The year is finally over, the holidaze are past, and I think my EOM-induced jetlag is mostly receded.
And now I've discovered that CodeCombat supports Io. Best surprise I've had all year. Might even keep that title through December!

It's marked experimental but I'm always up for a bit of frustration (or I wouldn't be interested in code anyway). Time to test it out!

Edit: Aww, massive letdown. It's not implemented anywhere near fully enough to be playable. Or maybe fun. I mean, basic loop structures aren't in place. So theoretically you might be able to play through (so far everything I've seen could be done purely by hand but I have no idea how long that will hold out) but you certainly won't learn anything useful or even enjoy the experience. Mind, this is only relevant to Io; I haven't looked at any of the other language implementations yet.

Friday, January 2, 2015

Good intentions

Intention does not matter in this existence. Only result can be meaningfully measured and therefore intention matters only insofar as your focus on it guides you to the result you intend.

Aphorisms about roads to various places are mistaken. If you were focused on your intention then the destination would be in sight and you'd know you were heading the wrong direction. Intention paves nothing as it isn't substantial enough in this existence to do so; intention must be the compass. Actions (even the act of speech) are your paving stones.

Thursday, December 18, 2014

7L7W Week 2: Io Day 2 round 2 continued>Toddling

I should probably check to see if something has defined the sum slot on Number and List first, but... let's start this simple.

Number sum := method(call target)
List sum := method(
total := 0;
foreach(val, total = total + val sum)
)

Io> a := list(list(1, 2, 3), list(1, 2, 3))
==> list(list(1, 2, 3), list(1, 2, 3))
Io> a sum
==> 12

As the title suggests, I think I'm getting used to this now. This may not be exactly how it should be done, but it was ridiculously easy to implement (even with accidental recursion >.> ). Implementing a sum method on two base prototypes of the language leaves me a touch uneasy but these are additions to the prototypes rather than redefinitions. If I were going to try this in production code of some sort I would need to either use a less generic slot name or properly check for an existing sum slot on both prototypes.
... Also it strikes me that the question was to write a program, not a method on the List prototype. Oh well. Nobody is grading this but me.

The averaging problem was pretty straightforward but I had some confusion around the select message. Mostly because I saw a reference in the programming guide to a method ISNUMBER() which doesn't appear to actually exist anywhere? Or at any rate I couldn't find it so I had to do this:

List myAverage := method(
values := call target select(v, v type == "Number");
if(values size == 0, Exception raise("No Number in target List"));
values reduce(+) / values size
)

Unlike the summing problem this solution will not handle multidimensional arrays. I could swap the reduce message for the sum method defined above but I'd have to handle n-dimensionality in the select message at the top of the method as well.

... I was going to finish day 2 today and post this. Actually I was hoping to post this yesterday but it has not been a very good week for side projects. Unfortunately it's going to have to wait. It might have to wait until the weekend. I want to get this posted at least and I'll try to get day 2 finished before Monday.

Tuesday, December 16, 2014

7L7W Week 2: Io Day 2 round 2>Finding my feet

I might be getting the hang of this.
recursiveFibonacci := method(n, 
if(n == 0, 
0,
if(n == 1,
1,
recursiveFibonacci(n - 1) + recursiveFibonacci(n - 2)
)
)
)

loopedFibonacci := method(n,
nSub1 := 0;
currentN := 1;
for(i, 1, n, 
currentN = currentN + nSub1;
nSub1 = if(i == 1, 0, currentN - nSub1))
currentN
)

Number recursiveFibonacci := method( 
if(call target == 0, 
0,
if(call target == 1,
1,
((call target - 1) recursiveFibonacci) + ((call target - 2) recursiveFibonacci)
)
)
)

Number loopedFibonacci := method(
nSub1 := 0;
currentN := 1;
for(i, 1, call target, 
currentN = currentN + nSub1;
nSub1 = if(i == 1, 0, currentN - nSub1))
currentN
)

Do I get double bonus points? Hm, no, probably not. It's not exactly a stretch to move from a parameter to calling the message target is it? These seem pretty self explanatory to me (Fib numbers aren't a new science after all) but I can't help feeling like it could be done better.

Division by zero? Sure, let's break basic math... >.<

Number divide := Number getSlot("/")
Number / = method(n,
if(n == 0,
0,
call target divide(n)
)
)

I did cheat a bit. StackOverflow pointed me in the right direction.

And it's bedtime now. I'll get the rest of the self study done tomorrow (with a grain of salt). So progress has definitely slowed in my 7(3!) week journey. However it's also getting more interesting so assuming there's a correlation between difficulty and interest... yeah.
Then again it may be due to my lack of cohesive sleep schedule (have I mentioned lately that ridiculous software installs suck?) which sadly will only get worse. There's another install this weekend (end of year compliance, yippee) then a family vacation (meaning all my wife's immediate family, which is neither vacation nor particularly conducive to any kind of study) right after Christmas... which is itself a disruption. Then of course there's the end of the year, which is another all-nighter (I've really got to streamline the end of month process)... I probably could have started this at a better time of year. Then again interrupted progress is better than sitting around playing video games or trying to study something that has gotten stale and boring. Maybe I'll take a break from 7L7W after week 2 and get back to some C#. Play the flipflop game with them. Or maybe not. Since I'm playing dablling all over the place maybe I'll crack that LISP book back open. I'm not sure the original  rationale for shelving it still holds. Ah, the possibilities.

Also, the song that's been driving me today like Paul Revere on speed. That's good stuff there. I must recant my uninformed, juvenile opinions of rap. I clearly had an insufficient sample size to base opinion on.

Monday, December 15, 2014

Google ate my organization

Damnit Google. The whole world may be going to flat, no order, bullshit but I personally keep my files organized in folders. I don't want to search every single bloody time I want to open something. I know right the fuck where it is, let me open it.

Or, I would know if you hadn't moved everything to this worthless damned timeline BS. Give me back my folders; I don't want to wait for you to load a Facebook-alike 'productivity' interface just so I can click through it every single time I try to open something. Talk about a waste of lifespan.

7L7W Week 2: Io Day X>Digging in

Feeling almost human again after my weekend. Serious 2 week prep & 4 hour imp software updates suck. Moving right along.

Let me try to break this down.

Io> test := method(stuff, stuff println)
==> method(stuff,
    stuff println
)
Io> test("Hello World")
Hello World
==> Hello World
Io> 

Interesting things are happening here. First I'm creating a slot in the Lobby...
Io> Lobby slotSummary
==>  Object_0x5bc8c0:
  Lobby            = Object_0x5bc8c0
  Protos           = Object_0x5bc860
  _                = "Hello World"
  exit             = method(...)
  forward          = method(...)
  set_             = method(...)
  test             = method(stuff, ...)

Io>

called test. But... I'm already ahead of myself. >.<

The method() block is sent as a message to the := assignment operator which becomes setSlot("test", method ... ) via a macro creating a slot in the Lobby and loads the method message into it. setSlot()sends the method block as a message, I think, and so the Lobby outputs the method with ==>.

In the next line I craft a message test and give it the string "Hello World" as an argument. This message is sent to the Lobby, where everything eventually lands I guess? It's the default evaluation context when there's no other object to catch the message. The Lobby responds to the test message with its test slot.

The Lobby's test slot is a method block that sends the println message to the first message argument (any additional arguments are ignored and generate no errors that I can see, coder beware). So a println message is sent to my "Hello World" object causing it to print to output. The "Hello World" message also gets sent on to the Lobby which outputs it with ==>.

That's a lot to follow in two lines of code. Time to take another hack at day 2.
Point of interest: the Lobby slot _ seems to contain whatever message was last output by Lobby via ==>. I could stand to learn the terminology for that. But I wonder how long it would take to crash the runtime by repeatedly sending Lobby slotSummary >.>