Archive

Archive for the ‘Essays’ Category

Designer Collaboration I: Respecting the PSD

September 4th, 2010 No comments

A few months earlier, while describing the characteristics and virtues of a development team of one, I mentioned how partnership between [aesthetic] design and development is a more than worthwhile exception to that model of going solo.  Now I want to explore how this particular collaboration finds its best execution.

The essence of the developer’s job here is to translate the designers’ design (I refer to this simply as “the PSD”, PhotoShop files being de facto standard for this kind of work) into live, working, spider-able HTML.  In this relationship, assuming the designer is worth their salt, the PSD can be related to as the immutable bible, the defining guide to design for the project.

To begin, it behooves a developer greatly to trust in the importance of implementing the PSD with high, pixel-perfect fidelity.  If this is not taken seriously, a good designer will insist that imperfections in a sloppy HTML implementation be corrected, and for the developer there is to get beyond defensive notions such as “no one will notice” or “it’s just a few pixels of white space”, and resist the temptation to write off the designer as an artsy ego-maniac with nothing better to do than whine about trivial matters to create busy work.

The path to appreciating the designer’s desire for high fidelity lies in appreciating the subtle structure present in the PSD itself.  This is where a designer being worth their salt comes into play: a good one typically imbues their design with numerous uniform rules which manifest in various places and provide a certain visual continuity that makes it look good.  A padding of 8 pixels will crop up again and again, or columns of content will line up horizontally with the menu item boundaries above, or the baseline of several disparate pieces of text will line up vertically to the exact pixel.

These sorts of things are almost never accidental: they reduce the visual entropy of the layout and bring order and balance.  The casual observer probably doesn’t look close enough to recognize this effort, but it registers subconsciously as a more pleasing experience.  Likewise when banging out an HTML implementation, it’s easy for a developer to overlook the unifying visual rules and make each portion of a design look right on its own, yet completely fail to achieve the design-wide continuity.

It’s no wonder that a designer would be remiss to see the carefully crafted aspects of their design (which, incidentally, is probably the rendition that the client approved) either ignored or butchered.  Even if an implementation is arguably 95% correct, it’s that last 5% that separates clumsiness from truly professional design.  Web designers are judged more readily by their websites than their PSD files, so it adds insult to injury when a first-rate design gets a second-rate rendition.

CSS to the Rescue

I used to think that HTML was an inherently finicky medium for presentation, and that differences between browsers and platforms would make any attempt at a uniform, pixel-perfect rendition of a design futile.  It turns out that with sufficient mastery of CSS & HTML one can realize most any design (I’ll cover rules and constraints for designers to play by when I turn the tables in the second part of this series, Respecting the HTML).

A quick aside to put this into context:  There was a time before I fully grokked CSS that I thought to realize, say, a precise 16-pixel spacing between two paragraphs you needed to do something funny like <font size="2"><br /></font> and cross your fingers it was right, or <img src="clear.gif" height="16" width="1">.  Painful and cumbersome, and a nice illustration of why learning CSS should be an alluring endeavor for up and coming web developer.

CSS, it turns out, is brilliantly suited for a developer to capture those subtle-yet-uniform rules of layout and spacing created so meticulously by designers.  I used to think woe is me for having to realize their designs in a clunky, unpredictable environment known as the rendering engines of all popular browsers and their versions.  Now it seems like designers have the tougher lot: they need to perfectly position all of those design elements on a PhotoShop canvas, whereas I can make a few measurements of pixel heights, widths, margins, and so on, write a few corresponding CSS rules, and the browser does my meticulous dirty work for me.

I used to think developers (myself included) were limited by the medium of HTML and browser rendering engines when it came to how close they could get a live web page to look like its original intended design, and that a large collection of imperfections would have to be pardoned.  Mastery of CSS reveals that, for the most part, there is no good excuse anymore when an HTML implementation deviates from the PSD.  If it seems that there is, chances are there’s a CSS guru out there who could make it right.

That said, there are somethings to be said for designing in a way that is savvy for the web, which I’ll cover next in Respecting the HTML.

Many thanks in this essay go out to Rob Fieldhouse of Playground, the designer with whom I’ve done the most designer/developer collaboration on web projects, and whose eagle eyes and elegantly structured designs guided me to this place of design rigor and appreciation.

Categories: Design, Essays Tags:

