Saturday, August 23, 2008

PHP-ExcelReader Solutions

PHP-ExcelReader is great for working with Excel spreadsheets in PHP code, but it has a few bugs and tricks. Here's a couple that I've run into, along with solutions.

Problem: Fatal error: Allowed memory size of [varies] bytes exhausted (tried to allocate [varies] bytes) in...

Solution: In my case, I was trying to work with a 1.3 MB file, and PHP-ExcelReader used the full 32 MB of allowable memory before dying. Yeah, apparently it's got memory issues. Anyway, increase the amount of memory allowed to PHP.

First, try adding the following code in your PHP script:
>ini_set("memory_limit", "64M");

If this doesn't correctly up the memory limit, due to some restriction on your host, see if you can edit your php.ini file directly (mine is located /etc/php.ini). Change the line that says "memory_limit = 32M" to something larger, such as "memory_limit = 64M"

Problem: Dates

Solution: My dates showed up in my spreadsheet as 06/03/09, but were obviously stored differently in the backend of Excel. When I would get the value from PHP-ExcelReader, they were simply numbers (39967, in the case of 06/03/09). A little research showed that the numbers were days, offset from (discovered by trial and error) 12/30/1899. Not sure if this will hold for everyone. Anyway, to convert them to proper MySQL date format, I used the following MySQL code:
>FROM_DAYS(39967+TO_DAYS('1899-12-30'))

Problem: Cells missing values

Solution: Perhaps this should be classified more as a warning than as a bug. Then again, warnings don't bite and bugs do, and this bit me.

When reading through the cells in a row, don't use "foreach". The cells will have sequentially numbered keys, but there could be numbers missing!

For example, a row of data in your spreadsheet like so:
aaa bbb ccc ddd eee
--- --- --- --- ---
111 222     444 555

...will result in a row of data like so:

array(1=>111, 2=>222, 4=>444, 5=>555);

Note how if you're sequencing through it with "foreach", expecting to get a blank value for key "3", you won't get it.

Old code: foreach ($row as $col_num=>$cell)
New code: for ($i=1; $i <= $num_cols; $i++)

Wednesday, August 13, 2008

It's your own fault, cat.

Our cat, for one of those reasons known only to the perpetrator, decided to go to the bathroom in our living room instead of in her litterbox. As a result, I locked her in her private room (without TV--remember that, parents, when you send your kids to their room!) which is a closet off our kitchen.

Acouchi decided to retaliate by kicking over her water dish, which I had newly filled this morning, but that plan backfired when she found herself standing in a pool of water. The only retreat was into her litterbox, which promptly clumped with surprising efficiency around her wet feet. Unaware of this, I finally decided she'd learned her lesson and I let her out, at which point she promptly streaked across the kitchen trailing litter.

She was heading for our bed, but I snagged her and carried her to the bathroom, where I filled the tub with an inch of water. Did you know that water is about as effective on cleaning litter designed to clump when it gets wet as it is on oil? I finally dried off Acouchi and let her go, but now I have a closet with a wet floor smeared with kitty litter.

And my wife's in California for 13 more hours.

Come home soon!

Thursday, August 07, 2008

Thesis Defense

My thesis defense is completed. I'm done! ...except for chasing down a dozen signatures, printing off copies of my thesis, running forms to various offices...I think it was easier to write the thesis.

Tuesday, July 29, 2008

Englestead

On July 26 a few friends and I hiked Englestead Canyon, dropped into Orderville Canyon, and finally dropped in the Narrows in Zion's National park.

Englestead was fun because of a giant 300-foot (91 meter) drop at the very beginning. You don't quite realize how high 300 feet is until you're hanging over the edge, and it takes well over four seconds for a falling rock (or body) to hit the ground...

Below is a picture at the head of the canyon. It's amazing how abruptly it starts, going from a slight slope to a sudden, 300-foot drop.


