Thursday, May 01, 2014

Sometimes Optimization Matters (Recursion vs Iterative OR "A 4 Billion Character String is REALLY Long")



Computers today are really fast. In fact, they’re fast enough that some people don’t bother to optimize a lot of code. Sometimes that’s okay – after all, premature optimization isn’t a positive thing and can see you spending a great deal of time in exchange for little or no gain. Other times, however, you know there’s going to be a difference of an order of magnitude or more on a computation intensive part of a system.

As an example, there is a coding challenge on CodeEval to find the character in a string at a specific location. You aren’t given the string ahead of time, just the first character and the pattern to use in order to build the string (up to a string length of 3,000,000,000).

I’ll summarize here since it’s pretty simple. The character set is 0, 1, and 2. The first character is 0. You build out the string by using the previous string as the first half of the new string and add one to each digit. This means that 0 => 01 => 0112 => 01121220 and so on.

You only want one character in the string (we’ll call it N). The rest, as far as you are concerned, is garbage.

The knee jerk reaction for a lot of people would be to build the string to the length that you need and just access the character directly. That might even be okay if your upper bound for length wasn’t 3 BILLION. Given that, however, you need a better way (I’ll show you why here in a little while).

If you take a minute to look at it, you’ll realize that, by following the pattern they’ve defined for the number, that you will always end up with a string that has a length of a power of 2 (1, 2, 4, 8, 16, and so on). That means that you can determine how long the shortest string of that pattern will be by taking x = Ceiling of log2(N) and then calculating 2^x.

That doesn’t help us much by itself, but with that information, the pattern, and the fact that we only need one character, it makes this problem a prime candidate for recursion.

Method 1 – Recursion

Recursion can be kind of a scary word for some people because initially it can be sort of difficult to wrap your brain around. However, given a little practice, the hardest parts of the exercise are structuring the problem in a way that you can use recursion and making sure that you actually write it properly (in fact, it took me a little while to get rid of a bug because I had a line of code in the wrong place).

I’ll link to the code here so I don’t have to walk through everything, but to put it succinctly, after calculating the needed string length, the recursive approach essentially keeps track of where the target character would be during each string transformation, uses that to calculate how many times the character would have to change (C) and then calculates our N = C % 3 (each character is essentially a one digit base 3 number, so we can get away with that).

It’s probably as close to doing the problem with pure math as you can get without actually having an equation. As a result, it’s quick. REALLY quick. Fast enough, in fact, that I had to measure runtime in ticks (according to MSDN documentation, it takes 10,000 ticks to make up a millisecond).

The chart below shows the runtime (in both ticks and milliseconds) of one calculation for each given string length (2^0 through 2^32) – not counting file I/O or output to screen (which the original project required). This is just the time from being handed the number to getting the answer to what N is.

Power of 2
Recursive Runtime (in Ticks)
Recursive Runtime (in Milliseconds)
0
4
0
1
10
0
2
4
0
3
4
0
4
5
0
5
5
0
6
5
0
7
4
0
8
5
0
9
5
0
10
4
0
11
5
0
12
4
0
13
5
0
14
5
0
15
5
0
16
5
0
17
5
0
18
5
0
19
5
0
20
5
0
21
5
0
22
6
0
23
6
0
24
6
0
25
6
0
26
6
0
27
32
0
28
6
0
29
6
0
30
6
0
31
7
0
32
7
0

Note that the 32 tick runtime for the 2^27 length string is an aberration (probably caused by time slicing in the operating system). Running it multiple times, every test case ran at 20 ticks or below (generally 10 ticks or less). The only reason it looks like a big difference is because ticks are really REALLY tiny.

So, to sum up the pros and cons for the recursive approach to this problem

Pros: Really fast. Takes up less memory because there’s no actual string being built.
Cons: More difficult to write and debug


Method 2 – Iterative (Don’t do it this way. Please)

Again, I’ll give you the code for this method.

This time, we’re actually building the string in order to find the character. There are a few problems with this.

First is that it’s SLOW. I initially tried doing it two different ways. The first way ran for over HALF AN HOUR trying to calculate the 2^32 length string before I stopped it. The way which is in the code linked above runs much faster because it uses String.Replace() but seems to use more memory.

Second, it takes up A LOT of memory because it’s actually building the string and keeping it in memory. That’s not a big deal when the string is small, but according to the formula here, the size of just the string at its maximum length is 512MB.

Below is the benchmark data for this approach using the same constraints (no file or screen I/O) and the same numbers as the recursive approach.

Power of 2
Iterative Runtime (in Ticks)
Iterative Runtime (in Milliseconds)
0
4
0
1
5
0
2
4
0
3
6
0
4
7
0
5
9
0
6
21
0
7
17
0
8
35
0
9
56
0
10
111
0
11
281
0
12
386
0
13
2011
0
14
6360
3
15
12657
6
16
12528
6
17
125246
61
18
57912
28
19
53481
26
20
101440
49
21
204253
99
22
400705
195
23
1250113
611
24
1778822
869
25
3158791
1544
26
6980949
3412
27
OME
OME
28
OME
OME
29
OME
OME
30
OME
OME
31
OME
OME
32
NA
NA

OME stands for Out Of Memory Exception. These test cases literally caused the program to exceed its allocated memory (it was compiled for “any processor” since NUnit’s test runner didn’t want to play nicely with forced x64 solutions).

The NA result at 2^32 reveals a special problem. In C#, a character at a specific index of a string is accessed by using stringName[int]. The catch is that 2^32 is larger than an Int (you need at least a Long if you want a number that big), so you’d need to compensate by doing a substring to chop off the first Int32.MaxValue and reducing the index by the same amount.

I did that in the first attempt at this problem, but since I found out it was going to throw memory exceptions, I decided that I’d refrain from re-implementing it for the sake of simplicity and more readable code.

As you can see, this approach is MUCH slower than the recursive one. In fact, the general trend is to roughly double the runtime for each larger string. This means that a string of length 2^32 would take roughly 384,000,000 ticks (38,400,000 times the length of time for the recursive solution assuming the recursive solution took 10 ticks).

This is, of course, assuming you made the string from scratch for every test case. You could get around that to an extent by storing the string and just building it out longer as needed. However, you’d still be eating up a lot of memory to store the string. At its longest, the string would be over 4 billion characters long.

That’s longer than War And Peace. This is why, sometimes, optimization really matters.

I’m not sure I really need to sum up the pros and cons for this approach, but

Pros: Stupidly easy to write
Cons: Slow and memory intensive.

That’s not to say that recursion is the right answer to every problem, because it isn’t. There are times, however, when the extra work in designing a more efficient algorithm in order to tackle a problem can really pay off.

Just some food for thought.

Current mood: thoughtful
Current music: Shawn Mullins – Lullaby

Wednesday, April 23, 2014

The Evils of Perl (or Logic Should Make Sense)


The people who know me professionally (even a little) have probably picked up on the fact that I hate Perl. I spent several years as a sysadmin, so I come by my Perl aversion honestly.

Don’t get me wrong, it’s a useful language and I found it to be a very handy tool, but it’s so very easy to make code that even the person who wrote it isn’t sure what it does. The next day.

Or it could be that I’m a crappy developer. Either’s possible. Maybe a little from Column A and a little from Column B.

It’s the only language that I’ve seen where your cat can walk across the keyboard and come up with a valid program. What does it do? We may never know. It may parse a file for a list of addresses, trigger an ICBM launch, or create animated gifs of dancing cats, but by gum it’ll run.

Personally, I’m hoping for the dancing cat gifs. Everyone loves dancing kitties.

My standard quip for why I finally stopped coding Perl is that in any sane language, to get the length of an array, you do something along the lines of myArray.length. That may not be exactly how it’s done, but it will be something similar.

In Perl, you do the following: $myArray = @myArray

You assign the array variable to a scalar variable (single piece of information. Int, char, etc.). This to me makes zero sense from a logical standpoint.

I made that comment about a week or so ago, and the person I was talking to said that it makes perfect sense because it’s an implicit type conversion. (I’m not sure if he was joking or not. I hope, and think, that he was).

He had a sort of point about implicit type conversion, but that sort of thing is supposed to follow a logical convention of some kind. For example, an implicit conversion from int to long makes sense (it’s basically just shoving existing data into a bigger container).

You could even make the case for implicit conversion between string and character array data types. I wouldn’t do it, because it’s probably better done explicitly so you don’t shoot yourself in the foot, but the argument could be made.