Programmer Resistance

July 28th, 2010 1 comment

A while back I interviewed a longtime client on how he viewed working with me: I was looking to get a real, introspective look on what works about my style of service, what’s lacking, why hire me at all, and so on.

I got a number of pearls out of the experience, but one in particular I’d never heard or even considered before: “What’s really nice is that you put up no resistance.”  Eh?  “Say more about that”, I replied.

Paraphrasing, he said that when there’s a problem or a snag I just go with the flow of whatever is deemed important and I’m game to just work any which way towards a solution.  Whenever faced with “hey, this isn’t working”, I’ll quickly improvise a fix and it’s NOT A BIG DEAL.  No resistance.

What a cool distinction.

For sure, it’s common in my field for formality and ceremony to get in the way of a quick, pragmatic solution to a problem (this is, after all, an industry that derives a lot of self-importance out of months long dev cycles, rigid road maps to follow, rigorous testing, and the occasional 370 million dollar error).  So if a programmer assumes the demeanor that doing X or changing Y will be a big deal and is likely to take loads of time or apt to cause tons of complications, their expertise and warning generally needs to be heeded, at least by non-programmers.  (This is not unlike the futility of arguing with your mechanic over the state of your car’s transmission, when you are not a mechanic.)

Being a low resistance programmer requires a combination of both mastery over the domain (necessary to responsibly perform a given task, correctly and without ill side-effects) and the discipline to not indulge in a story of exaggerated burden (which can be gamed for inflated pay and longer time lines).  So when it comes to the relative merits of programmers, low resistance is of course favorable, but only given comparably good end results.  Two programmers might share the “can do, no problem” attitude up front, but if one of them took 3 times longer than anticipated or made a quick mess of things, that’s a matter of being naive, not willing and able.

Every situation is different, of course (some things should be a quick fix, and others genuinely are a big deal), but over time I think it’s possible for a non-programmer to gauge what kind of programmer they are working with.  Say you have a programmer that you rely for keeping critical parts of your business operations running smoothly.  If it’s a pleasure to bring issues to their attention because you typically leave the interaction with a sense of peace and that all is well in the world, you probably have a programmer who makes your issues theirs, and then makes small and tidy work of it.  If you have someone you hate to bring problems too because it makes you feel like life is generally a complicated mess, then you probably have a programmer who’s more invested in telling you how hard their work is than actually tending to what you need them for.

Categories: Essays Tags:

The Curious Nature of Hourly Rates

July 1st, 2010 11 comments

There are some services for which I think the model of charging based on an hourly rate is appropriate.  Software development is not one of them.

Consider: some services fit the hourly model to a T.  These are jobs where the hours spent are directly proportional to the value realized by the hirer.  It makes sense that getting the hour long massage costs roughly double what the 30 minute session does.  Or manning a reception desk.  When somebody needs to be there, every hour that a body is there that creates value and fulfills a need of the hirer.

But software development runs counter to this notion.  We programmers are pretty much always hired to solve a real problem stemming from a real need, not to provide hours of coverage hunched over a keyboard, and certainly not to provide extended enjoyment for the client by virtue of working longer hours (the massage therapist might hear the phrase “hey, that’s nice, why don’t you do that a little longer?”, I don’t think a programmer ever has).

No, in software development it’s virtually always the opposite: the longer a project drones on, the more painful it is.  Just ask any stressed-out looking project manager who keeps getting excuses and pushed back deadlines from her development team.

But doesn’t more hours mean more quality?

Maybe, but that correlation is sketchy at best.  To realize a given set of features, a pro can often do it both better & faster: the number of hours spent becomes an argument against quality, not for.  (I’m much more apt to trust that a WordPress install got done right by someone else if it took them 15 minutes rather than 3 hours.)

Programmers can (and should) be hired on the overall demonstrable quality of their work, and a review of their portfolio plus a mutual understanding of the level of thoroughness/quality that is called for (throw-away prototype or enterprise level masterpiece?) keeps the fixed price model honest.  (Because yes, without that mutual understanding a developer could hack the fixed-price model by racing through a project and cutting corners, to say nothing of whether or not he’ll be hired again).

Alignment of Priorities

