Archive for the ‘Everything Else’ Category

I wish I didn’t care…

Tuesday, February 3rd, 2015

Path

Today I got another email from my lawyers about more pre-trial motion paperwork for the divorce. I don't know why this is an ongoing issue, but I have a feeling it's because Liza doesn't like the idea of getting less than she thinks she needs - or deserves. But the interesting thing is that it doesn't matter one little bit. Not one.

My wife of (now) 29 years can choose to divorce me without any consideration or cost to her. She can ditch me like a old shoe. I can't say a thing, I can't stop here in the least. And more importantly, she has the law on her side. There is no financial cost to her of this divorce - she gets awarded money not because she deserves it - but because someone decided that there are sufficient numbers of bad husbands out there that a woman should be able to divorce the worthless slug, and then be granted a portion of his money for the rest of time.

So I get these emails about giving them more financial information, and it just breaks my heart. I hate digging this up, and it makes me about as mad as I can be. But in the end - again - it doesn't matter one whit. The legal system in this state is not about justice and fair, it's about empowerment for women, and while at some level I understand that, I don't see that a judge should not look at the circumstances of the divorce, and say "Hey, you just got tired of this person, so you don't get all you want..."

But as I said... none of this matters at all. And it makes me sick. And I wish I didn't care at all. But it still breaks my heart.

Metra Changes – Just Keepin’ it Fresh

Tuesday, February 3rd, 2015

Metra Engine

This month Metra had another rate hike, and it was a pretty good sized one - I've heard that it was more than $15/month for most of the folks I talked to. It was 10.8%, and they didn't have one 'no' vote on the measure. From Naperville, it's now $185.25, and that's getting above my first car payment, but it's still way cheaper than a car, and I can't even imagine driving into the city on a daily basis.

So it's the cost of living in Naperville and working in Chicago. Maybe someday I'll be able to work at home again, and I'll be able to skip the monthly ticket, but for now, I need to come to Chicago, and I'm used to it.

Lie to Me on Netflix is Incredible

Monday, January 5th, 2015

TV.jpg

I've been having a little break before starting my new job at a new Shop, and I've had lots of time to catch up on shows on Netflix. One of my all-time favorites is certainly Lie to Me.

The acting, the writing, and the mere premise of the show is absolutely some of the best work I've seen in years. I mean it's on par with the best TV I've ever seen. That it only lasted a few seasons is sad, but predictable.

Great shows that appeal to me often don't last. There's not enough mes in the world to keep them going.

Happy Birthday to Me!

Wednesday, December 31st, 2014

Cake.jpg

Well... it's that time of year again, and I'm going to spend it quietly at home. Tomorrow I'm traveling to Indy to spend some time with my siblings as we're all gathering at my brother's place. It should be a lot of fun - it always is, and the food will be great, and my family makes me feel "normal".

Another year on the horizon, and in many ways, it'll be a lot better than the last, but there's so much pain in the future, I hesitate to think about it. Just take 5 mins at a time, and don't think too far into the future.

Marco Polo on Netflix is Excellent

Tuesday, December 23rd, 2014

TV.jpg

I'm on a little break, and I am watching the Netflix Original Marco Polo, and it's an excellent show. I'm a sucker for historical dramas, as I love to understand why and what were the causes for the turns and decisions in history. The writing is very good, and the acting and sets are just amazing. Well worth watching, if you have the time.

Touched by a Good-Bye

Friday, December 19th, 2014

Great News

I would not have thought it, but just now a co-worker came by to say they were going to really miss working with me. She was brought to tears. I was shocked. When I asked why, she said she came to work at Groupon because of our interview, and it really stuck out to her the passion and commitment. She wanted to do that.

I remember that interview, and I wanted that too. She could be really great. But she let management push her around, and that was a mistake. She's young, and there will be more times to work together.

It's surprising to me how we touch each other's lives without knowing it. I thought I was just a pain to the group - at least in a large part, but I wasn't - not to her. And she was touched enough to express it.

I have had a good run here. Learned ruby, clojure, a lot of good things, and I've clearly touched at least two people here. That's a good run. I have nothing to complain about.

An Historical Review of My Namesigns

Friday, December 19th, 2014

cubeLifeView.gif

While at The Shop, I've been given an interesting list of name signs for my desk. I was really fortunate to start in a good group - where there was a nice balance of work and play, and they all took part in giving people names on their name signs. While I could just save the paper copies, I decided that I'd spend a little time, do the CSS, and put them all - with a nice commentary, as a post.

Without further ado, let's get right to it.

I'm a little fuzzy about the first one, but I remember distinctly asking about the name signs, and where I could get the metal stands they all sat on. I didn't say that I was hoping to get a great nematic from someone in the group, but within a few minutes of me asking about it, Mike had gotten a new stand out of the office supply cupboard, and Gary had printed out a name tag for me:

What About Bob?

It was so nice because it's one of my favorite movies, and it was a wonderfully kind thing for the guys to do.

The next one, like all the others, were placed without my knowledge - which was the way the group worked. And I'm not sure exactly what I did to be awarded this name tag, but I'm sure it had to do with never giving up.

The Ineffable Will of Bob

This next name tag was clearly from a time when everyone in the group was sold on the idea of moving forward, and I was quoting National Treasure about what we still had to do before we got there.

Johnny Raincloud

This one came along after someone had doubted me on something, and I answered back the the childhood response that I used for many a year.

Double-Dog Sure

The ruby gem collection is impressive - some are good, others are great, but there is the tendency to go with Convention over configuration, and in that sense, there was a new feature the group needed to add - and were hoping that it already existed in the wild. In the end, I quipped that if it existed, that it would be...

One Spankin' Awesome Gem

There was likely a time when I brought in a cold. The group was tight, and it was a mistake on my part. I should have stayed home. But it earned me this name tag.

Patient Zero

It was customary to send out an email to the group when you were planning on working from home in the coming days. I was typing this email way too fast, and the title was a typo, but one of epic proportions in the group. I had people using this as the tag for working from home for months to come. It was my one, real contribution to the group's culture.

WTF <EOM>

My consumption of Diet Coke was certainly noted and talked about around the group. At the same time, I was working on a project called Dark Magic, and so they gave me the name tag:

A Machine That Turns
Diet Coke Into Dark Magic

During the Bitcoin boom, a few of the guys in the group and I talked about doing some interesting things with Bitcoin. I'm still interested in it, but the lack of a solid financial backing means that it's just too volatile for me. One of the guys joked that if that were solved, how would I feel then, and my response made several of them laugh. It was almost immediately my new name tag.

Fleece Them Mercilessly

While in a meeting with a group trying to internationalize the data on the cheap, the person presenting was very upbeat (to say the least), and while I wanted to temper the ideas with the reality, I wanted to also let this person know that I recognized their positive attitude. It was then my next name tag.

Your optimism is almost infectious

This next one came from Gary, but I wasn't really sure why. Just Gary being Gary, I suppose.

Robert B. "Bob" Beaty

And my final name tag came when a few in the group realized that we all had unique initials, and so made name tags for everyone in the group:

B

And now it's my last day at The Shop. I start a new job just after the holidays, and that's going to be very nice, but I'll always remember my first group here, and all these fantastic name tags.

Adium 1.5.11hgr5894, MSN, and OS X 10.10 Aren’t Happy

Friday, December 19th, 2014

Adium.jpg

A while back, just after switching to OS X 10.10 Yosemite, I saw that Yahoo! wasn't at all happy with Adium. It simply wasn't connecting. Thankfully, there was a known fix in the works, and it didn't take long for someone to build a version and post it online. Soon after that, the Adium developers posted a similar update to their Nightly Builds, and I picked that up to be a little safer.

I have to admit that I'm a little surprised that it took so long, but I was willing to let it go - Adium has been a really great Open Source tool for me over the years, and it's certainly possible that they just got caught up in other things, and didn't have time to make the release.

Now we're in a slightly different situation, and there's a problem with MSN Live:

Adium and MSN

The story is that MSN has changed the accpetable API ids and the one that Adium and libpurple is using is not on the "approved" list. There is another in libpurple now, but the Adium team hasn't picked it up, or hasn't integrated it, or hasn't released it. In any case, it's stalled. Badly.

Now I'm not a big MSN IM user, but it's there, and it's simple to fix, and it's ready to go, so let's get to it, guys. Or let's make it clear that there are no developers to support this, in which case, I'll pick up the mantle, and just do the things that I think need to be done to keep it moving forward.

My fear about this is that the codebase is in horrible shape, and it's hours and hours to figure out anything, and then it's horrible to build, etc. There's also the Colloquy concern - it stopped updating, and then Textual picked up the banner, and I bought that app off the App Store. If someone looks at the sad state of Adium, I see them coming to the same conclusion and making a paid multi-protocol IM client.

Another Boost in the CryptoQuip Performance (cont.)

Friday, December 19th, 2014

Clojure.jpg

