This web log is meant to be both technical and personal, generally detailing my exploits and adventures as well as providing notes and ideas.
- Bert JW Regeer (畢傑龍)

IE 6 and 7

I made a quick and simple decision which has already helped lift a weight off my shoulders. I have decided from this day on forward I will refuse to make my websites look and function right in IE 6 and IE 7. Dean Edwards has created a JavaScript that will attempt to fix IE 6 as much as humanly possible, forcing it to render everything correctly. It used to be known as IE 7, but he has recently released his latest version IE9.js which attempts to fix even some flaws that IE 8 has, while I am not yet ready to drop support for IE 8, I have enabled the latest and greatest version of this JavaScript so on any IE less than 9 the JavaScript will run.

To see everything that IE9.js supports visit the IE7.js Test Pages list and take your pick. The work that Dean has done is absolutely amazing and I am very happy that because of him I don't really have to worry about my websites in older versions of non-standards compliant browsers.

Even Microsoft sent flowers to the fake IE6 funeral with a note saying that we should stay tuned till this years upcoming MIX conference. I hope they say they are support HTML 5 and CSS 3 as that would be simply amazing. Maybe, just maybe they are switching from the old Trident based rendering engine to something more modern.

While I may dislike IE 6 and 7, I won't yet go so far as to put up a message just yet stating that people should get a better browser, I am removing a lot of stress and work in that I no longer have to support the old ageing browser.

Auto-updating Properties in Google AppEngine Models

In Google AppEngine a model may contain many different properties, from this model you can generate a form using djangoforms. This is all good and well until you have a required property on a model that needs to have part of it be calculated based upon something the user types in. For example, a blog entry generally has a "slug" which is generated from the title, now in Google AppEngine's models, if a property is required it has to be set at object creation time.

Djangoforms has a form.save(committed=False) that allows one to get back an unsaved Model, however since slug is not in the form (since it is auto generated) it cannot be set at model creation time. Even adding a hidden field to the form with the name of the property is not going to satisfy the model since a value of None is considered to be empty, which means it does not meet the required=True status.

After trying a multitude of different options I ran across an article about extending models that specifically talked about adding custom properties that were saved into the DB, and could be searched on, this got me digging and I found a blog post on the Google AppEngine blogspot about the exact same thing, using yet again a different example. The one that got me on the right track was the following post by Rodrigo Moraes on his custom model properties.

I came up with the following fairly quickly after also taking a look at googleappengine.ext.db within the Google AppEngine framework, however there is still an issue, for now the MagicProperty is only updated the first time the property it affects is set. I am not yet sure how to work around that, I will have to do some more digging, maybe there is a way to get notified if another property gets modified or updated.

import logging
from google.appengine.ext import db


def MagicProperty(prop, magic_func=None, *args, **kw):
	if magic_func:
		# No pants required.
		return _MagicProperty(prop, magic_func, *args, **kw)
	else:
		# We are putting some pants on the function.
		def pants(magic_func):
			return _MagicProperty(prop, magic_func, *args, **kw)
		return pants


class _MagicProperty(db.Property):
	"""MagicProperty which will modify output based on a function that it is given.
	
	Inspired by: 
	http://appengine-cookbook.appspot.com/recipe/custom-model-properties-are-cute
	http://code.google.com/appengine/articles/extending_models.html
	http://googleappengine.blogspot.com/2009/07/writing-custom-property-classes.html
	
	"""
	def __init__(self, prop, magic_func, *args, **kw):
		super(_MagicProperty, self).__init__(*args, **kw)
		self.magic_func = magic_func
		self.magic_prop = prop
	
	def attr_name(self):
		# In google.appengine.ex.db there is an explicit warning not to use this method, so we test for it first.
		if self._attr_name:
			return self._attr_name()
		else:
			return "_" + self.name
	
	def __get__(self, model_instance, class_instance):
		if model_instance is None:
			return self
		
		# TODO: If the property that this one is functioning on is changed, we need a way to know that so that we recalculate
		
		# Original __get__ in google.appengine.ext.db has getattr to retrieve the value from the model instance
		magic_done = getattr(model_instance, self.attr_name(), None)
		if magic_done is None:
			magic_done = self.magic_func(self.magic_prop.__get__(model_instance, class_instance))
			
			# Set the attribute in the model
			setattr(model_instance, self._attr_name(), magic_done)
		return magic_done
		
	
	def __set__(self, *args):
		raise db.DerivedPropertyError("MagicProperty is magic. Magic may not be modified.")