If we can assume that a contractor is guaranteeing satisfaction (and we probably should, right?), then a faster execution of a fixed-price project is in the best interests of both parties.  The client gets what they need sooner, and the effective hourly rate of the contractor is higher.  When an accurate sense of the quality to be expected and a correlate price tag are established, the fixed price model creates this nice alignment of priorities between contractor and client.

By contrast, hourly creates a misalignment of priorities of client and contractor: the contractor gets rewarded for dragging their feet and making problems out to be more complex.  Not a huge amount of course, because in the logical extreme they’d get dumped sooner or later.  But it’s just too easy to milk the clock and divert energy from actually solving the problem, to instead convincing ones self and others that it’s more difficult than not.

Effective software development is all about fewer smart hours as opposed to longer hard hours.  Pricing for it should probably then reflect that, and by the  same token programmers should probably strive to avoid the curse of the hourly wage.

Categories: Business, Essays Tags:

Selling Less is More

June 18th, 2010 No comments

It may be either a sign of laziness or of wisdom, but I’ve had a few conversations of late where I’m deliberately selling my clients on fewer and/or less complicated features.

On the surface this is bad salesmanship: I bill by the project, and of course the price tag for a given project grows with my estimate of the complexity of what I’m building (and hopefully the value gained by the client, as well).  The more features a client is certain they want, the more features I get to build and charge accordingly for that work.

So what’s up with my recent kick of advising fewer features?  Turns out it’s mostly situational with a dose of outside wisdom.  The projects I’m thinking of are both of an “expand in a new direction” variety: one is a pilot program to prove a new concept in their e-commerce, the other is to make a hub for a community to interact online in a way they haven’t before.

The dose of outside wisdom is the 37 Signals bit on the Race to Running Software which states simply “get something real up and get it up quickly”.  Both of my clients found it refreshing to hear things like “Tell you what, it’s just the pilot: we can leave the customer address book feature out for now, and add it in later if it turns out to be important.” and “Let’s see what your users do with just the ghetto-fab system of posting comments.  Then we’ll know what they’re bumping up against, if anything.  If it suffices, we’ll have saved ourselves a lot of extra work.”

Planning to build non-critical stuff up front involves a lot of guesswork and creates a bigger gap between speculation and real world feedback.

Would I like to be hired to build the customer address book feature?  Sure, it’s a tidy little feature that would be really slick and is clean to implement.  But let’s wait to see the first 5 repeat customers who place orders shipped to more than one address before we build it.  That will save time and money while we focus first on getting the system ready to launch at all.

It’s simply having an eye on the prize.  And I’m talking business win, not a juicier contract.

Categories: Business, Essays Tags:

Two Approaches to Spec’ing A Project

May 6th, 2010 2 comments

My recent involvement in spot checking someone else’s proposal really brought home for me an interesting dichotomy in approaches and schools of thought when it comes to spec’ing out a project.  (By “spec’ing”, I refer to the process of assessing and describing the specific needs of a project, and then assigning a price tag and time line to that assessment.)

My training (or, perhaps more accurately, my invented approach from when I started doing this back in the MonsterCommerce days) has taught me to do a rigorous analysis of all facets of the project up front.  I don’t submit a proposal until I can firmly describe what features will be included (to at least the level of detail of which entities the system will model and manage), and am able to assign a price tag to each one of those features.   There are a few pros to this approach that I can think of:

  • A pretty accurate price tag for the whole project falls out just by adding up the module costs, plus perhaps some overhead of communication, project management, and/or padding for middle- and end of-project tweaks and revisions.
  • I’m clear what I’m committing to so I know I can deliver on time (and not bust).
  • My client sees exactly what they’re getting: it’s an opportunity to verify that our understandings align, and they can spot if there is anything missing.
  • A sort of a la carte pricing becomes possible when clients can see how various features contribute to the cost: it enables them to tailor things to fit their budget or decide to hold off on certain features if necessary.

The major con of this approach is the time and effort it takes on my part to cook up such a rigorous sketch of the project before I see the first dollar.  The ability to do it quickly thanks to copious practice does well to mitigate this con, however.

The other approach then is of the quick, more glossed over variety.  This is where a price is given based on satisfying the high-level needs of a project, and that price will be set to cover a fair chunk of reasonable expectations to that end.  (In other words it’s like the contractor saying “We don’t need to go into details, I’ll price it so that no matter what specifically you’re thinking I’ll be happy to deliver.”)  I’ve seen it done often enough to know that it’s not uncommon, and there’s good reason for its popularity.  From the perspective of the one preparing the proposal, it’s quick, it’s easy, and though it may be accepted less often, it’s more profitable when it is.

Now with this dichotomy laid out it bears mention that the two approaches I describe are actually two points on a spectrum, one that extends out to greater extremes in both directions than what I describe above.

There is no objective best place on this spectrum to be for both clients or contractors, every point has certain drawbacks and merits.  (I may seem biased towards the detailed end, but rest assured I know the dangers of being too detailed: clients eyes glaze over, and/or they’ll feel locked in by too much contractual rigidity).  Still, if you’re hiring someone to do a project, it’s probably useful to recognize where your contractor is with their proposal: if you get a proposal where the feature scope is fuzzy AND it names a price, you’re probably paying for a big cushion of guesswork.

Categories: Essays Tags:

Fixed Price or Bust

April 17th, 2010 2 comments

It’s worth acknowledging that anyone who hires a professional to build a web application (me, for example) is taking a sizable risk: for a sizable amount of time and money, they will get an end product that doesn’t yet exist, the description of which itself is subject to ambiguities, misunderstandings, and mistranslations, and the implementation of which is often fraught with surprises and complications.

To mitigate this risk, a professional can (and in my opinion should) take a risk themselves: to deliver the system as specified for exactly the agreed upon price.

How could that be considered a risk?

Most web applications are inherently complex, and a large portion new applications consist of one or more novel problems to solve.  Both complexity and novel problems contribute to the likelihood of unforeseen gotchas, surprises, and challenges, and guesswork is accordingly injected into estimating the time and money involved.

Therefore when a professional gives a price, it’s an assessment of how much work a project will take that is made without the luxury of hindsight.   Saying something like “you know that thing I said would cost $800?  Yeah, turns out it’s harder than I thought and so it’s going to be $400 more.” to a client is an admission of a failure in making this assessment.

“Fixed Price or Bust” is the model I subscribe to handle this risk: I learn what I need to about the project, estimate the complexity of each segment, assign appropriate prices for each, and then for each segment, one of three outcomes will result:

  1. Nailed it. All went according to plan: I complete the segment within the time that I’d estimated, and all is well.
  2. Stumbled. It was harder than I thought: I got it done and on time, but not without sacrificing extra hours dealing with curve balls I failed to foresee.  I lost some time but gained some learning, and it looks just like the first case to my client.
  3. Bust. It was much harder than I thought: so much so that I need to let my client in on the problem(s) that have arisen and given them options.  This step constitutes reorienting to reality in light of new information and experience, because the estimate in this case has proved be wildly inaccurate/optimistic, and I take as much responsibility as I reasonably can: either we renegotiate the time line and/or cost, revise the approach somehow, or we drop the segment outright and I eat my time already spent.

Bust represents an occasion where a client is saddled with the uncertain complexities of software development, something we web professionals are hired to abstract away as much as possible.  Accordingly it should happen as rarely as possible.  In my 4 years of freelance web development there was only one time that I busted.

Fixed Price or Bust creates a responsibility on the side of the professional that I think goes a long way to support clients and foster trust in the process.  It puts the onus on a professional to accurately assess the complexity of a project.  They have strong incentive to get it right, and a strong disincentive to get it wrong.  If a segment of work turns out to be harder than anticipated, Fixed Price or Bust nearly ensures that the situation remains their problem, and not the problem of the client.  Working faster for a fixed price both increases the profitability of a professional as well as gets a client a completed project sooner.  It’s a great alignment of priorities.

Categories: Essays Tags:

Pretty Software for All

April 9th, 2010 1 comment

If web developers were elected, that’s one of the platforms I would run on.

All other things being equal, we’re all pretty much hard-wired to prefer pretty: the people we’re with, the spaces we live and work in, the scenery around us.

What we have to stare at on our computers is no different.

Making software that is pleasing to look at is a good way to honor your users.  It’s a way of saying “I know know you may be staring at this for a considerable amount of time, so I want you to enjoy it.”  Apple has done this remarkably well: I’ve been a Windows guy since my first computer, but I still have moments of being drawn to my gal’s mac… it’s just so… so shiny and looks so good.

Where Design Gets Neglected

In the realm of companies who need custom software built for strictly internal use, I’ve noticed a certain acceptability of ugly software.  After all, it’s not like the the users of it need to be sold on the design.  Once it’s built, that’s pretty much what they need to use to get their job done.  Adoption is mandatory and there’s only one option.

So the desire or tendency for companies to skimp on design, or for developers to phone it in (favoring instead to focus on making it work), is understandable, if not outright pardonable.

But the web, as a medium for creating applications, changes things a bit.

Design for, say, Windows desktop applications (a longtime dominant platform for corporate custom applications) has been largely tethered to the native look and feel.  When you build something to run on Windows, it’s presumably a path of least resistance.  You know the look:

The web, on the other hand, is aesthetically powered by its delightfully simple and powerful CSS technology.


That’s good news, because if you’re building a project that will run in a web browser and your developer is CSS savvy, the cost of realizing any given look-and-feel throughout the system is drastically reduced.  You can set up a developer with a PSD that reveals the aesthetics of the common widgets to be employed throughout the system (buttons, text inputs, tabbed regions, etc.), and he or she can remix and re-purpose those widgets to build the entire application to match.   If it’s built right, it’s just a matter of swapping out one or more images and/or tweaking one or more CSS rules to achieve system-wide design changes, from minor tweaks to thorough overhauls.

Why This is a Win

It’s true, ugly software that doesn’t need to be peddled to a finicky public won’t suffer from fewer sales, nor will it reveal to a wider audience any embarrassingly bad sense of taste.  The benefits of working daily on software that looks good are less tangible but still probably important: morale and productivity.  “I love what I do” is a good way to cause a highly effective team, just look at Zappos.  If you have a single program that must be worked on an hour or more a day by your team,  better to have that program say “I want your experience to be pleasant” than “this is ugly and we know it and we don’t care.”

The web era makes pretty software design much easier to implement, so with that lessened barrier it’s become an even better investment.  After all, the forces of aesthetic preferences are always at work in the consumer market for software.  The same human element is present for people who must work with corporate software, it’s just that, given the lack of choice, the effect plays out in different ways.

Categories: Essays Tags:

Creator/User Gap

March 27th, 2010 No comments

A lot of people have use for specialized, custom built software, but far fewer are able to create it themselves.  So it is common in my industry that software is created to be used by someone else.  This gives rise to a gap in the perspectives of the creator and user: the creator is often only a user to the extent that they ensure that every piece works as it should, whereas the user needs to use it in a real working environment every day.

What this means is that even a well meaning and highly talented developer can produce something that end users hate, simply for lack of the day-to-day user perspective.  Consider:

Creator: This feature works like a charm.
User: I use this feature 100 times a day but takes 4 clicks to get to when just 1 could do.

Creator: The login system works really nicely and is secure.
User: I get booted out of the system after 20 minutes of idle time, and my usual task away from the computer takes half an hour.

Creator: This downloadable spreadsheet report has all the info about orders placed.
User: I still take 4 hours a week to manually reconcile this report with our CRM system.

Creator: This date picker widget lets you quickly choose your date range for exporting orders.
User: I never need anything but the orders from the last 7 days, but I still have to always pick those dates using this stupid date picker.

This gap is only a problem when there is no communication between developers and users. And it’s not surprising that communication is generally sparse between the two.  Less-than-awesome software is more than common, and so among users there’s a common mindset that that’s just the way it is.  Either it can’t be any better, or perhaps the developer hates them.  (Though the latter is irrational, even I fall for it when I think of the development team behind IE6–I know they were doing their best.)  Both views give rise to a “I’ll deal with it” mentality, perhaps with a “well at least it’s better than the old system” thrown in.  Even if an end user can make requests directly of the developer (seldom allowed to avoid willy nilly wasting of expensive developer resources), the idea seldom occurs as a real possibility.

But what if that communication is strong and the custom development arrangement does allow for tweaking based on such real world feedback?  The above four hypothetical issues are ripe to be fixed with a little bit of tweaking, if only the developer knew about them.

A great solution to this gap is to have the developer become a user in the real working environment after the project has been presented as complete.  That time lays bare a great number of shortcomings that a system might have in actual practice.  It’s fun for everyone involved: the developer gets to be a hero and enjoy the satisfaction of making big win tweaks.  Users have their issues addressed and their needs met: their cool new system just keeps getting better, often within minutes of making a request.  And key stakeholders in the project are delighted by both the improvements and the happiness of the people using it.

A day on site spent beside end users  is something I’ve done now and again, but I haven’t thought to make that a more standard part of my service until now.  It’s that extra mile that provides so much with many kinds of projects.

Categories: Essays Tags:

A Team of One

March 23rd, 2010 3 comments

During the course of my programming career, I have found, without exception, the greatest success (be it measured in efficiency, the end result, or even my personal joy in the process) comes with solo projects.

After such a years-long track record it begs a question: am I just another example of the lone wolf coder who either cannot or will not play nicely with the other kids, or is there really something defensible in the idea of a programming team of one?  Central to The Mythical Man Month is the notion that adding people to the programming team of a late project will only make it later, but what about the other extreme?  Can minimizing the headcount to 1 make a better project, and if so, under what conditions?

Communication

Certainly there are some immediate gains that arise.  There’s no redundancy in learning the initial requirements of the project: one point of contact constitutes a massive streamlining of communications, and there is no opportunity for a game of telephone to distort the message as it disperses from client to team.  The same can be said of the nuances that arise during a project’s lifetime: tweaks can be made to a system’s architecture without the penalty of coordinating with other parties impacted by the change.

On a team of one, everyone is always on the same page when it comes to the state of progress and what’s currently on the client’s mind.  An entire class of meetings, the inter-developmental team meeting, can be nixed entirely.

Division of Labor

While out with a few of the guys of the Denver JQuery meetup group last week I heard a lot of people describe themselves as either “front end” or “back end” developers.  This is a useful separation of labor, for the skills of each are reasonably disconnected (front enders are charged mostly with the user interface and making the system look pretty, while back enders are more concerned with the business logic and data shuffling about).  But for most projects the roles are heavily intertwined.  Changes on one side will often necessitate changes for the other, which will take a cycle of communication/waiting/updating/integrating/testing among 2 or more people each time.   For a team of one who is master of both sides of the system, this communication is instantaneous and it’s just a matter of revising the work.

Come to think of it, it’s not just a matter of saving time.  If the logic and flow of a system are handed down from on high as immutable gospel, both parties can work on their parts separately and bring their work to make a near if not perfect fit.  But this is seldom the case.

What really happens is that original designs are either sketches or best guesses: either benefit by evolving from prototypes and earlier drafts.  Lowering the activation energy for tweaks allows it to evolve better simply because it’s less headache to explore new ideas.  When an idea implicates changes that create more work for others, given the choice you’ll more likely stick to the original spec.  If it’s just you and the code, you’ll be far more inclined to take risks.  When you hit a dead end, there’s no one you need to apologize to.

Worthy Collaboration

One piece of teamwork I’ve consistently found to be a great boon to a project is a clear cut relationship between aesthetic design and coding.  A great design for a project makes working on it a joy (bad design kills morale (or at least drains it) and no one is immune), and when I’m given a rich vocabulary of aesthetic elements I can remix and re-purpose them for whatever needs come about.  Thus design in projects is more of a one-time input rather than a you-work-on-your-part-and-I’ll-work-on-mine-and-we’ll-make-sure-they-fit-together-all-along-the-way.

Clearly a team of one needs to be able to many disparate competencies in order to pull off an entire project.  That might suggest that their talent might necessarily be spread thin, but I’m not so sure.  When I am ultimately accountable for a project, there’s much more a sense of pride and ownership for the end result.  You can’t hide behind a story that someone else dropped the ball if the project is less than great.  For those two reasons the entire process becomes the opportunity to really bring your art and have it shine.  Learning an extra trick and going the extra mile is much more enticing because it is much more noticeable and attributable.  Contrast this against the temptation to phone it in and just meet the spec requirements on a project where your part can’t override the overall momentum of the team.

Certainly the team of one is not much of a duplicate-able model for relying on all projects: the larger a project gets, the harder it is to find someone who can be the sole master of it all (let alone be interested in doing so).  But it may be a worthwhile direction in which to grow talent: rather than gauge merit and encourage development along the lines of having increasing years and experience within narrow X, be interested in growing an expanding base of proficiency in X, Y, Z and so on such that the size of a project that could be taken on by one person increases.  The power of a given group of programmers may be best measured as the size of the biggest project that one member of the group could handle alone.

Categories: Essays Tags: