Gluten and dairy free brownies

So I have this brownie recipe. I’m rather a fan of it.

I’m going to a friend’s party on Saturday. She’s recently concluded she might have problems with gluten, and she already has problems with dairy. This is sad, and I thought I’d attempt to bring some sort of tasty dessert she could actually eat. The brownie recipe seemed like a good candidate, as it’s actually quite light on flour and I’ve made it successfully with margarine before.

The first batch I made didn’t really work so well, but after some tinkering with the recipe this is what I came up with. It worked really very well.

  • 200ml sunflower oil
  • 2 cups caster sugar
  • 1 cup dark cocoa
  • 1 cup ground almonds
  • 5 eggs

Mix everything together very thoroughly, then bake in a greased tray as before (140C for about 20 minutes).

These seem to bake slightly faster than the normal brownie recipe. It might be worth trying a lower temperature.

I also think the amount of oil could be reduced slightly (it’s already reduced from my first batch).

But basically, the result is really good. I in no way feel like these are hurt by making them gluten free or dairy free – normally using margarine instead of butter results in a slightly less rich brownies, but I think the almonds help compensate for that, and they don’t hurt the texture at all.

This entry was posted in Food on by .

Teach me how to hire a diverse team, please

Hi. This post is for information – I’m not actually hiring at the moment, but when it next happens I would really like to know how to do it right. Also this is entirely a post off my own bat, rather than an official Aframe position on anything (though I’d expect and hope the rest of the company would agree with me).

So I work with a really great development team at Aframe. We’re a bunch of competent interesting people, and everyone is well motivated and good at their job. It’s nice.

There’s just one problem…

I say “people”, but that’s because I tend to default to gender neutral nouns and pronouns. I really mean “men”.

Generally speaking, straight white men.

I’m not 100% sure how this happened.

As far as I can tell, it’s not the result of explicit prejudice on our part. I don’t think it’s even the result of implicit prejudice, and I’d like to tell you a little bit about our current hiring process in order to back that up.

Here is the process we used for our recent hiring of back end developers:

  1. Applicants come in to our development manager. He does a basic screen for “not an utter waste of time” (e.g. “I am definitely suitable for your senior backend developer role because I know photoshop”) then passes the candidate on to the rest of us.
  2. We review the answers to a set of screening questions. We do not even know the candidate’s name, let alone CV, at this point. They are given a candidate number.
  3. If we like their answers, we send them a coding test. Still just a number, not a free person.
  4. If we like their answers, we’ll take them through a phone interview. We will vaguely look at a CV at this point for context for the interview. If their answers are borderline and we’re inclined to reject we might use the CV to get more evidence that they’re worth talking to, but we never rejected anyone on the basis of their CV at this stage.
  5. In the phone interview we ask the same list of questions of everyone. There is of course some general chatter as well, but in theory the decision is made on the basis of the answer to those questions.
  6. If they pass the phone interview, we take them through to an in person interview. This is a series of specific, structured, tasks.
  7. We make a hire/no hire/wait and see decision based entirely on the outcome of those tasks.

I largely think this is an example of Doing It Right. It’s not perfect, and we’ve had some complaints about specific details which we’re trying to improve, but it does a pretty good job at eliminating biases.

Except the only people who made it through to the phone interview stage in the recent hires I was involved in (for which we hired three people in the end) were white men.

I honestly have no idea if this was representative of the candidates we didn’t let through to phone interview. I assume it is, but because that stage of the process is blind I don’t really have any way of checking (I’ve asked to see if we can find a list of who the candidates were, but I don’t think we collated that information). But it would be surprising if these tasks introduced a bias. The only plausible biasing factor to them is that they’re quite time consuming (we’re working to reduce that as a factor – currently considering swapping the order of the phone interview and coding test).

As partial evidence that this works in eliminating bias, the Aframe back end dev team is significantly older than you might expect than a start up tech team. At 29 I think I’m the youngest in the back end team by some margin, and I’m the second youngest overall. I think the dev team’s median age is over 40, and the mean certainly is. Given that age bias is a huge problem in technology, and that a lot of it is probably subconscious, I think this is at least a point in favour of the process if not wholly convincing. It might also be that those of us who were hiring just don’t care that much about age, so hard to say for sure.

So, my assumption is that something is happening that is filtering people out before they get to us. I have three possible candidates for this:

  • Our job postings may be off putting in some way. Historically this was almost certainly the case, but I think we fixed that. I may be wrong. This is what we posted
  • Recruiters. We did use job boards (I think stack overflow was our most successful one there), but I think everyone we actually hired came through a recruiter. Recruiters are reportedly often assholes to deal with if you’re a woman
  • The initial “not an utter waste of time” review is not blind, and that’s a bit of a red flag. It’s supposed to be sufficiently black and white, with any shades of grey passed on to the rest of us, that I’d hope that it wasn’t introducing any significant biases here, but it was invisible to me so I can’t guarantee that
  • A lot of it is probably just the background population. My impression is that “straight, white and male” is by far the dominant demographic in the London startup scene. I don’t have statistics to back that up at the moment, but either way I’m sure it’s not as total as we were seeing. So this is probably a large factor, but I can’t imagine it’s the only one.

