A Short Practical History of the iPhone Design
Jun/100
I make no regular activity of finding fault in Apple or its products, but it’s no secret that Apple has so badly screwed up the design of the new iPhone 4 that they have forever lost a good portion of their sales this opening week. Sorry, left-handed callers.
Apple took their time to design the next-gen iPhone handset. Make no mistake about their carefully executed designs. After years of iPhone/Verizon users ripping on AT&T for its poor network and dropped calls, Apple had to show its cards, to prove that the iPhone’s design itself was not to blame for the dropped calls, unexplained signal dead zones, and speed limitations. Somewhere in Apple’s research labs, the designers of the previous iPhone handsets fully understood the signal problem. But they were designing a sleek new phone to redefine the industry. There could be no goofy antenna sticking out—it was about design and appearances. Placing the antenna internal to the casing required that the casing be made of a material that could feel sturdy while allowing the signal to pass through it. You have to make a compromise somewhere, even if it’s a small one.
So Apple creates its iPhone, ignoring Cisco’s copyright on the name, and tells the world it’s the best thing ever. Steve Jobs doesn’t actually sit down on a stool and design the physical components of the phone, so maybe he didn’t even know (at first) that there were compromises being made on the signal quality. It was “good enough” that it passed tests without trouble.
Since people by and large trust Apple to deliver magical products, just like they advertise, then of course its the fault of AT&T when the phone drops calls. But there’s no “control” in this experiment. AT&T has an exclusive on the iPhone. The truly dissatisfied unlock their phones and put them on T-Mobile or some other carrier. Do they have the same trouble as on AT&T? Hard to say. AT&T has the weaker signal in your area, so the iPhone signal flaw doesn’t rear its head when you use T-Mobile. You’re happy, and you only hate AT&T all the more, preaching its abomination of a network.
But the question didn’t really go away: does the design of the iPhone for some reason contribute to the dropped calls? Still no way to really prove it on a large scale.
When iPhone 4 makes its debut front and center on a bar stool, we found out something interesting, and one of the theories turned out to be right: the silver band around the edge of the new design was actually two antennae, to finally help prove the answer to the question about whose fault it is.
It was clearly understood by everyone, Apple researchers and commentators alike, that the two external antennae could not touch one another. Working around this, the Apple folks cut two slits down the antennae strips. Would this put an end to the signal issues? It’s a gamble, because if the new design remedies the issue, then it was Apple’s fault on the first 4 iterations of the product (iPhone, iPhone 2, iPhone 3 and 3GS). If the issue persists, then everyone will turn to AT&T with torches and gasoline. Either way, Apple doesn’t exactly “win”.
Stop and think to yourself: What 9th grader in a high school science class CAN’T tell you that if you touch both of the antenna strips at the same time, that something unexpected will happen? Surely Apple’s hot-shot team could guess what happens when you hold the phone the wrong way. I submit that it was not an oversight, it was not a mistake, and not everybody who tested the phone was right-handed (thus holding the phone in their left hand to dial).
Apple knew perfectly well that there was a problem. But Steve must be satisfied. There were deadlines. They were already slipping slightly out of the Hype lead in the smartphone market, with Android phones coming out every week, with bigger screens and a growing app store. They had to go with it, but only a few people fully understood the problems at stake. These people properly disclose their concerns, and so Apple decides it will test the phone out in the wild to truly see what happens. They have no reason to believe that the phone simply won’t work at all, so there are really only a few real reasons to test it out in public.
Apple is so dang sneaky that they’re terrified that someone discover the new iPhone 4 before its proper debut, so they have this tradition of creating fake shells for their new products that disguise it to look like their currently released one.
Major problem: Antenna issue completely unable to be given the left-hand test when it’s in a case.
Major inspiration: Antenna issue completely disguised when it’s in a case.
Major marketing hack: iPhone 4 announcement bears news that you can get the phone with a colored “bumper” skin, which covers only part of the phone. Which part? The antennae.
All of this leads back up to the primary question. Is the iPhone design still getting in its own way? Is the AT&T network as bad as Verizon advertises? Now there’s an antenna problem plaguing the blog headlines, YouTube videos piling up where people record their 3GS and their iPhone 4 and the left-hand chokehold of death, and where people spoof the “I’m a Mac, I’m a PC” commercials, where one character is an iPhone 4 and another is a Droid, and the iPhone keels over at the touch of the sexy girl wanting to hold him.
Apple will tell us in the coming weeks that engineering has its limits, and that they supposed that there could be issues when they exposed the product to the masses, and that they should make use of the “bumper” accessory that Apple so mercifully provides. Praise be to Apple for delivering us from our sorrows!
What’s next in this story? AT&T is a slut for the iPhone, and won’t call out Apple on the problem. They instead keep taking the heat for network problems while they keep paying Apple to have the exclusive contract, shrouded in mystery. When will the game be up? When will other carries be presented with Apple’s offer to allow them to carry the iPhone?
I hypothesize that Apple will continue to treat its product as a “privilege” for those who they choose to carry it. They will open it up to smaller carriers first, because they’re far more likely to generate warm fuzzy feelings about the iPhone and how great it is on T-Mobile. Another 6 months or a year down the road, Apple will release it to another carrier. Finally it will be everywhere, and people will no longer remember the tyrant AT&T network and its violations of love, life, and happiness.
And the whole time, nobody will be quite sure if the signal problem was Apple’s fault.
Google Chrome update breaks jQuery event binding
Jun/100
The unthinkable has happened to the much beloved Google Chrome, if you’re on the Dev channel. With current version at 6.0437.3 dev, and with jQuery 1.4.2, suddenly all event binding throws errors about “undefined” not having an attribute named “handler”.
Well, here’s the code that causes the issue, in the event (heh) that you’re working with the bind() method. While the code error pops up in the event add() method, the source (heh) of the issue is in bind():
if ( jQuery.isFunction( data ) ) {
fn = data;
data = undefined;
}
jQuery uses an internal function to determine if “data” is in fact the function you intend to bind to the event. If you’re a fan of using something like “jQuery(‘.myClass’).click(function(){ … });”, or “jQuery(‘.myClass’).bind(‘click’, function(){ … });”, you’ll encounter this issue.
The problem is actually within that jQuery.isFunction() call:
isFunction: function( obj ) {
return toString.call(obj) === "[object Function]";
}
Chrome, for whatever reason, returns “[object Object]” in the context of the jQuery code. Testing this basic pure-javascript assertion on the console will yield the proper “[object Function]” string, while somewhere in the depths of jQuery it does not.
The four mainstream browsers all seem to do just fine if you use the more natural test:
typeof obj === "function";
However, I am no jQuery internals ninja, and have no idea what the implications could be if you change this core utility.
But now you know.
I Would Walk 500 Miles…
Jun/100
I would walk 500 miles to burn Java, to destroy its children, and I would walk 500 more to hunt down its evangelists and also put them to the flame.
Despite the fact that I’ve been casually coding in Java for a few years now, here are 3 things I’ve learned that, while in your first year of coding in Java, you should not attempt without the supervision of a Java grandmaster.
Introspection/Reflection
Although Java has a fairly well-fleshed Reflection API, Java is just not made for it. There are too many wildly abstract Exceptions you need to catch for things that, within the context of the code you’re writing, would never happen. Any time you want to use reflection to force a call to a method, you’re forced to catch a possible “no such method” exception and other kinds of problems.
Fine—I get it, but it sucks. It’s just part of the nature of Java’s bias against RuntimeExceptions. Attack me as a Python lover, but if you ask me, testing is the only way to promise that your code works. It’s not enough if it just compiles, however much your IDE tries to make you feel good about that gross splotch of nested try-catch blocks.
Unfortunately, the only way to use Annotations in any clever runtime way requires reflection. I wrote an SQLite API on top of the standard JDBC driver with class-, field-, and method-based annotations. It was absolutely gorgeous. I’ve never seen a better SQL API for Java. I was in love for 3 days, between my development sprints. But then the horrors of reflection set in as I assembled the rest of the under-the-hood SQL for automatic population of fields and saving them to the database. I quickly got myself into a rat’s nest of ridiculous exceptions and impossible-to-call methods.
The bottom line: It’s impossible to put Java’s clever new Annotations to practical runtime use, outside of generating API docs and deprecation warnings. Java just gets in its own way for this sort of thing. Python’s idea of making “Decorators” (annotations) as functions that wrap the annotated method are brilliant, and far more flexible than basic annotations.
Date / Time manipulation
Very few popular languages have truly beautiful date and time APIs. They can all get the job done, but all suffer from quirks that require you to be a seasoned veteran (synonymous with having been kicked between the legs by the library at least two dozen times).
Even Python’s library is confusing, because there’s a datetime library and then a datetime sub-library inside of that. Good luck trying to remember if the date factory is in datetime or in datetime.datetime. Then add to the confusion that there’s a time and a datetime.time.
In Java, the problem is less about organization, and more about the actual API. Java is determined to deprecate everything good and holy, so they got rid of the Date class because of some historical issues in its implementation. Thus the Calendar class was born. The problem suddenly became that finding the difference between two Calendars was not a task that the Calendar class was willing to help you with. For all of the supposedly beautiful code that was written to track leap-seconds, it can’t freakin tell me the delta between two Calendars without manual fetching and number crunching of the individual fields.
There also seems to be no way to use the “roll” method of the Calendar class to add X to the minutes field, making the hours roll up if required. Once again. Really? You can’t help me with that?
Python brilliantly addressed these issues by having a object to represent a “time delta” All by itself it doesn’t represent a date or time, but it can be arithmetically added or subtracted against another date, time, or datetime object. If you subtract two datetime objects, you get a timedelta, reusable in whatever context you see fit. It rolls the overflow (or underflow) of any field into the other implied fields that must change.
The reason this yanks my chain is because it’s just an API issue, completely correctable by some nice code. The problem being augmented by the fact that you can’t help out the API by smartly overloading simple +/- operators in an intuitive fasion, a clean easy-to-read API is impossible. I understand the implication if operator overloading is exposed— C/++ is a testament to how things can get sticky. Java’s Date class has amazingly simple methods for flexibility, but deprecated everything but the constructor.
And why can’t I just instantiate a Calendar instance? What? I’ve got to do Calendar.getInstance()? Really? We couldn’t figure out a way to stick with the paradigm?
The bottom line: The Calendar class isn’t simple. It’s API is restrictive, for all the glory that is preached on its behalf. The only thing it is useful for is getting a millisecond timestamp and doing a cal1.before(cal2) test. Python’s APIs for the same kinds of tasks are relatively simple and are definitely straightforward considering the timedelta object.
1-Off Tests
Testing should not be a phase that happens after you’re done coding. Testing is what you do every 5 minutes, between changes that you make. This reduces the need for a debugging suite to just its profiling abilities. Barring those unforeseen issues that require deep debugging of special cases, you really shouldn’t think that you require a giant debugging suite as a necessary part of your programming groove. You should be testing constantly. That’s how you build stable code that you are intimately acquainted with. Go ahead and build your unit tests, separate tasks into methods, create an API. Fine. But those things still need to be tested, not just organized.
Given this kind of approach, testing a random idea for a few lines of code is extremely cumbersome. I’ve got to go start a new project in my IDE and do a build-n-run over and over again, or else execute directly from the class files, with or without a console open. The problem is that once even the various “Test” packages that IDEs create need to be compiled and run. To properly leverage those test packages, you’ve got to craft it intelligently, or else it’s no different than opening that scratch-pad project and pasting some lines.
Sometimes even just my math needs a quick sanity check. You can’t do a calculator-style check in Java. You’d be crazy to have a scratch-pad project for testing some several lines of code. What’s worse is when you test and you are wrong. Then you need to go back and edit the lines in that glorified text file and try again. It’s a terribly frustrating experience because there’s no accommodation for on-the-fly rapid tests.
Anyone who’s used Python knows that this is practically a non-issue for them. Python’s interactive prompt (zero setup required—it’s just there) is a Windows-R & Enter shortcut away. You can then hammer out whatever little business you’re fuzzy about. Especially considering that issue with date/time manipulation, Python lets you just HAVE AT IT and see what gives you the result you want. Sometimes seeing the stub API (like in IDE previews and return hints) isn’t enough—you’ve got to actually see the returned value of some library you’re trying to use.
The bottom line: I can’t code Java anymore without a Python prompt open, to simulate what it is I’m trying to do. It reduces my Java testing time down to less than half, because I’m more confident about my processes. Now that is an improvement to Java development. Who’d have thought?
The Bottom Line
I try hard to make Java “work” for me. The problem is that I run into way too many problems. I’ve previously written about my dislike for the language, and the commentary I received was that I was arguing about APIs. But isn’t that what a language is? A big API? I don’t like anything about the Java API. I don’t get excited about anything in that language. I never write a line of code and think to myself, “That is a great line.” I never wish I were doing something in Java instead of Python.
Harass the Python users of the world, you Java supporters. Go ahead. But it doesn’t do anything for your stance, even with your self confidence and your ability to make demeaning remarks about Python, a language you’ve probably never really used at all. Most of your arguments against Python’s paradigm have no important side effects that would stop me from using it anyway. Most of your arguments work from the assumption that “Java did it right” and that there’s no further room for improvement. Java will last for a long time. But so has C. That doesn’t make it the perfect solution. It has its uses, but it’s uses have their limits. My limits include sanity and a workable API. After all, code is read a lot more than it is written.
Your Technology Horoscope: Where do you fit into the Social Hurricane?
May/100
Expressing dislike for Facebook is easy these days; there is plenty of well-published ammunition blowing around blogs and even world-respected newspapers. So let’s clear up a simple fact right now, before we get our hands dirty: not everybody with an opinion is a bandwagon lobbyist.
Voicing an opinion on a subject, in other words, doesn’t mean that my views are unfounded and plagiarized from other public giants. I believe that there are several specific reasons why every Facebook user should be educated about the tool they use every day. Most of those reasons point to elevated caution while using Facebook, at the very least. What is perhaps more surprising in this call for caution is that Facebook isn’t at the center of the turmoil all by its lonesome.
There are stages of involvement with Facebook, Twitter and Foursquare, just like there are varying degrees of usage of email and perhaps limited reasons why you would want to pull out a record player. Not everybody needs these things, so it makes perfect sense not to use them at all if you feel so disinclined. I suggest that there’s benefit to using these services, but that they should be used with just a little bit of preemptive education.
There are a million different ways to “share” junk with people on the Internet. Everybody settles in where they seem to feel most comfortable, despite not having explored all of the options out there. My goal is to illuminate the bigger picture, so that this stops being an argument about Facebook, and begins to be a discussion about how the life can be made more interesting with selective technologies.
And now… where do you fit into the Hurricane of “social media”? While I describe the Hurricane (below) as a process, most people probably have some youthful energy that flung them deep into the progression before they ever realized they had a choice about their behavior.
The Beach
You can see this massive hurricane in the distance, knowing that it sooner or later it’ll be trying to blow down your house unless you decide to modify your definition of “fun.” You shake your head at the ridiculous youths trying to surf on the incoming tide at the fringes of the looming storm. Somehow they believe that it’s fun to be in there. You can’t wrap your head around that, so you’re boarding up your favorite vacation spot so that you can take cover in more a more comfortable area.
Most parents over 50 probably fit right here. There’s nothing in that hurricane that’ll make them feel more vibrantly alive by paddling headlong into it. Life was simple without this chaotic centerpiece of discussion, and they just don’t need it. They just don’t. Why should the idea of talking to old high school bullies and class presidents be compelling? They already have some communication pattern with distant friends which they’re comfortable with continuing, such as a Christmas card with a photo and a signature, an occasional phone call when there’s a new baby on the way, etc.
If this is you, then you’re probably not reading this article of your own accord; if you are, I applaud your ability to show an open mind!
People in this category probably will pass on of old age before they catch the same vision that the younger hip crowd is obsessing over.
The Cresting Water
At the fringes of the storm there’s a beautifully simple bit of entertainment to be had. One does this by making their own unique, personalized fun and games out of some rough water and a surfboard. For these people, there’s no reason to become hopelessly lost in the middle of the storm, but there’s good fun to be had by using the less intense waves at the outskirts to fulfill their need for play.
Parents and otherwise middle-aged adults may have dipped into this area after their children or colleagues have urged their participation. You may not “get it” quite yet, but you’re willing to dabble in this technology to satisfy others. Who knows? Maybe you’ve found yourself enjoying getting those handy text message updates from Twitter when your daughter does this “tweeting” thing.
The benefit to making friends in the cresting water is that you get to pick and choose the fun you want to have. You pick what you see and do. At any moment you could decide to have just one more run before getting back to the beach and heading in for the night. There’s very little pressure to go deeper into the hurricane because it seems to you that nobody ever returns from in there with their sanity intact. You’ve successfully leveraged Twitter, Facebook and email so that they have their proper place in your week. Email has been around much longer, so it makes sense if you tend to favor it above other forms of online communication.
Whipping Winds
Once you’ve lost the thrill of a few toddler waves, you move into slightly more exhilarating territory, where the wind sometimes stings and the water will tip you over for a few minutes before regaining your orientation and daily rhythm.
Countless children between 12 and 24 could fit in this area– it’s big enough for everyone, which is part of the danger. There are so many other friends blowing around in here that you’ve got an invested interest in staying put, even if you get tuckered out from time to time. You make compromises back in the real world by spending a bunch of extra time playing games and checking in with friends and what they’ve been up doing these last couple of hours. In fact, there are enough friends and familiar faces around here that there’s just too much to talk about in just one day, so naturally you have to pick and choose your “best” friends based on what kind of games and fun the group of you enjoy.
At this stage, your teen is somehow pushing the limit for the number of text messages your shared family plan is allotted without incurring extra fees. The teen can be so detached from certain of their real life tasks that they actually feel the weight of it burdening them from time to time. They’ve had Facebook arguments with exes, they’ve either played Farmville or Mafia Wars, or they’ve successfully spent a cumulative 3 hours this week in front of online quizzes like “Which DISNEY CHARACTER are YOU?” and a slathering of other variants of the same idea.
You may have gotten into this area by curiosity, but now you’re getting pulled in. You get really bummed when your office announces that they’re blocking Facebook from now on.
Because both you and your friends are so deeply involved with everything the others do, dropping out of the loop would just be lame at this point.
Swallowing Water
For the truly dedicated, for those who have no other reason to exist this week except to score a high-ranking position on the charts of Foursquare for your city, for those who actually do Facebook at all hours of the day and night: you’ve tasted life, you can see the light! You’ve been to the edge and back and now you make the trip each weekend. Your phone never stops making noises while you drive, eat, and sleep, and sometimes you find yourself sitting on the toilet with a phone in hand. You never do that overdue oil change because you’re much faster at browsing Facebook on your computer at home than on your phone while you wait for the 20 minutes it takes for the job to get done.
You smile and laugh and tell yourself you’re having fun! Isn’t this lung-full of salty water just the best thing since Facebook’s 4th privacy policy revision, or the 3rd unpopular visual redesign?
At this point, your heart is invested into the deepest parts of the hurricane, and well, home is where the heart is. You’re here to stay, even if it kills you! Hopefully someone will tag my waterlogged body in the photos they take. And people better push that “Like” button, or else I’ll be haunting them and making sure karma does some nasty stuff.
You’re in the for the long haul. It probably doesn’t even cross your mind anymore that you may want to give up these social addictions one day.
The Eye of the Storm
Usually when the author asks, “Can it get any worse?” the answer is “Haha, yes it can!” But this time, the strange moral of the story is that the very center of the hurricane of these social services, like Facebook and Twitter and the host of others, is actually quite calm. Think of what it must be like to achieve Social Nirvana. Whether you’ve gone through blood, sweat and tears to get there, or if you simply recognized the bad idea of tempting death by swimming through the middle of it and so decided to parachute in from above– the effect is the same. You stand in the middle of the whirling storm of useless status updates and shared information classified as “mundane” at best. You watch everyone outside of the Eye as they struggle to pretend like they’re still having fun at 2am commenting on every photo from a party last week. ”lol” this. ”lol” that.
From the inside, you get the serene landscape, harvesting the undeniable usefulness of these Social websites, while keeping yourself aloof from the whole drowning in text messages thing. Facebook, Twitter, Foursquare, Gowalla, Digg, Del.icio.us, Flickr, blogs, email, Google Calendar, phone numbers– they all become mere tools to help you achieve your tasks with ninja-like precision. Facebook is no longer a lifestyle; it’s just a URL. Twitter isn’t Life Eternal, where trending topics typically get played by unemployed kids making Mama jokes or “That’s What She Said” cracks; it’s just a way to hear about newsy things from your favorite figureheads in your range of interests.
The surprising benefit to being in the eye of the storm is that you actually find that you have no reason to want to leave. It conforms to your desires, in a far more flexible way than for those back in the Cresting Water. You’ve harnessed the power that has corrupted others. While others may regret the fact that they can’t really go back to the shoreline, you actually find that you have no immediate reason to do so because you’ve selectively invested only bits of your time into different services, and ultimately have little to lose from any one of them turning evil on you. If Twitter dies, you’ll find a new way to fill the hole. If Facebook goes belly-up, email still exists, and
Humor aside
The recent uproars about Facebook’s privacy issues come down to one thing, best explained by a short story for the sake of a comparison:
When “The Face Book” started, it was for college kids only– you had to have an EDU address from a list of schools to get an account. The logo was some blue-ish silhouette of a kid’s face with an 80’s haircut. The promise of The Face Book? That the site treated your personal info with utmost privacy, where absolutely nothing was revealed to people unless you decided that you trusted them. It was effectively a dating site, in terms of the privacy level. You could see basic details about a person if they choose to reveal such info, and then if you mutually decided to be friends, a more relaxed privacy environment was enabled.
The promise Facebook made was simple: “We’ve got your back. Go ahead, put stuff up here so that others can find you (if they’re looking).”
But now Facebook’s privacy policy is so wordy after several extensive revisions that it is several times longer than any other comparable site’s policy text. Now the policy forces you to link your musical interests to public Pages, or else you can’t list the info at all. In other words, the switch doesn’t even have two sides. You’re either making it public, or you can’t list the info at all.
Many people have no trouble at all with this techy mumbo-jumbo. ”Privacy” is (by now) just a buzz-word that got popular after these social sites gained notable momentum. Today, it doesn’t matter to people if all their basic profile info is public, because that’s what they signed up for. But for those of us who joined a vastly different “The Face Book”, it’s time to throw in the towel. We didn’t sign up for our info to slyly escape the 144,000 checkbox controls of double opt-out preferences.
The bottom line is that Facebook is a company trying to monetize their system. We are their value. Without the users, Facebook has nothing substantial to their name but a fancy Like button all over dying newspaper sites. They are madly trying to turn the Internet into an interconnected network, but they fail to understand that Internet is already just that. It’s like the AOL of the 90’s: people thought AOL itself was the Internet, and that meant that people would come to AOL for all of their information needs. Let’s not let Facebook stand on our shoulders in order to claim that they are the King of the Hill.
There doesn’t need to be a king of the Internet. (A President of the Internet is a different story entirely.)
Django multiple databases: The many-to-many nightmare
May/100
Despite Django’s new (official) support in 1.2 for multiple databases in a single project, there are plenty of ways you can shoot yourself in the foot with the lack of features it supports. I understand however that one might rightly recognize that as a brand new feature it should only be expected to lightly venture into the advertised capability.
My company’s use case is to design a collection of websites which are intended to be taken together as a series of services. Our goal is to provide a number of services, and so cross-selling the clients to our other products is exactly our endgame. Like any intelligent website, one would therefore expect that changing your password or profile image on SiteA would also update the information in SiteB, given our commitment to streamlining their experience. Sure, there are a number of ways to fudge this functionality without Django’s Multidb, but those solutions are hacks at best, and are not friendly to the overall Zen which Django aims to deliver.
The trouble with having separate databases for each site’s data, while configuring a standalone communal database for each site to confer to with user account verification, is that the ManyToManyField has some serious issues. In fact, the m2m relationship works only half of the time, and on the opposite half than you’d expect.
Consider the simple model in an app which sync’s its data to the “default” database (the database specific to this site only):
class Book(models.Model):
contributing_authors = models.ManyToManyField(User)
This works great as a trivial example: a book can have one or more Users attached to it as contributing authors.
If you’ve got a database Router configured to send all “auth” app models to the communal “global” database for user data, which I use the alias “common” to describe (”common” referring to the fact that all the sites refer to this single common database for their Auth needs), Django will understand that Users come from the “common” database, while Books come from the “default” database. For ForeignKey fields, this is pretty simple, but we shouldn’t forget that a defining attribute of the many-to-many relationship in SQL is that an intermediate table is created to map User and Book to one another. Django’s use of its Router system is ambiguous in the case of the following Django QuerySet API call:
book = Book.objects.get(id=4) book.contributing_authors.all()
Naturally, since Users are kept on “common”, one would expect that this query gets executed on “common”. But we only have our Router sending “auth” models to “common”. SQL must first hit the many-to-many management table to decide which User pk values to even look up. While Django tries to use “common”, it will raise an SQL-level exception about your “common” database not having a table named “myapp_book”. Clearly it’s correct: we expect that “default” has “myapp_book”, not for “common” to have it.
So what do you do? The following also throws the opposite database missing the opposite table:
book.contributing_authors.all().using('default')
The problem here is that Django is jumping to the M2M management table on the database you specify via the using API method, and there’s no way to switch the target database alias after that point.
But here is something curious– if Django jumps to the M2M table first, and if that M2M table is stored in the same place as the Book model, shouldn’t the following work, despite the oddities we’ve seen?
user = User.objects.get(username='bobdole')
user.book_set.all().using('default')
Indeed it does work. It jumps from “common” over to “default” right from the start. Since it has no values to look up on “common” (you’ve already selected your User and its pk), it rolls over to “default”, performs the JOIN on the M2M table, finds the proper Book objects and returns them. But now to leverage that backwards use of the API to reinvent a way to achieve book.contributing_authors.all(). The following appears to do the job, assuming you find a nice efficient way to limit the initial set of Users you want to scan:
class Book(models.Model):
users = models.ManyToManyField(User)
users.value_from_object = lambda obj: obj.contributing_authors
@property
def contributing_authors(self):
users = User.objects.all()
user_id_set = set()
for user in users:
if user.book_set.filter(id=self.id).using('default').exists():
user_id_set.add(user.id)
return User.objects.filter(id__in=user_id_set)
Now, there are two things to be said about this snippet:
First, it’s freaking ugly and inefficient to scan every user in the entire database and individually ask for each one’s book_set attribute. The fundamental problem discussed above bites us again if you were to try to use the User.objects manager: if Django must do a database lookup (and thus a JOIN) on the User table and the M2M table which reside on separate databases, the same errors will appear about missing tables, no matter what we pass to the using() API call. The solution is intrinsic to the fact that examining a specific pre-fetched User instance won’t require Django to look anything up on “common”, so specifying the using(”default”) option works beautifully in our favor.
Second, I’ve hacked the ManyToManyField’s method value_from_object to return the QuerySet that I go out of my way to build in contributing_authors. When Django’s forms API is in use, it will always try to look up the possible choices on the other end of the ManyToManyField. Why? I haven’t any idea really, because that’s not my area of expertise. Even specifying the queryset or choices to use on a custom ModelForm doesn’t work, because the forms API still calls value_from_object which normally returns an “all()” QuerySet, thus irreversibly causing the error we’re trying to avoid.
I will be continuing to develop this problem into a better solution, but for now, I hope that it helps serve as a bit sloppy documentation on what is going on here.
iTunes new feature: “Screw me” button
Apr/101
Perhaps they mean to give brainless kids a way to fit more of their music on their second-gen click-wheel iPod, or maybe they’re trying to snuff out mp3? No big deal either way. It’s not like I’m going to put a bloody checkmark on that option.
Final Fantasy XIII: Disc 2
Apr/100
(Other parts: Disc 1)
I’ll start things off by saying up front that Disc 2 has made an immense difference to my opinion of the game. Despite my pretty rough criticisms of Disc 1, the last half of Disc 2 really tipped the scales.
The beginning of this disc was pretty true and faithful to the game style that disc 1 had built up. In fact, there wasn’t much fanfare as the game winds down and tells you to put in the next disc. I had written my review of disc 1 after having played a couple of hours of disc 2, and my sentiments hadn’t changed at all. Everything began to swivel once Lightning and Hope end up in a situation that reunites them with Snow, who is joined by Fang, a character only glimpsed during the first disc when Snow starts throwing a tough-guy tantrum with damp eyes. But let’s not get ahead of ourselves.
Disc 2: Limit Break
Major good:
- Characters finally merit some emotional attachment by the end of Disc 2.
- Vanille is less stupid, Hope is less angsty
- Game has a purpose, understood by the characters
- Great character voice overs. I couldn’t appreciate this during the first disc’s distractingly poor story progression. I thought XII was good, but XIII is better.
Major meh:
- Too much use of background music which has vocals. This comprises only a couple of songs, but their repetitive use is pretty… meh. I enjoy those songs, but it feels like they’re being wasted on grinding areas.
- They *almost* make a character kill himself. Now that would have been a great twist to normal FF titles. Unfortunately they only use theatrics to make you believe for a brief time that said character is a goner.
- Shops are compressed into a meaningless magic save point service, removing entirely the discovery of rare items from remote and distant lands. Again, rather meh.
Major bad:
- Terrible interaction with the world around you. The world is a maze, and you’re the hamster. Everything else is colored tubes for you to run through.
- Characters still don’t quite understand what it is they’re after. Nor does the player. At least there are lots of story components that mean something after 20 hours of game play. The story itself is interesting, but they’re stretching the amount of story in FFVII disc 1 into all of FFXIII. Naturally things are moving more slowly.
Major “huh?”:
- The chocobo theme now has lyrics?
I had reached my limit of the bad. I was surprised by Disc 2 and felt energized by its story, finally giving the adrenaline to the story which it much needed. My limit had been surpassed, but good things came from it after all.
In-depth
Beginning at about 8 game hours, I was left the with the distinct impression that a 24-hour game length was going to be pitiful, assuming the next two discs were about the same length. Unlike several other Final Fantasy titles, XIII is ruthlessly linear, and so one cannot too quickly chalk game length up to the inter-disc common content they’ve got to store to play the game. Each disc’s areas are unique to that disc. I would venture a guess that disc 2 had more CG than the first.
I was happy however to discover that by the time it asked me to put in Disc 3 (which I was heavily anticipating, giving the game events), I had put in a total of 24 hours game time (inclusive of the first disc). This second disc had far fewer flashback moments to explain the pre-game 13 days, instead containing far more battle time.
An enormous amount of tension and frustration builds in the gamer as you experience the first disc and the beginnings of the second. This can be seen clearly in my shared thoughts about the former. The primary cause is lack of actual story events. The game wants to start off fast-paced, but it sets an ill precedent for the pace thereafter. Somehow VII pulled off a similarly paced intro with fewer problems in the immediate game hours afterward. The biggest issue as I played seemed to be that no two map areas seemed connected, because each time a splintered party duo would reach some area event, story focus would switch to another party who was now miraculously in another game area without really allowing you to see how they got there. This built a mounting annoying sense of the game taking control away from you. A companion plague was that none of the characters had any concrete reason for heading in their chosen directions. Each miniature group was either mindlessly running away or mindlessly meandering into the heart of Eden, Cocoon’s capital city, for no extremely good reason other than blind “rage” (for that’s that the Datalog entries keep referring to, although the character emotions didn’t perfectly match the description).
Snow’s predicament of being captured by the group Fang fronts turns out to be uneventful enough that the game only tosses you two brief scenes of Snow on board an aircraft as a prisoner, doing us the quick courtesy of introducing the ever-present Cid character. (The Cid role seems to be getting more diminished as Square goes forward.)
The primary story told at the start of Disc 2 is that of Lightning and Hope, who are reinforcing each others’ desires to be stupidly mad at relatively simple problems, yet refuse to actually face those problems. Hope is the primary troublemaker, as he becomes more and more determined to hurt Snow. Lightning begins to cool off as she realizes that she’s indoctrinating him with a desire to fight, fight, fight.
After a time, the story starts to (finally) accelerate as the depressed duo make it into the city in which Hope lives, a checkpoint area in their quest to kill stuff. Snow and Fang join up and the game immediately shakes up your party configurations (thank the heavens!).
At that point, despite some drawn out streets saturated with enemies, the game truly hits its intended speed, proving to be both emotionally charged and inspirationally difficult. There’s nothing like stepping out of a bombed house only to literally be fighting a massive strikecraft which you are meant to actually defeat. If you ask me, it’s always a good sign of a game’s game-face when they make you wonder if you’re actually supposed to lose or not.
One of the (few) problems with Disc 2 is that you are taunted with the fact that this game does not actually allow you to interact with the world. At all. Vanille and Sazh are in the middle of a Golden Saucer of sorts and you cannot interact with anything. To liven things up, it gives you a minigame of chasing Sazh’s Chocobo chick around, as it excitedly flies around the fully grown Chocobos in the small grassy areas of the city. A nice effort by the programmers, but it is a little weak in comparison to what one might have expected from the City of Dreams. God knows I want to chase Chocobo chicks around in grassy areas. Luckily they use Vanille’s internal conflicts to reveal new information here and there.
In order to get Sazh and Vanille reunited with the Lightning’s powwow, the games puts some pressure on the duo to drive some intriguing events that finally made me overcome my annoyance with their slow-moving story arch.
Balance in the Force
It was not until 22 hours into the game did it finally allow me to pick my own party leader and arrange my characters according to my heart’s desire. No sooner than I did so was I absolutely mauled by the battles that awaited. This surprised me, as I had carefully equipped my party with the items I desired them to have. There’s no such thing as an under-leveled character in XIII, so there was no excuse for failure. Just the same, I died twice within 10 minutes of game play. I decided to put my party back the way it was before the game let me change it, and I begin (slowly) conquering again. Stopping to think, I had to give a moment of silence for the SquareEnix guys who arranged the skills of the characters and balanced the parties in the story so delicately. Never in the game had I been hopelessly overwhelmed until the moment it trusted me to make my own party. As I made this realization, I became confident in my situation as the player. The game had thrown me a curve ball and I adapted to it.
Money is Everything
XIII leaves you with a hopeless amount of Gil for most of the game. Never does an enemy drop money like candy. This leaves the player in an awkward state of mind that they aren’t supposed to be buying anything, especially when Phoenix Downs are on the market for 1000 Gil, and your total stash is only barely double that. You spend a few game hours aboard an enemy airship on Disc 2, and a peek at your inventory by the end of it reveals the master plan for money in XIII: Credits. Credits are simple items dropped by military enemies in the game. They come in at least two flavors, one selling on the market for 2500, the other selling for 5000. Selling your entire stash of credits near the end of this airship area yields about 60,000 Gil, assuming you’ve been fighting most of the enemies you encounter (which are oddly simple to penetrate by running straight through the middle of them).
What else does a l’Cie do with 75,000 Gil but immediately go buying nuts and bolts for weaponry upgrades?
I had only dabbled in weapon and accessory upgrades until I realized how much money I had. The trouble with weapon upgrades previous to holding nearly 100k of Gil is that you can’t actually make any useful progress on accessories, let alone weapons. You hold lots of components for such upgrades, but most of them aren’t worth much, and they certainly don’t make a massive difference in the majority of cases. But once I had almost a dozen Perfect Conductors (better than other such conductors, such as the “super” variety) and 75,000 Gil, the waiting game was over. Within moments, I had Lightning and Fang’s weapons upgraded to give about +100 strength each. Considering those weapons start as +30 strength weapons, the difference is obvious once you’ve staggered an enemy. The entire purpose of the currency in this game is to upgrade your weapons, not buy new ones. The money converts directly to expensive upgrading components.
Final Fantasy XII started down this track of making enemies give you useless items which you could sell at shops for petty amounts of Gil. Eventually, you’d build up enough random items to actually mean something monetarily, but until then, your inventory was just plastered with items that may as well have remained nameless, for nobody could care less about the specific item. It was only about how much it sold for. XIII finally breathes some live into this issue by making components upgrade weapons, and forcing your R&D funds to come from your sold Credit Chips. This makes items useful, money meaningful, and your Inventory menu very tidy. All components are kept separate from your consumables. The latter is the list that appears in battle when you want to use an item. Rather than stupidly showing you skins and furs that you might want to throw at an enemy, XIII is conservative enough about items that your battle list is only 3-4 items long most of the game thus far. I bumped the count up to 5 when I bought some status-removing items (bad, baaaaad Fog status).
No MP == Dependence on Magic
I had seen accessories that I picked up refer to a “Pain” and “Fog” status, but what you don’t understand can’t hurt you. Until it creams you in battle. Fog is basically the “Silence” spell from traditional FF titles. The trouble in XIII is that since no MP costs encumber your battle plans, you’ve trained yourself to expect those Ravagers to support your physical attacks and boost that Chain bonus. When you realize that the Medic is being gravely silent back there, you suddenly notice the icon for this new Fog status, which quite literally cripples the entire character. Changing Paradigms does nothing, since both Hope and Vanille (the two primary Medics) are all-magic Saboteur/Synergist and Ravagers. Not a single useful action can come from the characters to remedy the situation, unless you’ve happened to have unlocked the Esuna spell on one of your other party members.
Let the Bodies Hit the Floor
The most bizarre discovery of higher-level magic is that it typically doesn’t increase the amount of damage the spell does. Aero, for instance, does X damage, and Aeroga does about the same. The critical difference is that 2nd and 3rd level spells are area-of-effect. More important is that the 3rd level spells (or -ga spells in general) tend to throw enemies into the air, giving your party a critical time advantage against your opponents. You realize the implications of this tossed-into-the-air effect once your party spends a good fraction of its time in battle rising into the air and then face-planting, instead of firing spells as intended. XIII invents some new status effects (positive and negative) to help and prevent this interruption, and it can frequently make an incredible difference in a boss fight.
Try, Try Again
Early in the game, boss battles meant that you had to try and fail several times before coming out victorious. By the end of this second disc, I had the hang of boss fights, although they still take quite a while. In fact, the Eidolons are typically a bigger challenge than the boss fights, although they end much more quickly, for better or for worse. Each character must conquer his or her Eidolon, their emotional state frequently triggering the fight to claim the power of the Eidolon. This battles usually prove more difficult because one does not actually kill the summon– instead you must perform some type of feat, such as high chain bonuses or defendability. Only after an indicative meter fills as a result of your actions can you end the battle.
The good news is that despite a fairly hard boss fight system, finally having three party members (instead of just two) really does wonders for your ability to multi-task healing and fighting when required.
And now on to Disc 3. Abrupt ending…. not quite sure what on earth happened, but the ship just disappeared into the wall of a busy sky scraper. But I can tell it’ll be good.
Stardock & Impulse: Day of Power is Waning
Apr/100
The idea of the Impulse gaming platform, strictly as an idea, is a great thing. The problems? To name a few of the headlining issues, the platform lacks just about every perk of the Steam platform such as achievements, friends, cross-game chat, on the fly game invitations to others wishing to join in your multiplayer session. The difference is stark: Impulse is a simple immature me-too idea, executed rather poorly, even given the company’s rather successful past.
The powering company Stardock has sadly crashed and is not so dramatically about slide off the edge of hope. There was once a day when Windows XP lacked the beauty and flexibility that we nerds wanted from it, and Stardock products such as Windowblinds, LogonStudio, ObjectDock and CursorFX (and numerous other interesting programs) were worth their memory footprint. But these days, Windows has cleaned up its visual appearance, and we find that the Stardock products simply aren’t required for those of us who only ever wanted an attractive UI. Windows is good enough as is. The UI has matured to something acceptable.
Not so long ago I had an urge to use Windowblinds, so I actually made the purchase at $20. I quickly regretted the decision as I found dozens of technical quirks which render the program intolerable on Windows 7. Much of the blame can be allocated to the immature gaudiness of the skins available, or at least the fact that the good skins were designed five years ago for Windows XP. And this seems to be the beat Stardock is struggling to march to: selling yesterday’s mediocrity at today’s prices. They’ve worked hard to make their software integrate more seamlessly with Windows 7, but dozens of UI elements are neglected and the overall magical effect of Windowblinds is lost. Despite a large effort on the part of their software team, the result is sub-par.
The fact is that Impulse, the relatively new command center for Stardock products new and old, is clearly not the winning choice of platform. I find the tale of Windowblinds to be a good description of how the whole Stardock experience is presented. Games like Supreme Commander are now getting their sequels published on Steam. There are too many benefits in Steam to pass up, especially if the game intends to incorporate a good online experience. Steam’s new UI beta really brings your impression of the platform up to modern expectations. Their effort to be the exclusively cross-platform client seems to be breathing new life into the program. Steam was just as ugly as the rest of poorly executed ideas out there, and it had the usability to match. Now that change is in the air, I expect that I will use it more and more in the coming months.
I don’t feel obligated to make a bullet-point list of what I find irritating about Stardock products, so let it suffice to say that the company as a whole has lost their audience. The skins on their sites are all clumsy and childish, their games don’t integrate players into a common community, and sadly the best content on the platform is the Stardock-supplied skins and games. Everything else is just noise. They need to get over their old products and either remake them with better standards in mind, or find something less ephemeral to skin.
No man can serve two masters
I serve Steam. If you’re skeptical, buy a good multiplayer game with your friends, and buy the Orange Box to kickstart your library of titles. You will soon see why Steam will soon win this silent war.
“Don’t Go Breaking My Heart”: The Epicenter of Bad Music Ideals
Apr/100
Elton John is a crazy case. On the one hand, he’s got brilliant tunes that even I can appreciate (like Benny and the Jets, which is a masterpiece of piano rhythm accompanied by interesting vocal ideas), yet you mix him with another artist and the radio begins puking “Don’t Go Breaking My Heart.” I hear this song day in and day out on the local radio, and I’m positive it carries all of the diseases so characteristic of music from the 60’s and 70’s (which unfortunately haunts certain of the musical styles of today).
Verse == Chorus
A flagship issue with songs such as the specimen at hand is that the words from the chorus and the words from the verses are primarily identical in content. Sure, we switch up “my” and “your” in the phraseology, but it’s the same bloody line. A chorus is only delimited by a switch to another melody line.
Singular idea, 4:28 of improvised nonsense
Yeah! We’ve got an idea for a song, where the key line is “don’t go breakin my heart”, and let’s write a chorus around that. And then let’s write the verses around that one line. … No, no, I’m sure it’ll be a hit. … It needs more work? What? This’ll sell instantly! The crowd wants “catchy” and “flashy,” right? I’m pretty sure they only want that one line anyway. I mean, it’s good, isn’t it? … You worry about the music, I’ll figure out some backup voices, and BAM, we’ll have a hit.
I hope I’m not the only one who can see why music from certain artists is so shallow. I’m not looking for a ballad on each and every track, but I find it worrisome that popular music is characterized by a big budget compensating for a lack of effort to write more than 5 contiguous words that get stamped here and there.
At least the rappers understand the notion of adrenaline in their music, even if it fits this same paradigm.
Start strong, make ‘em forget what “musical build” feels like
I’m really glad that humanity invented the “bridge” concept, where a (typically) second chorus gets followed by some climax of melody and vocals, really nailing the feeling of the song. It makes the rest of the song worth it, even if “the rest” is less exciting material.
Other examples could fit this model better than “Don’t Go Breaking My Heart” (such as ABBA’s “Dancing Queen”), but one can’t deny the utter lack of journey in these songs. A dearth of variance is left in the wake of the remaining 4 minutes after the introduction to the song. Starting off with a chorus is a dangerous business, because the chorus is the intentionally repetitive catchy part. By kicking things off with your best part, you’ve hopelessly dashed to pieces the expectant feeling of musical build. If you listen to the song while quietly sitting at your table, you’ll find yourself thinking, “wow, it’s still not over? This is repetitive stuff.”
It’s only in a dance club, or a party or other rave-like experience in your car do you not actually pay attention to the whole song. You therefore are more forgiving, because all you heard were the memorable parts anyway.
Maybe I’m just crazy, but my appreciation for music is a bit more deeply rooted than just craving a redundant melody with the same song slogan over and over again. I understand the human need for latching onto familiar sounds, like you’ve found footing in the song, but I tend to ask for a bit more than just temporary footing.
I’d have shot myself of insanity had I written and practiced “Don’t Go Breaking My Heart” every day before recording. I really would have ended it all. I therefore conclude that musicians are by definition more resistant to the anxiety of singing redundant tunes, since they practice each song many more times than you’ve ever listened to them. It’s too bad that more musicians can’t find their way back from being lost in that ocean.
