“I will totally destroy you.”

December 8th, 2008 :: 4:51pm

Hey kids,

Just a small shout-out to say that I’m still doing well. Work is going well; I’ve been given the leeway to pursue my ideas for the improvement of Educational Statistics in Namibia, and I think my teammates and I will really be making a difference in our terms here. Basically our goal is to expand the capacity and functions of the current Educational Statistics department in the Ministry of Education. Right now, they collect a lot of data and put the results in a book and distribute that at the end of each year, one book to each school. That book inevitably disappears into the principal’s office, and most people I’ve talked to have no idea that Namibia even has an Educational Statistics department. So first, we’re going to make examination results for schools available online, and we’re going to add to that some analysis, including resources available at schools, teachers’ qualifications (in an aggregated form), and learners’ living situations. And we’re going to make it easy to compare two schools, overall and by subject. My personal goal is for village people to compare two neighborhood schools, realize that their children are going to the school producing learners with lower grades, and then apply pressure to the principal. This might not happen for five years, but it’s a nice dream.

One great thing that happened over the last week is that I found a great town house to rent for the next year at least. (This means that I don’t need to bike around town all weekend looking for places any more, or call housing agents who say “That place is already taken”.) The place is beyond anything I hoped I could afford (I took an 80% salary cut upon taking this job), and I am very happy to have found it. It’s got three bedrooms, 2½ bathrooms, kitchen, living room, and a dining room. There’s a balcony upstairs available from 2 of the bedrooms, and a patio outside in the backyard.

This is quite a step up from what I’m currently living in, and indeed what I even want to live in. By living in such a nice place, it’s obviously in a good neighborhood, and so the people who I could really enjoy sharing time and culture with are not living around there. Most people in this nice neighborhood tend to stick to themselves. It actually was a very difficult decision to make; but the size of the place won me over. Why? 2 reasons: 1. YOU can stay with me, comfortably and not on the floor, when you come to visit! 2. Ping-pong table in the dining room? Yes.

Which brings us to the most important point of this post. At my previous job at WeBuildPages, I played ping-pong almost daily. It developed friendships, it got the blood flowing in the middle of a brain-crunching muscle-atrophying computer programming day, and it provided for excitement and friendly competion. So since I’ve been back in Namibia, I’ve been suffering from ping-pong withdrawal. I have been asking many people if they know where I can play, and most people don’t even know what it is. Some people know what it is, but have no idea where it can be played. Finally I’ve found some fellow ping-pong players who play in a league, but unfortunately the league doesn’t start up again until after the New Year, and somehow the ping-pong tables “aren’t available” until that time. So I’ve been dreaming of just going and buying a table, but until I found this large apartment, I’ve had no place to put it.

You can imagine my surprise, then, after telling my boss that I’ve been really missing ping-pong, and that I’m going to buy a table, and asking him if he knew what it was, that the first thing he said was “I will totally destroy you.” Turns out he played a heck of a lot of ping-pong during his years studying in Australia (the land of the speed-cameras… be careful!), and he’s got the talk to match. I’m totally pumped to get this town house and table ready for service! But I’ll bet he’s never faced a serve like mine!

To wrap things up, I wanted to show you some pics of the food I’ve been cooking for myself, using the professional guidance I’ve received while studying under the Browns for a wonderful year.

Eggplant Lasagna!

Hickory Burger!

Salmon, greenbeans & bacon, mashed potatoes!

Christmas comes to Namibia too!

Third week, third gear

November 26th, 2008 :: 4:43pm

Hey kids,

Here’s another long-delayed post. This one will have pictures of my office, pictures of my flat, tell you what I’ve been up to since I’ve been here, and give you a better idea of my job.

(Click the photo for more inner-office photos.)

But I’d like to start out with what the several people have commented on from the previous post–that being my desire to paint my office walls. It was the thing most people responded on. I’ve been told to drop it, wash the walls, and I’ve been described as potentially “presumptuous.” I wasn’t being totally serious about needing it painted, but would you really want to be in that dirty office for two years? I had to empty it, I had to remove a year of dust which had settled on everything – even inside the cupboards, so I kind of have a desire to start fresh from square one. I guess I didn’t clarify the reasons for painting those walls, so let me take this opportunity to do so now:
1. The walls need painting. Sticky tack has been left on the walls for years, and I had to pry it off with a knife. There are black dots all over the place where a few bulletin boards could have gone. Imagine you move in to a new apartment and the previous tenant had a bike which seemed to be used to ride up and down the walls. Shouldn’t’ve the landlord scrubbed that crap off for you?
2. That being said, why not change the color? Why not yellow? If every office is painted baby-blue-gray, a little should brighten it up!