I got another email from my friend on the updates I'd made to the solver, and he pointed out that the pattern function we were using:

  (defn pattern
    "Function to take a word (as a string) and return a vector that is the
    pattern of that word where the values are the index of the character.
 
      => (pattern \"see\")
        (0 1 1)
      => (pattern \"rabbit\")
        (0 1 2 2 3 4)
    "
    [word]
    (let [dw (distinct word)]
      (map #(.indexOf dw %) word)))

does something that's not strictly necessary to the proper functioning of the algorithm - the distinct call on the input word.

If we have a function that maps these words into some kind pattern, then it really doesn't matter what the pattern is - as long as it's just the pattern, and is not able to be confused with another pattern. So if we choose to change the code to look something like this:

  (defn pattern
    "Function to take a word (as a string) and return a vector that is the
    pattern of that word where the values are the index of the character.
 
      => (pattern \"see\")
        (0 1 1)
      => (pattern \"rabbit\")
        (0 1 2 2 4 5)
    "
    [word]
    (map #(.indexOf word (int %)) word))

where we are ignoring the cost of the repeated characters in the word in terms of the index they represent, then we have a similar pattern that's deterministic and comparable, but it lacks the call to distinct, and so it's going to be a little faster.

In the REPL, we can see the old way:

  cq.main=> (time (dotimes [_ 100000] (dpat "bivteclnbklzn")))
  "Elapsed time: 8.748 msecs"
  nil
  cq.main=> (time (dotimes [_ 100000] (dpat "bivteclnbklzn")))
  "Elapsed time: 8.158 msecs"
  nil

or about 87 nsec/call. That's fast. But when we test the new non-distinct mapper, we get:

  cq.main=> (time (dotimes [_ 100000] (pattern "bivteclnbklzn")))
  "Elapsed time: 4.859 msecs"
  nil
  cq.main=> (time (dotimes [_ 100000] (pattern "bivteclnbklzn")))
  "Elapsed time: 4.972 msecs"
  nil

or down to about 49 nsec/call. That's another significant percentage on that call, but I doubt it'll convert to something really significant in the overall solution. It's down to about 5 to 6 msec per benchmark solution. Not bad, considering it's all on a laptop, and all on the JVM. I do love this game!

Another Boost in the CryptoQuip Performance

Thursday, December 18th, 2014

Clojure.jpg

Today I got an email from my friend about the times we were getting on the pattern function in the code - that function that turns the word into a sequence of ints that corresponds to the character pattern of the word. So we might have:

  => (pattern "see")
  [0 1 1]
  => (pattern "rabbit")
  [0 1 2 2 3 4]

At the time, my best code looked like this:

  (defn pattern
    [word]
    (mapv (into {} (map vector (distinct word) (range))) word))

and the times we were getting just for this function were not as good as his version:

  (defn pattern
    [word]
    (loop [p [] d {} n 0 f (first word) r (rest word)]
      (if f
        (if (contains? d f)
          (recur (conj p (d f)) d n (first r) (rest r))
          (recur (conj p n) (assoc d f n) (inc n) (first r) (rest r)))
        p)))

On 1000 calls he was beating me by a couple of milliseconds - and it makes sense... he's building the map as he goes, and I took the time to build it up-front, and I'm paying the cost for it. The big cost is that I then have to run map again to use the map I just created. His code builds and uses the map at the same time.

So I was trying to think of a way to speed up the process, and I couldn't think of a simple way, and then I decided just to try a simple test - use the Java indexOf method to get the index on the distinct string and then return that. The code then becomes:

  (defn pattern
    [word]
    (let [dw (distinct word)]
      (map #(.indexOf dw %) word)))

The times were startling:

  cq.main=> (time (dotimes [_ 1000] (bob "bivteclnbklzn")))
  "Elapsed time: 0.342 msecs"
  nil
  cq.main=> (time (dotimes [_ 1000] (bret "bivteclnbklzn")))
  "Elapsed time: 3.605 msecs"
  nil

where bob is my new version with indexOf and bret is his version with the loop/recur.

A factor of 10x. Wow! Ten times faster. Make the string and use the inherent properly of the string and it's index to do the mapping. What a hoot! I have really enjoyed working on this with my friend.

When we put this into the web server, we get even better solve times:

[12:29:13.757:qtp1360409373-14] INFO  cq.block - Finished match-up [8 words] in 1ms.
[12:29:13.763:qtp1360409373-14] INFO  cq.block - Finished solve in 7ms.

...just amazingly fun.