31 Jan 2019

feedPlanet Twisted

Itamar Turner-Trauring: Do they have work/life balance? Investigating potential employers with GitHub

When you're searching for a new programming job you want to avoid companies with long work hours. You can ask about work/life balance during the interview (and unless you're desperate, you always should ask), but that means wasting time applying and interviewing at companies where you don't want to work.

What you really want is to only apply to companies that actually allow-or even better, encourage-good work/life balance.

Close reading of the job posting and company hiring pages can sometimes help you do that, but some good companies don't talk about it, and some bad companies will just lie.

So in this article I'll explain how you can use GitHub to empirically filter out at least some companies with bad work-life balance.

Let's look at GitHub profiles

If you go to the profile for a GitHub user (here's mine) you will see a chart showing contributions over time. The columns are weeks, and each row is a day of the week.

Each square shows contribution on a particular day: the darker the color, the more contributions.

What's most interesting here are the first and last rows, which are Sundays and Saturdays respectively. As you can see in the image above, this GitHub user doesn't tend to code much on the weekends: the weekend boxes are mostly blank.

You can also use this UI to see if the company uses GitHub at all. Given this many boxes, the user's employer probably does use GitHub, but you can also click on a particular box and see the specific contributions. In this case, you would see that on one particular weekday the user contributed to "private repositories", presumably those for their employer:

On the other hand, if you were to click on the weekend boxes you would see that all the weekend contributions are to open source projects. In short, this user doesn't code much on the weekend, and when they do it's on personal open source projects, not work projects.

Generalizing this process will allow you to filter out companies that don't have work/life balance for developers.

Investigating work/life balance using GitHub

There are two assumptions here:

Company size you can figure out from the company page or LinkedIn, usage of GitHub will be something we can figure out along the way.

This is not a perfect process, since users can disable showing private repository contributions, or it's possible the developer has personal private repositories. This is why you want to check as many profiles as possible.

Here's what you should do:

  1. Find a number of programmers who work for the company. You can do this via the company's website, and by the company's page on LinkedIn, which will list employees who have LinkedIn profiles. You can also check for members of the company's GitHub organization, if they have a public list, but don't rely on this exclusively since it will likely omit many employees.
  2. For each programmer, use your favorite search engine and search for "$NAME github" to find their GitHub profile. Try to do some sanity checks to make sure it's the right person, especially if they have a common name: location, organization membership, technologies used, etc..
  3. For each programmer, check if they contribute to private repositories during the week. You do can this by visually seeing if there are lots of green boxes, and by clicking on the Monday-Friday boxes in the timeline and reading the results below. If they mostly don't, the company might not use GitHub.
  4. If they do use GitHub at work, for each programmer, check if they code on the weekend. You can visually see if they have lots of green boxes on Sundays and Saturdays.
  5. If they do code on the weekend, check if those are work contributions. You can do this by clicking on the weekend boxes and seeing if those are contributions to private repositories.

Additional tips:

By the end of the process you will often have a decent sense if most of the programmers are coding on the weekend. Note that this method can only tell you if they don't have work/life balance-you still can't know if they do have work/life balance.

So even if you decide to apply to a company that passed this filter, you will still need to ask questions about work/life balance and listen closely during the interview process.

Always do your research

Before you apply for a job you should always do your research: read their website, reads all their job postings, talk to a friend there if you have one… and as I explained in this article, their GitHub profiles as well. You'll still need to look for warning signs during interviews, but research is still worth it.

The more you research, the more you'll know whether you want to work there. And if you do want to work there, the more you know there better your interview will go.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

31 Jan 2019 5:00am GMT

25 Jan 2019

feedPlanet Twisted

Moshe Zadka: Staying Safe with Open Source

A couple of months ago, a successful attack against the Node ecosystem resulted in stealing an undisclosed amount of bitcoins from CoPay wallets.

The technical flow of the attack is well-summarized by the NPM blog post. Quick summary:

  1. nodemon, a popular way to run Node applications, depends on event-stream.
  2. The event-stream maintainer has not had time to maintain it.
  3. right9control asked event-stream maintainer for commit privileges to help maintain it.
  4. right9control added a dependency on a new library, flatmap-stream.
  5. flatmap-stream contained malicious code to steal wallets.


A number of methods were done to disguise the attack.

The dependency was an added in a minor version, and a new version was immediately released. This meant that most projects, which pin to minor, would get the updates, while it stayed invisible on the main GitHub landing page, or the main npm landing page.

The malicious code was only in the minified version of the library that was uploaded to npm.org. The non-minified source code on both GitHub and npm.org, as well as the minified code on GitHub, did not contain the malicious code.

The malicious code was encrypted with a key that used the description of other packages in the dependency tree. That made it impossible to understand the attack without guessing which package decrypts it.

The combination of all those methods meant that the problem remained undetected for two months. It was only luck that detected it: the decryption code was using a deprecated function, and investigating the deprecation message led to the issue being figured out.

This bears thinking about: if the code had been written slightly better, the problem would have still be happening now, and nobody would be the wiser. We should not discount the possibility that currently, someone who followed the same playbook but managed to use AES correctly is still attacking some package, and we have no idea.

Solutions and Non-Solutions

I want to discuss some non-solutions in trying to understand how this problem came about.

Better Vetting of Maintainers

It is true, the person who made this commit had an obviously-auto-generated username (<word>-<digit>-<word>) and made few contributions before getting control. But short of meeting people in person, I do not think this would work.

Attackers adapt. Ask for better usernames, they will generate "<firstname>-<lastname>" names. Are you going to disallow my GitHub username, moshez? Ask for more contributions, you will get some trivial-code-that's-uploaded-to-npm, autogenerated a bit to disguise it. Ask for longer commit history, they'll send fixes to trivial issues.

Remember that this is a distributed problem, with each lead maintainer having to come up with a vetting procedure. Otherwise, you get usernames through the vetting process, and then you use those to spam maintainers, who now are sure they can trust those "vetted".

In short, this is one of the classical defenses that fails to take into considerations that attackers adapt.

Any Solution That Depends on JavaScript-specific Things

This attack could easily have been executed against PyPI or RubyGems. Any solution that relies on JavaScript's ability to have a least-access-based solution only helps make sure that these attacks go elsewhere.

It's not bad to do it. It just does not solve the root cause.

This also means that "stop relying on minified code" is a non-solution in the world where we encourage Python engineers to upload wheels.

Any Solution That Depends on "Audit Code"

A typical medium-sized JavaScript client app depends on some 2000 packages. Auditing each one, on each update, would make using third-packages untenable. This means that start-ups playing fast and loose with these rules would gain an advantage over those who do not. Few companies can afford that pay that much for security.

Hell, we knew this was a possibility a few months before the attack was initiated and still nobody did code auditing. Starting now would mostly mean availability bias, which means it would be over as soon as another couple of months go by without a documented attack.

Partial Solution -- Open Source Sustainability

If we could just pay maintainers, they would be slightly more comfortable maintaining packages and less desperate for help. This means that it would become inherently slightly harder to quickly become a new maintainer.

However, it is worthwhile to consider that this still would not solve the subtler "adding a new dependency" attack described earlier: just making a "good" library and getting other libraries to depend on it.


I do not know how to prevent the "next" attack. Hillel makes the point that a lot of "root causes" will only prevent almost-exact repeats, while failing to address trivial variations. Remember that one trivial variation, avoiding deprecation warnings, would have made this attack much more successful.

I am concerned that, as an industry, we are not discussing this attack a mere two months after discovery and mitigation. We are vulnerable. We will be attacked again. We need to be prepared.

25 Jan 2019 5:00am GMT

Itamar Turner-Trauring: A 4-day workweek for programmers, the easy way

You're dreaming of a programming job with 30 hours a week, a job where you'll have time for your own projects, your own hobbies. But this sort of job seems practically non-existent-almost no one advertises programming jobs with shorter workweeks.

How do you carve out a job like this, a job with a shorter workweek?

The ideal would be some company or employer where you just can ask for a shorter workweek, without having to apply or interview, and have a pretty good chance of getting a "yes".

In this post I'll talk about the easiest way to get what you want: negotiating at your current job.

The value of being an existing employee

as an existing employee you are much more valuable than an equally experienced programmer who doesn't work there.

During your time at your employer you have acquired a variety of organization-specific knowledge and skills. It can take quite a while for a new employee to acquire these, and during the ramp-up period they will also take up their colleagues' time.

Here are just a few of the things that you've likely learned during your time as an employee:

Not only do you have hard to-replace skills and knowledge, you also have your work record to build on: your manager knows what you can do. Once you've been working for a manager for a while they'll know your skills, and whether they can trust you.

A real-life example

In my own career, being an existing employee has benefited me on multiple occasions:

After a number of years working as a software engineer for one company, I got a bad case of RSI (repetitive strain injury). I could no longer type, which meant I could no longer work as a programmer. But I did stay on as an employee: one of the managers at the company, who I'd worked for in an earlier role, offered me a position as a product manager.

In part this was because the company was run by decent people, who for the most part took care of their employees. But it was also because I had a huge amount of hard-to-replace business and technical knowledge of the company's product, in a highly complex domain.

I worked as a product manager for a few years, but I never really enjoyed it. And with time my hands recovered, at least partially, potentially allowing me to take up programming again. After my daughter was born, my wife and I decided that I'd become a part-time consultant, and take care of our child the rest of the time, while she continued working full-time.

My manager was upset when I told him I was leaving. I felt bad-but really, if your boss is unhappy when you're leaving, that's a good thing.

In fact, my boss offered to help me find a less-than-full-time programming position within the company so I wouldn't have to leave. I'd already made up my mind to go, but under other circumstances I might have taken him up on the offer.

Notice how I was offered reduced hours, even though companies will never advertise such positions. That's the value of being an existing employee.

Asking for what you want

Unless you work for a really bad manager-or a really badly managed company-a reasonable manager would much prefer to have your experience for 4 days a week than have to find a train a replacement. That doesn't mean they'll be happy if you ask for a shorter workweek: you are likely to get some pushback.

But if you have a strong negotiating position-financial savings, valuable work, the willingness to find another job if necessary-there's a decent chance they will eventually say "yes".

Does negotiating seem too daunting, or not something you can do? Plenty of other programmers have done it, even those with no previous negotiation experience.

Much of this article was an excerpt from my book, Negotiate a 3-Day Weekend. It covers everything from negotiation exercises you can do on the job, to a specific script for talking to your boss, to negotiating at new employers if you can't do it at your current job.

With a little bit of practice, you can get the free time you need.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

25 Jan 2019 5:00am GMT

18 Jan 2019

feedPlanet Twisted

Itamar Turner-Trauring: Negotiate your salary like a 6-year old

You're applying for jobs, you're hoping to get an offer soon-and when you do you'll have to face the scary issue of negotiation.

If you read a negotiation guide like Valerie Aurora's HOWTO (and you should!) you're told you need to negotiate: you need to ask for more. And that's good advice.

The problem is that asking for more is scary: it feels confrontational, your body will kick in with an unhelpful adrenaline surge, it's just not comfortable. And honestly, given you only negotiate your salary every few years, that adrenaline surge probably isn't going to go away.

But I think you can get past that and negotiate anyway-by embracing your inner 6-year old. In particular, a 6-year old negotiating for snacks on a playdate.

Snack time!

Let's set the scene.

A 6-year old named Emma is visiting her friend Jackson, and now it's time for a snack. Jackson's parent-Michael-now needs to feed Emma.

Michael would prefer the children not eat crackers, but he has a problem. Michael has some authority over Jackson since he's his parent, and some knowledge of what Jackson is willing to eat. So he can say "you're eating one of these mildly healthy snacks" and that's the end of it.

But Emma is just visiting: Michael has less authority, less knowledge, and a hungry 6-year old is Bad News. So Michael comes up with an acceptable range of snacks, and tries his best to steer towards the ones he considers healthier.

The conversation goes something like this:

Michael: "Would you like some fruit?"

Emma: blank stare.

Michael: "How about same cheese?"

Emma: shakes her head.

Michael: "Yogurt?"

Emma: shakes her head.

Michael: "Crackers?"

Emma and Jackson: "Yes!"

Michael has committed to feeding Emma something, he doesn't want her to go hungry-but he doesn't have the normal leverage he has as a parent. As a result, Emma can just stall until she gets what she wants. Particularly enterprising children will ask for candy (even when they would never get candy at home!), but stalling seems well within the capacity of most 6-year olds.

Salary time!

The dynamic of hiring a new employee is surprisingly similar.

Whoever is making the offer-HR, an internal recruiter, or the hiring manager-has already committed to hiring you. They've decided: they had interviews and meetings and they want to get it over with and just get you on board.

So they come up with an acceptable salary range, and offer you the low end of the range. If you accept that, great. And if you say "can you do better?"

Well, they've already decided on their acceptable salary range: they'll just move up within that range. They're not insulted, they're used to this. They're not horrified at a hole in their budget, this is still within their acceptable range.

You went from fruit to crackers, and they can live with that. All you have to do is ask.

Embrace your inner 6-year old

Much of what determines your salary happens before you get the offer, when the decision is made about what salary range to offer you.

You can influence this by the language on your resume, by how you present yourself, how you interview, and by noting you have competing offers. It may not feel like negotiation, but it's all part of the process-and while it's a set of skills you can master as an adult, that part is far beyond what your 6-year old self could do.

But the actual conversation about salary? Pretend you're 6, pretend it's a snack, and ask for more-chances are you'll get some delicious crackers.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

18 Jan 2019 5:00am GMT

09 Jan 2019

feedPlanet Twisted

Moshe Zadka: Checking in JSON

JSON is a useful format. It might not be ideal for hand-editing, but it does have the benefit that it can be hand-edited, and it is easy enough to manipulate programmatically.

For this reason, it is likely that at some point or another, checking in a JSON file into your repository will seem like a good idea. Perhaps it is even beyond your control: some existing technology uses JSON as a configuration file, and the easiest thing is to go with it.

It is useful to still keep the benefit of programmatic manipulation. For example, if the JSON file encodes a list of numbers, and we want to add 1 to every even number, we can do:

with open("myfile.json") as fp:
    content = json.load(fp)
content = [x + (2 % i) for i, x in enumerate(content)]
with open("myfile.json", "w") as fp:
    json.dumps(fp, content)

However, this does cause a problem: presumably, before, the list was formatted in a visually-pleasing way. Having dumped it, now the diff is unreadable -- and hard to audit visually.

One solution is to enforce consistent formatting.

For example, using pytest, we can write the following test:

def test_formatting():
    with open("myfile.json") as fp:
        raw = fp.read()
    content = json.loads(raw)
    redumped = json.dumps(content, indent=4) + "\n"
    assert raw == redumped

Assuming we gate merges to the main branches on passing tests, it is impossible to check in something that breaks the formatting. Automated programs merely need to remember to give the right options to json.dumps. However, what happens when humans make mistakes?

It turns out that Python already has a command-line tool to reformat:

$ python -m json.tool myfile.json > myfile.json.formatted
$ mv myfile.json.formatted myfile.json

A nice test failure will remind the programmer of this trick, so that it is easy to do and check in.

09 Jan 2019 6:00am GMT

Itamar Turner-Trauring: Competing with a "Stanford grad just dying to work all nighters on Red Bull"

A reader of my newsletter wrote in, talking about the problem of finding a job with work/life balance in Silicon Valley:

It seems like us software engineers are in a tough spot: companies demand a lot of hard work and long hours, and due to the competitiveness here in Silicon Valley, you have to go along with it (or else there's some bright young Stanford grad just dying to work all nighters on Red Bull to take your place).

But they throw you aside once the company has become established and they no longer need the "creative" types.

In short, how do you get a job with work/life balance when you're competing against people willing to work long hours?

All nighters make for bad software

The starting point is realizing that working long hours makes you a much less productive employee, to the point that your total output will actually decrease (see Evan Robinson on crunch time). If you want to become an effective and productive worker, you're actually much better off working normal hours and having a personal life than working longer hours.

Since working shorter hours makes you more productive, that gives you a starting point for why you should be hired.

Instead of focusing on demonstrative effort by working long hours, you can focus on identifying and solving valuable problems, especially the bigger and longer term problems that require thought and planning to solve.

Picking the right company

Just because you're a valuable, productive programmer doesn't mean you're going to get hired, of course. So next you need to find the right company.

You can imagine three levels of managerial skill:

When you look for a job you will want to avoid Level 1 managers. However good your work, they will be happy to replace you with someone incompetent so long as they can get more hours out of them. So you'll be forced to work long hours and work on broken code.

Level 3 managers are ideal, and they do exist. So if you can find a job working for them then you're all set.

Level 2 managers are probably more common though, and you can get work/life balance working for them-if you set strong boundaries. Since they can recognize actual competence and skills, they won't judge you during your interview based on how many hours you're willing to work. You just need to convey your skill and value, and a reasonable amount of dedication to your job.

And once you've started work, if you can actually be productive (and if you work 40 hours/week you will be more productive!) they won't care if you come in at 9 and leave at 5, because they'll be happy with your work.

Unlike Level 3 managers, however, you need to be explicit about boundaries during the job interview, and even more so after you start. Elsewhere I wrote up some suggestions about how to convey your value, and how to say "no" to your boss.

Employment is a negotiated relationship

To put all this another way: employment is a negotiated relationship. Like it or not, you are negotiating from the moment you start interviewing, while you're on the job, and until the day you leave.

You are trying to trade valuable work for money, learning opportunities, and whatever else your goals are (you can, for example, negotiate for a shorter workweek). In this case, we're talking about negotiating for work/life balance:

  1. Level 1 managers you can't negotiate with, because what they want (long hours) directly conflicts with what you want.
  2. Level 2 managers you can negotiate with, by giving them one of the things they want: valuable work.
  3. Level 3 managers will give you what you want without your having to do anything, because they know it's in the best interest of everyone.

Of course, even for Level 3 managers you will still need to negotiate other things, like a higher salary.

So how do you get a job with work/life balance? Focus on providing and demonstrating valuable long-term work, avoid bad companies, and make sure you set boundaries from the very start.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

09 Jan 2019 5:00am GMT

12 Dec 2018

feedPlanet Twisted

Itamar Turner-Trauring: Tests won't make your software correct

Automated tests are immensely useful. Once you've started writing tests and seen their value, the idea of writing software without them becomes unimaginable.

But as with any technique, you need to understand its limitations. When it comes to automated testing-unit tests, BDD, end-to-end tests-it's tempting to think that if your tests pass, your software is correct.

But tests don't, tests can't tell you that your software is correct. Let's see why.

How to write correct software

To implement a feature or bugfix, you go through multiple stages; they might be compressed or elided, but they are always necessary:

  1. Identification: Figure out what the problem is you're trying to solve.
  2. Solution: Come up with a solution.
  3. Specification: Define a specification, the details of how the solution will be implemented.
  4. Implementation: Implement the specification in code.

Your software might end up incorrect at any of these points:

  1. You might identify the wrong problem.
  2. You might choose the wrong solution.
  3. You might create a specification that doesn't match the solution.
  4. You might write code that doesn't match the specification.

Only human judgment can decide correctness

Automated tests are also a form of software, and are just as prone to error. The fact that your automated tests pass doesn't tell you that your software is correct: you may still have identified the wrong problem, or chosen the wrong solution, and so on.

Even when it comes to ensuring your implementation matches your specification, tests can't validate correctness on their own. Consider the following test:

def test_addition():
    assert add(2, 2) == 5

From the code's perspective-the perspective of an automaton with no understanding-the correct answer of 4 is the one that will cause it to fail. But merely by reading that you can tell it's wrong: you, the human, are key.

Correctness is something only a person can decide.

The value of testing: the process

While passing tests can't prove correctness, the process of writing tests and making them pass can help make your software correct. That's because writing the tests involves applying human judgment: What should this test assert? Does match the specification? Does this actually solve our problem?

When you go through the loop of writing tests, writing code, and checking if tests pass, you continuously apply your judgment: is the code wrong? is the test wrong? did I forget a requirement?

You write the test above, and then reread it, and then say "wait that's wrong, 2 + 2 = 4". You fix it, and then maybe you add to your one-off hardcoded tests some additional tests based on core arithmetic principles. Correctness comes from applying the process, not from the artifacts created by the process.

This may seem like pedantry: what does it matter whether the source of correctness is the tests themselves or the process of writing the tests? But it does matter. Understanding that human judgment is the key to correctness can keep you from thinking that passing tests are enough: you also need other forms of applied human judgment, like code review and manual testing.

(Formal methods augment human judgment with automated means… but that's another discussion.)

The value of tests: stability

So if correctness comes from writing the tests, not the tests themselves, why do we keep the tests around?

Because tests ensure stability. once we judge the software is correct, the tests can keep the software from changing, and thus reduce the chances of its becoming incorrect. The tests are never enough, because the world can change even if the software isn't, but stability has its value.

(Stability also has costs if you make the wrong abstraction layer stable…)

Tests are useful, but they're not sufficient

To recap:

  1. Write automated tests.
  2. Run those tests.
  3. Don't mistake passing tests for correctness: you will likely need additional processes and techniques to achieve that.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

12 Dec 2018 5:00am GMT

09 Dec 2018

feedPlanet Twisted

Moshe Zadka: Office Hours

If you want to speak to me, 1-on-1, about anything, I want to be able to help. I am a busy person. I have commitments. But I will make the time to talk to you.


  • I want to help.
  • I think I'll enjoy it. I like talking to people.


I can offer opinions and experience on programming in general, Python, UNIX, the software industry and other topics.

How did you come up with the idea?

I am indebted to Robert Heaton for the idea and encouragement.

Should I...?

Sure! Especially if you have few connections in the industry, and have questions, I can talk to you. I am a fluent speaker of English and Hebrew, so you do need to be able to converse in one of those...

E-mail me!

09 Dec 2018 5:30am GMT

03 Dec 2018

feedPlanet Twisted

Itamar Turner-Trauring: 'Must be willing to work under pressure' is a warning sign

As a programmer looking for a job, you need to be on the lookout for badly managed companies. Whether it's malicious exploitation or just plain incompetence, the less time you waste applying for these jobs, the better.

Some warning signs are subtle, but not all. One of the most blatant is a simple phrase: "must be willing to work under pressure."

The distance between we and you

Let's take a look at some quotes from real job postings. Can you spot the pattern?

If you look at reviews for these companies, many of them mention long working hours, which is not surprising. But if you read carefully there's more to it than that: it's not just what they're saying, it's also how they're saying it.

When it comes to talking about the company values, for example, it's always in the first person: "we are risk-takers, we are thoughtful and careful, we turn lead into gold with a mere touch of our godlike fingers." But when it comes to pressure it's always in the second person or third person: it's always something you need to deal with.

Who is responsible for the pressure? It's a mysterious mystery of strange mystery.

But of course it's not. Almost always it's the employer who is creating the pressure. So let's switch those job requirements to first person and see how it reads:

That sounds even worse, doesn't it?

Dysfunctional organizations (that won't admit it)

When phrased in the first person, all of these statements indicate a dysfunctional organization. They are doing things badly, and maybe also doing bad things.

But it's not just that they're dysfunctional: it's also that they won't admit it. Thus the use of the second or third person. It's up to you to deal with this crap, cause they certainly aren't going to try to fix things. Either:

  1. Whoever wrote the job posting doesn't realize they're working for a dysfunctional organization.
  2. Or, they don't care.
  3. Or, they can't do anything about it.

None of these are good things. Any of them would be sufficient reason to avoid working for this organization.

Pressure is a choice

Now, I am not saying you shouldn't take a job involving pressure. Consider the United States Digital Service, for example, which tries to fix and improve critical government software systems.

I've heard stories from former USDS employees, and yes, sometimes they do work under a lot of pressure: a critical system affecting thousands or tens of thousands of people goes down, and it has to come back up or else. But when the USDS tries to hire you, they're upfront about what you're getting in to, and why you should do it anyway.

They explain that if you join them your job will be "untangling, rewiring and redesigning critical government services.". Notice how "untangling" admits that some things are a mess, but also indicates that your job will be to make things better, not just to passively endure a messed-up situation.

Truth in advertising

There's no reason why companies couldn't advertise in the some way. I fondly imagine that someone somewhere has written a job posting that goes like this:

"Our project planning is a mess. We need you, a lead developer/project manager who can make things ship on time. We know you'll have to say 'no' sometimes, and we're willing to live with that."

Sadly, I've never actually encountered such an ad in the real world.

Instead you'll be told "you must be able to work under pressure." Which is just another way of saying that you should find some other, better jobs to apply to.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

03 Dec 2018 5:00am GMT

29 Nov 2018

feedPlanet Twisted

Hynek Schlawack: Python Application Dependency Management in 2018

We have more ways to manage dependencies in Python applications than ever. But how do they fare in production? Unfortunately this topic turned out to be quite polarizing and was at the center of a lot of heated debates. This is my attempt at an opinionated review through a DevOps lens.

29 Nov 2018 5:00pm GMT

Moshe Zadka: Common Mistakes about Generational Garbage Collection

(Thanks to Nelson Elhage and Saivickna Raveendran for their feedback on earlier drafts. All mistakes that remain are mine.)

When talking about garbage collection, the notion of "generational collection" comes up. The usual motivation given for generational garbage collection is that "most objects die young". Therefore, we put the objects that survive a collection cycle (and therefore have proven some resistance) in a separate generation that we scan less often.

This is an optimization if the probability of an object that has survived a cycle to be garbage by the time the next collection cycle has come around is lower than the probability of a newly allocated object to be garbage.

In a foundational paper Infant mortality and generational garbage collection, Dr. Baker laid out an argument deceptive in its simplicity.

Dr. Baker asks the question: "Can we model a process where most objects become garbage fast, but generational garbage collection would not improve things?". His answer is: of course. This is exactly the probability distribution of radioactive decay.

If we have a "fast decaying element", say with a half-life of one second, than 50% of the element's atoms decay in one second. However, keeping the atoms that "survived a generation" apart from newly created atoms is unhelpful: all remaining atoms decay with probability of 50%.

We can bring the probability for "young garbage" as high up as we want: a half-life of half a second, a quarter second, or a microsecond. However, that is not going to make generational garbage collection any better than a straightforward mark-and-sweep.

The Poisson distribution, which models radioactive decay, has the property that P(will die in one second) might be high, but P(will die in one second|survived an hour) is exactly the same: the past does not give us information about the future. This is called the "no memory property" of Poisson distribution.

When talking about generational garbage collection, and especially if we are making theoretical arguments about its helpfulness, we need to make arguments about the distribution, not about the averages. In other words, we need to make an argument that some kinds of objects hang around for a long time, while others tend to die quickly.

One way to model it is "objects are bimodal": if we model objects as belonging to a mix of two Gaussian distributions, one with a small average and one with a big average, then the motivation for generational collection is clear: if we tune it right, most objects that survive the first cycle belong to the other distribution, and will survive for a few more cycles.

To summarize: please choose your words carefully. "Young objects are more likely to die" is an accurate motivation, "Most objects die young" is not. This goes doubly if you do understand the subtlety: do not assume the people you are talking with have an accurate model of how garbage works.

As an aside, some languages decided that generational collection is more trouble than it is worth because the objects that "die young" go through a different allocation style. For example, Go has garbage collection, but it tries to allocate objects on the stack if it can guarantee at compile-time they do not "escape". Because of that, the "first generation" is collected at stack popping time.

CPython has generational garbage collection, but it also has a "zeroth generation" of sorts: when functions return, all local variables get a "decref": a decrease in reference count. Those for whom that results in a 0 reference counts, which is often quite a few, get collected immediately.

29 Nov 2018 3:00am GMT

20 Nov 2018

feedPlanet Twisted

Thomas Vander Stichele: Recursive storytelling for kids

Most mornings I take Phoenix to school, as his school is two blocks away from work.

We take the subway to school, having about a half hour window to leave as the school has a half-hour play window before school really starts, which inevitably gets eaten up by collecting all the things, putting on all the clothes, picking the mode of transportation (no, not the stroller; please take the step so we can go fast), and getting out the door.

At the time we make it out, the subway is usually full of people, as are the cars, so we shuffle in and Phoenix searches for a seat, which is not available, but as long as he gets close enough to a pole and a person who looks like they'd be willing to give up a seat once they pay attention, he seems to get his way more often than not. And sometimes, the person next to them also offers up their seat to me. Which is when the fun begins.

Because, like any parent knows these days, as soon as you sit down next to each other, that one question will come:

"Papa, papa, papa… mag ik jouw telefoon?" (Can I have your phone? - Phoenix and I speak Dutch exclusively to each other. Well, I do to him.)

At which point, as a tired parent in the morning, you have a choice - let them have that Instrument of Brain Decay which even Silicon Valley parents don't let their toddlers use, or push yourself to make every single subway ride an engaging and entertaining fun-filled program for the rest of eternity.

Or maybe… there is a middle way. Which is how, every morning, Phoenix and I engage in the same routine. I answer: "Natuurlijk mag jij mijn telefoon… als je éérst een verhaaltje vertelt." (Of course you can have my phone - if you first tell me a story.)

Phoenix furrows his brows, and asks the only logical follow-up question there is - "Welk verhaaltje?" (Which story?)

And I say "Ik wil het verhaaltje horen van het jongetje en zijn vader die met de metro naar school gaan" (I want to hear the story of the little boy and his dad who take the subway to school.)

And he looks at me with big eyes and says, "Dat verhaaltje ken ik niet." (I don't know that story)

And I begin to tell the story:

"Er was eens… een jongetje en zijn vader." (Once upon a time, there was a little boy and his father. Phoenix already knows the first three words of any story.)
"En op een dag… gingen dat jongetje en zijn vader met de metro naar school." (And one day… the little boy and his father took the subway to school. The way he says "op een dag" whenever he pretends to read a story from a book is so endearing it is now part of our family tradition.)

"Maar toen de jongen en zijn vader op de metro stapten zat de metro vol met mensen. En het jongetje wou zitten, maar er was geen plaats. Tot er een vriendelijke mevrouw opstond en haar plaats gaf aan het jongetje, en het jongetje ging zitten. En toen stond de meneer naast de mevrouw ook recht en de papa ging naast het jongetje zitten." (But when the little boy and his father got on the subway, it was full of people. And the little boy wanted to sit but there was no room. Until a friendly woman stood up and gave up her seat to the little boy, so the little boy sat down. And then the man next to the woman also stood up and his father sat down next to him.)

"En toen de jongen op de stoel zat, zei het jongetje, Papa papa papa papa papa papa papa…"(And when the boy sat down on the chair, he said Papa papa papa papa papa papa)

"Ja?, zei papa." (Yes?, said papa.)

"Papa, mag ik jouw telefoon"? (Papa, can I have your phone?)

"Natuurlijk jongen….. als je éérst een verhaaltje vertelt." (Of course son… if you first tell me a story.)

At which point, the story folds in on itself and recurses, and Phoenix's eyes light up as he mouths parts of the sentences he already remembers, and joins me in telling the next level of recursion of the story.

I apologize in advance to all the closing parentheses left dangling like the terrible lisp programmer I've never given myself the chance to be, but making that train ride be phoneless every single time so far is worth it.

Flattr this!

20 Nov 2018 2:19am GMT

12 Nov 2018

feedPlanet Twisted

Itamar Turner-Trauring: Enthusiasts vs. Pragmatists: two types of programmers and how they fail

Do you love programming for its own sake, or do you do for the outcomes it allows? Depending on which describes you best you will face different problems in your career as a software developer.

Enthusiasts code out of love. If you're an enthusiast you'd write software just for fun, but one day you discovered your hobby could also be your career, and now you get paid to do what you love.

Pragmatists may enjoy coding, but they do it for the outcomes. If you're a pragmatist, you write software because it's a good career, or for what it enables you to do and build.

There's nothing inherently good or bad about either, and this is just a simplification. But understanding your own starting point can help you understand and avoid some of the problems you might encounter in your career.

In this post I will cover:

  1. Why many companies prefer to hire enthusiasts.
  2. The career problems facing enthusiasts, and how they can solve them.
  3. The career problems facing pragmatists, and how they can solve them.

Why companies prefer hiring enthusiasts

Before we move on to specific career problems you might face, it's worth looking at the bigger picture: the hiring and work environment.

Many companies prefer to hire enthusiast programmers: from the way they screen candidates to the way they advertise jobs, they try to hire people who care about the technology for its own sake. From an employer's point of view, enthusiasts have a number of advantages:

  1. In a rapidly changing environment, they're more likely to keep up with the latest technologies. Even better, they're more likely to do so in their free time, which means the company can spend less on training.
  2. Since they'd write software for free, it's easier to pay enthusiasts less money.
  3. It's also easier to get enthusiasts to work long hours.
  4. Finally, since enthusiasts care more about the technical challenge than the goals of the product, they're less likely to choose their work based on ethical or moral judgments.

But while many companies prefer enthusiasts, this isn't always in the best interest of either side, as we'll see next.

The career problems facing enthusiasts

So let's say you're an enthusiast. Here are some of the career problems you might face; not everyone will have all these problems, but it's worth paying attention to see if you're suffering from one or more of them.

1. Exploitation

As I alluded to above, companies like enthusiasts because they're worse negotiators.

If you love what you do you'll accept less money, you'll work long hours, and you'll ask less questions. This can cause you problems in the long run:

So even if you code for fun, you should still learn how to negotiate, if only out of self-defense.

2. Being less effective as an employee

Matt Dupree has an excellent writeup about why being an enthusiast can make you a worse worker; I don't want to repeat his well-stated points here. Here are some additional ways in which enthusiasm can make you worse at your job:

3. Work vs. art

Finally, as an enthusiast you might face a constant sense of frustration. As an enthusiast, you want to write software for fun: solve interesting problems, write quality code, fine-tune your work until it's beautiful.

But a work environment is all about outcomes, not about craft. And that means a constant pressure to compromise your artistic standards, a constant need to work on things that aren't fun, and a constant need to finish things on time, rather than when you're ready.

So unless you want to become a pragmatist, you might want to get back more time for yourself, time where you can write code however you like. You could, for example, negotiate a 3-day weekend.

The career problems facing pragmatists

Pragmatists face the opposite set of problems; again, not all pragmatists will have all of these problems, but you should keep your eye out to see if they're affecting you.

1. It's harder to find a job

Since many companies actively seek out enthusiasts, finding a job as a pragmatist can be somewhat harder. Here are some things you can do to work around this:

2. You need to actively keep your skills up

Since you don't care about technology for technology's sake, it can be easy to let your skills get out of date, especially if you work for a company that doesn't invest in training. To avoid this:

3. Pressure to work long hours

Finally, you will often encounter pressure both from management and-indirectly-from enthusiast peers to work long hours. Just remember that working long hours is bad for you and your boss (even if they don't realize it).

Programmer, know thyself

So are you an enthusiast or a pragmatist?

These are not exclusive categories, nor will they stay frozen with time-these days I'm more of a pragmatist, but I used to be more of an enthusiast-but there is a difference in attitudes. And that difference will lead to different choices, and different problems.

Once you know who you are, you can figure out what you want-and avoid the inevitable obstacles along the way.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

12 Nov 2018 5:00am GMT

09 Nov 2018

feedPlanet Twisted

Itamar Turner-Trauring: The cold incubator: the VC dream of workerless wealth

Chicken incubators are hot: eggs need heat to thrive. This was a different sort of incubator, a glass enclosure within a VC office. The VCs had the best views, but even we could look down ten stories and see the sun sparkling on the Charles River and reflecting off the buildings of downtown Boston.

It was summer when I joined the startup, but even so the incubator was freezing. The thermostat was skewed by a hot light sensor right below it, and the controls reset every night, so mornings were frigid. I took to wearing sweaters and fingerless gloves; the team at the other side of the incubator had figured out a way cover the AC vents with cardboard in a way that wasn't visible to passersby.

But I didn't have to suffer from the cold for very long. Soon after I joined the startup I unwittingly helped trigger our eviction from the rent-free Eden of the incubator to the harsher world outside.

The fall from grace

Most of the people who worked out of the incubator just used a laptop, or perhaps a monitor. But I like working with a standing desk, with a large Kinesis keyboard, and an external monitor on top.

My desk towered over everyone else: it was big and imposing and not very neat. Which is to say, the incubator started looking like a real office, not a room full of identical tables with a few Macbook Airs scattered hither and yon. And standing under the freezing air conditioner vent made my arms hurt, so I had to setup my desk in a way that was visible from the outside of the incubator.

And that view was too much for one of the partners in the VC firm. There were too many of us, we had too many cardboard boxes, my standing desk was just too big: it was time for us to leave the incubator.

The dream of workerless wealth

VCs take money, and (if all goes well) turn it into more money. But the actual reality of the work involved was too unpleasantly messy, too uncouth to be exposed to the sensibilities of wealthy clients.

We had to be banished out of sight, the ever-so-slightly grubby realities of office work hidden away, leaving only the clean cold dream of capital compounding through the genius of canny investors.

This dream-a dream of profit without workers-is the driving force behind many an investment fad:

And if you work for a VC-funded startup, this dream takes on a nightmarish tinge when it turns to consider you.

Unbanished-for now

The point here is not that VCs want to reduce effort: who wouldn't want a more efficient world? The dream is not driven by visions of efficiency, it's about status and aesthetics: doing actual work is ugly, and paying for work is offensive.

Of course, some level of work is always necessary and unavoidable. And so VC firms understand that the startups they fund must hire workers like me and you.

But the cold dream is always there, whispering in the background: these workers take equity, they take cash, they're grubby. So when times are good hiring has to be done as quickly as possible, but when times are bad the layoffs come just as fast.

And when you are working, you need to work as many hours as humanly possible, not because it's efficient-it isn't-but because paying for your time is offensive, and so you better damn well work hard. Your work may be necessary, but to the cold dream it's a necessary-and ugly-evil.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

09 Nov 2018 5:00am GMT

07 Nov 2018

feedPlanet Twisted

Moshe Zadka: The Conference That Was Almost Called "Pythaluma"

As my friend Thursday said in her excellent talk (sadly, not up as of this time) naming things is important. Avoiding in-jokes is, in general, a good idea.

It is with mixed feelings, therefore, that my pun-loving heart reacted to Chris's disclosure that the most common suggestion was to call the conference "Pythaluma". However, he decided to go with the straightforward legible name, "North Bay Python".

North of the city by the bay, lies the quiet yet chic city of Petaluma, where North Bay Python takes place. In a gold-rush-city turned sleepy wine country, a historical cinema turned live show venu hosted Python enthusiasts in a single-track conference.

Mariatta opened the conference with her gut-wrenching talk about being a core Python developer. "Open source sustainability" might be abstract words, but it is easy to forget that for a language that's somewhere between the first and fifth most important (depending on a metric) there are less than a hundred people supporting its core -- and if they stop, the world breaks.

R0ml opened the second day of the conference talking about how:

Talks are still being uploaded to the YouTube channel, and I have already had our engineering team at work watch Hayley's post-mortem of Jurassic Park.

If you missed all of it, I have two pieces of advice:

If you went there, I hope you told me hi. Either way, please say hi next year!

07 Nov 2018 8:00am GMT

02 Nov 2018

feedPlanet Twisted

Itamar Turner-Trauring: When and why to clean up your code: now, later, never

You've got to meet your deadlines, you've got to fix the bug, you've got to ship the product.

But you've also got to think about the future: every bug you introduce now will have to be fixed later, using up even more time. And all those deprecated APIs, out-of-date dependencies, and old ways of doing things really shouldn't be there.

So when do you clean up your code?

Do you do it now?



In this article I'll go over a set of heuristics that will help you decide when to apply three kinds of fixes:

  1. Updating dependencies that are out-of-date and usages of deprecated APIs.
  2. Refactoring to fix bad abstractions.
  3. Miscellaneous Cleanups of anything else, from coding standard violations to awkward idioms.

Heuristics by situation


Before you start building something in earnest, you might start with a prototype (or what Extreme Programming calls a "spike"). You're not going to keep this code, you're just exploring the problem and solution space to see what you can learn.

Given you're going to throw away this code, there's not much point in Updating or Miscellaneous Cleanups. And if you're just trying to understand an existing API or technical issue, you won't be doing much Refactoring wither.

On the other hand, if your goal with prototyping is to find the right abstraction, you will be doing lots of Refactoring.

  1. Updating: never.
  2. Refactoring: now if you're trying to prototype an API or abstraction, otherwise never.
  3. Miscellaneous Cleanups: never.

A new project

When you're starting a completely new project, the decisions you make will have a strong impact on the maintenance code going forward.

This is a great opportunity to start with the latest (working) dependencies, situation-specific best practices and maintainable code, and the best abstractions you can come up with. You probably won't get them completely right, but it's usually worth spending the time to try to get it as close as possible.

  1. Updating: now.
  2. Refactoring: now.
  3. Miscellaneous Cleanups: now.

An emergency bugfix

You need to get a bug fix to users ASAP. While you might see problems along the way, but unless they're relevant to this particular bug fix, it's best to put them off until later.

Sometimes that might mean fixing the bug twice: once in a quick hacky way, and a second time after you've done the necessary cleanups.

  1. Updating: later.
  2. Refactoring: later.
  3. Miscellaneous Cleanups: later.

New feature or non-urgent bugfix

When you have a project in active development and you're doing ongoing work, whether features or bug fixes, you have a great opportunity to incrementally clean up your code.

You don't need to fix everything every time you touch the code. Instead, an ongoing cleanup of code you're already touching will cumulatively keep your codebase in good shape. See Ron Jefferies' excellent article for details.

  1. Updating: now, for code you're touching.
  2. Refactoring: now, for code you're touching.
  3. Miscellaneous Cleanups: now, for code you're touching.

A project in maintenance mode

Eventually your project will be finished: not much new development is done, and mostly it just gets slightly tweaked every few months when something breaks or a drop-down menu needs an extra option.

Your goal at this point is to do the minimum work necessary to keep the project going. Refactoring and Miscellaneous Cleanups aren't necessary, but Updates might be-dependencies can stop working, or need security updates. And jumping your dependencies 5 years ahead is often much harder than incrementally doing 5 dependency updates at yearly intervals.

So whenever you have to do fix a bug, you should update the dependencies-ideally to Long Term Support releases to reduce the need for API usage updates.

  1. Updating: now, ideally to Long Term Support releases.
  2. Refactoring: never.
  3. Miscellaneous Cleanups: never.

Balancing present and future

Software projects tend to ongoing processes, not one-off efforts. A cleanup now might save you time later-but if you have a deadline to meet now, it might be better to put it off even at the cost of slightly more work later on.

So takes this article only a starting point: as with any heuristic, there will be exceptions to the rule, and you need to be guided by your situation and your goals.

There's always too much work to do: too many features to implement, too many bugs to fix-and working evenings and weekends won't help.

The real solution is working fewer hours. Learn how you can get a 3-day weekend.

02 Nov 2018 4:00am GMT