Some Thoughts, Written

Python Mock and Autospec


by Maria on 23 Aug 2018 - 05:16  

Auto speccing means that your fake object will have the same signature as the object it is mocking. This can come in very handy if you want your fake object to receive the same input that your original object would.

First let's look at an example where the inputs don't matter. Below I have made an abbreviated fake request response object for mocking Note that this looks very different from the actual response object returned from the requests library.

Actual Response object:

In particular the json method signature is different, and it is missing all manner of methods and attributes. And, more importantly we weren't even trying to mock post itself, iow we don't care at all what parameters were used to call, we are only faking what it is returning.

But, it returns the stuff that our code expects and uses.

Here is the mock:

class FakeRequest():

    Fake a response from the request library


    status_code = 201

    original = {"result": {"silliness added"}}

    text = json.dumps(original)

    content = bytes(text, 'utf-8')

    def json(self):


        Return a small subset of what the api might return


        return self.original

And here is an example of using that mock in a test:

@patch.object(requests, 'post')

    def test_can_post(self, mock_requests):


        Verify call actually happens and data is returned on single step post

        Mocking this, to limit hitting an actual endpoint.


        mock_requests.return_value = FakeRequest()

        processed_stuff = run_code_using_request()

        self.assertEqual(processed_stuff, "I made a thing")

In this case, we did not care what the inputs to the requests post method was or anything beyond what was in our fake request. So, we could create a fake object that looked nothing like what we were mocking. This can be very handy, and it worked fine, because we were not trying to call our fake post with any parameters, and especially because we were not trying to call it with any parameters that are internal to the place where we are mocking. However, if we want to mock something that is being called internally with parameters that are specific to the internal code, and we care about those parameters, life becomes more difficult.

I ran into this when trying to mock middleware for Flask. Here is what the middleware class you create looks like when you add middleware to flash:

class SillyMiddleWare(object):

“””Silly WSGI middleware


def __init__(self, app): = app

def __call__(self, environ, start_response):
    Stuff that happens when an endpoint is hit, but before the endpoint code runs

    print(‘doing something silly in every http request’)

    return, start_response)

Now, I wanted to bypass the middleware, because it was adding an authentication layer I didn't want to use for most of my tests, but clearly I couldn't do the same thing I had done to mock the class returned by requests. I needed my mock to return its input parameters, because that is what the __call__ method is doing. Turns out this is easy with autospec. Since I needed to do this almost everywhere, I put it in my setup for my basetest, which is subclassed by all of my tests. This way, for the the tests that did not need it, I could just over-ride it.

Because I was mocking a class method, I needed to include an input for self:

def mock_acls(self_acls, environ, start_response):

    return, start_response)