(Click the photo for more flat photos.)

Now onto the flat I’m currently in. I moved in here because the landlord didn’t need a long-term contract signed and it was about half-price as backpackers in the area. The flat has three bedrooms, each with it’s own bathroom. We three share a kitchen. It’s a nice place with nice people, but I need something bigger in the long run. On top of that, the landlord has presented me with a 12 month contract, using language from three languages, which clearly outlines that she can do no wrong, and I can have no recourse if she does things in a “reasonable” amount of time. Riiight. So I have yet to sign that. Oops, one of the clauses in that contract is that I’m not allowed to talk about it, unless you’re my lawyer. So today, please be my lawyer. Anyway, I am looking for a bigger place, so this contract isn’t something to worry about (or sign).

Work is still somehow. The boss is still out more than he is in, and my talents aren’t being utilized. Either my value hasn’t been made clear, or nobody really cares – both of which are possible! I don’t see enough for two years here. Actually, the project I was supposed to be working on was completed last year without anyone telling me. And the boss has said for additional programming projects “as long as there is a donor to fund a project, we’ll just subcontract the work out.” So what the hell am I for then? Well currently we have 20 people from various regions entering in data from databooks that were filled in by principals from Namibia’s ~1700 schools. Every databook has several mistakes, requiring phone calls to principals to correct them before they can be completed entered into the computer. As you can imagine, this is a slow process. And to add Namibia’s humor factor, each government employee who has a telephone is limited to a certain maximum phone bill each month. And after a few days, I’ve reached my maximum. So I can’t do any calling until next month (December). Maybe that’s why people sleep during the day.

Click for more photos of our most recent Hash

Finally, I’d like to report on my activities every Sunday starting at 15:30. I participate in a “hash,” which is an international group of people who get together to do something. We hike. Well, it’s a drinking club with a hiking problem as they like to say. Anyway, it’s a bunch of foreigners and a bit of cool locals that make a nice mix and good times. We hike a trail, a different one every week, and each hike is followed by formalities which cannot really be explained, just accepted. Everyone gets a chance to drink their drink from a baby toilet. Please no questions now-I have no idea. Check out the pictures.

OK, this post has been long overdue! Sorry for that.

The simple life

The important things

First day, first gear; second day, second gear

November 6th, 2008 :: 4:35am

(Click the photo for more office photos.)

Here’s a long-overdue update on my new job in the Ministry of Education in Namibia. I started on Monday, arriving at 8 o’clock. My boss, well actually I now have 4 bosses, so to be more specific my second boss up the chain, the one who will be doing most of the directing, is in Botswana for the week. Botswana, for those who don’t know, is a different country, and so that make giving directions a little difficult. Orders were left with a co-worker (we don’t use that word here, we much prefer “colleague”) to give introductions get me started. Apparently those orders didn’t reach him, and quite soon it was clear that there was nothing really to do.

I was assigned an office the week previous, so I spent two hours collecting the 3 cabinets full of paper and transporting them into a store room because the person who previously occupied this office didn’t move his stuff out. The next 6 hours were pretty boring. Government work, as I am learning, actually really matches what you hear – inefficient, bureaucratic, and wasteful at times.

The second day, my job was to choose furniture to put in the office. Furniture is ordered from the Government Store, which is then back-ordered to the companies which produce it, and with luck, 6 months later your furniture will arrive. Is there any way to speed this up? Well, if you bike the 2km down to the Government Store Warehouse and only choose items that are there waiting to be chosen, the back-order doesn’t need to happen and you get the furniture fairly quickly–provided your supervisor, his/her supervisor, and his/her supervisor all agree that you need/can purchase said furniture with Ministry money.

