Archive for the ‘Coding’ Category

Dealing with Rule-Based Systems

Wednesday, October 24th, 2012

Building Great Code

I've built a few rule-based systems in my time. Nothing like an Expert System, but enough to know that the business logic of most businesses is a complex thing, and care needs to be exercised in creating the rules, naming the rules, putting the rules into a cohesive system, and in general, making it work. What I'm a little surprised about today is that this isn't something that people seem to naturally pick up on.

I'm looking at code written by a smart guy. He's no dummy. He's got experience as well. Yet it seems that he's into making the worst named rules, and combining rules in ways that it's not clear what's being checked (asserted) in a rule, and why. The resulting combination of these rules is worse that just a series of if/then/else statements because it hides the things that are being checked behind very poorly named methods.

Yikes!

So today I did a lot of clean-up. The rules are clear, more reasonably named - when the functionality changed, and the layout is far better. I was pairing with someone and they weren't able to follow until I made it clear that there really was a "good way" to write these rules, and combining completely different rules into one wasn't really a "winning way".

It's not done, but it's getting closer, and I'm really surprised that this part of the codebase is so easily done. I had expected more, but again, it was blown out of proportion due to the things I'd heard from the people working on it.

Get good data. Understand it. Write good rules. Combine them. It's really not all that hard.

Dealing with Lazy People in the Office

Wednesday, October 24th, 2012

GottaWonder.jpg

Today I had a really sad realization - there are a lot of lazy people in the world, and unfortunately, I have the pleasure of working with a few. These aren't the Code Monkeys I've written about several times - these are just really honest to goodness lazy people. Just looking to do the least work they have to do in order to get by. Fighting about it in meetings even. Amazing.

Case in point: Countries. We get the demand for things from a service that gives us location information as postal codes. In the US, that's great as a 5-digit zip code is just the right "size" for the localization of the demand. But in Canada, I found out that I should only be looking at the first three characters of the postal code. OK, I can do that, but the question then becomes: What country am I in?

I was thinking it would be a simple thing to have the service that generates this data to add that in. After all, it knows the postal code, so it's got to know the country - right? Well… as it turns out, it should, but it's written by some really bad coders, and it doesn't. And these bad coders are lazy to boot, and aren't interested in adding it.

OK, after about 30 sec of this "debate", I just said I'd do it. It took me about 30 mins to add this to my code, and now it's done. They later realized that they needed this as well, so they have hacked something together that I couldn't possibly care less about, but whatever. I have the country now.

I'm now able to map the postal codes right, but it's amazing how hard some people fight against making their code better - only to later realize that they should have made it better in the first place, and put another hack on a hack, etc.

Not me. Amazing people.

Cleaning up CSV ‘keys’ to All Lower-Case

Wednesday, October 24th, 2012

bug.gif

One of the problems of working with a lot of string data posing as enumerables, is that people are fuzzy logic kind of things, and the difference between "Wed to lead" and "Web to Lead" is totally lost on most people. But for the logic in the computer, they are apples and oranges. Unfortunately, we can't really turn them into enums, we have to leave them as strings. But the look-up tables have a certain case - defined by the Data Science guys, and that's something I had to work around.

Sadly, I couldn't just lower-case all the data as I read it in - that would adversely effect the look-up results. What I needed to do was to specifically lower-case the components of the key for the table, and leaving the rest of the data alone.

My goal in this little bit was to keep the knowledge of the key generation in the class doing the look-ups, and I got what I wanted. But I needed to make it a little smarter than it was originally. Not bad, and in the end, I don't have to worry about case of any of these "string enums".

Some Days I Want to SCREAM!

Tuesday, October 23rd, 2012

There are times I'm amazed I keep my mouth shut. Today has given me several such times. Really. I'm grateful for this job, I truly am. I like that I'm learning ruby, and there's a lot of interesting work there, to be sure. But I'm working with the Code Monkeys, and it's really getting on my nerves today. Really.

One instance today was best typified by the mental picture of working around a bunch of eighth graders. Yup, kids. I enjoy chatting just fine. There's nothing wrong with learning more about your co-workers, but there's got to be a point where you turn around and get to work. After all… we're here because it's a job, not a clubhouse.

I don't know about the rest of the group, but I'd be home if it didn't matter to anyone else. I don't love the chair, or the desk, and the commute - well… don't even get me started. But it's OK - for a place to work.

I just seem to be in the vast minority some days. They want to play around, giggle, watch bouncing cats on a 40" plasma TV for fun - for far, far too long. Again, I like my job, but this is really getting annoying.

And if I say anything, I'm the kill joy, or the "old" person that doesn't understand the value of fun. After all, they'll get the work done - eventually.

Please… if you could get all the work done in the time you give it, think of what you could accomplish if you came in before 10:00! Or stayed after 4:00. Or didn't mess with the bouncing cats. It'd be like you had an entire day extra. Wow!

But that's only part of it… the other part is what I blame on the Agile approach, and it's focus on continual refactoring.

Again, don't get me wrong, I like that there's a focus on refactoring in the workflow - it allows you to go back when things have really changed, and fix them up the way you would have if you'd have known what the end-result was really going to be. But there should be a limit to this. Fixing broken, or badly laid out code is OK - if you're adding something, but if you're just looking around and just decide to change the code "because", then what you're really doing is wasting time. Lots of it.

You're also really running the risk of breaking things - unless you're really careful. I'm not convinced a single one of the Code Monkeys I work with is really careful. Smart - yes. Careful - not in the least.

There's no solution because it's all a matter of degree. I may think it's "too much", but that's an opinion, and as long as management is OK with the productivity, then there's nothing that's going to be done about it.

Upgrading to JRuby 1.7.0 – Not So Easy…

Tuesday, October 23rd, 2012

JRuby

This morning I wanted to again try to get JRuby 1.7.0 installed and working for our project at The Shop. It's not that it wasn't working - in fact, I figured out that it was all in the handling of '/../' by Dir.glob() in JRuby - but we have a way around that, so we're good to go. No… this was meant to wait until 1.7.0 final was out, and then move to it as a group.

The test repo I've been working with is pretty simple, but it has all the components I need. It's got an .rvmrc that points to the right version of JRuby:

  export JRUBY_OPTS="-Ilib --1.9"
  rvm use jruby-1.7.0@jar-test --create

and so I should be able to simply install JRuby and use it:

  $ rvm install jruby-1.7.0

but when I do that, I got all kinds of problems. Problems with bundler, problems even with rvm. So I go to the jruby channel on IRC and ask what's up? I get the answer:

  $ rvm get head

Seems the latest stable rvm can't handle the install. I had to get the very latest version to make it work. Yikes!

After that, you might be tempted to install jruby-1.7.0, but don't! There's one more thing that's a known issue with Mac OS X and rvm - the CodeSign with OS X. Currently, it's not working, so you have to:

  $ chmod -x $rvm_path/hooks/after_install_codesign

to make it not executable. This will then leave you with something that will work when you install jruby-1.7.0:

  $ rvm install jruby-1.7.0

Still, when I did that, I was able to then use it:

  $ cd jar-test
  Using /Users/bbeaty/.rvm/gems/jruby-1.7.0 with gem set jar-test
  $ bundle install

and everything gets up to date.

Very cool - but had I not messed around with this for an hour, I would have been a lot happier.

Refactoring a Hash to a Hashie::Mash

Monday, October 22nd, 2012

Code Clean Up

This afternoon I wanted to do a little refactoring on the codebase for the project I'm working on. Right now, one of the two main classes we're using in the code is real just a ruby Hashes, and while that's great for loading and persistence, it's not really where we would like to be, and there's a decent Open Source gem called Hashie. This guy is really just methods on top of Hash that allow you to use the "dotted notation" as opposed to the "bracket notation":

  # the old way:
  a = merchant["name"]
  # the Hashie::Mash way:
  a = merchant.name

This makes the code look a lot simpler - though it doesn't really make it any better. However, it adds nice convenience methods as well:

  a.name = nil
  a.name?   # => false

The real goal is to move a lot of the methods that take a single argument - the Demand, and looks into it for some bit of information, and make them methods on the Demand so that it's a lot clearer where the business logic is being held.

There were a lot of little complications - primarily because of the fact that Ruby devs hate writing comments, and so the code is the comments, and I had to do quite a bit of digging to know how to handle an initialize method on a subclass of Hashie::Mash. Ugh… I do wish they'd learn to comment things.

I got a lot of work done, but not enough to call it a day, so I moved it all into a branch and I'll work on it more tomorrow.

Careless Code Monkeys

Monday, October 22nd, 2012

Code Monkeys

This wonderful Monday morning has been trashed by a particularly careless Code Monkey I work with. I know he probably meant well, but he checked in code - to master, that was then deployed to production, that broke production. Why? Simply because he didn't check.

I'm not perfect. I make a lot of mistakes. But this was one that I really got a little steamed about. I don't make mistakes like this - and even if I did, I'm here in the morning to clear them up! This is my real gripe.

It's one thing to be careless if you're the one cleaning up the mess. As I've said to my kids over and over again, I'll eat in the living room because I'm the one that cleans it up. They can't because they simply don't.

I want to just shame these Code Monkeys into taking a little more personal interest in their work. Take a little more time - check. Make sure. Don't just assume that because it's checked in and the CI build worked that everything is going to be OK. It might, but it might not. And it's those "might not" cases that really make or break your reputation.

The particular Code Monkey that broke production today is a nice guy. He's personable, likable, nice to talk to, and just a plain "good guy". But he's careless. He isn't a details person. He can write code, but it's a mess and it takes a lot longer than I'm used to - for a guy that's clearly well beyond the "junior" phase of his career. I don't want to yell at him, so I don't. But it's hard not to. He should know better, but I know this isn't going to be a lesson he learns this time - if ever.

He's just careless.

Finally Finished Performance Testing

Friday, October 19th, 2012

Today I was finally able to finish up the performance testing for the Amazon EC2 instances and the SCN1 datacenter machines. There's no question that our datacenter machines are better, but the question is by how much? And how do they handle the load? Well… now we're ready to answer at least a few of these questions.

SNC1 Tests

It's nice to see the parallel processes on the A64 box flatline over 6 processes - but that's because there are 24 cores on that box, and that leaves 4 per process - still a lot.

I've decided to cap the processes on the EC2 machines at 3, and give the SNC1 machines at least 6 - maybe more. We'll have to see how it works out when we get things in house and I can start to migrate things to the new boxes.

I’m not sure being agreeable is that nice either…

Friday, October 19th, 2012

This morning there were some problems with the UAT runs from last night. FIrst off, it took 10 hours to run, and there were a lot of problems because a change wasn't put into the newly refreshed Salesforce sandbox that we are using - so I got the Crack Monkey-like request from Jerry asking why they didn't run. I looked into it knowing that because of the Salesforce problem it didn't really matter - it'd be fixed and it'd run Sunday night just fine.

Not good enough for Jerry.

So he wanted me to re-run them, and at 10 hours, I was a touch reluctant. Still, I remembered the other exchange, so I simply said: "Sure. Love to."

Jerry was a little taken aback. Clearly he could tell I was shutting down.

Don't care. It's not going to get me in trouble, and he's clearly not going to listen to me anyway, so what difference does it make?

None.

There are times it’s hard to be nice…

Thursday, October 18th, 2012

attitude.jpg

This afternoon my patience has severely been tested by a co-worker. The exchange was pretty simple: He wanted to make sure that he knew what was going to run in UAT this evening, as he wants to push the rollout of the application to more people. He specifically asked me if a series of cities were going to be included in the run.

"Yup" I responded.

Not 60 seconds later he asked the exact same question again!

I'm going to pause the story for a moment to reflect on this behavior in general. Skipping medical conditions, there's no good reason for this kind of behavior. I can't think of a one.

  • If I'm wrong well… I won't check again in such a quick time - I just looked.
  • If I'm lying I'm not about to be that stupid to confess so soon
  • If I didn't read it right I'm not going to think this time is any different. After all, it's not that hard a question.

Yeah, I can't see a good reason to ask again. One thing does pop to mind:

Insanity: doing the same thing over and over again and expecting different results. - Albert Einstein

Back to our story...

I wrote back:

Remember when we had that talk about communicating effectively? When you asked me something, and I pointed out that I'd just used those exact words? Well… I can point you to the code, or you can trust me that: "Yes, those are in the Original Six and Top 40"

I realize it was a little snippy, but I wanted to try and re-enforce the point that we had talked about this behavior in the past, and that indeed, this was one of those times that I had told him exactly what he wanted to know, and it wasn't likely to change with the second request.

I think it's just hard to be nice all the time.