class TestStuff(unittest.TestCase)

    def setUp(self):

        self.acls_mock_patch = mock.patch.object(ACLMiddleware, "__call__", autospec=True,

        self.acls_mock = self.acls_mock_patch.start()

    def tearDown(self):


Now, this would not have worked at all with our requests example, because autospec forces us to have objects that have the same signature (inputs and outputs) as the original object. This has more implications if you are patching an entire class. With autospec you cannot add methods or attributes that are not in the class you are mocking. This can be a good thing, as it is possible for tests to pass when using mock, even if the code is broken.

See this article: Mocking has a Weakness, Speccing Removes It

Note from the above example, that it is possible to mock just one method from a class, you just have to make sure you include a self variable.

Python Mock and Autospec ~ Comments: 0

Add Comment

I am a badass


by Maria on 01 Apr 2017 - 06:31  

I, like many people I know that suffer from Imposter Syndrome, fluctuate from feeling like a fraud and feeling like, maybe okay. Recently, I decided to give Toastmasters a try. Not because I thought it would help with Imposter Syndrome, but because I want to become a better speaker. The first assignment is to talk for five minutes about yourself. This was a revealing task for me, as I had to look at my life and come up with some sort of theme, regarding my life, to talk about. And what I learned is that, I may, in fact, be a badass. I'm trying it on for size, anyway. So, I am posting the script of my talk here, as well as I can remember it, so that when I am feeling like a fraud, I can see evidence that this may not be true.

My Ice Breaker Speech

There is a famous poem by Robert Frost about walking in the woods, and coming to a fork, and possibly taking the path less traveled. This poem has often been misinterpreted, but this is not poetry 101, so we will move on. As I look back over my life so far, it seems that I have taken the advice often ascribed to that poem to the extreme, and have more often than not, chosen the most difficult, arduous, god-awful path I could find, sometimes just making up my own. This seems related to another theme in my life, that I seem to be drawn to "guy things".

Starting about the 3rd grade, I regularly played tackle football with the boys in my neighborhood. I was always the only girl, and yes, I could usually tackle the boys, though most were bigger and older than I.

At the age of 17, I joined the U.S. Army as a truck mechanic, volunteering to go to Korea, and airborne training. I would have volunteered for ranger training, if they had let women then.

After the Army, I went to college. I majored in physics. While a student, I discovered I was pregnant, and decided to become a single mom. I did not let this stop me from applying for, receiving, and accepting a scholarship to study physics at a German University (in German, of course), taking my 9 month old girl with me for a year in Germany.

Soon after I returned, I graduated. While studying physics, I had gradually become more interested in biophysics, and since I did not feel ready for grad school, I tried to figure out how I could earn a living while learning more biophysics. I knocked on doors in the Biophysics and Physiology Dept. at the University of Washington, and eventually found a couple of professors who were willing to take me on as a software developer for them. I had almost no coding experience. I, and I must assume they, assumed I could figure it out as I went. Which is what I did. I learned coding, as well as system administration, and worked in the department for many years.

Life, it seems, sometimes does not believe that your choices are difficult enough, and after I chose to move out from the house I had shared with my long term boyfriend, I soon discovered that I was pregnant. And that my boss was moving to NYC. Once again, I was an unemployed single mom during a recession. As the tech sector started to recover and begin hiring again, it became obvious that it would be nearly impossible for a self-taught, female, software developer to move from academia to industry. I probably don't have to tell you what I decided to do. I returned to academia in order to fill in the gaps in my knowledge, both in software development and career development. I networked, gave a talk, and generally moved way out of my comfort zone. And, a year and a half ago, I was hired by Disney as a Senior Software Engineer.

One thing I have learned is that it is not strictly necessary to always travel alone down forlorn paths. And so, I am happy that all of you are joining me on my latest journey down a well-trod path to become a better speaker.

I am a badass ~ Comments: 0

Add Comment

Power and Prince


MyLife, MyRamblings

by Maria on 11 Mar 2017 - 23:51  

I was in the US Army in Korea working as a truck mechanic when I was just 18 years old. It was one of the most difficult years of my life. My roommate used to say, I must have looked like an ex-girlfriend of my commander (that he hated). I spent one-third of my tour in Korea on restriction. I was not an angel, by any means, but I was also just a kid, and clearly being made an example of. But, I was also lucky. My roommate befriended me, took me under her wing, and when she had to leave Korea before me, made sure there would be someone else looking out for me after she left. I honestly don't know how I would have survived that year without her. She was my best friend for that year, and I learned so much from her. But, the three most important things that I learned were:

  1. Prince is awesome.
  2. Women have to look out for each other.
  3. There is always someone whose life sucks more than mine.

Aletha never complained about her situation. But I could easily see, that as much as my life sucked while I was in Korea, and it did, Aletha was in a worse position. She had young children that she couldn't see while in she was in Korea, which was a year assignment. I can't even imagine how hard this was for her. This was in the days of no internet, just very expensive long distance phone calls, across many time zones. While in Korea, she realized that she didn't love her husband, that he didn't respect her, and that she was in love with a man she met in Korea, whom she would have to say goodbye forever to, when she left at the end of her tour. Lame.

It is so hard for me to listen to Prince now. It makes me happy, because Prince. And it makes me sad, because he is no longer with us, and it takes me back in time to visit a person I have lost track of, but after decades, still has a big place in my heart. Wherever you are Aletha, I hope you are having a great life, and that you know how much I appreciate you looking out for me all of those years ago. I do my best to pay it forward. :)

I still work in a male-dominated industry (software), and I still try to reach out and help other women. And I still listen to Prince.

Prince On Arsenio Hall

Power and Prince ~ Comments: 0

Add Comment



MyLife, MyRamblings, Tech

by Maria on 28 Feb 2015 - 23:37  

The other day I was at a meetup, and the subject of allies came up. Specifically, how white males can be allies for women and minorities in tech. I was reminded of an incident that happened to me while I was in the Army, and I thought it might be a useful story to a larger audience.

Many years ago, I was a truck mechanic in the Army National Guard. By coincidence, my motor pool was losing its Motor Sergeant at the same time that our unit was being consolidated with another unit. I was next in line to be Motor Sergeant. So, I was taking over at the same time that our motor pool was more than doubling in size, and, of course, the new mechanics were all male, and did not know me. The first weekend was rough. The new guys were clearly reluctant to take orders from me, and things weren't going so well. Weirdly, the next weekend was completely different, and I couldn't figure out what had happened that I had suddenly gained their respect. I was talking to a guy in the motor pool that I had known for years, and mentioned how much better things were going, and I didn't understand what had happened. He was a big, charismatic guy. The kind of guy that people intuitively look up to and respect. He told me he had seen what was going on, and the next time the new guys were hanging out and talking, he had joined their conversation. When my name had come up, he had told them, "Nah, man, she's alright. She knows her shit, and she's cool." And that was literally all it took. One person, alert enough to see that someone was being undermined, simply because of their sex, and stepping up to defend. It would have taken me months to get to that place of respect without him, assuming I ever could have.

That respect, is given by default to members of the majority, but must be earned by someone not seen as already 'in'. There are, of course, exceptions in both directions to this, but I think it is an excellent rule of thumb. It is so much easier and effective for someone of the majority to point out this imbalance, then it is for the person being disrespected, or anyone else in the minority, to do it. This is truly one of the best examples of how allies can help.

If you see someone that you think is not being taken seriously simply because of their race, sex, orientation, or whatever, step up, and say something. A simple, "hey, let's hear her out", can do wonders in making people realize their unconscious biases are showing through. Just asking a question that shows that you are taking her seriously, can make others realize that they may have been overlooking something. 'What did you say? That sounded like a pretty good idea, can you explain it again, I'm not sure everyone heard it."

Pay attention when a woman/minority says something. How are people reacting? Listen, observe, speak up. This is stuff that allies have to look for, because it is very easy to not see it, if you are not in the minority, and especially if you also feel like you are fighting to have your voice heard. (Cause, yeah, life is hard for those in the majority too. Word.) Members of the majority can shout down others, and generally lose no respect from the majority because of it. Women and minorities can lose respect, simply by fighting to have their voice heard. Allies amplifying their voices is absolutely critical to getting more women and minorities to stay in tech.

Some humor, which somehow feels appropriate. XKCD awesomeness.

Allies ~ Comments: 0

Add Comment

Busy, Shmizzy


MyLife, MyRamblings, Tech, Code

by Maria on 21 Oct 2014 - 06:43  

So, last post, I had been told by someone at a user group that I could not become a great programmer working by myself. I really love my job, so I set out to find a way to do exactly that.

As I thought about my predicament, I thought, sheesh there must be hundreds of people just like me at the university in exactly the same pickle, all of us working mostly by ourselves in research labs all over campus, and probably a good percentage of us self-taught. I started poking around the UW website, and was surprised to find no sort of network of developers. So, I started one. In May of this year, I began tying to figure out how to track down fellow developers at the UW, and it turns out this is no easy task. But, as of October there are 87 subscribers, so I'm making progress. If you know any software developers at the UW, please send them to this site:

to subscribe to my mailing list.

We have started having regular meetings as well. It has been a lot of fun. We have been looking at code, and talking about research and software development. I started my list at an opportune time, because others were also feeling there was a void. There is now an organization at the UW called eScience, and they are very interested in improving coding practices in science at the UW. When they found out about our group, they volunteered to help out. Currently they help with organization and bring snacks to our meetings, total win! Additionally, as a community we are receiving many awesome opportunities. For example, in November, I and many others on the list will be attending a Software Carpentry Instructors training.

Which I am really looking forward to. Science and coding, why not do both well? Plus, we get to do this:

09:15: Teaching as a performance art (2)

So we can share the love.

I have been looking for ways for our group to meet on a regular basis to do some live coding, and I am contemplating starting a coding series of sorts. My current idea is that I'd like to take this book:

Head First Design Patterns

By Eric Freeman, Elisabeth Robson, Bert Bates, Kathy Sierra

and go through it as a group. Each time we meet we would talk about one or more patterns, and talk about how it translates into the various languages that people in the group know, and hopefully do some group or pair coding and share it.

So, if you have tried something similar, I'd love to hear how it went! Or if you have ideas of other things that have worked with your group, I'd like to hear that too. Finally, we are always looking for speakers that have experience in the juncture of code and science, especially with incorporating best practices, so feel free to drop me a line if you want to help or come talk!

In addition to this group I have formed, I have just started TAing for an Introductory Python Course, because there is no better way to really learn material, then to teach it!

I don't know if I am becoming a great programmer, but I am learning a lot. Maybe not as quickly as if I were working daily with other developers, but I get to keep my cool job, and still learn more about best practices and about coding from other developers, so I'm pretty sure this is the appropriate response:

Busy, Shmizzy ~ Comments: 0

Add Comment

So sue me, I've been busy


MyLife, MyRamblings, Tech, JobHunting

by Maria on 20 Oct 2014 - 06:56  

This is a longish rambling essay, I mean a super interesting essay, explaining why I haven't posted in so long (I've been very busy!), what I've been up to (talking to people, ye gads!), and some advice for job hunting, especially if you aren't currently worried about employment (cause job hunting sucks and you should worry, er I mean, prepare before you're out there!).

I want to tell you a story. A few years ago, I found myself pregnant fairly soon after receiving word that I would be losing my job. The only reason I mention that I was pregnant is because that meant I really couldn't spend much time job hunting before I lost my job, even though I had quite a few months warning. I would be getting decent severance, so I wasn't too panicked. Yes, the economy still sucked, but it was starting to recover, and tech jobs were the first returning. Other people staying in Seattle from my lab had managed to find new employment before my boss moved, which I also took as a good sign. The last time I had been out looking for work was during the dot com bust, and while it had taken a few months, I had more experience this time. So, a few months after my boy was born, my job went away and I received a rude awakening. The job market had changed.

I've already done a rant about tech interviews, so I won't rant about that again. And of course, the job market had changed in quite a few ways in 12 years, but one of the biggest lessons I learned was the importance of networking in today's market, and how when you find yourself unemployed, that is not the ideal time to start networking. We have all heard about how important networking is, but what does that mean? Well, I think the bottom line is, it means getting to know lots of people that are willing to recommend you for a job. Yes, someone you meet once or twice at a networking event may tell you that their company is looking for someone that has your skills, and they may even get your resume in front of the hiring manager, which is definitely a step up from applying through a website, don't get me wrong, but it is not your most likely route to a job. What you really want is for someone who knows you, your work ethic, your personality, and your skills and also know the hiring manager pretty well, to recommend you. Someone you met at a networking event a few times, just can't do that. So, the way to effectively network is to get to know as many people as well as possible. Not just any people, but people that understand the skills needed to do your job, iow people doing your job or a pretty similar one. You need to get to know them as well as possible by talking shop, and a lot of it, and not just about your favorite movie or whatever. You know you have probably reached that with someone when you would be completely comfortable recommending them for a job, so yeah, this takes a while, and if you can do joint projects, all the better. And then, when you are looking for a job, you should personally hit up every one of those connections, and ask them if they have heard of any job openings you may be interested in. And remind them you are looking on a regular basis, but somehow strike that balance of not being a pest, but keeping your name in their thoughts. I'm afraid I don't have much advice on that last one, and I suspect it depends on the person and the method as much as anything.

So now I can finish my story. The reason I had lost my job was because my boss had moved to NYC, and I was unable to move to NYC. After months of hitting total dead-ends looking for work, my old work called me back in to take down some servers that my former boss had left running. Someone new was taking over his old space, so all of his old stuff needed to be taken care of. I went in and dealt with everything, and started to walk out the door. And then I stopped and went back, because I thought, well I should probably introduce myself to the new person and let her know who I was so she could contact me if she found more stuff or had questions about anything. When I went in and introduced myself, she started asking me about what I had done for Mike, my old boss, and it turned out she was in the same boat Mike was, she had moved across the country and left her programmer behind. Neuroscience research with primates is a small field, so of course, she knew Mike, and so Mike's recommendation was valuable, and skills needed for both jobs greatly overlapped. So, when I finally found employment, it was a combination of serendipity and because of someone I knew well. Yeah, n of 1, I know, but, heh, the internet.

So, when I looked back on my 12 years of being a sysadmin and a software dev, I realized that I could pretty much count on one hand the number of other software developers I knew in the Seattle area. So, if I didn't know very many people who could recommend me, and I suck at interviews, it is no wonder I had such a hard time finding a job in the tech market! Why did I know so few other developers? This was for many reasons, but the main one was that I was in academia in a fairly secure job the whole time, and wasn't really thinking enough about life after my current gig. My ways of improving myself had always been books, mailing lists, and classes, which doesn't get you out in the community much. Plus, I had been working as both a sysadmin and a developer, but quite frankly the sysadmin required much more constant learning and tended to hog my learning time, because it involved so many different technologies and programs. I decided during my period of unemployment I wanted to focus on software development, and clearly, if I was going to continue to be a coder and be able to deal with any future unemployment or career moves, I was going to have to change how and what I was learning drastically. And so, the introvert starts the slow task of reaching out.

I started going to various meetups, and other local meetings of coders and learning more about how to become a better developer, figuring it would be good to kill two birds with one stone. And, while it has never been clear to me why I would want to kill two birds with stones, it was abundantly clear why I needed to both network and become a better developer. Since I was a self-taught developer, who had spent all my time in academia, I knew there were some holes in my skills and knowledge. In the meantime, I was really loving my new work at the University, but I was a little worried, because I was once again working by myself in a science lab with a bunch of primarily science researchers who knew a little about coding. One day at an event I was talking to people about becoming a better programmer. They were emphasizing pair coding, code reviews, working in a team, etc. and so I asked how I could improve when I worked by myself. One of the developers I was talking to told me that he didn't think anyone could become a great programmer working by themselves. Not the answer I was looking for.

Next post: How I responded

So sue me, I've been busy ~ Comments: 0

Add Comment

Amish Ground Beef and Noodle Casserole


by Maria on 11 Aug 2014 - 04:57  

Haven't posted in quite some time, as I have been very busy, but a tech post is coming up soon. In the meantime, food!

This casserole was pretty awesome. I wish I had been thinking to take a picture. It is basically a slightly less time consuming lasagne. My casserole dish was very full. I didn't cook it the full hour, and that was no problem. Everything was sufficiently cooked going in, it is just a matter of letting the flavors blend as much you want.

I started with this recipe:

which was adapted from a recipe in an apparently fantastic cookbook that Ali Phillips recommends that you buy immediately, New Recipes from Quilt Country: More Food & Folkways from the Amish & Mennonites.

And then I adapted it a bit more. Added garlic, veggies, and spicy sausage, while cutting back the meat total and the dairy total slightly. It is still very rich and very yummy.

   * 1 1/2 cups sour cream (a 16-ounce container - 1/2 cup)
   * 1 1/2 cups small-curd cottage cheese (a 16-ounce container - 1/2 cup)
   * 1/4 cup finely chopped onion
   * 3-4 cloves garlic
   * 2 Tbsp. minced fresh parsley
   * 10 button mushrooms
   * a few handfuls of spinach (could have put in more)
   * 1 bell pepper
   * 1 7- to 8-ounce package medium egg noodles
   * 1 Tbsp. vegetable oil
   * 1 pound lean ground round or well-trimmed chuck
   * 1/2 pound spicy italian sausage
   * 1 6-ounce cans tomato paste
   * 1 small jar pizza sauce, about 14 oz.
   * 1 Tbsp. minced fresh basil, or 1 tsp. dried
   * 1 Tbsp. minced fresh oregano, or 1 tsp. dried
   * 1 tsp. salt
   * 1/2 tsp. coarsely ground black pepper

1. In a small mixing bowl, combine the sour cream, cottage cheese, parsley, and spinach; set aside. In a large saucepan, cook the noodles according to the package directions. Drain and set aside.

2. Heat the oil in a large sauté pan, over medium heat, add onions, garlic, mushrooms and pepper. Cook till the veggies are starting to get tender, but still have some crunch. Set aside in a bowl.

3. Add more oil to the large sauté pan, as necessary, over medium heat, and add the ground beef, stirring now and then until the meat is no longer pink. Drain off all liquid and discard. Stir in the tomato paste, pizza sauce, basil, oregano, salt and pepper and simmer for 5 minutes.

4. Preheat the oven to 325-f degrees. Grease a 9 x 13-inch pan and begin layering as follows: one-third of the meat sauce, one-half of the noodles, one-half of the sour cream mixture, and all of the veggies. Repeat these layers (except no more veggies left) ending with the meat sauce. Bake covered for 1 hour or until the casserole is bubbly. If you would like, remove the cover the last 20 minutes of baking to crunch up the topping a bit. Allow to stand for 15 minutes, then serve.

Amish Ground Beef and Noodle Casserole ~ Comments: 0

Add Comment

Unit Testing with Panda3D


Code, Python, Panda3D

by Maria on 28 Jan 2014 - 01:40  

I've been playing around quite a bit with Panda3D lately. Panda3D is a game engine originally created by the Disney Corp.; it's a framework for 3D rendering and game development for Python and C++ programs. When I was first learning Panda3D, it was not obvious to me how to do unit testing, and I didn't see any documentation about it, so I thought I would share what I have learned. I think there are a few keys, which I will go over briefly, and then share the code.

1. Don't render to screen, but don't use window-type 'none' either. The one bit of advice I could find about unit testing with Panda3D, suggested using window-type none, but if you do this your camera node becomes noneType, so you will probably have to make changes to your code. Instead use window-type offscreen.

2. Use a setUpClass to instantiate your game. Panda3d has a lot of overhead that you don't want to reload every time you run a test.

3. Have a setUp method to re-configure your game to its starting state. Reload any configuration files here, and move players and objects to their starting positions. This way you you are always starting in the same state without having to re-instantiate your game. This does mean that you should separate setting up the game scaffolding from the initial configuration in your game file, but this is a good idea anyway.

4. The only real change you should need to make to your code is including an if __name__ == "__main__": conditional at the end. This will allow you to instantiate the game and start the task manager running automatically if you start the game from the command line, but won't if you import the class as a module.

5. You can step the task manager directly from the test code, allowing you to run the game for just as long or short as you need to, in order to test the logic for that particular test.

So that I don't have to worry about updating the website if I change the code, I'll point you directly to my GitHub repository for the code. Happy testing!

Unit Testing with Panda3D ~ Comments: 0

Add Comment

The Elephant in the Room


MyRamblings, MyLife, Tech, JobHunting

by Maria on 21 Sep 2013 - 06:27  

Elephant, not in a room

For about 13 years, I have worked in a neuroscience lab as a programmer and a sysadmin. The last time I was interviewing for a job, I had to convince my potential employers that I was smart, dedicated, easy to work with, and would get the job done. Fortunately, I'm pretty good at that. I knew very little about how to program, but I convinced my future boss that I had a plan, the dedication, and the smarts, to teach myself how to program, so I was hired as a programmer.

And now I have 13 years experience as a programmer and a system administrator, so theoretically, it should be easier to get a job. Unfortunately, the interview has changed. It is no longer enough to tell the interviewer what I have done, what I can do, and how I work. The amount of information about me that is available to a potential employer is way more than it was 13 years ago. But, this time around, what potential employers really want to know, is can I solve a toy programming problem, while they watch me and evaluate me (or worse, evaluate me over the phone using a shared doc), under more or less a timed condition. These are the worst possible conditions for me to perform under, and this test has nothing to do with how I will perform as an employee. Seriously. It doesn't reflect how well I program or how much I know about programming or what kind of an employee I am.

I understand that everyone gets nervous about interviews. But, clearly, some people do not become as brain dead as I do. I have been working hard to overcome this. I practice as much as I can, but the situation is frustrating. I know that if I continue to practice, I will get better at it, and eventually I will be able to finish an interview without feeling like I can no longer even recite the alphabet. (I find practice interviews help only a little bit, since most of the pressure is missing.) Eventually, with enough time and practice, I'll get lucky, and the interview will consist of questions that don't put me in panic mode. But, why should I have to do this? Why have we settled on this as the process, when it has so little to do with what candidates need to succeed at work? Interestingly, the process favors people who job hop a lot, and therefore get more practice with real interviewing. That, and showoffs.

And why are interviews a particular problem for me?

It isn't the male environment. I've been living in a mostly male world since I started playing tackle football with the neighborhood boys at age 8.

When I was in the Army, I attended a school to learn large diesel truck mechanics. At one point in the school, one of the instructors had me take over the class, because he felt I knew the material better and was a better instructor. As an undergrad, I was fine with teaching the first year physics lab series, even enjoyed it. For years, I taught weight training. Clearly, the problem isn't speaking in front of people.

It is not the white board. As someone who has been in academia for a very long time, I am very intimate with the white board, and even its predecessor, the black board. It is a very useful tool for sharing ideas with others, and I am more than happy to write code on it, if I feel like we are collaborating and/or learning, and not like I am being judged and timed.

It is not the pressure, per se. Pressure I can deal with, and can thrive in. I ran a mail server for years, and there is nothing quite like the pressure of the mail server going down while your colleagues are at an important conference and very dependent on email. This sort of pressure can energize me.

It isn't even that I don't like these sorts of coding problems, I actually do, as long as I'm doing them in my living room in my pajamas for fun.

So, what is it then? I first noticed this problem of my brain shutting down when I was an undergrad in the physics department. I knew the material. I did well on the assignments. And then, I looked at the test and my brain stopped functioning. What was different about physics and auto mechanics? Well, physics is definitely more difficult (unless you're engineering the auto, or troubleshooting the electrical system, and not just replacing the cv boot). But, that certainly can't explain all of it, because I was doing fine on assignments, and even quite a few of the tests, even though I sometimes felt like I was working at half brain capacity. So, it wasn't simply the difficulty of the material.

Instead, I think it was the structure of the testing. In the physics department, the tests were usually designed so that most people wouldn't finish the tests, and so that no one would get a perfect score. They didn't always succeed in their design plan, going in both directions. I remember tests where the mean was 25 out of 100, and I remember tests where a couple of people managed to get perfect scores. But, usually the mean was right around 50%. This was much different from the auto mechanic courses, and quite frankly, different from most of my other college subjects. And it was demoralizing and scary. And it didn't help that instructors often said things like, 'It should be obvious that...', for things I didn't find obvious at all. Fortunately, none of them were patronizing. Oh, wait. And the more I became insecure about my abilities, the more difficult the tests became. I saw this happening, but could not find a way to stop it. I nearly switched majors because of it. I feel the same kind of pressure now in interviews, but there are different factors.

1. As many geeks are, I am an introvert. I have a hard time talking to strangers, especially small talk. I've mostly gotten over this, but when combined with the other three factors, I think it still plays a role.

2. I think before I speak. So, sometimes there are those long pauses that interviewers hate, because they want to know what is going on in your brain. I try to go back, and say this is what I thought of, and why I rejected it, but it is very difficult for me to speak while I am thinking. Weird, I know. Apparently, this is a thing. And, when I realize I have been silent for a while, I get nervous about that, and we start another cycle of brain freeze.

3. I sometimes experience Impostor Syndrome. I am hyper-aware of how much I do not know. I love learning, and am constantly learning and growing, but sometimes the awareness of how much I don't know makes me feel inadequate, hence, an impostor. And admitting that I sometimes experience Impostor Syndrome makes me feel inadequate. Totally kidding, the recursion is not infinite.

4. I do not have formal CS training.

All of this means is that I become particularly terrified during interviews, but NONE of these things has ever had any bearing on my actual work. Impostor Syndrome seems to particularly affect women, and so I have to wonder if it is the confluence of some of these factors: introversion, impostor syndrome and awful tech interviews that discourage geeky women in particular from staying in the tech industry. Of course, it is more complicated than this, but I do believe the interview structure sure can't be helping the numbers of women. If I, and I am stubborn, and I love making my life as difficult as all hell, sometimes wonder if I should bail because of interviews alone, then it must also be a factor for others.

So, what can be done? What is it that employers really need to know about an applicant before they hire them?

1. Will they get the job done? If they don't know something they need to solve the problem, do they know how to figure it out in a reasonable time? Do they know how to google (seriously, this is an art), and regularly use IRC and/or mailing lists? Are they organized, and do they approach problems reasonably systematically? Do they know how to troubleshoot? Are they tenacious? Do they know when to ask a mentor/colleague for help? Are they willing to try new things?

2. Are they reasonably easy to work with?

3. Do they fit in with company culture and the particular team?

Is there anything about the current popular tech interview format that answers these questions?

My best experience with an interview was one in which the interviewer described what the group was working on, and specifically what I would be working on. We discussed ways to move forward on the current project. We discussed existing problems, my ideas on what to do, and their ideas on what to do. We discussed which technologies I had worked with before, how deep my understanding of them was, which ones were new, and how I would get up to speed on the new ones. At the end, I think we both felt pretty comfortable about what we were getting. I understand that sometimes companies don't want to divulge this much information about what they are working on. But, they can certainly say something like, on day 1 when/if you start here, you will be using technologies, A, B, and C. Which of these are you comfortable with, and which do need to get up to speed on? How would you go about getting up to speed? Which combinations of technologies have you used before, and what were the challenges in how they worked together?

Ideas on other ways to understand applicants:

In that interview, we did not sit down and look at any code, but I could imagine sitting down and looking at a bug in some code and discussing how to solve the bug. Since most of a programmers time is spent debugging, refactoring, optimizing, and testing, and often you are dealing with an existing code base, it seems that talking about refactoring and troubleshooting are way better ways to learn how a person thinks, in a way that is relevant to how they will perform on the job. And I do mean talking, not testing their coding ability. In all of the interviews I have had so far, absolutely no one has asked about troubleshooting and refactoring code. Try some pair programming. Have a candidate look at some code and describe to you what they think the code is doing. If the company is sensitive about its code base, maybe they can fork some open source code that is close to a realistic problem they might face, and the interviewer and interviewee could discuss the merits of the code, maybe even hack on it a little, on an actual computer. Yes, if you feel a deep need for the candidate to write some code, at least have them work on a computer, preferably their own, without someone looking over their shoulder. How about some pair programming or or pair troubleshooting so it feels collaborative, and more like what actually working with this person will feel like? Who says you can only discover how someone thinks by talking to them while they are thinking? Why not wait until they are done, and then you can talk about why they made the choices they did, and what other things they thought of and rejected? I have had companies ask me to write sample code, and then bring me in for an interview, and never bring up the sample code at all. That makes no sense to me. Ask them why they made the choices they made, if they have thought of any ways to improve it, etc. Try to help the candidate feel more comfortable, because that is more realistic for how they will work. For coding, stick with computers. Whiteboards are really awesome for discussing concepts, illustrating (literally) what code is doing, and designing, and can be used for these things during interviews, but despite what I said above, they kind of suck for actually writing code.

Recently I was talking to a recruiter at a large company, and he mentioned how this company was going to start offering tech interview classes. Really?!?!?! This is ridiculous. If your interview process is not screening for what you need it to screen for, and if you know there are qualified people out there, that you want to hire, and you find yourself starting to offer them training on how to get through your interview process, then it seems that it is the process that is screwed up, and not all of the qualified applicants who can't seem to jump through your hoops. Think out of the box, employers!

The bottom line is this, if I am treated as if I am an expert, and you are inviting me in to see if I can help you to solve a problem, you are going to get a much better idea of how I work and how I am to work with, than if you give me a random problem to solve and ask me to solve it on the whiteboard while you watch me and your watch.


Other people complaining about tech interviews in interesting ways:

The Elephant in the Room ~ Comments: 2

Add Comment

More Tries in Python


Code, Python, Tech

by Maria on 13 Sep 2013 - 06:40  

In the previous blog post we tried to figure out what the python code I found on Wikipedia that was supposedly returning an iterator over the items of the Trie was actually doing, and then we sort of ran with that to gain some understanding of Tries, generators, and recursion in Python. And that was great, but in the end we didn't really have anything useful. Our method returned all of the letters in our Trie, one at a time. It seems it would be more useful if it returned all of the words in our tree, so let's try doing that. Since we have a goal, let's create a test so we can tell if we have reached our goal. Here is our test code:

import unittest
from trie import Trie

class TestWords(unittest.TestCase):
    """Tests for function words"""

    def setUp(self):

        self.mytrie = Trie()

    def test_default_case(self):
        """Test words retrieves all words properly from Trie."""
        expected = ['ant','ante','antic','antsy','antse','ban','banana']
        actual = []
        for words in self.mytrie.words():
        print 'actual', actual                                                                                          
        print 'expected', expected                                                                                        

if __name__ == '__main__':

I've made a fairly complicated, but relatively small, Trie, to really give our code a run for our money. And yes, I even made up a word. And, of course, our method fails miserably. So, let's see about getting some words instead of letters.

We know that many of our words have prefixes in common, that is the point of creating a tree like this. So, the general idea is going to be to collect letters and re-use them. To begin, let's just start collecting letters, and spitting out what we have when we reach the end of a word. We can tell if we are at the end of a word by whether there is a node.value.

    def words(self, prefix = []):
        """Return an iterator over the items (words) of the 'Trie'."""
        word = False
        for char, node in self.root.iteritems():
            if node.value:
                yield ''.join(prefix)
            for i in node.words():
                yield i

And, our test fails!

actual ['ant', 'antic', 'anticsy', 'anticsye', 'anticsyee', 'anticsyeeban', 'anticsyeebanana']
expected ['ante', 'antic', 'ant', 'antsy', 'antse', 'banana', 'ban']
FAIL: test_default_case (__main__.TestWords)
Test words retrieves all words properly from Trie.
Traceback (most recent call last):
  File "", line 27, in test_default_case
AssertionError: False is not true

Ran 1 test in 0.001s

FAILED (failures=1)

I have printed out the expected and actual list of words, and we can see immediately what the problem is. We need to figure out how to delete the letters we no longer need. How do we decide when we should delete a letter? Let's take a look at our Trie:

It looks like we will need to delete letters when we come to the end of a word, but only if that letter is at the end of a branch. How will we know? And how many letters will we delete? When we get to the end of the word antsy, we will need to delete just the y, but when we get to the end of the word antse, we will need to delete both the e and the s. (We actually have no way of knowing which branch will be traversed first; since the tree is based on a dictionary, which node it traverses first is random.)

What would be really useful at this point is if we knew at each branch how many words share that prefix. We could certainly figure this out by traversing the tree once, and then using the information when we traverse the tree again to get the words. But, it seems like this might actually be useful information, in and of itself. So, maybe this is something that really should already be available. This is the advantage with playing around with your proposed data structure before production use. We can still go back and add functionality. So, let's put some new code in our add function to keep track of the number of words using a given prefix. The first two methods of our class now look like this:

class Trie:
    def __init__(self):
        self.root = defaultdict(Trie)
        self.value = None
        self.count = 0

    def add(self, s, value):
        """Add the string `s` to the                                                                          
        `Trie` and map it to the given value. Additionally, keep track of
        how many words each node is shared with.

        head, tail = s[0], s[1:]
        cur_node = self.root[head]
        cur_node.count += 1
        if not tail:
            cur_node.value = value
            return  # No further recursion                                                                    
        self.root[head].add(tail, value)

Very simple addition, which is going to make our life much easier. We may also want to create a method that returns the number of words in our tree that share a particular prefix we may be interested in, but for now, let's finish our iterator.

For every letter that we find, we now know how many words use that letter, so if we keep track of how many words we find that are using each letter, we can compare the two. When we reach the end of a word that is also the end of a limb, we need to delete at least to the last branching point, but possibly farther. We traverse A-N-T-E and we have hit an endpoint. The E only has one word associated with it, so we can delete it, but the T has 5 words associated with it, so we need to check if we have finished 5 words yet. We can't just keep one running tally of words finished, because sometimes we will be keeping track of multiple branching points. For example, we need 5 words for the T, but only 2 for the S, but can be working on completing both of those branches at the same time. Clearly, we need to keep a list of words finished for each letter. We start at the A, we have finished no words, [0], continue to the N, [0, 0], and now to the T, [0, 0, 0], but now we have finished a word, so we go back and add 1 to everything [1, 1, 1]. Let's go to the E, we have [1, 1, 1, 0], and once again we have finished a word, so we now have [2, 2, 2, 1]. We are now at the end of a limb, so we delete letters.

But, wait, how did we know we are at the end of a limb? Well, we know we are at the end of a word, since we can check to see if there is a value associated with it. And if we check the node.count at this point, we can see that this letter is associated with just one word, so we must be at the end of a limb. Great, we can delete letters. How many? We have to check. We delete the E, then check the T. The T has 5 words associated with it, but we have only 2 recorded for the T, so we can't delete it yet. We are done deleting, as no earlier letters can possibly be ready for deleting yet. Now we go to the I, but wait, our letters-visited-list is [2, 2, 2, 1]. Hmm, looks like we need to remember to delete the 1 at the same time that we delete the letter. Makes sense, as this list should correspond to our prefix list. We are at [2, 2, 2, 0] now. We go to the C, and we are at the end of another word, so the array becomes [3, 3, 3, 1, 1]. We check our node.count, and it is 1, so we are at the end of a limb. Delete letters at the end of our array until we get back to the T, which is still a 5, and we are only at 3. Great, seem to have the hang of this. But, we have now checked the T twice, and you may remember that we are not actually going to have access to that node when we backing out. You can tell this is true, because when we were getting the letters, and not deleting any of them, we did not see multiple T's. The final word was 'anticsyeebanana', so the algorithm was just tacking on more endings, and not re-visiting previous letters.

What would make more sense anyway is to keep an array of the nodes we have visited, and what their corresponding word counts should be. So, that list would now look like [5, 5, 5, 1, 1]. Now we just compare the arrays and when numbers are equal, get rid of those letters. Well, we still must only check when we are at the end of a limb. But, this seems a little over-complicated too. What if we just collected the word count array from the nodes, and subtracted 1 from the whole array whenever we hit the end of a word? Any letters currently in the array would be ones that this word would be a part of, since it is just a representation of the letters in the prefix array. Any zeros would represent the letters (and positions in the word count array) we need to delete. Let's try it.

    def words(self, path = [], prefix = []):
        """Return an iterator over the words of the 'Trie'."""
        for char, node in self.root.iteritems():

            # if there is a node.value, then we are at the end of a word and
            # we should yield the word and subtract 1 (word!) from the
            #  entire node path
            if node.value:
                yield ''.join(prefix)        
                for x,y in enumerate(path):
                        path[x] = y - 1

            # if we are at the end of a word and the count is 1,
            # we are at the end of a branch, and it is time to
            # delete letters back to the last branch we haven't
            # gone down yet.
            if node.value and node.count == 1:
                    for j in range(path.count(0)):
                        del path[-1]
                        del prefix[-1]

            for i in node.words():
                yield i

And, let's run our test.

actual ['ant', 'antic', 'antsy', 'antse', 'ante', 'ban', 'banana']
expected ['ante', 'antic', 'ant', 'antsy', 'antse', 'banana', 'ban']
Ran 1 test in 0.000s


Left the print statements so you could see the words. So, at this point, we should create a bunch more tests to check more edge cases.

Do you suppose this is what the author was trying to do with the code in the Wikipedia article? Is there any way to do this without including the node.count or checking the tree twice?

You can find my code on GitHub.

Finally, here is a nice post about how Tries are useful for word storage for computer versions of Boggle, without ever mentioning the word Boggle.

More Tries in Python ~ Comments: 0

Add Comment

see a list of all Blog Entries

Top of Page