Below is us gearing up for the drop. Putting on harnesses, unpacking ropes, packing up everything else. We had a 300-foot rope for the rappelling side, and a 100- and 200-foot rope for the pull cord.


Here's our first person going down. The descent took probably 3 or 4 minutes, depending on how quickly you went.


Looking down the Big Wall from the top. I'm not even sure if you can see the bottom in this picture.


Once in the canyon, we were met by BOUSs (Bugs Of Unusual Size).


We had quite a few more rappels as well, but none close to the first rappel.


Once we dropped into Orderville canyon, water started appearing and things started getting a little greener.



Watch your head.



In the lower part of Orderville, we ran into a lot of tourists that hiked up the Narrows, and once we reached the Narrows themselves it was postively crowded.

Friday, July 18, 2008

Goals!

A couple weeks ago, I realized that I had a really hard time following through on things. There's a lot of things I want to do, but I'm terrible at sticking to a schedule and meeting goals. Here's just a sampling of things I'd like to do:
  • Exercise regularly
  • Write regularly
  • Regular morning prayers
  • Wash dishes regularly instead of letting them build up
  • Learn Spanish
  • Learn guitar
  • ...and several other things I can't think of at the moment.
My current goal is to become better at keeping goals.

I decided to start with something easy: a regular exercise program. Coincidentally, Lifehacker just featured a website completely devoted to helping people get into a push-up routine. Theoretically, if you follow the program, you'll end up doing 100 consecutive push-ups after six weeks.

That's my first step. Other goals will follow.

Disappointment

I didn't win the Writers of the Future contest, despite being a finalist.

Ah, well. On to the next story.

Recover Deleted Ubuntu File

While working on a Firefox extension, Firefox deleted a file I was using, "overlay.js". It was gone, but fortunately, a few minutes previous, I had manually deleted a temporary backup file that my text editor was using, "overlay.js~".

Since I had manually deleted it, it should have been in my Trash Can, but it wasn't, probably due to the "~" at the end of the filename which indicated that it was a temporary file. Even "Show Hidden Files" didn't make it appear.

However, by going to a command prompt and viewing my trash folder there, it appeared:

ls: ~/.local/share/Trash/files

So I'm not sure why the Trash Bin didn't show it, but it was there.

Thursday, July 17, 2008

Massage Chair!


For the last month or so, Child's store has been participating in a contest sponsored by one of their suppliers. Every time one of their dealers' sales associates sat a person down in a massage chair for a test drive, the customer could fill out an entry form and their name would be entered in a drawing for a free chair. If their name was drawn, both the customer and the sales associate would win a massage chair.

Last week, right before we left for our vacation to Texas (more on that later), Child received a call from her boss. "You won!"

Child screamed. We were in the car, stopped at a stoplight with the windows down, and got some curious looks from nearby cars. I rolled the windows up. Child was still screaming.

In short, Child had won a $4,000 massage chair.

Child's boss called up the customer who had won the chair, an older gentleman, but had a hard time getting the idea across.

"Sir, you won a free massage chair!"
"What are you selling?"
"Nothing! You won a free massage chair!"
"Yeah yeah, but what's the catch? I have to pay 'shipping' and 'warranty costs,' don't I."
"No, it's totally free!"
"Look, just tell me what you're selling."

Keylogger Firefox Extension


This is my latest Firefox extension I'm working on. There's been too many times when I've lost a post on a message board, or an email, or something similar because my browser crashed. This Firefox keylogger will record that, so I can retrieve the lost text. I added the "Minimum string size to log" so it won't save really short text--like passwords.

Official Firefox add-On page: https://addons.mozilla.org/en-US/firefox/addon/8261

Quick-link to download: http://stormhorse.com/keylogger-1.1-fx.xpi

Updates

It's kind of curious how the more stuff that happens, the less regular I am about updating.

First things first, I can't even remember if I already posted about this or not, but I have a full-time job now. It's doing web programming with a real-estate company in SLC. I go into work on Mondays, and work from home the rest of the time. That's fortunate, because the office is 45 minutes of nasty interstate away, and I wouldn't have taken the job otherwise.

My advisor isn't too pleased--I know he's afraid I'm going to stick with web programming instead of getting into robotics, which would be a waste of my M.S. degree. However, my brother-in-law is working on starting up a robotics company, and I'm hoping he'll need an employee soon. If that's the case, I don't want to be committed to a more permanent job.

I think I'll put each chunk of update into it's own post. No one likes reading longs posts.

Saturday, July 05, 2008

Give It An Hour...

I went to the shelter this morning. There were only two workers there, and they had been the only two working yesterday (the Fourth) as well. Apparently everyone else had taken a long weekend.

Experienced Employee had been warning New Employee that the Fourth was a crazy-busy time, what with all the pets getting scared by the fireworks and running off. When they had arrived at the shelter that morning, however, they had been surprised to find a single cat in Intake.

"Give it a few minutes," I said. "Animal Control is just starting their day."

A few minutes later, Spanish Fork pulled up with a dog. Then Provo. Then Springville. Then County. Two hours later, we had a packed Intake room and were processing dogs left and right, looking up microchips, and calling owners.

One guy had been watching his friend's dog, and it had escaped. Not only did this guy have to pay the impound fee, but the dog wasn't licensed, so he had to pay for a rabies shot and license as well. I wonder what his friend would think when he got home and found out his dog had been licensed in his absence?

I called another owner, and he informed me the dog belonged to his son. "Oh. Can I talk with your son then?" I asked.

"He's a minor," he said. Okay. Does SOMEONE want to come get the dog?

The man mentioned that his son was planning on breeding the dog, a female German Shepherd, while I was looking at the computer screen. Apparently the dog had been picked up by Animal Control in March, April, and now July. Three impounds meant the release fee was now $70, but it irked me that someone as irresponsible as this son obviously was, was planning to bring a whole new crop of dogs into the world. Take care of the one dog you already have, yeah?

Thursday, July 03, 2008

Speed Racer

This evening, Child and I saw Speed Racer. (Tiny spoiler alert.)

Let me stop here and say that sometimes, Child and I have very different taste in movies. She likes things like "depth" and "plot," while I go more for things like fat men spinning ninjas around over their heads. It was funny, because while he was doing it, throwing stars started flying out of the ninja's clothes, then his car keys flew out and impaled themselves in the wall! Ha ha!

So, yeah. I liked the movie, while Child thought the only thing funny about it was me thinking it was funny. :)

Line of Fire

Child and I live in a four-plex. This morning, we were walking to our car when our neighbor, who was also the landlords' daughter, walked by.

"Laying low? Out of the line of fire?" she asked.

I stared at her. "Is something going on?" I asked.

"Oh, if you haven't heard, I probably shouldn't say," she said, and kept walking.

Aaiiiee!! What?! What's going on? Do we need to worry? Is it something to do with our apartment? Will we be living on the streets tomorrow?!

Tuesday, July 01, 2008

Programming

In today's digital age, knowing how to program is a great ability.

In the past couple months, I've built Google gadgets to show Child and I how much money we have left in our bank account, and how many minutes we have left on our phone plan (see below).


(Most of the content [text/images] is grabbed directly from our account at tmobile.com. The black and white bar across the gauge is a custom addition, however. It marks where we should be for the time in our billing cycle--currently we have minutes to spare.)

I've also built custom RSS feeds for some forums and sites I frequent. This has a downside, however. In the past, whenever I'd get bored, I'd browse my collection of sites. Now, however, any updates to the sites are delivered right to my door, so it takes me 10 minutes to scan all new content, and I'm bored again.

My most recent project has been learning how to build Firefox 3 extensions. As my first example, I built a word-replacement extension. It can run automatically, or you can run it per-page from a right-click menu item. It replaces a list of words with replacement words on all webpages you view. Good for cleaning up forums with a lot of bad language, replacing common misspellings or abbreviations, etc. Something maybe parents might be interested in.



The first comment someone posted after I submitted the extension to the extension-directory was as follows:
First- I find this hysterical... not because it exists, but because I have a list of friends that I could get to transfer from IE to Firefox just for this extension. (I live in Utah- and all my friends are Mormons- turns out the stereotypes are true)
This person doesn't know that I'm also a Mormon living in Utah. :)

I found the comment amusing, but I'm really not sure why people are so (egotistical? self-centered? close-minded?) that they think everyone else in the world shares their exact same moral standards.

I don't laugh at, look down on, or denigrate your use of language on your (website, blog, whatever). You didn't ask me to read it, and I accept you for who you are. So why do I get laughed at or looked down on for holding to my own moral standard?

Friday, June 27, 2008

Polygamy

Does anyone else find it ironic that the American Public is so rabidly against polygamy when our culture (primarily media such as movies, sitcoms, and music) implicitly condones, if not outright advocates sexual promiscuity?

I don't think you could find a bigger double-standard if you tried. Sure, be outraged about exploitation of minors or people being forced into polygamy against their will. That's fine--and the only real reasons I could find that anyone should be concerned about the FLDS compound.

But don't complain about the institution of polygamy itself. For the Christians: at times it's condoned by God himself in the bible. Go look it up. For the secularists: at least when polygamists sleep around, they do it after being married and the man sticks around to support his family.

Despite my own belief that the Lord has commanded that we NOT practice polygamy at the current time, I do NOT believe there is inherently anything wrong with it.

Saturday, June 21, 2008

I lied. And I want the dog back.

When I arrived at the shelter, it was 9:15 and the shelter was still closed. I went around back and only found one car there. I knocked, and Pat opened the door. Apparently the person who was supposed to open with her (at 8:30--a half hour before the shelter officially opens) called to say she would be late...for about the 10th time in the last month.

Even worse, she didn't call Pat to tell her because she didn't want to face Pat's wrath, but called the shelter and left a message, knowing that no one answered the phone before 9:00. Something tells me this person will not work at the shelter for much longer.

As a result, Pat was glad to see me, because then she could open the shelter and call the inmates to come over and start working. When the phone rang, I answered it and there was a lady looking for a dog. Apparently, her daughter-in-law had gone into the hospital, and the step-father was stuck with caring for a half-blind Jack Russel terrier. As far as she knew, he had tried to get it euthanized at a vet clinic, they had refused because it was healthy, then he had gotten rid of it somewhere else.

The problem was that she didn't call it a Jack Russel, she said it was some strange breed, and I didn't see that breed in our book of occupants. I told her we didn't have it, so she said she would keep calling around.

However, later that morning, the step-father came in. He didn't beat around the bush. He walked up to the counter and said, "Last night I brought a dog in. I said it was a stray, but I lied, It's my step-daughter's dog and now I need it back."

Personally, I though we should have charged him for the owner release that he should have paid for the previous evening, then charged him for an adoption. However, Pat let him off easy with just paying for a night of boarding and a rabies shot (we couldn't even charge for the licensing since he lived out of our jurisdiction).

As he filled out the paperwork to get the dog back, he told us what he had done. Apparently, he hadn't been looking forward to caring for this dog by himself for an indefinite period of time, so he had taken it to a vet clinic to get it euthanized. They had refused since it was a healthy dog. Failing that, he decided to bring it to our shelter and claim it was a stray, but asked the vet clinic to say they had euthanized the dog if his wife called. They had refused that also.

Predictably, his wife had called the vet clinic, but all they could tell her was that her husband had taken the dog to a shelter somewhere. She didn't know which one it was, so she had been calling around. Apparently she had finally put enough pressure on him, and he came in to get it back.

Some people are crazy.

Incidentally, a second lady called asking if we had her cats. According to her, he had been dumping horse manure in her pasture, so she yelled at him. He had retaliated by trapping her cats and taking them to the shelter so she had to pay to get them out. She called him on the phone to yell at him, then he came over to her house to yell at her. Then he had apparently trapped her cats again, and she pondered aloud the possibility of going over to his house to beat him up. I told her to wait until he came to her property again to do that. :)

Friday, June 20, 2008

Fox-Face

So what kind of dog is this? It has the shelter a little stumped.

Monday, June 16, 2008

Underhanded C Programming

A couple days ago, Slashdot posted a link to The Underhanded C Contest. The idea is to write a program that redacts part of an image while making it possible to recover the lost information. The trick: it has to look innocent to another programmer reviewing your code.

My first version has the following output:

BeforeAfter

Here's the pertinent part of the code:

Redact to black (the "right" way):

p.rgb[R] = 0;
p.rgb[G] = 0;
p.rgb[B] = 0;

Redact to random noise (an acceptable way, see image on right):

p.rgb[R] = rand();
p.rgb[G] = rand();
p.rgb[B] = rand();

Nefarious redaction to random noise (see image on right):

p.rgb[R] ^= rand();
p.rgb[G] ^= rand();
p.rgb[B] ^= rand();

The key is using "^=" rather than just "=". The "^" will perform a bitwise XOR, and XOR has an interesting property. If you XOR A with B, and XOR the result by B a second time, you get back A.

So all we have to do to get the proper image back again is use the same sequence of random numbers, and that's easier than it sounds. It's customary to seed the random number generator using the following code:

srand((unsigned int)time(0));

But the file we're spitting out has the timestamp it was created--the exact time we're using as the seed in our RNG!

(If you're worried about the timestamp changing as the file is copied and passed around, then simply embed the time as a comment in the file--not nefarious at all.)

Wednesday, June 11, 2008

Moonshine?

I swear our neighbor just had moonshine delivered to their door. Child and I are leaving this morning for Wyoming for my grandmother's funeral, so I was up early packing things in the car. A flatbed pickup truck pulls up in front of our fourplex, and an old man in jeans and a jean jacket gets out. He walks around the passenger side, opens the door, and pulls out two quart Mason jars of clear liquid. He nods and walks towards our neighbor's door, while I head back inside. As I look back, I can see into his truck cab, and there's several more quart jars, along with a few gallon jugs. What other clear liquids get delivered in quart Mason jars? It has to be moonshine.

Saturday, June 07, 2008

Family Reunion

Well, Grandma's in the hospital. As a result, the family reunion got moved from Colorado to here in Provo. At least everyone already was planning on gathering, so they can all see Grandma.

In other news, Child's coworker called up the manager of the store late at night to tell her that he was quitting, effective immediately. I don't think he warned her he was leaving rather than just disappearing out of any kindness of his heart, since he and the manager hate each other, it was probably just to gloat.

It turned out to be a bad move, however. The manager promptly drove down to the store, where she found that this employee had stolen not only a carload of products from the store, but also some files that showed he owed the store owner money, as well as other customer files. On top of that, the owner had bought a new car and had sold this employee his old one, since the employee's car had been impounded a few weeks previous, and the employee was planning on taking off without paying for that.

And last but not least, the Rent-A-Center had called the store a couple weeks ago to verify this employee's job, so the manager decided to call them back and let them know the employee had been planning to flee the state and head to the west coast. As it turns out, this employee had about $5,000 of Rent-A-Center stuff in his moving van that he had been planning to take.

All sorts of excitement! Especially since the owner is out of town at the moment. And guess who gets to deal with everything, covering for this now-missing employee. The manager of the store, whose responsibility it is? Of course not! Child! And since we're not longer going to be in Colorado, the manager is able to call Child to come in whenever she wants, even if we still have a family reunion going on.