Amazon is in that club of employers (Google, Twitter, Facebook, Microsoft, etc), where working there functions as a stamp of quality. Their employees are frequently cold called by recruiters working for other members of the club, middle tier companies, and start ups that cannot get enough people through their personal network. Amazon pays very well relative to most jobs, even many programming jobs, but it does not pay as well as other members of the club. The salary is just a little less than you’d make elsewhere, but equity and bonuses are backloaded such that many people are driven out before they receive the bulk of them. The health insurance isn’t as good. I realize paying for your own lunch is normal, but Amazon makes employees pay for a lot of things other companies offer for free, like ergonomic keyboards. And then there’s the work environment.
How does Amazon maintain a talent pool equivalent to the other prestige club members while paying less?
This is anecdotal, but my friends at Amazon are much more likely to have come from unprestigious companies or schools than my friends at other club companies. Working at Amazon doesn’t make them smarter, but it does provide widely-accepted proof of their intelligence that they didn’t have before, and can leverage into cushier jobs later. In some ways Amazon’s reputation for chewing people up and spitting them out is a feature here, because leaving after 18 months raises 0 questions among other employers.
So my hypothesis is Amazon invests more in finding and vetting smart people who aren’t currently holding Official Smart Person Cards, and that part of employees’ compensation is getting that card. In this way it’s like the US Armed Forces, which are grueling and don’t pay well but people tend to leave them with many more options than they started with.
I’m unconvinced this is a winning strategy. Operational turnover is expensive, and bad working conditions decrease people’s productivity even when they’re well compensated. But it does at least explain why it hasn’t collapsed already.
Recently I read So Good They Can’t Ignore You. I have well known trouble distinguishing “things the book said” from “thoughts I had while reading it”, so I’m just going to tell you what I thought and if you’re interested you can track down the book and see how original this was.
The book’s official tagline is “Why Skills Trump Passion in the Quest for Work” and it frames itself as anti-passion, but Newport eventually admits that’s a marketing hook. Mostly his thesis is that passion alone will not make you happy, and skill can be used to extract concessions from your employer that make life more pleasant, so you should focus on skill. Passion is a great driver for developing skills so that seems like a weak criticism of passion (he puts all the positive aspects of passion under “mission”), but he also suggests that it’s impossible to find something you’re really passionate about until you have a certain amount of skill, so still focus on that. Given the essentially infinite number of skills available it seems like there’s room for your interests to have input earlier in the process. I think what he’s really attacking is the idea that your job should be a source of entertainment. That has given me severe clarity in what I’m looking for job-wise.
The epitome of the jobs-as-entertainment model is “Choose a job you love, and you will never have to work a day in your life”. That is neither true nor desirable, unless you use a very specific definition of work. Let’s take this blog. No one is forcing me to write it. For the first year I had something like five readers, most of whom I regularly talked to in person. Obviously it was motivated entirely internally, which is another way of saying “powered by love.” And yet, it was still work. Even if you discount all the reading I did as “things I would have read for fun anyway”*, and the thought I put into it as “a thing I can’t stop my brain from doing”, I have to organize my thoughts and translate them to things other people can understand. I had to configure the page layout so it was neither hideous nor generic. I had to proofread and correct mistakes. I had to retype entries from scratch after WordPress broke again. I had to correct all the typos Beth pointed out to me after I published. Nothing past writing the first draft could be considered entertaining the way playing Twenty is entertaining, and even the reading, thinking, and first drafts took considerable time and effort. That sounds like work to me. And yet obviously I was doing something I loved because there was no other reason to do it. **
Love doesn’t erase the fact that something is work. It can motivate the work, it can cushion the annoyances of work, it can give you the incentive to continue when you would otherwise give up, but it can’t erase it. And I kind of resent attempts to try. I am a grown up human, I do not need swings or field trips to chocolate factories to trick me into swallowing a pill showing up.
What I do need is a good working environment, clarity around my goals, and the tools to achieve them. Those are what let me accomplish things, which is the reward I want from work. An occasional morale event when I we’re all producing really good work together can be really rewarding, but frequent events (like my job has) when I’m unhappy with my productivity feels like… like eating too much dessert when what I really need is a nutritious meal. My taste buds notice the sugar but I don’t get any of the associated psychological rewards, and it turns into queasiness. Speaking of which: office candy counts as entertainment but the nutritious-organic-local-cuddled meals at work are productivity aids. Let’s not throw the baby out with the bathwater.
Like 80,000 hours, So Good They Can’t Ignore You has a large emphasis on building career capital. This section isn’t perfect. A lot of the case studies are opportunistic (in the positive sense of the word), and serendipity is not repeatable. I feel like it’s skipping a critical step without acknowledging it. It’s also a little too “be a good worker bee until you’re called up to the the big leagues” for me; traditional corporate or academic paths work for a lot of people and the whole “the only thing holding you back is fear” narrative is stupid, but there’s a lot of other paths to success that get a lot less publicity. But this was still useful.
I have some topics I find both interesting and skills that would be useful in an associated career. But as you may have noticed, I have a lot of interests, many of which require expensive, brittle credentials to pursue. It would suck to spend years in school only to get bored with the field. I highly suspect interests are a better predictor of what will be entertaining than what will be rewarding. What SGTCIY suggests in this situation (actually all situations, but I think it applies to me more than most) is to build capital in things that will be useful in service to lots of interests/goals. Like, say, programming, a skill and job I already have but really always skated through on raw intelligence and a willingness to do low status work. Between this book and not getting a job I really wanted I’ve started make deliberate choices and investing.
It’s also really nice to read a career guide by someone with a career that is not writing career guides (Newport wrote the book in between finishing a computer science PhD and starting a professorship), and one with writing skills to boot. I finished the book in two days because it was just that readable.
*I used to read things with the explicit goal of blogging about them; they were worth blogging about so rarely I stopped.
**I was planning on using the blog as a portfolio for job purposes, but one of the reasons blogging works as a signal of interest and skill is that it’s so costly and low-reward no one would do it unless they loved it.
In Utopia of Rules David Graeber introduces the concept of interpretive labor. This will be stunningly useful in discussing how to handle sensitive discussions and yet there’s nothing on the internet about it, so please forgive this digression to explain it.
No two people are alike, everyone interprets a given action a little differently. Often you need to put work in to understand what people mean. This can be literal- like straining to understand an accent- or more figurative- like remembering your chronically late friend is from a culture where punctuality is not a virtue, so it’s not a sign they don’t value you. The work it takes to do that is interpretive labor. Interpretive labor also includes the reverse: changing what you would naturally do so that the person you are talking to will find it easier to understand. Tell culture is in large part an attempt to reduce the amount of interpretive labor required. Here are a few examples of interpretive labor in action:
Immigrants are expected to adopt the cultural norms of their new country.
Parents spend endless hours guessing whether their infant is crying because it’s hungry, needs a fresh diaper, or just felt like screaming.
Newbies to a field need to absorb jargon to keep up, or experts need to slow themselves down and explain it.
There’s a whole chain of schools that teach poor, mostly minority students business social norms, by which they mean white-middle-class norms. There is no school teaching white middle class kids how to use the habitual be properly.
Crucial Conversations/Non-Violent Communication/John Gottman’s couples therapy books/How to Talk so Kids Will Listen and Listen so Kids Will Talk are all training for interpretive labor.
Graeber himself is talking about interpretative labor in the context of bureaucratic forms, which can simultaneously dump a lot of interpretative labor on the individual (bank forms don’t negotiate) but alleviate the need to be nice to clerks.
Comments in code.
With a few very specific exceptions (accents, certain disabilities, ), interpretive labor flows up the gradient of status or privilege. This can get pretty ugly
People who insist their code is self documenting.
Girls are told “snapping your bra means he likes you” and then expected to no longer be mad about it.
Bullied kids are told to forgive and forget because their bully “is trying to say they’re sorry”, even after repeated cycles of faux-apologies and bullying.
This is more tenuous, but I think there’s a good argument that a lot of the emotional abuse on the estranged parent boards comes from parents expecting unfair amounts of interpretive labor from their children, adult or minor.
Fundamentalist husband expects his wife to know his emotions and correct for them while he actively hides the emotion from himself.
A paraphrased quote from Mothers of Invention: A woman’s house slave has run away, greatly increasing the amount of work she has to do herself. She writes in her diary “Oh, if only she could think of things from my point of view, she never would let me suffer so.”
I think a large part of the anger around the concept of trigger warnings is related to interpretive labor. It shifts the burden from traumatized listeners to protect themselves or calm themselves down, to speakers to think ahead if something they are about to say could be upsetting. That’s work. Speaking without thinking is much easier. Like, stupidly easy. Ditto for Christians who feel they’re being oppressed when they’re asked to consider that not everyone has the same beliefs. That is way more work than assuming they do.
How does this relate to altruism? Charity generally flows down the status/privilege gradient, especially from rich to poor. If the givers don’t consciously change the rules, they will end up demanding large amounts of interpretive labor from their beneficiaries, and do less good in the process. Arguably this is what’s happening when Heifer International gives people livestock and they immediately sell it- the rich people decided what to give without sufficient input from the poor people they were giving it to, and the poor people had to do extra work to translate it into something they want. Or this post on Captain Awkward, from a woman trying to teach her tutoring volunteers to not be racist.
EDIT 9/7/18: I think I in appropriately conflated two different situations in this post: situations where interpretive labor closes the whole gap (e.g. understanding an accent), and things where even after correct interpretation there is still a problem. The problem in that bullying example isn’t just that the victim doesn’t understand how the bully wants to apologize, it’s that the bully is going to keep bullying.
I had this great essay written in my head about how good testing was great when you were learning, because you can’t copy paste tests like you can product code. Then it turned out that it was impossible to test notifications. Not difficult, literally impossible. The ability to test directly has been deliberately blocked for security reasons, and you can’t mock it because the relevant class doesn’t have a default constructor. The most direct path I see right now is extending EasyMock to work on classes without default constructors, and I assume if that were easy someone would have done it already.
So here’s Hunger Tracker version 0.3, sans Aesop. It has all the features I promised in 1.0, but there’s some UX work I want to do before calling it done.
I’ve always admired Test Driven Development and longed for it from afar, but never had a chance to use it until I was on my own project. Most times when you crave something this intently it’s a let down, but no, this is every bit as fun as I thought it would be and more. It’s so relaxing, and it takes so much less mental RAM. I won’t go back to any other way.
I keep trying to explain why it is better and exactly how it made it obvious what I needed to do, but everything I write comes out boring and I don’t think it explained it anyway. Let’s try an analogy. You know how when you attempt a big cleaning project the middle looks worse than if you’d never started? And if you misjudge your energy level it stays that way, and then gets worse because you’re still living your life? Or maybe you misjudged the amount of space something required and your plan becomes unworkable, at which point you can improvise or revert? That’s what regular coding feels like to me. You don’t know if something’s working until it’s all working.
I’ve been cleaning up my apartment lately, including getting rid of things I don’t want and rearranging things I have so they are more accessible/easier to find/take less space. And I am being very careful not to do that. I pick tasks that can be done incrementally. If I want to move things from cabinet A to cabinet B, things in cabinet B get moved to cabinet C first. But cabinet C doesn’t have to be their permanent home, just a pareto improvement over the old one. I have consolidated three dressers into 1 + some other storage bins. I will probably rearrange those storage bins and the remaining dresser as I learn more about how the current arrangement works, but I was never going to be able to plan that out ahead of time anyway. This way I never get stuck halfway through, out of energy or realizing my plan is unworkable.
That is what TDD feels like to me. You might technically be writing and erasing a lot more code, but the mental effort is so much less. Every step leaves you a little bit better off, and you can concentrate your efforts on one problem at a time.
I was really unimpressed with the android tutorials I saw. I did Udacity’s, which is officially recommended by Google, but didn’t provide reference code or a way to check your project, so if something didn’t work you didn’t know where the error was. That’s bad enough when it’s a technology you’re well versed in, but with a new tech you don’t have any debugging tools. It’s like trying to learn a foreign grammar by having it explained to you in its own language, when you don’t even have any vocabulary yet, except your brain hasn’t been crafted by millions of years of evolution to do it. There are other tutorials, but most of them were written for the now-deprecated Eclipse IDE. Translating from one IDE or build system is not a big deal when you’re familiar with at least one of them, but at the beginning you don’t even know what to Google. That’s why you’re doing a tutorial. It’s even more fun with Android because it uses a bunch of very common Java tools but requires slightly different usage than everything else.
So what I actually did was do Udacity long enough to know how to make baby’s first project, come up with a concept that I was pretty sure I could subdivide into google-able problems, and then did so, one at a time. I learned testing basically from scratch, because the two tutorials that covered it required me to know a ton of abstract android architecture, and none of it was explained well enough to mean anything unless you had already coded. “Make minor changes until you understand the permutations” is how every programmer I know learns, and yet no class teaches this way.
All of which leads me to believe a test-driven tutorial could be really useful. I’m picturing a project with a few very simple UI elements, and a series of commented out tests. Users would uncomment the tests one at a time, in order. The test would fail. The error message would be informative, maybe there would be a few suggestions for how to solve it. Then they would research on their own until they found a solution. They would know they had done it right because the test would be passing. Plus they’d learn testing tools at the same time, and those are extremely useful. This may be my next project.
TDD got me all of the features I wanted in HungerTracker 0.2 except notifications. I’m still poking at it, but notifications require a deep understanding of several concepts I’ve entirely ignored until now, and need several moving parts to work together to verify any of them. So here’s version 0.2, which has a greatly improved button layout and a scrollable list that shows as many or as few entries as actually exist.
Hunger Tracker needs to persist data past the closing of the app. Knowing nothing about Android I googled “android write to file” and used the first reasonable looking thing that came up. This was sufficient to let me write to and read a file, which was good enough for a first try and powerful enough for me to release version 0.1. But as I planned the next step I ran into problems. The read function I found required me to specify the number of chars I wanted in advance. I couldn’t spot the end of the file so I grabbed a fixed number of entries every time. I could extract the data as strings but couldn’t figure out how to make a proper scrolling list (even though I’d done one in the Udacity tutorial). Attempts at fixes felt muddled and high friction, which is usually a sign I’m afraid of losing data, either to a hard drive failure or to a introducing a bug and failing to detect it.
Step 1 in fixing this was setting up my github account so I had proper version control. Step 2 was testing. I spent a long while figuring how to properly test the kind of android class I was using (“android unit testing” being a surprisingly unhelpful search term), and then some basic tests of “The text fields that should be there, are they there?”.
The next step was to test the data storage. But I couldn’t figure out how to unit test that. If I tested whether the app was writing to the correct file I needed to look for the exact same file. But that means updating the test every time I change the name of the file, which I didn’t want to do. Plus seeing if the correct thing is written to it is ugly. Tests should be atomic (meaning it doesn’t matter what order you run them in), but the file is persistent, meaning I either need to clear it every time or factor in what previous tests have done. Plus I would have to shape the test around the exact storage format the app was using, but again that means making the test dependent on an implementation detail. I could trigger writing and then reading and make sure the display element was correct, but that’s testing two different things and a unit test should only test one.
What I finally worked out was that the handling of persistent data was not actually a core function of HungerTracker’s MainActivity. What I needed to do was separate out those functions into a separate class, and then use mock objects to make sure the expected calls were made. E.g. instead of the app writing to a file and the test looking at the exact file and verifying the writing, the app calls the HungerTrackerWriter object. The test swaps out the real HungerTrackerWriter with a fake one, and monitors that the expected call is made. This leaves the HungerWriter proper tests blissfully unaware of the implementation details while still verifying that the app is doing what was expected.
[Technical details: somewhere I read that the android junit framework handled mocks easily. This was something of an exaggeration. It has built in mocking for a lot of Android specific classes, but nothing for user created classes. There are many well regarded Java mocking libraries, none of which provided comprehensive instructions that worked for me. Apparently they integrate weirdly with Android? My first round of mocking was hand-written, just so I could work on test code. I never did get the best regarded library, Mockito, working, but I eventually cobbled together a set of build instructions that made EasyMock work]
You might think that making that big a change in order to make something more testable is the tail wagging the dog, but as I was doing it something magic happened. Those problems with reading exactly as many entries as there were and putting them in a list (as opposed to reading exactly 10 and dumping them in a string) were suddenly much easier to conceptualize. What seemed so muddled when it was part of HungerTracker was suddenly easy to think about when it was part of HungerTrackerWriter.
If you are super curious, here is the code before the refactor, here is the code after, and here is the test code with mocks.
Extra Credits is a video series on game design and the game industry. It has interesting insights I don’t see elsewhere, but it is also… low density. You could compress most episodes into a single written paragraph and lose nothing. I tend to watch them when being told the same thing over and over with completely unnecessary accompanying graphics is calming, rather than annoying, which isn’t very often, so I only just caught this video on whether games can induce empathy.
If you are not in the mood to be reassuringly talked down to, they helpfully provide a summary:
Many studies have investigated whether or not there is a link between video games and violence, but few have looked at the bigger picture. What is the correlation between video games and empathy? Since games put us, as players, in the role of characters who are not ourselves, asking us to understand their situation and the problems that they face, they have the potential to teach us about how to empathize with others. While many gamers have anecdotal evidence about games that made them feel a character’s pain, there’s a disappointing lack of formal studies into that side of the question.
I didn’t think anything of it until a week later at my Effective Altruism meetup, when we were discussing egalitarianism/maximization. In a nutshell, EA believes that all lives are equally valuable, so if you can save two lives for $n each or one life for $2n, the most moral thing to do is to save the two lives. Phrased that way I don’t understand how it’s at all controversial, but in practice it comes up against many people’s instinctive priorities. For some, passing over a homeless person to give to GiveDirectly doesn’t just give them fewer warm-fuzzies, it feels actively immoral. Someone at the meeting suggested it was a matter of empathy- people naturally feel more empathy the more often they see someone, or the more they have in common with them.
This is of course obvious, which is why so many charities try to up the empathy you feel for their beneficiaries, by implying you’re helping a particular person when you’re not, or just sending a letter with a few heartwarming stories of all the injured dogs they’ve saved that year.* They do it because it get donations, but it’s very hard not to slide into poverty porn. I find those examples really manipulative, but I loved the ability to choose out specific recipients when donating to Modest Needs so clearly I’m just as susceptible.
This is where I thought of that Extra Credits video. What if instead of telling people how awful extreme poverty is, we gave them a video game demonstrating both the difficulties poor people faced and the resources they used? Some things I would like to include:
Trade offs, trade offs, trade offs. Do you invest in your child’s schooling or new farming equipment?
Bee Sting theory– demonstrating how it is easy to do the right long term thing when you have a few problems, but when too much is wrong sometimes palliatives are all you can manage.
The importance of social capital. The poor (both in the US and the 3rd world) get a lot of criticism for spending so much on alcohol and ceremonies, but the fact is that that builds social relationships that can be crucial later on. This doesn’t mean spending a lot on booze and parties is optimal, but that the change must come at a societal level.
How many well intentioned NGOs fail. E.g. my continuing hate for the play pump.
Ideally you’d like to convey the scope of preventable deaths. I don’t know how to do that respectfully. You could do something like Shelter or The Oregon Trail, where you go in knowing some characters will die and the goal is to save as many as possible, but that seems a little horrifically callous.
I have several ideas for how to do this. You could do the trade offs with a choice mechanism like that of Depression Quest or Long Live the Queen. Soha Kareem has has apparently done some great work with video games to express her experience of microaggressions and sexual abuse.
EA strikes me as having a real comparative advantage when it comes to producing video games, relative to other charitable movements. And by “real comparative advantage”, I mean “lots of programmers”.** None are games programmers specifically, but it might be a skill worth picking up.
*Pro-tip for my local humane society: this may not work as well on cat owners as you were hoping.
**We were up to two non-programmers at the last meeting. High five.
Dear frantic and desperate programmers: if you are looking for an example of a populated android activity test file, go here.
Dear everyone else: you may wonder why that was necessary. Let me explain. There are five billion tutorials on how to build android apps and two on how to test them. Both are full lessons requiring a lot of knowledge of android to make sense of them and are based on Eclipse (deprecated) and not Android Studio, neither provides a decent sample file for steal-and-mutate learning. For those of us who want to write tests because we are learning to program for android and are worried a new technique might break our lovingly created app in ways we don’t know enough to fix, this is frustrating.
[For the slightly more advanced among you: yes, you could try searching github for the name of the class you know must be involved in your testing. Unfortunately the push for testing means that 95% of what you find are stubs with no actual tests.]
To be fair, I’m pretty weird in wanting to write tests so early. I complained to a stranger at a party that work on Hunger Tracker had stopped because I couldn’t find an android testing tutorial and he expressed surprised, because he’d watched people release much more complicated apps without a single automated test. I know that works for some people, but it would drive me absolutely nuts.
The point of testing isn’t to make the product work. The product is going to work, or you’ve failed. The point of testing is to make your work on the project faster and less stressful. Every time you change anything, and sometimes even when you’re sure you’ve changed nothing, you risk breaking something. The more time or changes that pass between you breaking something and you noticing it is broken, the more effort it takes to fix. You could manually test every time you change every little thing, but it’s boring, time consuming and prone to error. Computer science selects for the opposite of people who are good at doing the same thing over and over again.
So you do the programmer thing and write a program to do it for you. It’s just that the program is tests of the software. You can run this new program as often as paranoia or check in rules compel you. This frees up your time from manual testing, your mind from tracking your changes and worrying what might possibly have broken, and decreases the time to notice breaks. The mere act of writing the tests often encourages good code structure by making you think about it rigorously, the same way writing a program makes you define your problem until you practically don’t need a computer to do it. And in my particular case, when the project is as much about learning as it is producing anything, it’s good practice.
Good testing is especially critical in my case, because I’m working on this project in little bits at a time. If I break something and don’t notice it until two CLs later, I might as well be debugging someone else’s code. I know what people about the devs whose code they are forced to debug without tests or documentation, because I’ve said it, loudly, and at length. I may have expressed a wish for weapons. I would hate for someone to think that about me, especially myself, and testing is the cheapest way out of it.
When I started this blog I intended to leave programming for medicine fairly soon. After a long medical leave that let me recover from burnout, I realized that programming is actually a really valuable skill and before I throw it away and spend several years in school, I should see how far it can take me towards my goals. My goals are unchanged (mostly around nutrition and mental health, but with some bonus input from Effective Altruism), but maybe there’s a better way I can contribute.
Eventually this means founding or joining a company working on something I care about, but I’m still not capable of consistently working sufficient hours to work with other people. But I can play on my own projects with no coordination costs, so I started learning to program for android. Meanwhile on the health end, my nutritionist informs me there are states of hunger between “unpleasantly bloated” and “would shank an infant for juice” that are useful to experience, and that the first step to achieving that is tracking my hunger consciously. She meant with pen and paper, but I am an engineer, so I wanted something on my magic pocket computer to do it for me. I’m sure something exists on android that would do this, but I couldn’t find it, so I did the logical thing and started developing my own.
Thus was born the Hunger Tracker app. Here is my dream feature list for Hunger Tracker:
Alarm goes off at pre-set or random times (your choice), to shut it off you enter a number between 0 and 9, representing your fullness level.
Timestamp + fullness level data is dumped…somewhere, I don’t know. A google docs spreadsheet would work for me but there’s probably other services I should integrate with.
UI not actively offensive
Here’s what version 0.1 does
No alarm, user must manually call up app.
User enters number in ugly ass UI. Actually user can enter any arbitrary string, but don’t, it will break the retrieval.
User can retrieve first 10 numbers entered. Any further entries are skipped, if there are too few entries the last one is repeated.
It’s a debug build rather than a release build because Android Studio won’t produce a working release build and fixing that is not at the top of my priority list.
If you are interested, you can download version 0.1 here and install it the usual way for non-market apps. If you are spectacularly interested, you can check out the source code at github. Comments are extremely welcome
My next step is not actually features, but testing, which I will explain in the next entry.