See the fireworks Craig Nicol created by blogging on WordPress.com. Check out their 2015 annual report.
Note : Family is important, so after this schedule, I’ll be taking a break until the new year.
I had a few problems with this bug in the WordPress Android client, but I’ve really come to find the ability to schedule posts for the future valuable. Although I always try to post at lunchtimes, I find my commute by train is a perfect opportunity to write. It gets my head in the right place in the morning and allows me to dump and forget in the evening.
Whether you blog or not, I’d recommend writing an agenda or a synopsis of your day. Nothing as formal as a task list, unless you want to, but something to reset your thoughts in the right direction. A train without WiFi is perfect as there’s fewer distractions.
Even if you do blog, don’t always expect to publish each dump you write, some prose is just between you and the trash. And some will take months, or years, to form into a coherent post.
If you don’t know what to write about, scan other blogs or news sites, write up a list of 20 topics to work through as recommended by Simple Programmer.
Most importantly, if you want to write, write. Write notes, write ideas, and mix them up. Write lots, and review it. And find a time that works for you, and schedule for the future, so it has a chance to surprise you and inspire you again.
Any good developer or system administrator is largely invisible, working behind the scenes, quietly delivering value without fanfare or ceremony. If you get noticed, chances are that something went wrong.
You need a particularly special mindset to survive in such an environment. You have to be self motivated and strive for quality in yourself. There may be others in your team, but if you want praise from the customer for a job well done, you’ll likely be disappointed, even when everything goes to plan. In a recent report comparing the system I’m leading to similar systems elsewhere, the biggest praise we got was only having a couple of lines describing the system in a report full of challenges and recommendations for the other systems.
So, don’t look at what you’re doing as work, you have to have passion and pride in your abilities. Ultimately you develop software because it rewards you directly. It gives you the chance to learn, to explore, and gives you the satisfaction of solving problems.
So, how can you be more resilient to customer feedback? Once you understand that 95% of the users ignore you because the system is good enough (although, if you start shadowing them, you may find improvements), what do you do with the 5% who tell you it doesn’t work?
Be fair. Understand that it is a real problem for them. The thing that isn’t working is causing them pain. Listen with patience and humility. Don’t feel pressure to fix it straight away. Software is complex, and their problem might not be the highest priority. Go away and think about it, reflect before you answer. With practice, you’ll be able to do this on the spot, but make time to reflect your default position.
Jack of all trades
You’re a developer, that doesn’t mean you’re able to work the fancy cooker your parents just bought, it doesn’t mean you’re an expert psychologist who can understand what’s happening in your user’s mind. It doesn’t mean you’re an expert designer who can make everything as pretty as a sunset. But you’ll be asked to do all these things.
Have an armchair view of everything, but be ready to delegate knowledge.
If everything was working perfectly, you’d be out of a job, so embrace the cracks, the complaints and the quibbles. That’s where we improve.
It’s a difficult mindset to cultivate. When you get it and are in the zone, it’s effortless in a way that is hard to explain. It basically feels no different than writing in proper English.
When you don’t have it, it’s like trying to speak in a different language. Which makes sense, but it isn’t quite exact.
I’ve been coding for so long, thinking in code is second nature, but I liken it to when I learned to drive. At first I was very bad, I made a lot of mistakes and it really knocked my confidence, but I stuck at it because I lived in the country and had no choice, I was still nervous after passing my test, and it took about another 2 years before I got to the point where I wasn’t consciously thinking about the mechanics of driving, the meaning of each marking and road sign, and how to react to different conditions.
A lot of people I’ve mentored get scared when they lose confidence, but that’s an important step, and it always takes a long time to get past the conscious thinking stage, where they’re switching between the customer domain and the coding domain rather than thinking in the customer domain and writing in the coding domain.Switching to Haskell got me back to newb mode again. It’s less like programming and more like magic. I can see how it works, and it does things as expected, but intuition tells me it shouldn’t work.
And then I read Code rant: Learn To Code, It’s Harder Than You Think, and it got me thinking about the AI Gods, and how unnatural it is to think in code. And that’s important. When you talk to users and customers, and when you talk to managers, they look at all the information saying coding is easy and then ask why it’s taking so long, or why you can’t just put that number there, and then switch off when you try to explain. Indeed, you can end up in a meeting like this one:
The expert : https://www.youtube.com/watch?v=BKorP55Aqvg
So it’s important for people to understand that code is hard, and it is a specialist skill, whilst still trying to encourage people to take up software, because we need a new generation of AI gods, and they need the time, and the inclination to grok coding.
I grew up in the 8-bit days, with the MSX, and coding was an integrated part of the experience. The command line was the programming language, and all the magazines has type-ins, so there was a lot of opportunity to practice typing, as well as coding, which is a valuable subsidiary skill. There’s a similar modern experience with the Raspberry Pi, but the industry as a whole has moved on so much, that the days of spending a few hours typing to get something that has the same surface quality as the games in the shops, are mainly behind us, at least as far as the big box games, rather than the casual field. And it will be about games, because who is going to write a tax auditing application for fun?
How do I learn?
So if you’re just starting out, and you want to write software, or you want to be the next AI God, what do you need?
Here’s what I think is most important:
- Teach yourself. Attend classes if it helps, but if you’re not self-motivated to learn and keep up to date, you will quickly fall behind.
- Crave simplicity. Challenge yourself to cut complexity, to streamline. The less code you have to write, the easier it is to work with. Always seek new ways to simplify what you do.
- Practice the basics. Use the many programming exercises to capture branching, modularisation, testing. Find examples you like, either smaller exercises, or complex Mandelbrot calculations and keep reworking them to understand new languages, or to challenge yourself to understand that basics. Can you write a program without if statements, or can you throw away the tests and rewrite the code?
- Practice often. Spend 20 hours writing code. Then reflect, understand what you know, and write more. The more you write, the more you’ll understand what you don’t know.
- Read code. And think about it. Just because it exists, doesn’t necessarily mean it’s good, but think about how you would solve the same problem. Understand what decisions were made and why.
- Understand principles deeply, technologies less so. Know what it means to be Object Oriented, or Event Driven, or Functional. Understand what they are and how to use them. It doesn’t matter whether you’re using C# or Python or VB or Java or Haskell or The Next Big Thing. If you understand the principles, you can apply them with whatever syntax your current language provides, and you can understand what to use when.
- Think in code, but talk in human. If you can’t explain what you’re doing to your users or your manager, you don’t understand it enough. Crave simplicity in your communication as well as your code.
- Talk publicly. Present, blog, chat. Find a local user group and connect. If you’re enthusiastic, you’ll be welcome. If you’re shy, everyone will understand. We’ve all been there.
- Simplicity doesn’t mean brevity. Be as brief as possible, but don’t lose context, or nuance. Be clear.
For those of you with experience, what else would you add?
I’ve worked in successful waterfall projects, and failing ones. I’ve worked in successful agile projects, and failing ones. And when I had the chance to switch from waterfall to agile, it wasn’t because I was chasing a bright light, not caring if it was the headlight of an oncoming train, it was an experiment, to see if the obstacles I had seen in waterfall were fundamental to software engineering, or were a function of how the projects had been run.
I read about scrum, and I embraced it. It gave me structure, as I was used to, and I could introduce it slowly. It had patterns I could follow, ceremonies to perform, so I didn’t have to think about being agile, and I could sell it easily to my manager – don’t do meetings that way, do them this way. Don’t plan that way, plan this way.
And things didn’t go as smoothly as I hoped. We missed deadlines, our estimates were wrong, but at least we had more deadlines so we could reflect on why we missed them, and at least we had numbers so we could quantify the estimate errors, and correct for them. And so we thought about process, and we added ceremony, to make sure the mistakes we made weren’t made again.
We missed deadlines, our estimates were wrong.
We did daily stand-ups, we had retrospectives every 4 weeks as the sprint ended. And we were thorough. They took most of the day, they involved everyone, and copious notes were taken, and actions assigned.
And people were bored. We missed deadlines, our estimates were wrong.
We started using story points, because estimates weren’t working, we did planning poker to make sure everyone understood, and we tried to agree on what a Story Point meant. To nail it down, to quantify it. And we argued over it, and we spent a day planning.
And people were bored and frustrated. We missed deadlines, our estimates were wrong.
But we delivered on time, because we controlled the scope, and we extended our working hours.
And people were frustrated. And we wondered why our estimates were still wrong.
And we realised we didn’t need the daily stand-ups because we always talked. And we didn’t need the retrospectives because everyone was bored, and we could talk about the issues with the few developers who cared about the issues.
And we had more time to deliver story points. And we controlled the scope. And we talked. And we delivered. We got better at meeting deadlines. We got better at estimating.
And then I was told we weren’t agile. I was asked where our ceremonies were.
And I realised, it’s not about the ceremony. It’s about the principles. The ceremonies are the scaffolding that help the principles to develop. If you have a new team, or a distributed team, that don’t talk every day, a daily stand-up is a good scaffold for communication.
If you don’t have a good feedback mechanism, and the team have trouble trusting, a retrospective, and many of the anonymous feedback mechanisms, are a good way to get the issues out in the open, so that they can be addressed. If the team trusts each other to talk, and to address the issues, just have your retrospective in real time, with the people affected.
Understand why the ceremony exists. Use it to support the principles, not to curtail them. If it doesn’t work, drop it. Be agile. Don’t stick to scrum.
I was reading Mark Rendle’s Futurology post, looking at the economics of plenty and how that changes our relationship with technology, and it reminded me of a train of thought I had around the future of AI.
It started with a series by the BBC, and the question : Will a robot take your job? which inevitably led me to thinking about the Luddites and sabotage, as skilled workers saw their jobs being lost to technology, at the same time as mass production and specialism, as described in the Wealth of Nations, lowered prices and raised living standards.
In some ways, AI is in a similar position, although the jobs being lost are more and more highly skilled, leaving people either climbing up the skill chain chased by the machines, or sidestepping the machines into, say, the service industries where customers prefer the human touch. But there’s only so much space left for human when cheap, smart machines start proliferating. They don’t need to be smarter than us, just cheaper. At it’s logical conclusion, the number of jobs left for humans could easily become less than the number of people available to work. ( Artificial intelligence: ‘Homo sapiens will be split into a handful of gods and the rest of us’ | Business | The Guardian)
There’s a lot of possibilities for how this will play out, and I’ll explore some of the other options in a later post, but in the spirit of Star Trek and Mark’s post, let’s assume that the cheaper, better machines trajectory lowers the poverty line enough, and humans are altruistic enough, that actually everyone can be fed, watered and connected without the need to sell labour to pay for it. And the other technology Mark mentions, such as 3d printing, will be key to that. There’s also political changes that will help, such as Finland’s proposal to guarantee everyone an income, which is also supported by politicians in the Netherlands and the UK’s Green Parties.
On the consumer front, digital goods are moving to cheap, and sometimes free, subscriptions as Amazon, Google, Apple and others compete, although it’s not clear whether the original creators are supported adequately by these services.
I’m not convinced that it’s the end of money. As a vehicle for trade, especially as people specialise in their line of work, as discussed by Adam Smith, money is a useful abstract. You can choose to trade your work for a cat, whereas I can choose to trade it for musical instruments.
The question isn’t about the end of money, it’s about whether we can or want to separate labour from money, and money from status. When the Fundamentals of labour are subsumed by machines and status is a cheap subscription away, whether you are a consumer or a producer, is money still a means to itself? Can it still buy power and influence? Can it be used to control supply? Unfortunately, I fear it will, and whilst that lasts, the people who think in code, and the personal services industry will hold on, but everyone else will watch, and maybe fight, as the machines come after their jobs.
“We must do something”
“How about we paint this elephant pink and let it rampage through the nursery?”
“Well, it’s better than nothing, I suppose”
No, no, no, no
There’s a limit to what you can do. If you don’t know your next step, step away from the keyboard, grab a coffee, or a whiteboard, or a book. If you’re still not sure, write some tests to experiment, and throw them away so you can think about the full impact before you wrote the final version.
A man of action forced into a state of thought is unhappy until he can get out of it. – Franz Kafka
Movement isn’t always progress
Just because you’re doing something doesn’t mean it’s productive, if it’s poorly conceived and planned, if it’s reactive rather than proactive, it’s just as likely to be actively harmful. Bad code isn’t technical debt, it’s a trapdoor, or a cancer if it starts to spread.
Adding code without requirements is a clear way to hokey-cokey code or creeping complexity. If you can’t say that your change will improve the code for other developers, the customer, or the users, stop and think.
It’s not just changes that cause problems. Unthought architecture can be even more dangerous. Obviously statically typed code is better than dynamic, because the compiler does something to protect you. Except static typing doesn’t protect you from null references, it doesn’t protect you from yourself.
It’s obviously better to have some logging than no logging. Unless you log everything and can’t find anything. Unless you log user and database passwords in the clear on your web server.
Every line of code you write is a breeding ground for bugs and security holes. If you remove complexity, and embrace simplicity, nothing is the most secure, most reliable way to implement something, and you need to justify the risks that come from changing that by giving the change a reason to happen.
It’s not just code
Is it better to have a project plan for a different project with different deadlines than no project plan? And even if it has the name of your project at the top and estimates you wrote, is it still a realistic plan for your project?
And are they your use cases?
Strive for quality via simplicity (and go read Zen And The Art Of Motorcycle Maintenance: 40th Anniversary Edition to truly understand that). You Aren’t Going To Need It. So don’t write it, until you do. Embrace nothing when the right something is unclear.
It’s not always easy, especially when we want to look busy, but sometimes your most productive hour is the one you spent watching that presentation on your todo list, rather than writing that $6bn dollar error.
Change requests are a major part of software development. If you think in an agile way, every card is a change, and that is what your development delivers. I still don’t trust change.
Impact Assessments try to document what impacts a change will have, both the desirable, and the inevitable. Good code is code that makes this easier, but many changes don’t respect good code boundaries, especially changes around the inflection points.
Let’s consider the shopping example from the inflection points post again. We take payment, we send an email confirmation, we start a warehouse workflow and a delivery workflow.
The boss announces some brilliant news. Your UK operation has bought out your US distributor, and all he wants to do is update the system so that US buyers can use the same shopping cart. That’s it. Simple change, allow USA addresses and credit cards.
Except your payment provider doesn’t accept credit cards. No problem, US cards can use the distributor’s existing payment provider. Add a branch, close the story.
Except your shipping provider has a different API for their US site. No problem, add a new handler, add a branch on shipping address when you create the shipping request inside the payment method. Close the story.
Except the distributor has their own warehouse and you need to Decrement their stock levels and kick off their stock process instead. No problem. Abstract it behind a warehouse handler, add a branch on shipping address when you create the packing request inside the payment method. Close the story.
Except the payment adds VAT to all the orders, when it sends them to the payment provider. No problem, add the
US state rates in the payment page, and pass the new total to the credit card provider. Close the story.
Now count the new decision paths, and the implicit coupling you’ve now introduced between the payment processor, the order calculations, the packing handler and the delivery service. Wouldn’t it be better to have a US and a UK order and just branch once?
At this point you may want to cancel any new requirements until you can refactor.
And I haven’t got through all the implications of this change for this step, and this is just one change. Has anyone else seen this happen?