Today I turned my XBox 360 on for the first time in three weeks and was greeted by the telltale sign that your 360 has bit the dust: The dreaded Red Ring Of Death!
I got the refurbished unit back in 10 days. details in the full article
My first experience with craigslist this week was a good one. In case you’re not up on the latest trends, craigslist is an online classified advertisement site where it is free to post a classified ad. Its one of the big reasons that the classified section in your newspaper keeps getting smaller and smaller. Anyway, I was trying to sell a fridge. I put the ad up, and not 5 hours later I got a reply from a buyer. He picked up the fridge and paid in cash the same day!
So in case you’re keeping score: Craigslist – 1, Mass-emailing your family – 0
Previous to my new job it had been a long time since I did any programming in asp. That would have been around 2003 when working on the Augustana College marketing club webapp. I was soured on it then, convinced that PHP was the superior language. To be fair, asp.net is more of a set of tools for creating a webapp (since you can use any .net language you want), where as classic asp was really its own language.
Lots of things have changed since then and I’m finding myself enjoying building apps in asp.net as opposed to PHP or Java. I will still maintain that Java lends itself better to large, scalable webapps because of ejb and its built-in transaction handling. However, if your goal is to make a complex UI and make it quickly, I’d lean towards asp.net
My website has been down for the last 2+ days. The reason: Dreamhost upgraded to Rails 2.0 without any warning. Since some of my code was not 2.0 compliant – BAM! down goes my site.
In case I can help anyone else out of a bind, or avoid this horrible fate, here are the steps I had to take to get my website back up and running with Rails 2.0:
Add a config.actioncontroller.session entry to my environments.rb file. I added it within the Rails::Initializer block. This was in response to the following error I found in my production.log file: A secret is required to generate an integrity hash for cookie session data. Use config.action_controller.session = { :session_key => “_myapp_session”, :secret => “some secret phrase of at least 30 characters” } in config/environment.rb
Luckily the error tells you exactly what to do
Next, I had to fix this error: undefined method ‘paginate’
I fixed it by installing the plugin ‘classic_pagination’. To do this you simply have to run
“script/plugin install svn://errtheblog.com/svn/plugins/classic_pagination” from your project root.
Apparently they took out built-in pagination support from Rails 2.0. This will_paginate plugin is supposed to be better, but I didn’t care to figure out how to work it right now.
Finally, I had to fix all of my start_form_tag entries.
This is the second part of a two-part article. I was recently laid off from Nuance Communications. This is the story of what I did at Nuance and why I was laid off. Part 1 was the “why I was laid off”. This part two is about my part on the ill-fated FX project.
The FX team was very diverse and we made heavy use of offshoring/outsourcing. There were five full time developers(including myself) and the project manager, John Vasicek, in Chicago. We had around 12 people in the Ukraine, 10 in India, and 15+ in Hungary. The project was being managed and driven out of Chicago. We had status calls every morning at 8am CST, which was around 5pm in Hungary, 6pm in the Ukraine, and 8pm in India. A team leader from each of the Hungary, Ukraine, and India teams was always present, as well as all of the Chicago developers. Communication was a real problem at times. The project manager required that all offshore developers know English, but just because someone understands English doesn’t mean you can carry on an effective verbal conversation with them. Instant messengers were used a lot, and whenever we simply couldn’t understand someone over the phone we would have them email or IM us what they were trying to say. We also made use of Adobe Connect, which allowed an offshore developer to demo a feature to us before delivering it by sharing their desktop over the internet.
As I got more involved in the project, my role shifted from developer to that of a coordinator, communicator, designer, and reviewer. This goes for every one of the Chicago developers – We had to know how the application worked, but our main responsibility was to make sure that the offshore developers could do their job effectively. The design & development process for a feature would often go like this:
The feature is requested by Product Management. Detailed requirements are written.
A Chicago developer (like myself) would create high level requirements on how this feature should be implemented. We would specify things like what tables, columns, or classes should be created, and any design hints on how data should flow through the system.
An offshore developer would create a detailed design using Enterprise Architect.
The design would get reviewed the Chicago developer.
An offshore developer would be asked to implement the design.
The completed feature would be demoed and delivered (or sent back for more polishing).
Some Technical Notes: The UI was slick. It was all web 2.0 and ajaxy. It was also the most difficult part of the application to create. technical content alert It was decided early in the project that we would use our own AJAX framework. Client page would request data from the server, which was returned in proprietary XML formats representing different data structures. These XML formats were designed and documented for every server interface. Data from the server would get displayed in the UI through a complicated data-binding mechanism. I never did quite understand how the data-binding worked; All I know is that it made heavy use of XSLT, which I couldn’t read. I recall that we had this one file, named “test1.xsl” that did the majority of the UI generation, and none of the developers in our Chicago office knew how it worked. Text1.xsl was developed by the Hungarians . Here is a good example of a challenge with offshore development – If FX had gone to market and these Hungarians left the project, we would have had a hell of a time working with all of thisXSL. end technical content alert FX Project Timeline From my Perspective
May 2005 – Nuance (then Scansoft) acquires Medremote Inc.
Feb 2006 – Nuance acquires Dictaphone
Later 2006 – DragonMT 8.0 is cancelled. Nuance stops selling DragonMT.
April 2007 – “FX” project is approved and is to be based on DragonMT architecture. RTMscheduled for end of 2007.
May 2007 – FX Engineering Kick-Off meetings
July 2007 – FX 1.0.2 “i2” delivered to QA
December 24, 2007 – FX 1.0.4 “i4” delivered to QA. RTM scheduled for June 2008.
April 8, 2008 – Nuance Announces E-Scription Acquisition. Internal communication makes clear that FX will be cancelled pending merger approval by the SEC (This day sucked. coincidentally I also had jury duty that same week)
May 21, 2008 – Nuance-Escription merger closes
May 23, 2008 – My last day of employment with Nuance
May 27, 2008 – My first day of employment with Geneca
Some concluding thoughts: For the last year I’ve invested a lot into the FX project, and I was really devastated when it was canceled. That being said, I’ve wasted no time finding new employment as I started with Geneca, a consulting company, this week. I owe a lot to my managers at Nuance for all of the opportunities I was given. I like to think that I’ve gotten better experience in the last 4 years
This is the story of the Dictaphone FX project – of how it almost was, and how it got canceled – from someone very close to the project (me). I have since been released from Nuance and am now working for a company called Geneca. This article is rather lengthy for me and covers several topics. This is part 1, which covers the business perspective, or ‘Why Nuance canceled the project and laid me off’. Part 2 will cover the technical perspective, of ‘What went into FX’.
I will start with the business side. Let me begin by explaining a little about what FX was for, and what Medical Dictation and Transcription is.
At large hospitals (and increasingly at smaller clinics), the facility will create a medical report for every visit you make to the hospital, or for every test done while you are there. Your doctor will make a voice recording of your session, and that recording will get routed via the transcription workflow solution to a Transcriptionist that could be in the next room, or in the Philippians, to get transcribed (The hospital decides the routing). Once transcribed, the report will automatically print out at the hospital and/or get filed into the Hospital’s Electronic Medical Records system (EMR). When speech recognition technology is applied, the document is automatically transcribed and the Transcriptionist becomes an Editor.
Now on with the FX story: “FX” was just a code name. The product had been branded “Dictaphone Powerscribe MDx”, and later re-branded “Dictaphone 360”. This product was to be Dictaphone’s next-generation transcription workflow solution* – the successor to the aging iChart and EXText/EXVoice products. FX addressed all of iChart’s shortcomings, especially in the areas of scalability, reliability, and user-friendliness. It also had a few features which would have made it stand out in the market, including a complex yet intuitive MT & QA job allocation system, support for different QA levels, and a post-release QA grading system.
At the time Nuance announced its intention to aquire EScription, we were 2.5 months away from going to market with FX. The beta was in full swing and the schedule had finally stabilized. Everyone in the Chicago office had been putting extra hours(55+/week) on this project for the better part of a year. I was tired of the long weeks but also excited that the end was in sight. So what happened? Why did Nuance cancel FX? Honestly, I’m still asking myself that question. The information I have says that Escription has an inferior UI, less features, and an inferior architecture to that of FX. However, Escription’s speech recognition component is supposed to be considerably better. This is personally frustrating to me because while the speech team did work with the FX team, they were managed by different people. If speech is such a critical component and ours was obviously inferior to the competitor, why were we not putting more emphasis on improving it? Alternatively, why could FX not gone to market and then improved the speech system? In the end, as I understand it, it all came down to money. Because EScription’s profit margins were so high, Nuance could afford to pay them $460 million and still increase the earnings per share by $.01.
EScription’s profit margins are an area that I think needs a little more attention. The Nuance administration talked about Escription having the best profit margins they had ever seen. The charts I saw showed margins in the 45% range, meaning that they made $.45 on every $1 they charged a customer. The business was designed to create great margins, however. They only had around 10 clients, all of which were large hospitals. As anyone in the industry will tell you, there are higher margins to be had at larger hospitals. I have even heard that EScription would turn down smaller clients that did not fit their business model. The point I’m trying to get at here is that these profit margins will not be sustainable as the EScription product takes on more and more customers.
See part 2 of this article for the technical perspective of the ill-fated Nuance FX project.
have implemented AJAX style comments system. If you click on the ‘Add Comment’ button below you can see it. The difference is that now you are presented with a comments form appears within the existing page instead of a comments form being on a new page, as was the previous behavior. This is AJAX, and it is the technology that people are calling Web 2.0.
What’s the big deal you ask? By having the ability to only update parts of a web page instead of updating the whole page every time you invoke some function, it makes the browser act more like a desktop application than a web page. The end result is more robust applications served over the web. Think google maps or facebook.
I have created a linkedin profile. At first I thought linkedin was going to be a facebook or myspace ripoff, but I see now that it’s really a great tool for professional networking. In fact, given that I’m studying business administration and that I have a passion for web applications, I think that linkedin is pretty awesome. www.linkedin.com/in/johnsonchristopherg
I recently developed a useful ANT task to automatically increment a version number on your Java project when using perforce as your source control application. This task is intended to be run as part of an automated build (via cruisecontrol). It checks out version.properties and checks it back in after incrementing.
Notes:
The task will look for the following files in the same directory as your build.xml. You should be able to figure out what parameters belong in each file by looking at the task. files: version.properties, buildnumber.properties, p4.properties
In the lines where I print the full version number I have broken it up into two lines for display purposes. In practice you will want to keep it on one line.
<target name="create-label" depends="compile-src">
<copy todir="${ant.library.dir}"
file="medremote_dev/tools/jakarta-oro-2.0.8.jar"
overwrite="false"/>
<property name="p4.properties"
value="p4.local.properties" />
<property file="${p4.properties}" />
<property name="p4.port" value="${p4.port}"/>
<property name="p4.client" value="${p4.client}"/>
<property name="p4.user" value="${p4.user}"/>
<!-- must supply password in globalopts when the perforce server uses sessions -->
<property name="p4.globalopts" value="-P ${p4.password}"/>
<property name="p4.path" value="{p4.path}"/>
<echo>p4.path is ${p4.path}</echo>
<!-- sync buildnumber.properties and version.properties for edit -->
<p4sync view="${p4.path}/source/buildnumber.properties"
force="true"
globalopts="${p4.globalopts}"/>
<p4sync view="${p4.path}/source/version.properties"
force="true"
globalopts="${p4.globalopts}"/>
<!-- increment buildnumber.properties -->
<chmod file="buildnumber.properties" perm="ugo+w"/>
<attrib file="buildnumber.properties" readonly="false"/>
<buildnumber file="buildnumber.properties"/>
<tstamp/>
<!-- Updates the version.properties file -->
<property prefix="label" file="version.properties"/>
<property name="new.version.major" value="${label.version.major}"/>
<property name="new.version.minor" value="${label.version.minor}"/>
<property name="new.version.iteration" value="${label.version.iteration}"/>
<property name="new.version.build" value="${build.number}"/>
<property name="new.version.drop" value="${label.version.drop}"/>
<!-- update version.properties -->
<chmod file="version.properties" perm="ugo+w"/>
<attrib file="version.properties" readonly="false"/>
<propertyfile file="version.properties">
<entry key="version.major" value="${new.version.major}"/>
<entry key="version.minor" value="${new.version.minor}"/>
<entry key="version.iteration" value="${new.version.iteration}"/>
<entry key="version.drop" value="${new.version.drop}"/>
<entry key="version.build" value="${new.version.build}"/>
<entry key="version.date" value="${DSTAMP}${TSTAMP}"/>
</propertyfile>
<echo>Creating Label: ${new.version.major}.${new.version.minor}.
${new.version.iteration}.${new.version.build}"</echo>
<p4change description="Increment build number via automatic build"
globalopts="${p4.globalopts}"/>
<!-- open buildnumber.properties and version.properties for edit
(even though we already incremented it)-->
<p4edit view="${p4.path}/source/buildnumber.properties"
change="${p4.change}"
globalopts="${p4.globalopts}"/>
<p4edit view="${p4.path}/source/version.properties"
change="${p4.change}"
globalopts="${p4.globalopts}"/>
<!-- submit properties files to source control after incrementing build -->
<p4submit change="${p4.change}"
globalopts="${p4.globalopts}"/>
<!-- label the project -->
<p4label
name="FX${new.version.major}.${new.version.minor}.
${new.version.iteration}.${new.version.build}"
desc="label created during automatic project build"
view="${p4.path}/..."
globalopts="${p4.globalopts}"/>
</target>