So, that’s enough about us. Now we get to the real point of this post: What can we actually do to improve things?

Useful advice I’ve received so far:

  • Get people from a range of demographics to review your job posting, even if they’re not interested in applying
  • Be really explicit with recruiters that you want a diverse range of candidates. If they claim they don’t have a diverse range, use a different recruiter
  • Target professional networks that have a more diverse selection of members rather than relying so heavily on recruiters
  • Keep doing what we’re already doing – keeping as much of the screening process as possible blind. Where not possible, keep it structured. Where not possible, at least try to decide based on concrete results rather than “I liked them”

Like I said, we’re not hiring at the moment, but when we do next it would really be nice if we knew what to do to avoid this happening. Any advice you can offer would be greatly appreciated.

Feel free to leave comments, contact me on twitter as DRMacIver or by email if you want to keep it private.

This entry was posted in Feminism, Hiring on by .

Saturday night madness

This weekend seems to by my last weekend without a party this year, so I’ve been taking advantage of it to write code.

(21:49:32) David: I decided to write C instead of being social. It’s almost the same thing
(22:01:05) m.: haha
(22:01:12) m.: you mean eye-gougingly awful?
(22:04:20) David: I *like* writing C.
(22:04:34) m.: sick cunt
(22:05:17) David: It’s one of those things where it’s nice as a break from high level ruby bullshit
(22:06:53) David: Ruby: “Yes I know this looks like you’re setting a field but actually you’re invoking method missing which mixes in a module that accesses a database so it’s really doing a network round trip except when you’re using the caching layer of course”
C: “Yes I know this looks like you’re setting a field but YOU’RE NOT BECAUSE YOU’RE A MORON WHO DIDN’T INITIALIZE YOUR MEMORY AND OH LOOK A SEGFAULT ARE YOU HAPPY NOW MOTHERFUCKER?”
(22:07:01) David: A change is as good as a rest and all that

Behold my rock and roll lifestyle.

This entry was posted in life, programming on by .

A non-transitive tournament

I have a reason for thinking about this, but don’t want to get in to the philosophy behind it, so let this post stand on its own as just a neat thing.

Consider the following game: You have a tournament of players. Each player is a rock, a paper or a scissors. Victory is determined in the usual way, with a coin flip or some other arbitrary decision between players of the same type (we’re only going to consider tallies of the number of players of each type, so it doesn’t matter who wins).

A tournament is played as follows: Pick two players at random. They fight. The loser drops out. The tournament is one when only one player is left.

Now, consider a tournament with one scissor and many papers but no rocks. The scissors is a guaranteed winner. Now add a rock. What happens? The scissors still probably wins – the paper is likely to kill the rock before the rock kills the scissors. But what happens as you keep adding rocks?

When you add the first rock, obviously it introduces the possibility that paper can win: The rock can kill the scissors, at which point the remaining paper obliterates the rock. As you add more rocks this becomes more likely to happen and scissor’s chance of winning drops.

There turns out to be a nice formula for the probability of scissors winning in this case. If we write \(S(r,p,s)\) as the probability of scissors winning with r rocks, papers and s scissors then \[S(r, p, 1) = \frac{p(p+1)}{(p + r)(p + r + 1)}\]

(Unfortunately I don’t have a nice proof of this. I arrived at it empirically with the aid of wolfram alpha, then proved it inductively using the recurrence on the probabilities)

So as you can see, the probability of victory for scissors monotonically decreases towards zero as \(O(\frac{1}{r^2})\).

So scissors is likely to lose after a few rocks have been added (the probability drops to half or less when \(r \geq \frac{1}{2}\left(\sqrt{8 p^2 + 8p + 1} – 2p – 1\right)\). Now you know), but what is the probability of a rock victory?

Not so good it turns out. As far as I can tell there’s no nice general formula for rock and paper victory probabilities, but I’ve done some calculations for simple cases and I have some code for solving the general case and I’m sorry to report that the chances of success for rock are looking pretty grim.

The problem intuitively is that with a lot of rocks you’re likely to kill off the scissors before it manages to kill off all the paper. Empirically, the best number of rocks appears to be \(\lfloor p / 2 \rfloor + 1\), but even then the probability is pretty low.

Here are some graphs of the probabilities of rock victories:

With 1 paper:

With 2 paper:

With 10 paper:

Empirically it seems to be the case that the single paper scenario is the only one where rock is ever tied for victory probability, let alone winning, and is also the only case where it ever is more likely to win than scissors.

That’s about it in terms of what I can prove or demonstrate about this problem. I’m interested in it, but it seems harder to get a handle on than I’d expect (or I’m worse at this sort of maths than I think I should be. Probably both). As a parting shot, I’ll leave you with some python code to calculate the probabilities:

class ProbabilityTable:
  def __init__(self):
    self.table = {}
 
  def S(self, rock, paper, scissors):
    if scissors == 0: return 0.0
    if rock == 0:     return 1.0
    if paper == 0:    return 0.0
    key = (rock, paper, scissors)
    if key in self.table:
      return self.table[key]
    total = rock + paper + scissors
    result = (self.S(rock - 1, paper, scissors) * rock * (rock + 2 * paper - 1) + 
              self.S(rock, paper - 1, scissors) * paper * (paper + 2 * scissors - 1) + 
              self.S(rock, paper, scissors - 1) * scissors * (scissors + 2 * rock- 1)) / (total * (total - 1))
    self.table[key] = result
    return result
 
  def P(self, rock, paper, scissors):
    return self.S(scissors, rock, paper)
 
  def R(self, rock, paper, scissors):
    return self.S(paper, scissors, rock)

Note: The dynamic programming is Important here. It takes the run time from \(O(3^{r + p + s})\) to \(O(r + p + s)\).

Let me know if you figure out anything about this problem that I haven’t spotted or didn’t prove.

This entry was posted in Numbers are hard on by .

Playing to your strengths can be a weakness

If you tried to hire me as a sysadmin I would politely explain to you that you had misunderstood my skill set.

If you tried to hire me as a front end developer I would less politely explain to you that you needed your eyes checked and your head examined.

There are things that I am good at. There are even things that I am very good at. Systems administration, user experience and visual design are very emphatically not in those categories.

I’m probably more trustworthy as a sysadmin than the average dev, but not a lot. I wouldn’t like to comment on where my visual design skills are compared to the average dev – I’ve worked with plenty of people who have worse, but that’s because the teams I’ve worked in have typically had a bit of a back-end/front-end imbalance.

The point is, there are people who are good at these things, and I love working with them. It’s truly a delight working with good people who have different and complementary skill sets to your own, because you can compartmentalize problems and trust them to handle the parts you’re not good at. The reach of a good team is vastly greater than the reach of the individuals within it, and the reason is division of skills far more than it is division of labour.

But where do you draw the line?

The problem is you can easily get into a pattern of over reliance. If you always work with people who are much better at something than you, you can get into a habit of handing over even the smallest tasks to them. This can be a bottleneck even when you are working with them – your five minute task might take days to complete because the front end or opts team are busy with a major feature and doesn’t have time to do the task you need.

I’ve worked with people who basically refuse to touch the front end code. I’m not quite that bad – I’m perfectly happy to make changes to html or javascript, but I tend to draw the line where I’d have to make significant UI or style changes. I think this is more or less reasonable. Similarly I often chip in at work and do a little bit of sysadmin, but I leave any serious tasks to our actual sysadmin. So at work I don’t think my balance is too bad, though I could probably go further in each direction than I currently do.

For me, somewhere this really comes out is when I have side projects.

I have a lot of ideas. Sometimes I implement them. The problem is, what will usually happen is that I will implement them and go “Halp! Mike! I can’t make this pretty!”. Mike will then kindly step in and make it pretty for me, but I’ll probably feel like a bit of an ass about it.

The reason is that I’ve got so used to working with Mike and other people who are better at front end than I am that I’ve come to the conclusion that I’m simply not good at all. Design is just a thing I can’t do. A fact which causes me painful limitations but you’ve got to face reality, right?

Except it turns out it’s not really true.

I’m not good at design, but I can put together something entirely functional. With practice I may even upgrade myself from not bad to actually good (I doubt I’ll ever be amazing. If nothing else I don’t care enough to put in the practice).

For example, I did Github Explorer on my own and you know what, it’s fine. It’s nothing original design-wise and it sure isn’t going to win any prizes, but it doesn’t need to. It just needs to look ok and present the underlying idea.

Would it be better given the attention of a dedicated designer and front-end expert? Oh, certainly. But there are a lot of ways to make it better, and it doesn’t really need any of them. It’s fine.

Which I guess is really the core of my point: Knowing the things that you’re not good at is important. Working with people who are good at the things you are not is great, because it expands your reach. But often you are good enough at these things, and if the thing you want to achieve is already within your reach then relying on other people to help you achieve it is unnecessary, and believing that you need to do so will limit what you can achieve when those people are not available.

This entry was posted in life, rambling nonsense on by .