Ask HN: How can I complete a project?

12 points by SmokyBorbon ↗ HN
Thank you for taking the time to read and respond to this.

I am a self-taught programmer. I used to teach a PHP/MySQL course at a community college. I currently work in technical support for a web hosting company. I'm really good at fixing errors in other people's code or adding new features. I suck at taking my own projects from start to finish.

I will start a new project and make tons of progress. Then, I won't have time to look at it for a couple of days. When I try to continue, I can understand the code but I have no idea where I was going with it. I'll either want to rewrite large sections of code or start over.

I document lines of code as I write them but I have no idea how to plan or document the project itself. I started using an IDE (Netbeans) but I still use it like a plain text editor.

I've used frameworks including CodeIgniter and Laravel before but I still end up with a mess.

How can I plan/organize my code/workflow to become a professional programmer? Any websites or books you could recommend would be appreciated.

9 comments

[ 0.25 ms ] story [ 31.2 ms ] thread
If you're like me, I toy around with side projects until they get boring. I'm great at 'proving the concept', and when I'm hired for pay, I don't generally have the same problems, but problems without clear objectives, or 'side projects' generally end up dying on the vine. A couple of improvements I've made over the years that help me finish.

1) Do the boring parts first. Start off writing (or using libraries for) the boring parts of your code that you don't like. Profiles? Logins? That sort of thing? You can generally drop something in that will service the need with very little effort, and replace it later if and when it gets traction. This leaves the 'fun' parts of code to be written that I generally prefer to work on.

2) Start using Github, as much as you can. Make meaningful commit messages, so that you can look at your commit history and see what you were doing and what you planned to do next. I often misuse the commit log and put things in like "Finished such and such, but I really need to implement function_x()". This lets me know what was a priority the last time I was working on it so that I don't start on new_function_y and then lose steam when I realize that, oh yeah, I forgot to do function_x, which new_function_y will need.

3) Use Github issues. If something isn't working as expected, only fix it if it's something dire. If it's just a glitch, or a render bug or something minor, then just create a Github issue to come back to it later. Also important that you set milestones. Alpha, Beta, Closed Beta, Release.. something like that. Don't tie to version numbers, just tie your milestones to actionable times. If you can implement three features and fix five bugs and then be able to show it to friends and family, that should belong to a 'closed beta' milestone. After that, let them report issues back to develop your 'open beta' milestone.

4) Break things down into the smallest tasks possible and avoid scope creep. Make an issue for every new enhancement and bugs. Pick a couple of boring issues and 1 really exciting one to work on per day. If the features are big enough that you can't do a couple a day, then they probably need to be scoped down and broken up in to smaller issues. How many you do a day isn't as important as making sure to knock out more boring things than exciting things to keep momentum going. By the time you get to the exciting thing, you should feel accomplished and motivated by the two boring things you already knocked out.

5) Hold yourself accountable to someone, something. If you've got potential customers as friends, let them in on it. Keep them updated weekly or bi-weekly. If you don't have potential customers, use a wife, a girlfriend, a teacher, a friend, whomever. Ask them to keep you moving forward and specify dates for milestones. There's a big difference between slacking off on your own and slacking off when you know that somebody at the end of the week is going to expect a progress report.

JACKSON STRUCTURED PROGRAMMING

No, just kidding.

Before you start just do a very brief sketch of what you want to achieve. Keep putting notes on this as you go through. This is rough and informal and will change.

When you leave off make a huge comment with some notes - "implement this, that, the other. Don't forget that you were having trouble with that."

When you go back to a project have one tiny feature in mind, and do that. Don't try to finish the whole thing. Little steps.

I recommend Pivotal Tracker or Trello for organizing tasks.

It's easier with N > 2 people involved but the rough workflow goes:

a) create a story in Pivotal that covers a new use case or a tweak to an existing one

b) start the story, work on the use case, add notes at the end of working on it so next time you work on it you can reference them

c) when you finish it, mark it 'finished', then deploy it and mark it 'delivered'

d) Then do acceptance testing: ideally automated, but manual is fine too for most cases. This is where it's nice to have a 2nd person check it for you. If it works, approve it, if not, reject it and go back to work.

Also, if you're not using unit tests, they're really helpful to keep you on track - never walk away with passing unit tests, and you always have something to start with next time you go to work.

I appreciate you recommending these tools to me but they aren't going to benefit me if I only have a vague idea of what a "story", "use case", "acceptance test", "deliver", "deploy", or "unit test" mean. I only know how to write code. Is there a website or book you can recommend that teaches these things?
Honestly? Wikipedia has a decent overview.

The tl;dr versions:

Story: A story is literally a story about what you would like your project to do: "I want to be able to find and read news", for example on HN. That's what they call items entered into pivotal.

Use case: One way someone might use your project to accomplish a task. "I would like to reply to an email" for example.

Acceptance test: A test, manual or automated, that is the criteria for whether something is acceptable for a given use case

deliver: There's a button, it says deliver, you click it. Usually means making something available for testing

deploy: Put your project onto a server where other people can use it

unit test: An automated test that tests a very small amount of code, a 'unit', and is used for making sure that unit works correctly. C.f. acceptance tests above, which test a much larger amount than one 'unit'. An example would be a test that tests one function, one method, or one line of code.

Joined Pivotal Tracker and started dumping my project info on it until I found out that there is no story/task dependency!! That left out feature completely ruins the whole system. How can they not have it? Do you know any similar applications that you can build dependencies into?

i.e. for B to be in the "Current" queue, A must be complete

This is one of the main reasons I use cucumber, I write out a feature and then work my way through it. This works great on a side project because you can drop what you're doing and come back to it a couple of days later. You just run your last spec and get back into flow. To make sure you always know where to jump back in just make sure you have a failing scenario when you finish up for the night or whatever. It doesn't even matter if you've started writing the code for it, just write out the scenario in english and you're good to go.
Is it a code problem or a productivity problem?

Code productivity: Using issue tracking like FogBugz or Github really helps you make sure you work on the important bits first to get a minimum viable product.

I try to think 'Lean Startup' on my projects. Only create the features you really need. Get the bare minimum thing working properly and get feedback/testing from someone who would actually use your product/service. Iterate. Be agile.

More generally: The basic productivity techniques can be a distracting read http://www.43folders.com/howto.

Breaking things down to much can create overhead. I've been trying to improve the way I stay on task. Not just working on the project, but working on the most critical parts without getting distracted. Its too easy go on a tangent, and research something which wasn't critical.

I'm currently refining a method I call ReasearchLock: keeping track of the current task so I don't deviate from it. Things which appear critical often turned out not to be if I tried to get by without them and just left them for later.

I outlined my original idea in a note: http://njoin.co.uk/grains/5107d5516decf91f10000002 but have refined it since.