The approach that the DateTimeProperty takes is one that I can't use because my class is dependant upon an external property, not whether or not a value was set when the object was instantiated.

Google AppEngine is posing some rather interesting challenges. Although, for slugs it may not be entirely bad that it can only be set once, as that means title changes on the article won't cause the slug to change possibly breaking old links. This definitely requires more research and more thinking.

Interesting bug

I was starting to see something interesting in the output from my Google AppEngine based project. I was automatically creating a link based on a config setting, named SETTINGS["contact"], and the code would work perfectly the first time the page was created and loaded, however multiple refreshes of the same page would show that the link was gaining slashes even when it shouldn't have.

The logic was as follows:

if contact is "mailto:" then do nothing
else
        if contact does not start with "/" or not with "http"
                contact = "/" + contact

This code would work perfectly the first time around, however if I had properly tested by setting contact = "/contact" as well, I may have caught this bug faster.

However since that piece of code was only being called once per page view, it worked perfectly as far as I was aware, the thing is I started seeing more and more slashes being prepended to contact each time I refreshed the page. I looked at the code above, and did not see that my logic should have contained an "and" instead of an "or". Even so if the code is being loaded once per page view the variable "contact" that started off containing the word "contactme" should only turn into "/contactme" and not "////contactme" on the fourth page load.

Each time I added in a logging or debugging statement and refreshed the page it would go back to "/contactme", I would change another thing, or add another debug statement and "/contactme" was there staring me in the face. It took me a little while before I hit refresh a couple of times and noticed that my debug output now contained what I had seen beforehand. That is when it hit me, Google AppEngine caches imports that included my global variables. As long as I did not modify any of the files in my project it would happily use the cached variable, which after the first reload would contain "/contactme", then because of my use of or instead of and, would become "//contactme" on the second reload.

Google AppEngine has some very aggressive caching, which may well be required to have it run at the scale Google wants it to run. This is just another warning for myself that I need to watch out when I modify global variables and that they will stay the same across different sessions.

This is the logic I ended up with:

if contact is "mailto:" or contact starts with "http" then do nothing
else
        if contact does not start with "/"
                contact = "/" + contact

Works exactly how I had expected it to work.

Followup on my previous post; workaround choices not accepting tuples in AppEngine

In my previous post I was contemplating moving the forms back in with the model, I have now completed that transition. The form now lives in the same file as the model itself, which has made maintaining the two much easier since they are practically tied together. Also, since Google AppEngine does not allow one to set the choices field of a model property to something along the lines of: (("item", "user friendly item"), ("item2", "User friendly item 2")) in its choices initialiser; to have a form give the user the choices with the user friendly items but have the backend store "item", this is a work-around that solves the problem.

REDIRECT_CHOICES = (
	(301, "301 - Permanent Redirect"),
	(302, "302 - Temporary Redirect"),
	(403, "403 - Access Denied"),
	(404, "404 - File Not Found"),
	(500, "500 - Internal Server Error")
)

class Shorturl(db.Model):
	uripath = db.StringProperty(verbose_name="Path", required=True)
	httpcode = db.IntegerProperty(verbose_name="HTTP code", required=True, default=301, choices=[x[0] for x in REDIRECT_CHOICES])
	location = db.StringProperty(verbose_name="Location")

class ShorturlForm(djangoforms.ModelForm):
	httpcode = forms.IntegerField(widget=forms.Select(choices=REDIRECT_CHOICES), required=True, label='HTTP code')

	class Meta:
		model = Shorturl

Given the above tuple it will set the choices in the model for Google AppEngine and pass it to the field on the Django form allowing user friendly output. This will allow the user to pick the right redirect choice without having to know that various different redirect codes.

Project file structure

I'm currently working on a new website that will be hosted on Google AppEngine, however I am currently in the middle of revamping some older code and realised that maybe just maybe it belongs with the model rather than in a separate directory.

The setup currently is to have a models directory and a forms directory, they contain the models and the forms respectively, however I am starting to realise more and more that the form is a direct extension of the validation required in the model (which is not possible with the current database stuff that Google AppEngine offers), the form is taking user input and making sure that it is correct and then just passing it off to the model to check it into the datastore.

I'm thinking of merging the form into the model source code so that I can remove the forms folder entirely, since it just doesn't make sense to have the two in separate locations whereby one may be changed but the other may not. I'm afraid that they may get to be out of sync, and cause issues.

Will have to think about it for a little bit, no need to make rash decisions this late into the evening and blow away part of my source tree.

End of an Era

Today is the close of an era in computing, one that I find extremely sad because of all of the things that Sun has given to the world in terms of creations. Many things in computing would not exist today were it not for Suns engineers. It is sad to see a company that was so full of potential get sold to a company that has been known to be notoriously aggressive about keeping everything a company secret and not sharing.

Goodbye Sun (Already redirects to Oracle, even all the content has been moved).

Arizona; I'm here to stay for a little longer

Major corporation contacted me this past monday while I was in Colorado (Helped a friend move there!), and unfortunately they do not think they have a place for me on their team.

On the 15th of January I had my first interview with the corporation, and unfortunately I really think I didn't get hired because of that interview. During the interview I was extremely nervous and was unable to calm my nerves as I was unable to gauge the feelings of the guy on the other end of the phone. The connection quality was extremely low and there was much static as such I had to repeat much of what I said during the interview multiple times, and had to ask for the interviewer to repeat the questions. During this same interview I also completely blanked out and mixed up seven different programming languages. Afterwards when I was able to think clearly again I realised how easy the question was and implemented what the interviewer had asked for in minutes.

The second interview came an hour later. This one went extremely well, best of all the phone connection was perfect so I was able to understand the interviewer and him me. He was interested in some of the projects I had worked on in the past and was able to get me to loosen up and feel more at ease. The programming questions he asked me were easy to implement and I did much better, this time writing almost valid C++ programs without any significant issues. The guy was much more easy going, and we even had a pretty good conversation over email after the interview was over regarding the Near Space program I was a part of.

As mentioned before, I did not get the job. I was really looking forward to it as it would provide some very unique and interesting challenges that I wouldn't have been able to find at any other workplace. Great perks and benefits and I would have been amongst some of the smartest people in the world. I'm attempting to put it all behind me. I've been firing off my resume to all kinds of different job opportunities. If you happen to know anyone that is hiring a computer programmer/software engineer with experience in Unix based operating systems and a big interest in hardware design (electronics) please contact me using bertjw@regeer.org as my email address.

--

Before I went on vacation I decided to purchase a Flickr Pro account to upload my staggering amount of pictures to the internet so that I could more easily share with my friends and family. Please feel free to peruse my Flickr Photostream. I took some pictures while I was on break in Hoboken from across the Hudson towards New York, I personally find them to be absolutely fantastic, so please take a look at my pictures of New York during the day and night. I've always loved doing night photography of cities and towns, but never really get the opportunity to do so. These pictures were taken from the balcony in my dads apartment, which is right on the river.

--

In closing I just wanted to link to the XKCD comic that was just published a couple of hours ago: Spirit. Now, generally XKCD's comics are funny, however this one just hit close to home as I have always thought of the robots I have built as beings, as equals. The first thought that came to mind was Fry's dog in Futurama. It is by far one of the saddest scenes in Futurama invoking some very powerful emotions. Randall does a good job in personifying Spirit in this cartoon! I really have to stop cutting onions while browsing the web!

Late nights and Interviews

244 is a Hardware Studio if you are to believe the sign outside of the door, however really it is just an empty workspace/lab where individuals such as myself can sit down and start doing work, or procrastinate. It is open 24/7. Every Saturday a group of ex and current students from UAT gather in the lab and sit down together to work on various projects and to just have fun. We off course have our very own resident pizza connoisseur, and everyone adds to a large pot of cash so that at around 10 PM we all get some of the best pizza available around town.

Last night was another of such nights. Some people were playing MW2, others were working on Java/C# homework and I was working on my next project. My next project is rather interesting in that it has required research on my part as to how to accomplish what I want safely. Being in the lab surrounded by people also working generally gets me working on my projects as well. I've got a general layout of the electronics involved in my head, and I know what I need to do it safely, so now I need to start gathering the parts, sampling certain chips from manufacturers and sourcing other parts that I can't sample.

All of my research gets collected in various locations, right now most of it is still in my bookmarks bar, which is starting to overflow so much that it is becoming a useless tool, I've been trying to look for a tool that can help me organise my projects far more efficiently and in a way that will allow me to add notes to web pages, or at least to links.

