My cousin Judy is visiting from London. She had a flght from Heathrow to Newark, but given today's awful weather, she was redirected to Albany, about three hours from Newark by car. Because Albany's airport isn't prepared to handle immigration, she could not disembark.
After over three hours on the ground, the flight finally left for Newark.
when to made several rotations around an arbitrary area
then redirected to Boston.
This is not Judy's day.
Wednesday, July 29, 2009
Monday, July 27, 2009
The kind of customer service I like
Kudos to Telestream, authors of ScreenFlow. This is the kind of customer service I admire.
When all too often I hear nothing about bug reports, here's someone just letting me know my request hasn't been forgotten.
Thanks, Willow.
When all too often I hear nothing about bug reports, here's someone just letting me know my request hasn't been forgotten.
Thanks, Willow.
Monday, July 20, 2009
How not to empower your users; don't let them use their primary email address.
Awesome.
PSE&G only allows you to set up one customer service account per email address. So, if you live on one property in their service area, and then move to another property in their service area, you must register a new account with a brand new email address.
I'm genuinely still a little shocked. No matter how hard I tried, I could not find a way to either add a second account or remove the first one to my email address. I messed with pseg.com for 15 minutes, so I called them for help. After 20 minutes on hold, I asked how to change the account. The customer service representative told me, no, I couldn't do that, I had to create a new account. Being hasty, I thanked the CSR and ended the call, assuming he was just wrong.
Registering a second account with the same address failed. Registering a second account with email+pseg@domain.com also failed, not because it was a duplicate but because PSE&G considers that an invalid email address. Honestly, not much of a surprise, that.
So I called again. Was it really like that? After another 20-minute hold (whoo, these guys are popular) I confirmed with a second CSR that, yes, really, it was like that. She said I should just "create another email at like yahoo mail." The CSR agreed to lodge my complaint and I rung off for the second time.
I have one email address upon which I rely, the destination of all my important personal correspondence. Why should PSE&G email have to be delivered elsewhere? I could create a second account whose purpose is merely to forward all mail to the primary one. I refuse to have to remember a new email account just to pay my electric bill. I'm still hoping that one day all my accounts can be registered through OpenID, so this is somewhat the opposite of that goal.
Perhaps people are so dissatisfied with PSE&G that they vow to move out of their service area before ever using them again?
This is a bug, plain and simple. Most likely a bug in requirements or design. And it got me thinking: what different developement phases might have created such a problem?
In my many years working in the pharma consulting industry, there was a common phrase for difficult non non-negotiable tasks: Phase 2. Could this just have been considered a Phase 2 project, complete with database normalization redesign?
Could be. After all, this consumer site is just over 100 days-old.
Sunburst2!
PSE&G only allows you to set up one customer service account per email address. So, if you live on one property in their service area, and then move to another property in their service area, you must register a new account with a brand new email address.
I'm genuinely still a little shocked. No matter how hard I tried, I could not find a way to either add a second account or remove the first one to my email address. I messed with pseg.com for 15 minutes, so I called them for help. After 20 minutes on hold, I asked how to change the account. The customer service representative told me, no, I couldn't do that, I had to create a new account. Being hasty, I thanked the CSR and ended the call, assuming he was just wrong.
Registering a second account with the same address failed. Registering a second account with email+pseg@domain.com also failed, not because it was a duplicate but because PSE&G considers that an invalid email address. Honestly, not much of a surprise, that.
So I called again. Was it really like that? After another 20-minute hold (whoo, these guys are popular) I confirmed with a second CSR that, yes, really, it was like that. She said I should just "create another email at like yahoo mail." The CSR agreed to lodge my complaint and I rung off for the second time.
I have one email address upon which I rely, the destination of all my important personal correspondence. Why should PSE&G email have to be delivered elsewhere? I could create a second account whose purpose is merely to forward all mail to the primary one. I refuse to have to remember a new email account just to pay my electric bill. I'm still hoping that one day all my accounts can be registered through OpenID, so this is somewhat the opposite of that goal.
Perhaps people are so dissatisfied with PSE&G that they vow to move out of their service area before ever using them again?
This is a bug, plain and simple. Most likely a bug in requirements or design. And it got me thinking: what different developement phases might have created such a problem?
- Requirements gathering phase: perhaps nobody mentioned this as a possibility. Better still, someone mentioned it as a very rare occurrence.
- Design phase: maybe this was an intentional design decision. Maybe they don't particularly care about account history as a person moves between properties.
- Database design: assuming a SQL database back-end, perhaps the whole product is wrapped around a database that has a single table called ACCOUNT with columns email_address and account_id. perhaps they can get a lesson in Third Normal Form.
- User acceptance testing: perhaps no managers or testers had recently moved within the PSE&G service area, if at all.
- Middle-tier design: first thing I'd do is grep for function createaccount($emailaddress, $accountid)
- Contract negotiations: The back-end support team has a charging structure based on the number of accounts.
- UI design: I ... can't really find a way that UI design gets in the way. Here's the registration form. Maybe you can see something.
In my many years working in the pharma consulting industry, there was a common phrase for difficult non non-negotiable tasks: Phase 2. Could this just have been considered a Phase 2 project, complete with database normalization redesign?
Could be. After all, this consumer site is just over 100 days-old.
Sunburst2!
Friday, July 03, 2009
Generic types are not required for covariance
Java 5.0 introduced Generics. It also introduced covariant return types. Wikipedia does a fine job describing covariant return types.
Since they were released simultaneously, I consider them to be tightly coupled. For instance, here are simplified versions of an interface and implementation I recently wrote:
Note: I am having difficulty representing greater-than and less-than symbols in Blogger's editor, so you'll have to do with { and }.
Version 1: Java 5, Generics, Covariant return types
With Java 1.4, the code would have to look like this
Version 2: Java 1.4
Version 3: Java 5, Covariant return types
Thanks to David Plass for pointing this out.
Since they were released simultaneously, I consider them to be tightly coupled. For instance, here are simplified versions of an interface and implementation I recently wrote:
Note: I am having difficulty representing greater-than and less-than symbols in Blogger's editor, so you'll have to do with { and }.
Version 1: Java 5, Generics, Covariant return types
public interface Model{T extends Model{T}} {
T read(InputStream in);
T write(OutputStream out);
}
public class MyModel implements Model{MyModel}Thanks to the covariance, I can write a method chain like this:{
public MyModel read(InputStream in) {
...
}
public MyModel write(OutputStream out) {
...
}
public MyModel setName(String name) {
...
return this;
}
public String getName() { ... }
}
new MyModel()
.read(in)
.setName("foo")
.setStopAtMain(false)
...
.write(out);
With Java 1.4, the code would have to look like this
Version 2: Java 1.4
public interface Model {And the method chain would result in a syntax error:
Model read(InputStream in);
Model write(OutputStream out);
}
class MyModel implements Model {
public Model read(InputStream in) { ... }
public Model write(OutputStream out) { ... }
...
}
public static void foo() {Which you could hack around with an ugly cast:
new MyModel()
.read(in)
.setName("foo")
^ The method setName(String) is undefined
for the type Model.
.write(out);
}
public static void foo() {Back to the Java 5 example: My point is just this: covariant return types don't require generics. All that messy code in version 1 could look much simpler because covariant return types exist on their own without generics:
((MyModel) new MyModel()
.read(in))
.setName("foo")
.write(out);
}
Version 3: Java 5, Covariant return types
public interface Model{{T extends Model{T}}
TModel read(InputStream in);
TModel write(OutputStream out);
}
public class MyModel implements ModelLesson learned: I know generics fairly well, but there's a difference between knowing when it's useful and when it isn't. Said another way: when you have a Generic hammer everything looks like a generic nail.{{MyModel}
public MyModel read(InputStream in) {
...
}
public MyModel write(OutputStream out) {
...
}
public MyModel setName(String name) {
...
return this;
}
public String getName() { ... }
}
Thanks to David Plass for pointing this out.
Subscribe to:
Posts (Atom)