Failing to find the furniture you want at the Government Store is not the end of the world, but it then does imply you’ve got a lot of leg-work to do. You are allowed to find a particular item at three different stores, get quotations, and then the Ministry will issue a purchase order for that item (provided all the signatures can be obtained), and then you can go get it. You might already see the problem coming if you remember that after my first 2 years in Namibia, it took me a full month to visit the grocery store because of all that darned selection. Those choices! What I mean is this: when you want into a store in Namibia looking for an item, that store typically doesn’t have much of a selection. If you want a desk, they’ve got desk. If you want a computer, they’ve got computer. Oh, but wait, you wanted the computer with this option and this other special thing? No, we’ve got computer, but it doesn’t have that extra stuff. You want a desk with 4 drawers down the right side? No, our desk doesn’t have that. OK, so in the country capital, Windhoek, it’s really not as bad as I make it out to be. But there really are 3 office furniture stores in the country, and the chances they all carry the same item that I want (in order to get the 3 quotations) is pretty slim… So you eventually learn to break it down by function, not stock number. For example, on the quote form, you’d write: “desk: N$5,600.25,” not “IKEA desk: Svën: N$4025.28.” So it’s manageable, just a lot of leg-work.

Day three was spent actually doing some work. The colleague who was given authority to get me started was traveling to “The North” (an area of relatively high population occupied by one “tribe”, where my Peace Corps service was) to give a presentation of the educational status of the schools in that region (think “state”). So I helped extract slides from a slideshow that were relevant to his presentation and put them in a new one. Hey, they don’t call me a computer expert for nothin’. I earn this, people. Anyway, 11:00 came around and he left for the 7 hour drive. So that left me with 6 hours to kill. I started to work on my work permit application form (which takes between 1-3 months to approve, so you’ve got to have a work visa to cover you while you wait for the work permit to get approved.) At the end of the day, I revisited the Government Store in order to verify the numbers I had corresponded to the furniture I desired, and I also checked out the smaller things, like waste baskets, desk-top files, scissors, bostik/prestik/sticky-tak or whatever-you-call-it.

The big uproar at work is that the new guy wants to paint the office. The new guy is me, and the office is dirty and needs painting. In order to do this, I needed permission from 3 people: my Directorate Director, the Maintenance Deputy Director, and the Maintenance Control Works Inspector. Then we needed to fill out some paperwork and send it over to the Ministry of Works, who could quite possibly take several months to come over and paint this small room. OK, so I’ll do it myself, right? OK, but we still need all that permission. And heaven forbid if I want to change the color… (which I do).

Can’t say too much about the actual work I’ll be doing, because I really have no idea. Here is my official job description:

Post: Programmer/Application Developer
Supervisor: Senior Database Administrator – EMIS [Education Management Information Systems]

The EMIS Division serves management and planning in the Ministry by providing information to support the effective and efficient operation of the Ministry. The Division provides analytical information on the operations of the Ministry, which is required by various components of the Ministry and external organizations and individuals. It supports the Ministry in respect of monitoring and evaluation of its activities.

The Database Management and Administration Subdivision is an Information Communication Technology arm of the EMIS division and is tasked to take a complete care of the EMIS database, with its general functions outlined below. He or she will assist the DBA [DataBase Administrator] in the following general functions:


  • Physical Design and Creation of the Database
  • Production Support
  • Performance Tuning
  • Access Privileges
  • Backup/Recovery
  • Programming Guidelines
  • Upgrades


  • Ensure that all tuning of applications are accomplished as expected
  • Assign user roles and provide security for applications
  • Develop and review programming guidelines to allow the most efficient development of applications
  • Create and maintain production, test and development database environments for EMIS
  • Provide advice to application programmers in the effective use of database languages
  • Provide training to beginners and advanced users and other key personnel
  • Work on routine assignments applicable to the system
  • Attend and participate in seminars or workshops to remain current with information technology and especially those pertaining to education
  • Develop data capturing programs
  • Design alternative databases for capturing, storage and processing of information to be acquired (ad hoc surveys)
  • Maintain and update the EMIS software and hardware systems
  • Develop the electronic information distribution systems and ways to maintain them
  • Update the policy frameworks with the latest data by manipulating the database
  • Constantly review and update the data capturing programs
  • Assist in maintaining the servers and the server room
  • Train regional officers on minor database administration issues
  • Decentralization of EMIS activites to the regions to enable speedy data capturing and reports
  • Maintain a web-based system to enable the decentralization function to take off the ground and monitor its growth and enable data capturing at the lowest possible point in Education
  • Set up dedicated EMIS service in the regional offices to enable the regional staff to do data entry, cleaning and report building, yet connected to the main server in the head office.

