(…) Gore has been a team-based, flat lattice organization that fosters personal initiative. There are no traditional organizational charts, no chains of command, nor predetermined channels of communication. Instead, we communicate directly with each other and are accountable to fellow members of our multi-disciplined teams. We encourage hands-on innovation, involving those closest to a project in decision making. Teams organize around opportunities and leaders emerge.
Tag Archives: Quality
Best books of 2008
You might remember my beloved mantras: learning a new programming language and reading at least 6 relevant books every year. Following the 2007 edition, here’s the list of the 8 books I have enjoyed most in 2008, ordered by a purely subjective and absolutely irrational decreasing preference. I strongly recommend all of them!
Winner: Geekonomics: The Real Cost of Insecure Software by David Rice
Runner-up: The No Asshole Rule: Building a Civilized Workplace and Surviving One That Isn’t by Robert I. Sutton, PhD
And 6 more:
- Software Estimation: Demystifying the Black Art by Steve McConnell
- Modern C++ Design: Generic Programming and Design Patterns Applied by Andrei Alexandrescu
- It’s Not How Good You Are, It’s How Good You Want to Be by Paul Arden
- RESTful Web Services by Leonard Richardson and Sam Ruby
- JavaScript: The Good Parts by Douglas Crockford
- Programming Collective Intelligence: Building Smart Web 2.0 Applications by Toby Segaran
The Dirty Little Secret of iPhone Development
This is happening right now, at a web agency near you.
The dot-com boom of the 90′s spawned a brand new generation of coders and software developers, including me, by the way. While before that time the term of “software developer” might have been reserved to system programmers fluent in C, COBOL, C++ or other languages, right now the vast majority of developers I know spend their time writing web applications, either public or in a private intranet, in J2EE, ASP.NET, Rails, PHP, you name it.
I have said before that writing web applications should be taken as seriously as writing desktop systems. Call me names if you want, but I’m a big fan of Joel’s Test.
However, after all this years, after the Chaos reports, after Peopleware, after the Mythical Man Month, people still treat quality as an afterthought. And also complain about how much software sucks, how expensive it is, and how late it arrives, by the way. Now that the iPhone SDK is widely available, that the App Store is selling more apps that we could have had imagined 6 months ago, many web agencies want to jump to native iPhone development contracts, which are hype and nice and pricey and whatnot. Which is only going to make things worse.
The dirty little secret in this story is this: iPhone development looks more like developing applications for a desktop operating system, and less, much less than web development. And I’m frightened to see some small shops (and even bigger ones), who never attained a real level of professionalism or quality in their software tasks, starting projects and realizing, later, when they are over budget and behind schedule, that this kind of applications requires a different mindset.
Saving a Failing Project
In 2006 I had the opportunity to work as a “project leader” into a small failing project. Three developers were working in an ad hoc basis, creating a software application for an important client (a government office in Lausanne), without any kind of detailed formal specification, without any kind of design documentation, and with strong pressure from the management to release the application, even if not in an usable state. Needless to say, the project was also beyond budget.
I had just joined this company a couple of days ago, and the management asked me to take the project in charge. Not an easy task, particularly because it was my first experience of this kind. Continue reading
Quick spec from your Python tests
Using Python’s own unittest package, here’s a small script that can iterate over your test suite to output a small, quick, nice list of the tests in your application:
[source:python] import unittest
loader = unittest.TestLoader() tests = loader.loadTestsFromName(‘path.to.your.tests.package’) for test in tests.tests: print test._tests[0].class.name.replace(“Test”, “”) for method in test._tests: print ” %s” % method._testMethodName.replace(“test“, “”).capitalize().replace(“_”, ” “) [/source]
This would yield something like this: Business
Accounts have at least one entry
Clerks cannot close accounts
Security
Users can create new accounts
Anonymous users cannot access private areas
...
Of course, you’ll get better results if you follow Google’s naming conventions for your tests… ;) This is not rspec (nor an alternative to it) but it might be useful to some of you.
Just as a reminder for Django users: you might need to
setenv DJANGO_SETTINGS_MODULE application.settings
or
export DJANGO_SETTINGS_MODULE=application.settings
in order to make the script work properly! At least I had to :)
REST + HTTP (Basic + Digest) Authentication support for Django’s test Client class
Django has a nice support for unit and functional testing; however, its django.test.client.Client class does not support PUT and DELETE requests, which might be useful if, like me, you’re doing some kind of REST implementation using that framework. There’s an open ticket about it, but for the time being, here’s my wrapper that supports those methods as well as GET and POST:
[source:python] from cStringIO import StringIO from django.test.client import Client as DjangoClient, encode_multipart from django.utils.http import urlencode import base64 import md5
class Client(DjangoClient): “”" Wrapper and drop-in replacement around Django’s own test “Client” class, providing PUT, DELETE and OPTIONS support, as well as HTTP Basic + Digest Authentication support. NOTE: the django.test.client.Client does not directly support PUT, DELETE or OPTIONS requests so we’re using the “request()” method directly… there’s an open ticket about it: http://code.djangoproject.com/ticket/5888 “”"
auth = { }
def http_basic_login(self, username, password):
base64string = base64.encodestring('%s:%s' % (username, password))[:-1]
self.auth = { "HTTP_AUTHORIZATION": "Basic %s" % base64string }
def http_digest_login(self, method, url, params, response, username, password):
(authmeth, auth) = response['WWW-Authenticate'].split(" ", 1)
if authmeth.lower() != 'digest':
return
amap = {}
for itm in auth.split(", "):
(k, v) = [s.strip() for s in itm.split("=", 1)]
amap[k] = v.replace('"', '')
try:
realm = amap['realm']
qop = amap.get('qop', '')
nonce = amap['nonce']
opaque = amap['opaque']
except:
return
cnonce = "01b6730aae57c007"
nc = "00000001"
query_string = "&".join(["=".join(item) for item in zip(params.keys(), params.values())])
uri = url + "?" + query_string
ha1 = md5.md5('%s:%s:%s' % (username, realm, password)).hexdigest()
ha2 = md5.md5('%s:%s' % (method, uri)).hexdigest()
if qop:
chk = "%s:%s:%s:%s:%s:%s" % (ha1, nonce, nc, cnonce, qop, ha2)
else:
chk = "%s:%s:%s" % (ha1, nonce, ha2)
response = md5.md5(chk).hexdigest()
self.auth = {
"HTTP_AUTHORIZATION": 'Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s", opaque="%s", qop=auth, nc=%s, cnonce="%s"' % (username, realm, nonce, uri, response, opaque, nc, cnonce),
}
def http_logout(self):
self.auth = {}
def pre_request(self, url, data):
r = {
'CONTENT_LENGTH': None,
'CONTENT_TYPE': 'text/html; charset=utf-8',
"HTTP_USER_AGENT": "Django Unit Test HTTP Client",
'PATH_INFO': url,
'QUERY_STRING': urlencode(data, doseq=True),
}
r.update(self.auth)
return r
def get(self, url, data, **extra):
r = {}
r.update(extra)
r.update(self.auth)
return DjangoClient.get(self, url, data, **r)
def post(self, url, data, **extra):
r = {}
r.update(extra)
r.update(self.auth)
return DjangoClient.post(self, url, data, **r)
def delete(self, url, data):
r = self.pre_request(url, data)
r["REQUEST_METHOD"] = "DELETE"
return self.request(**r)
def options(self, url, data):
r = self.pre_request(url, data)
r["REQUEST_METHOD"] = "OPTIONS"
return self.request(**r)
def put(self, url, data, form):
BOUNDARY = 'BoUnDaRyStRiNg'
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
encoded = encode_multipart(BOUNDARY, form)
r = self.pre_request(url, data)
r.update({
'CONTENT_LENGTH': len(encoded),
'CONTENT_TYPE': MULTIPART_CONTENT,
'REQUEST_METHOD': 'PUT',
'wsgi.input': StringIO(encoded),
})
return self.request(**r)
def hello(self, url, data, **extra):
"""Sends a fake 'HELLO' request which returns a 405 answer :)"""
r = self.pre_request(url, data)
r["REQUEST_METHOD"] = "HELLO"
r.update(extra)
return self.request(**r)
[/source]
Hope it helps! Of course you could extend this to support OPTIONS, HEAD or other HTTP methods you could find in the specification.
Update, 2008-03-05: Following Yoan’s comment below, I’ve DRYed the code a bit. Neat.
Update, 2008-03-11: I’ve added HTTP Basic Authentication support to the class (and changed the post title accordingly).
Update, 2008-03-13: Another modification: now the client supports HTTP Digest Authentication (Yay! To use it, make a first call to your server and then pass the response as a parameter to the http_digest_login method), plus support for the OPTIONS verb, plus another method which sends a method with a “HELLO” verb, which of course does not exist… and which will (normally) return a 405 response!
Another category for this blog
Those who read my blog know that I tend to write about software quality issues fairly often; particularly about open spaces and my aversion against them :)
I thought it was time to group all those entries into a WordPress category of its own: “Quality”. Feel free to check the articles in there, and of course, to leave any comments that you want.
Total Quality Management and Software
Introduction
Total Quality Management is one of the founding pillars of modern mass-production economy, of which the software industry is by far the youngest (and most rebel) child. This article will provide a short discussion on some TQM principles and about their applicability to software projects. Continue reading
Factors for Software Project Quality
Introduction
I strongly consider that the following three items are of high relevance for software project quality:
- Developer workplace conditions
- Tracking data of past projects
- Management commitment to quality
In this article I will give an overview of them, providing some personal experience about each. Continue reading
A Simple Recipe for Podcast Success
I am subscribed to quite a few podcasts and screencasts here and there. And I’ve come up with a very basic (albeit limited and you could even say irrational) way of determining which to keep listening and which to throw away immediately:
The quality of the material… and the voice of the speaker.
I’m not Pavarotti nor Alfredo Caruso, but some voices just irritate me. I just experienced this through the Heroku screencasts; the guy’s voice is not really nice (at all), kind of creepy even, hard to follow, I don’t know how to describe it. It is annoying to follow a 10-minute presentation like this; really, I’m sorry, but that’s how I felt it, even if his service seems really interesting and I might even try it in the future.
Compare now with Ryan Bates of Railscasts: his voice is adapted, serious yet young, with the right pitch and speed. It makes following the explanations easy, moreover taking into account that I’m not a native English speaker. The Railscasts are a perfect example of what I like in podcasts and screencasts: short descriptions (15 min max) of extremely useful features, with practical uses and with some background as well to get the idea. The site (and Ryan) is absolutely brilliant.
As I said, is a purely subjective point of view, but that’s (one) of the criteria I use to decide whether to keep listening to a podcast / screencast or not. The other being the contents, of course; throw in a nice voice spitting nonsense and you won’t have much better luck than the Heroku guy.
The notable exception to this rule must be obviously David Heinemeier Hansson; his first videos showing how to do a weblog in Rails in 15 minutes are just insane; the guy’s voice is really awful, too highly pitched and somehow disturbing. But the stuff he showed was great, and I stuck with that instead :)