My phone screens with the large company I mentioned in my previous post went okay. The first phone screen I was extremely nervous and was unable to really understand the guy on the other because of a bad phone connection (It was his end, my phone had full signal strength). Not only that, but I felt that he wasn't really interested and I couldn't get a good vibe from him. I was so nervous my brain melted together multiple programming languages to create a mish-mash of crap that wouldn't compile unless you happened to write a parser that could take JavaCPythonJavaScriptRubyC++Scheme syntax. If you have done so, well kudos to you! The second phone screen went much better, this interviewer was interested in my Near-Space balloon launches which helped ease my mind, and while on the interview he was able to give me feedback, tell me a little bit about himself and just in general provide some banter while I was trying to program which really helped. Hopefully they average the two of them out, and I get a passing grade. Now the waiting game starts all over though, so I hope to hear back from them within the next week. I really hope I didn't screw it up for myself.

2010 -- Where is HAL to tell me that it can't do this?

The absence, or rather outdated blog posts on this blog have a myriad of different reasons for existing, and while I feel guilty for not having updated nearly as often as I believe I should have it was with good reason.

2009 was my year. It was the year that I completed an awesome internship courtesy AEC Consultants, and it was also the year that I completed my last two semesters (I took a break over the summer, my first break in eight semesters of non-stop schooling). This past December 22nd, 2009 I turned in my last assignments and my paperwork for my degree application. If everything goes right (and that is a big if, considering UAT has screwed people over before), I will have finally graduate with a Bachelor in Computer Science: Software Engineering, or something along those lines. It took me nine semesters, over a three year period to complete my degree.

Only recently has it begun to sink in that finally I am considered to have the knowledge and the know-how to be responsible enough to WORK somewhere. Society believes that people that own a simple little piece of paper that says I have a degree means I can be a meaningful part of society. Little did they know they were wrong, but let them dream! ;-).

Yes, this also means that this time I am looking for a full-time work position. In the past year I have found that Phoenix is not exactly the greatest city for finding work in the software engineering field, however I will keep looking.

There is one thing going for me, a major company located in California contacted me, and asked me if I would like to work for them. I eagerly answered yes, and I am now going through their very rigorous and stringent interview process. To me it is an interesting challenge and so far I am actually enjoying it.

A new chapter has started in my life, and it was started in full with the change from 2009 to 2010. Kind of fitting that my life takes a major new turn, with new roads and new obstacles after society as a whole celebrates having lived yet another 365 days through four different seasons (there where seasons exist, Phoenix does not count).

Grilled Cheese Sandwich, Re-invented

While I may not be a master chef coming up with great new ideas to make people's mouths water, I do enjoy experimenting with new ideas. Two of my favourite easy to make food items are "Eggy in a Basket" and ever since Katie showed me the "real" way to make one, the grilled cheese sandwich. Grilled cheese sandwiches are absolutely amazing, however there are improvements that could be made.

After Katie butters two pieces of bread, she throws on some parmesan cheese along with some garlic salt, then in a hot skillet one side goes, stack some shredded cheese on top, and place the second piece of buttered bread on top, butter side up. Wait for the bottom piece to brown, then flip the whole thing, grill until the bottom is brown and crunchy. Absolutely tasty, I am making some modifications in an attempt to make it even better by adding an egg to the mix.

What you need (Makes 1 sandwich):

1 Egg
2 Slices of Bread (Sourdough works really well, anything sliced thick)
1 cup of shredded cheese (Or more, this is too taste)
Parmesan Cheese
Garlic Salt and/or Italian Seasonings (as desired)

Here are the steps, along with pictures:

1. Butter the bread on one side, and cut a hole in the middle of one of the slices.

Add on some Italian Seasonings or Garlic Salt to taste, and cover in parmesan cheese.

2. Place the slice of bread with a hole in it, butter side down in the pan, and crack the egg into the center

Cover with a lid to help the egg harden.

3. Once the egg whites seem to have mostly solidified, flip it over. Now stack cheese on top.

4. Place the other slice of bread on top, and cover with lid again.

5. Once the butter on the top slice of bread starts melting and the bottom slice of bread has sufficiently hardened crusts, flip the whole thing over.

6. When the bottom slice of bread has sufficiently browned and has become nice and crunchy it is time to consume it

7. Cut it down the middle, depending on how long you cooked it the yolk should still be a little runny or soft:

(please be aware that eating raw or undercooked foods can pose a hazard to ones health, I am not responsible for any illness because of your inability to cook foods properly)

8. Enjoy the Eggy in a Grilled Cheese Sandwich.

Syndicate content