However, using implicit conversion to cast an array to (effectively) an integer in order to get the length of the array doesn’t make any logical sense. It’s like buying a chicken because you want a renewable source of pineapples.

In what non-Euclidian universe does this make sense?

“Well, I just need to figure out how long this array is, so I’ll assign it to a scalar and HOLY CRAP! THERE’S CTHULHU!”

Ia! Ia! ArrayLength! Fhtagn!

Any language that will summon Cthulhu by simply using it is probably a bad choice…

Now, if you don’t mind, I’ve got to Great Old One proof my office.

Current mood: Amused

Current music: Charlie Daniels Band – The Devil Went Down to Georgia

Tuesday, April 08, 2014

In The Beginning



In the beginning, there was a television. To the television was attached a Tandy TRS-80 CoCo. Then he said, let there be code. And there was code, and it was in BASIC. He was a child and found the fact that he could make a computer do things to be really cool.

As a teenager, the internet was laid open to him. HTML was discovered and there were many horrible mistakes made, including the dreaded animated gifs of flaming skulls and spinning things. The land was known as GeoCities, and it was eventually cast into perdition for its sins.

Then was Java made known unto him, and, though he tried, he found it confusing. This was the first age of Java, so he was not alone in this.

Lo then did he graduate high school and make his way to college in an effort to learn to do this shit properly.

There did he learn of many things – Pascal and Prolog, C and C++, Scheme and Assembly, Socket programming, the creation of data packets, and stack traces among many other skills and pieces of arcane lore.

He paid the campus ferryman with his toils as a sysadmin where he applied logic to a place of chaos known as a non-profit. All the while, using his position as an excuse to do things programmatically so as not to have to run around the hilltop known as The Ridges as often.

Then did he return to Java, and he found it…okay. After all, with a background in object oriented programming, data structures, and the like, Java now made much more sense.

Upon his path, however, he decided that Java was not the right tool for him, so he endeavored to learn C#. Additionally, in order to wipe away, or at least atone for, his past sins of using Perl, he also learned Ruby to an extent that would allow himself to get into (and hopefully out of) trouble on occasion.

He walked the paths of desktop development and eventually began to work in order to master the arts of web development as well using the MVC framework. So, then, did his past of using HTML and CSS come back to him (though, thankfully, the flaming skulls and spinning things did not), and that is where he stands as of this day.

Current Mood - Tired
Current Music - Shades Apart - Stranger By The Day

Wednesday, February 26, 2014

TDD Saves Me From Myself



I’ve gotten into TDD at least a bit over the last few months. It has a learning curve, but I’m finding that it sometimes saves me from myself (and saves me time in debugging).

Part of my problem, like a lot of people, is that I sometimes over think things or fail to see something as being multi-purpose.

A perfect example was a code kata I started yesterday. It’s a fairly simple exercise – given a file with a list of numbers, take each number, reverse it, add it to the original number, and check to see if the result is a palindrome. Repeat until the number is a palindrome.

Simple stuff, really, but it’s a nice thought exercise.

It started off well. Decided to tackle the number reversal first. Since we’re dealing with data being snagged from a file, I decide to do the reversal with strings (since the data is already in string format, I can do most of the things required by the problem without having to typecast between string and int).

I name it ReverseNumberAsString since that name says what it does fairly well (it’s not the greatest name, but it’s the first function I’ve written in the solution, and we can refactor later).

Fast forward a bit to my writing a function to test if a number is a palindrome. This is where I start to over think things (and where TDD tells me I’m an idiot).

It’s been a long day and I’m a little fried, so the first solution that comes to mind is to set pointers at the front and end of the string and just walk them toward the center, comparing, until they reach the middle or find something they don’t match.

(Hey, I spent years doing C and C++ code. Give me a break)

I test a negative case first, and the test fails. I’d set the tail pointer to string.Lengtrh instead of string.Length-1 (it happens. I was fried.) I fix it, run the test, and it passes. Yay

Try to test for a positive case and the test fails. I go to look at the code to figure out why and, after a minute or two, I realize that I’m stupid, because I’ve already written the answer somewhere else in the code.

ReverseNumberAsString reverses a number that’s in the form of a string. No it doesn’t. It reverses a string. Period. I’m a dummy.

Rename the function to ReverseString like it should have been from the beginning and use that. Compare forward to backward. If it’s a palindrome, they should be the same thing.

Look at that. It works. Who would have guessed.

Thank you, Nunit, for making me stop and see that I’m being dumb.

Current mood - calm
Current music - Dirty Vegas – A Million Ways

Thursday, February 06, 2014

My Take on Professional Codes of Conduct at Conferences


 

Preface: Please keep in mind that I am not trivializing sexual harassment or sexual assault. I have loved people who have been victims of sexual harassment, sexual assault and even rape. I myself have been a victim of sexual harassment and sexual assault.

I am offering an open, honest opinion from someone who has not only the right to an opinion as a person, but a sense of perspective as the victim of and friend of victims of sexual harassment/assault. You are allowed to agree or disagree with me as your conscience so dictates.

 

Recently, there’s been a lot of push to force software development conferences to have a code of conduct.

Honestly, any code of conduct that could be adopted for a professional conference could be limited to “Be a professional” or “Don’t be an ass”. We’re all supposed to be there to learn new things, maybe to meet new people, see old friends, and generally grow as professionals and individuals (male, female, gay, straight, bi, black, white, red, yellow, green, polka dotted and everything in between).

A lot of what sparked off the recent debate was an incident that happened at a regional conference a year or so ago (and I will admit was completely unacceptable. In fact, it was horrifying, honestly).

However, a conference code of conduct wouldn’t have done anything to prevent the incident for a few reasons:

 

1) It only came to light *months* after it happened (if you don’t say anything, nothing can be done by the organizers. I know some of the organizers and you’d be hard pressed to find a better, more caring group of people. If they had known, they would have done what they could.).

2)It happened before the conference even started, and not at the venue (it occurred at a bar at the resort the conference was held).

3) Having a code of conduct doesn't stop people from doing bad things. People stepping in and saying something while it happens or before it has a chance to happen does.

 

Having a Code of Conduct that prohibits unprofessional behavior at a professional venue is the conference version of security theater. The only thing it does is make people “feel” safer (and that’s, honestly, a disservice, because *life* isn’t safe and we need to be aware of that. It lets us better prepare for when things do go wrong – and given enough time, chances are something will happen to all of us).

It’s the equivalent of a store having a sign up that says “Don’t steal stuff or we’ll call the cops.” It should be common sense and, code of conduct or not, most conference staff that I have known will deal with any problems that arise.

 

Is there a solution?

 

Yes, well more or less, but like most real solutions, it’s not easy. The best solution is to be responsible for ourselves, to be decent people, and to look out for each other.

That last item is the big one. So many people now “don’t want to get involved” when they see something bad happening. There are a lot of reasons for this – Sometimes people don’t feel like their stepping in will solve anything. Sometimes they are afraid to say anything. Some of them even think that someone in a position of power should be taking care of it.

I have news for you: You need to swallow your fear and speak up when you see it happening anyway. It’s your duty as a member of society to help each other and that includes stepping in and asking if there’s a problem if something looks fishy.

We’ve become far too isolationist as individuals and have become conditioned to “let someone else deal with it”. That needs to change.

I’m not saying to lynch someone you see doing something questionable. Step in, make sure things are okay and then respond appropriately.

Yes, I’m a fairly large (some may say frightening looking) guy. Yes, I’ve been a victim of harassment and assault. No, I don’t think a Code of Conduct will change anything. Changing ourselves will. The demands for a Code of Conduct are just another cry to make it someone else's problem.

I do my part. If I see something “off”, I see if there is a problem and work to resolve it. I ask that others do the same. It’s the only way things will get better.

 

Current mood: contemplative

Current music: Coldplay – Charlie Brown

 

Thursday, October 31, 2013



Happy anniversary

Monday, October 14, 2013

Monday, September 30, 2013

The Javascript Drinking Game

 
 
The Javascript Drinking Game
 
  1. Procure several bottles of your favorite liquor with a high ABV percentage (it will help the pain go away better).
  2. Take a drink every time Javascript does something that a sane programming language does not.
 
 
You know what? Just open the bottle and drink until you pass out. The result is the same and this way you might stay conscious a little longer…
 
Current mood: Tired
Current music: Garbage – Run Baby Run

Monday, June 10, 2013

Cooking Time: Pizzeria Style Garlic and Herb Breadsticks



1 ½c Flour plus extra for dusting
1tsp Dry active yeast
1tsp Salt
¼c Grated Parmesan cheese
1Tbsp Italian Seasoning
1Tbsp Garlic powder
2Tbsp Olive oil plus extra for coating
Hot Water
Grated cheese (Mozzarella, Colby Jack, etc - optional)
 

  • Combine dry ingredients except optional grated cheese in a large mixing bowl and mix thoroughly.
  • Add 2Tbsp olive oil and enough hot water to make a pliable dough.
  • Turn dough out onto floured surface and kneed dough.
  • Roll dough into a ball, coat with olive oil and place in bowl covered with a towel for 1 hour so dough can rise to approximately double its original size.
  • Preheat oven to 400F
  • Punch down dough and roll out to a size of approximately 8”x9” and place on baking sheet, pizza pan, or cast iron skillet
  • Brush surface with olive oil, cover with towel and allow to rest in a warm place for 10 minutes
  • Cut dough into 8 horizontal slices, while maintaining the loaf’s shape
  • Cover dough with grated cheese (if using) and place in oven for 15 minutes or until a toothpick inserted in the bread comes out clean

Monday, May 20, 2013

Your Code Sucks


 
I’ve seen a few people that I know berate people for the quality of their code and say things like they should just go and deliver pizzas.

You aren’t your code. Code is an expression of the skill, mindset, and situation facing the person who wrote it at the moment it’s made. Nothing more. In fact, it may be the chaining together of those factors from several people as the code is maintained.

There may be things about the situation that you don’t know. Maybe the person was under insane time constraints. Maybe they were thrown into a technology they had no experience with. Hell, maybe they were just having a bad day.

You may not like maintaining the code – I know I don’t, but I try not to berate the person doing it because I don’t know what lead there. (If I know the person in question and know that they just don’t care, that’s a different story)

There are a couple of appropriate responses to “your code sucks”.

  • Where can I improve?
  • Yes, it sucks. So does everyone else’s. I’m working to improve. Are you?

Improvement is the important part.

Yes, my code sucks. It always will, but it gets better every day.

Does yours?
 

Current mood – tired
Current music – 10,000 Maniacs – Candy Everybody Wants

Wednesday, May 01, 2013

Learning




After a couple of false starts, I started digging into learning ASP.NET MVC a couple of months or so ago.

First, I decided that I also wanted to learn webforms, just in case.

Don’t look at me like that. I learned the error of my ways after my eyes started to bleed and hands began reaching out of the walls for me. Though I’m not sure that was caused exclusively by webforms. That may have been caused in part by my recitation out of a book of really odd Latin poetry that I ran across…

Either way, I stopped trying to learn webforms, so mission accomplished. Now if the really creepy looking guy would stop making faces at me in the mirror when I try to shave, that’d be great. Oh, wait, that’s me. Sorry.

Next, I tried just diving in by starting with Professional ASP.NET MVC by Galloway, Haack, Wilson, and Allen.

This, for me at least, was kind of a mistake. The first couple of chapters were okay, but the first chapter on the topic of Views was full of hand waving and a sense of go screw yourself. It all kind of boiled down to “I’m not going to discuss the code. I’m just going to go off on tangents that you don’t need right now.” (This is a pet peeve of mine)

That’s not to say that the book is bad. It’s actually quite good as long as you have a rough idea of what’s going on (which I didn’t at the time). Otherwise, it got a bit frustrating. I'm going back over the book now, in fact.

I ended up going online to find the music store tutorial that was mentioned in the book and working through that first. That worked a lot better for me, but it could just be that I’m a bit slow. Who knows.

Going on the premise that I learn a lot better by playing with something once I’ve figured out the basics, I decided to rebuild my website with MVC. After all, it was just static pages, so I wouldn’t have to worry much about the M portion of things.

As a result, I got a decent grounding in the use of Controllers and spent a small mountain of time re-arranging the structure of the website to comply with the MVC principles.

Of course, I also got to do some much needed housekeeping, so that’s a plus. It just took loads of time because there were probably 40 or so pages.

In all honesty, most of my frustration was dealing with CSS3 (the site’s last incarnation used CSS2 and a lot of things have changed) and getting all of the settings right (both on my end and on my hosting provider) to get web publishing to work from Visual Studio.

The site isn’t “finished”. I’ll probably always have things that I want to do to it, but it is published. The visual changes are fairly minimal. Mostly, the menu has just moved to the top instead of running down the left side. However, things are a lot different on the back end.

Now I get to move on to more complex stuff.

Current mood: tired
Current music: David Gray – Babylon


Tuesday, April 16, 2013

I'm Not an Expert


 
I’m not an expert. On anything, really.

Don’t get me wrong. There are things that I’m good at, but I wouldn’t call myself an expert on them.

Part of the reason that I don’t consider myself an expert on anything is that I’ve done so many varied things. I’ve never settled into just one area of development (or anything else).

I’ve had a lot of hobbies, interests and jobs that range from martial arts, to carpentry, blacksmithing, gardening, cooking, and (obviously) software development (among many other things).

That kind of spread isn’t exactly the sort of thing that screams “I’m the greatest person in the world at one thing.” It does, however, lead to being able to look at problems from a lot of different angles and helps you come up with a solution to something you may have never seen before.

I sometimes get asked what my specialty is by people who won’t take “I don’t know” for an answer, and the only thing I can think to say is that I’ve learned to ask questions that get me the answers that I need.

I may not know a thing, but I can generally figure out a way to find the answer.

I suppose that you could say people like me specialize in being generalists, but I think we just suffer from a combination of ADD and having to take on multiple roles. Somehow, it works out, though.

Current mood: thoughtful
Current music: Goo Goo Dolls – Give a Little Bit

Sunday, December 30, 2012

Motivation


It’s generally really easy for me to keep going if I’ve already got a bit of momentum, but if things have derailed me and caused me to focus elsewhere, Newton’s First Law decides that it also applies to motivation and proceeds to kick my backside.

Translation – if I stop, it takes real work to get going again.

It’s also fair to say that, for me at least, large tasks are intimidating, but breaking them into smaller chunks makes them more manageable because it lets me just consider the current step and leave subsequent steps for a little later.

Big = difficult. Little = easier. Makes sense, right? Less stuff, less to be overwhelmed by.

Or, to paraphrase my sifu a bit “Concentrate on now right now. Later will come when it is time.”

A few years ago, I found a way to motivate myself when learning something new from a book or video as well as when working on projects. Thankfully it plays into the fact that I’m a big fan of marker boards (I have several in my office to help keep myself organized and to brainstorm) so it doesn’t take any additional expense on my part.

I write the name of the book or video series on the marker board and then put down the chapter or video numbers. As I work through it, I erase the numbers for the chapters that I’ve covered.

 
This does two things:

First, it lets me keep track of where I am. This is especially helpful if I’m doing a video series or a web-based lesson plan.

Second, it lets me see that I have actually been making progress so I don’t get lost in the feeling that I’m never going to get anywhere in what I’m doing (I’m pretty sure that I’m not the only one that has this problem. It’s downright overwhelming to look at how much you have to learn, and every time you learn something, it shows you other things that you need to learn).

Some people will prefer to strike through the numbers or put a check mark next to them after they’ve finished, but I prefer to erase for one very simple reason – it lets me actually SEE the list of things I need to do shrink. If the numbers are still there, the size of the task never visually changes so my brain still says “Hey, there’s still this daunting list of things that we have to do.”

If I erase the numbers, my brain goes “Wow. We’re making progress! Maybe we can do this thing after all.”

Yes, it’s a stupid psychological trick, but in my case it works.

I guess that means it’s not so stupid after all…

 
Current mood: undecided
Current music: Adam and the Ants – Room at the Top

Thursday, December 20, 2012

Product Review – Mimo 720S



A couple of weeks ago, I won a Mimo 720S (7” USB touch screen monitor) at the CONDG holiday party.

I’d seen them before online and was never really tempted because it just didn’t seem that useful. I mean, after all, a 7” screen isn’t that large. It’s okay for a tablet, but as a 2nd or 3rd monitor?

I’ll admit that I was wrong.

The screen’s a resistive touch screen, but it doesn’t take a lot of pressure to make it work unlike a lot of other resistive screens. That’s not to say that it doesn’t occasionally lose track of the fact that you’re doing a “click and drag”, but nothing’s perfect.

The size of the screen is just about perfect to fit on the desk under my monitor in the space where I usually put a book if I’m using it for reference. Since I have electronic copies of most of my tech books as well as paper copies, the Mimo’s primary purpose for me is as a book display.

Setting the size of the book to 120% in acrobat allows most books to be readable and take up most of the screen and since the Mimo is on an integrated stand, I don’t have to look at a book that’s lying flat like I do with its paper counterpart.

I’m also wondering how it will do as a test screen for mobile app development. Since it rotates 90 degrees, you could emulate either a phone or a tablet.

Honestly, my only complaint is that the screen isn’t a little bit bigger. I think a 10” screen would be just about perfect.

Just be sure to update to the latest drivers and calibrate the touch screen with the Calibrate program before you use it. Otherwise, you’ll be wondering why the mouse moves on your main monitor when you touch the Mimo

Friday, December 07, 2012

GPS - The Angry Wife Edition


I live in a city where I frequently have no idea how to get where I’m going. I used to use MapQuest before I got my GPS several years ago.

It’s a wonderful device, but I refer to it as “The angry little woman in the box” because the voice sounds rather annoyed when it says “recalculating” if you miss your turn or opt for another route. In fact, I think they must have multiple clips for “recalculating”, because she sounds angrier every time she says it, but that could just be my imagination.

It’s like having an irate spouse in the car with you (my girlfriend agrees).
 

 

“Turn left”

I don’t want to turn left. This road is a better option

“Recalculating. In 0.5 miles, turn left”

No, I want to stay on this road. It lets me bypass a lot of nasty intersections and is only 2 minutes slower

“If you don’t listen to me, why do you even take me along?”

I do listen to you, but in this case, I know a better route for this part of the trip

“You don’t love me anymore. I saw you looking at that other GPS in the store”

That’s a model for hiking and geocaching

“She’s a model, is she?? I bet you felt her up too! Damned skinny bitch”

Oh, now you’re just being silly

“I am NOT being silly. You don’t touch me like you used to! I catch you looking at other GPS’es and now you don’t even listen when I tell you to turn left!”

I’m just saying that this time, going straight is a better option.

“That’s it! I’m going to my mother’s! TURN RIGHT!”

 

 

Tuesday, October 30, 2012

Sunday, October 14, 2012

Oct 14


Happy Birthday

Tuesday, October 09, 2012

Recruiters





The tech job market in Columbus seems to be picking up quite a bit. This is a wonderful thing for a lot of people since we like to be able to pay rent and buy sandwiches.

Unfortunately, it also means an increase in the number of people that call themselves recruiters whose only purpose is to spam as many people as possible in the hope that some company will hire one of them so said “recruiter” can get a commission.

These people are not really recruiters. They’re parasites. Real recruiters are a completely different creature.

If you’re a “recruiter” and are located in an off shored call center, you aren’t really a recruiter. I’ve gotten a few calls of this sort in the last few weeks and they’re driving me up the wall – Broken English, lots of call center noise in the background, and follow up emails that say things like “I enjoyed speaking with you” when all they did was leave a voicemail.

If your “job description” is a page full of bullet points that tell me absolutely NOTHING about the position, you’re doing it wrong. I once got an email from a “recruiter” that had about 20 bullet points worth of “description” and all it really said was “write code, conform to company standards, and you won’t be supervising anyone”.

Don’t tell me that you have something you think I would be “perfect” for without telling me why. This is especially true when the job is for something I’ve never done before. This is the most common kind of resume spammer “recruiter”. Thankfully they also tend to be the least tenacious and easiest to ignore.

If you’re contacting me about a job in Ohio, but you’re located in New York, you’re doing it wrong. You can’t know about the developer community in Columbus, Ohio if you’re located in Rochester, New York. If you’re not in the geographic area that you’re hiring for, you’re probably doing it wrong (there are exceptions, but they’re not that common).

Bad recruiters leer at and hit on my girlfriend while she’s at an after users group meet-up with me (true story, sadly. Karyl almost dumped her drink on the guy).

By contrast, good recruiters generally display the following qualities:

  • They work through word of mouth networks in the developer community. Referrals are the source of most of their candidates.
  • They will tell you the name of the company that they are trying to put you in touch with to make sure you haven’t already submitted to them since multiple submissions basically kill your chances.
  • They take some time to learn what you’re looking for instead of trying to shoehorn you into every position that comes across their desk.
  • They take time to help prepare you for the interview. They will give you an idea of what to expect both in terms of interview techniques (if there are any tests, etc) and corporate culture including suggestions of how formal or casual to be in the interview.
  • They do not act like a creep and hit on my girlfriend.

Good recruiters are worth their weight in gold. Bad ones only serve to make everyone’s lives difficult. Sadly, the good ones are also about as rare as gold while the bad ones abound.

Current mood: tired
Current music: The Call – Let The Day Begin

Friday, June 29, 2012

Lunch Time



 

Since some of the Devs on my twitter list seem to be in the mood for soups/stews and Bill (@sempf) suggested I place this recipe here, I present to you

Lamb Stew

  • 1lb ground lamb or beef
  • 6 cups beef broth (I use the beef base from Das Dutchman. It’s inexpensive and takes up much less storage space. It’s available at some area Kroger stores as well as here)
  • 1 cup white wine
  • 1 package beef stew seasoning
  • 1 cup pearled barley
  • 8-12 oz package of mushrooms (washed and diced)
  • 6-8 carrots, sliced
  • 2-6 whole tomatoes (about 1-1.5lb). Diced
  • 1-2 medium onions, diced
  • 1 can whole kernel corn (optional)
  • Red pepper to taste

Brown meat in 5qt or larger pot (I use a 5qt cast iron Dutch oven)
Add remaining ingredients and bring mixture to a boil
Reduce heat, cover and allow mixture to simmer for 2-3 hours, stirring occasionally.
It may be necessary to add water to the soup as evaporation will occur

Makes 1 gallon + of stew.

Friday, December 09, 2011

Ebook Pricing





This started off as a bit of a mini rant on twitter the other day, but I thought it deserved to be fleshed out a bit as well as updated since some other information came to my attention this afternoon.

I love my Nook and take it pretty much everywhere. I consider it a great way to carry not only a book or two to read for pleasure but also a way to carry and access my programming books when I’m not near my bookshelf.

My major complaint is how much the ebooks cost in comparison to their paper counterparts. Sure, they knock a couple of dollars off of the price, but for books that cost $20-40, that’s really not much of a savings.

This isn’t just a whine on my part. Logically, ebooks should be cheaper. Think about it – they require no paper, no shelf space, no transportation costs (other than an internet connection) and can be replicated essentially forever (or at least until a publisher’s claim to the book ends and it reverts to the author)

I’m not complaining that programming and technology books are expensive. Given the amount of work that has to go into them, the limited market, and limited shelf life of most technologies (unless we’re talking about something like the K&R C book), they have to be relatively pricy in order to make a profit. I understand and accept that. We all need to make a living.

What I’m complaining about is the price difference, or rather almost lack of one, between the traditional paper books and the matching ebook. In some cases, as @jbehren pointed out, sometimes the ebook can cost more than the paper one (which is ridiculous unless, perhaps, you are paying to get a copy before the paper book even hits shelves and you just can’t wait).

The question, then, is what is a reasonable price for an ebook as compared to the paper one? Of course, the publishers would claim that their current prices are reasonable, but I disagree. Taking into account the savings caused by the lack of materials and associated costs, I’d say probably about half the price of a paper book.

Books are fairly pricy to write, but most of the cost is in the actual manufacture, shipping and storage. At half the cost of the dead tree edition, there should be enough money to still make a decent profit on the endeavor.

The half price range was sort of my gut feeling for a while, but today it was more or less confirmed by O’Reilly. For people that have an account at oreilly.com, all of their ebooks are buy one, get one free with coupon code (just look in your account under the heading Membersip).

Additionally, they will sell you an electronic copy of most of their books (bundled in multiple formats, not just PDF) for $5 if you register the paper version with them. It only applies to O’Reilly and MS Press titles so I can’t get epub copies of my Pragmatic Programmers books, but it’s a great start. (For the record, I got the PDF version of the Programming Ruby book cheaply when I bought the paper version during the Pragmatic Programmers special a while back, but PDFs don’t always scale well on smaller e-readers so availability in a variety of formats is a great plus).

I cheered when I saw the $5 electronic copy “upgrade” option, because, to me, that’s sort of the sweet spot for that service. I would gladly pay an extra $5 to have lifetime access to an ebook version of programming books that I own. In fact, I spent some time today registering my O’Reilly books so I can buy the epub copies later.

I don’t know if this is a limited time offer or one which they always have, but it is sort of telling as far as book pricing goes. It’s also something well worth taking advantage of.

Current mood: tired
Current music: Smashing Pumpkins – Cherub Rock