Back to Africa

October 22nd, 2008 :: 8:45am

It took a bit more than a year, but the job I’ve been hoping to get for quite a while is finally happening. After 20 hours of flying and a night in Jo’burg, I arrived in Windhoek, Namibia, being greeted by a fellow ex-Peace Corps Volunteer and two friends. It was a warm welcome back.

Image credits: the CIA World Factbook and myself.

The job, which will begin after a work visa is issued and a contract is signed, is firstly a web programming/database designer post and secondly a sharing post. Statistics about the Namibian education system are collected in an “Annual Education Census” from each school principal and sent to the central office in Windhoek for entry into a database. Our primary goal is to decentralize this data collection, letting the 13 Namibian regions (think somewhere between states and counties) input the data into the database themselves. This will require a web interface for data entry that sanity-checks all inputs and is easy to use by an entry-level computer user. We’ll also be creating simpler ways for Governments, NGO’s and other organizations which require statistics about the education system to obtain them.

I’ve been away from home for 5 days now and I have to say it’s been tough. A lot of stuff has happened in the last month, including my last grandparent dying. Our family came together and friends came to support us, and it was really very nice. Of course it also showed me what I was walking away from to take the job in Namibia, and that was the hardest part. I’m also going through some cultural adjustment, despite being in the fairly cosmopolitan capital, and in general just trying to be at peace with my place in this city. But looking forward, I’m happy to be here and I’m sure the work will be very rewarding.

The ex-Peace Corps Volunteer who greeted me at the airport has taken me on two hiking/walking/running events where locals or ex-pats get together and do some kind of activity. The first was a “hash,” which was a mountainous hike with primarily ex-pats and loaded with ceremony, sexual innuendoes, and at the end, a wonderful cookout. The second was a 5K suburban run/walk with a bunch of locals and ended with a few drinks to share. Both helped to get my mind off the people I’m missing from home and also helped warm me up to the people I might be seeing every week.

I have a temporary cell phone number: 011-264-81-405-3722. Phone cards exist for around $0.25/minute, AT&T is near $1/minute. Namibia is currently 6 hours ahead of Eastern Daylight time, so don’t wake me up!

I’m thinking to go the 6 hours to the North of Namibia to visit my local family and friends for couple days before returning to Windhoek and starting the job. I’ve found an apartment which is coming available next month which isn’t ideal, but it is cheaper than the backpacker where I’m staying, and will be a good place to base myself out of while I’m looking for a more permanent place. The goal would be a safe/peaceful location with enough space for visitors who wouldn’t have to sleep on the floor…. (hint hint – this would be your cue to check plane fairs to Windhoek [airport code: WDH], and remember to clear your cookies each time you check the same fare, because they raise it each successive time, those bastards!)

Scalar::Util and x86_64

July 6th, 2008 :: 4:17pm

Recently (28 June 08), my 64-bit CentOS machine started sending me error reports from cron jobs running perl scripts that had been running fine until now. There was a problem coming from Scalar::Util:

Use of uninitialized value in concatenation (.) or string at /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/Scalar/Util.pm line 30

I’ve seen this problem before, as on this comp.lang.perl.misc post from Tim Boyer.

A force re-install of the Scalar::Util package in cpan does the trick:

cpan> force install Scalar::Util

However, while looking at Scalar/Util.pm around line 30, I found another bug which was hinted at by the first bug, but still only runs if there really is something to croak about:

Scalar/Util.pm version 1.19 lines 28-31:

if (grep { /^(dualvar|set_prototype)$/ } @_ ) {
    require Carp;
    Carp::croak("$1 is only available with the XS version");

If the array @_ contains either ‘dualvar’ or ‘set_prototype’, croak should be called with $1 filled with the string that matched. Unfortunately, this doesn’t happen. The ‘grep { /pattern/ } @_’ construct returns an array of values from @_ that matches the pattern. The if statement around it is true if the array returned from grep contains at least one element, meaning at least one element in @_ matched the /pattern/. Capturing within this construct does not work outside the { /pattern/ } block, and therefore the $1 will not get filled with the first (or any) string that matched the pattern.

This could be fixed by separating tests, as follows, although there is probably a much sexier way to do it:

if (grep { /^dualvar$/ } @_ {
    require Carp;
    Carp::croak("dualvar is only available with the XS version");
if (grep { /^set_prototype$/ } @_ {
    require Carp;
    Carp::croak("set_prototype is only available with the XS version");

I’ve emailed the author of Scalar::Util to see if this change can be made.

19 July 2008: Update
I found the proper place to report bugs in perl modules available on cpan, which is http://rt.cpan.org. Then I found a previous bug report that was for this exact problem.

It’s at: http://rt.cpan.org/Public/Bug/Display.html?id=31054

Sorry for the outage

June 11th, 2008 :: 8:49am

If anyone really cares, sorry for the outage last night.  We had a tornado warning so I turned all the computers off and unplugged them in expectance of certain doom.  It was windy, but the rain and thunder didn’t live up to what I’ve seen on the Weather Channel.

Mail.app rules [and no AppleScript]: Blocking spam by SpamAssassin’s X-Spam-Bar header

May 11th, 2008 :: 7:40pm

As I was writing my previous post about using Apple Mail’s rules and AppleScript to block spammy email messages, I realized there was a much easier way to do it, without using AppleScript. When I was going through the headers added by SpamAssassin, I noticed that the X-Spam-Bar header’s length represented the spaminess score. So instead of using AppleScript to parse the X-Spam-Score header as a number, I could just use rule conditions to weed out particularly spammy emails.

The following rule definition does almost exactly the same thing as the AppleScript in the previous post:

If [all] of the following conditions are met:
    [Subject] [Begins with] [***SPAM***]
    [X-Spam-Bar] [Begins with] [+++++++++]
Perform the following actions:
    [Delete Message]
    [Mark as Read]
    [Stop evaluating rules]

Two things might be of note here:

  • The ***SPAM*** tag in the message’s subject is added by our SpamAssassin setup automatically. We don’t actually need it to make this rule work, but I figure it probably cuts down on some processing time.
  • The X-Spam-Bar header is not initially a choice in the rule adding/editing dialog. You have to add it to the list by choosing the [Edit Header List] option from the bottom of the [Subject] select menu.

This rule takes advantage of the X-Spam-Bar header, which, if the spam score is 9.0 or greater, will contain at least 9 ‘+’ symbols, and will thus be deleted.

The one thing it doesn’t do is mark the message as spam, which helps teach Mail’s spam analysis engine. If anyone knows how to do that with Mail’s rules, please leave me a comment and let me know!

Mail.app rules and AppleScript: Blocking spam by SpamAssassin’s X-Spam-Score header

May 11th, 2008 :: 7:10pm

At work, our mail server uses SpamAssassin to block undesired messages. We’ve got the spam threshold currently set at 6, meaning that any message with a “spaminess” score of 6.0 or more is determined to officially be spam. But since we don’t want to miss a customer’s email coming from a recently blacklisted domain, we don’t have SpamAssassin automatically delete the spammy messages, rather it just tags their subjects and delivers them to their recipients.

SpamAssassin also adds a few headers into each email it passes on. An example of each header is included after it’s description.

  • X-Spam-Status: A line indicating whether the message is spam or not, and it’s spaminess score. [Yes, score=19.2]
  • X-Spam-Score: The message’s spaminess score, multiplied by 10. [192]
  • X-Spam-Bar: A series of ‘+’ symbols, each one representing 1 spaminess point. [+++++++++++++++++++]
  • X-Spam-Report: The full spaminess detection process report of the message. [Example too long to include.]
  • X-Spam-Flag: A simple yes/no saying whether the message is spam. [YES]

Since all the spam got through, I wanted to at least delete the emails which were definitely spam. Since a spam threshold of 6 was doing almost a perfect job of keeping the real emails clean and marking the spam emails as such, I decided that a spaminess score of 9 or more would indicate that an email was definitely spam, and could without consequence be deleted.

Everybody at work uses Apple’s Mail program for their emailing, so I wrote an AppleScript to be triggered from a rule that will delete any email with an X-Spam-Score header value of 90 or more. The AppleScript is shown here:

on perform_mail_action(theData)
  tell application "Mail"
      set theMessages to |SelectedMessages| of theData
      set theRule to |Rule| of theData

      repeat with theMessage in theMessages
        set theHeader to the header "X-Spam-Score" of theMessage
        set theSpamScore to the content of theHeader as integer
        if theSpamScore ≥ 90 then

          -- Make sure the message is marked as junk
          if the junk mail status of theMessage is false then
            set junk mail status of theMessage to true
          end if

          -- Don't let the message show up as unread
          set the read status of theMessage to true

          -- Delete the message
          delete theMessage

          -- No need to check this message against anything else
          if stop evaluating rules of theRule is false then
            set stop evaluating rules of theRule to true
          end if
        end if
      end repeat
    end try
  end tell
end perform_mail_action

And to attach this script to a rule in Mail, we used this

If [any] of the following conditions are net:
    [Subject] [Begins with] [***SPAM***]
Perform the following actions:
    [Run AppleScript] [/path/to/my/script.scpt]
    [Stop evaluating rules]

One thing which might be of note is that SpamAssassin automatically prepends the ***SPAM*** string to the subject line of every email it believes is spam.

Archive::Zip reading from a scalar

March 27th, 2008 :: 7:36pm

Recently I spent a day trying to get Archive::Zip to open an existing zip file which was already loaded into memory (and stored in a scalar variable). It just wouldn’t work, so I tried the simplest possible example in a separate file, and it still wouldn’t work. Eventually I discovered a solution, though not perfect, it works for me, and I hope you can use it.

The simplest example of the functionality was included as one of the example files, readScalar.pl. This file uses IO::File to load a zip file into a scalar variable, and then uses IO::Scalar to open a seekable filehandle to that scalar which Archive::Zip can use with it’s readFromFileHandle method to load in the zip file.

Unfortunately, even this example wasn’t running on both my Mac OS X box or my CentOS box. I was getting an error that looked like this:

error: file not seekable
at /Library/Perl/5.8.6/Archive/Zip/Archive.pm line 437
Archive::Zip::Archive::readFromFileHandle('Archive::Zip::Archive=HASH(0x18e0700)', 'IO::Scalar=GLOB(0x1917dd8)') called at ./readScalar.pl line 20

After some Google searching, I came upon some bug reports on CPAN that dealt with this:


They both promised that the problem would be fixed in the next major release of Archive::Zip, but here we are, a couple years later, and it still doesn’t work.

The solution that worked for me was a combination of the user-submitted fixes. At the end of my perl script, I overrided Archive::Zip::Archive’s _isSeekable method with code suggested by NEDKONZ, and it looks like this:

# Override the _isSeekable function in Archive::Zip
no warnings 'redefine';
package Archive::Zip::Archive;
sub _isSeekable {
    my $fh = shift;
    if ( UNIVERSAL::isa( $fh, 'IO::Scalar' ) )
        return $] >= 5.006;
    elsif ( UNIVERSAL::isa( $fh, 'IO::String' ) )
        return $] >= 5.006;
    elsif ( UNIVERSAL::can( $fh, 'stat') )
        return -f $fh;
    return UNIVERSAL::can( $fh, 'seek');
use warnings 'all';

This function living in the bottom of my code ended the “error: file not seekable” problem. Of course, you could also just edit your Archive/Zip/Archive.pm file and fix it forever, rather than including this function in every file that needs to read a Zip file from memory.

Impressed with HP tech support

November 19th, 2007 :: 5:11pm

Recently at work we had a printer network card fail. It had happened in the past a couple of times, and we just assumed that since the network cards were two years old or so that we should just buy some new ones.

I decided to go online to check out which cards are recommended by people who’ve had similar experiences. What I found instead was that this particular model of printer network card had a serious design flaw, and instead of screwing their customers and saying “buy a new one,” HP decided to extend the product warranty for 5 years, whether it was purchased from them or not, and they are replacing my card with a newer card which doesn’t have the same problem. This resolution was achieved with an 8 minute phone call.

I just wanted to take a blog post to give three cheers to HP for fully supporting a lemon product, even though I purchased it more than 4 years ago!

If you’ve got an HP JetDirect 615n printer network card, and it failed, you should do this:
0. Note your new warranty information is good until the end of October 2008 (http://www.hp.com/pond/jetdirect/j6057a.html)
1. Call 1-800-HP-INVENT
2. Navigate the prompts to tech support > JetDirect.
3. Tell them about the problem.

If you’ve got the same problem I had, they’ll send you a new card, with next-day shipping! If not, good luck! Here’s a link to HP’s site describing the bad cards: