Of Poker, Microservices and Software Craftsmanship

image

Last week I was at Craft Conference in Budapest. I attended a one day workshop called Lean Poker. I’m really glad I attended the workshop. I learned a lot about many different aspects of software delivery and I will share my learnings with you here.

Continuous Delivery

ThoughtWorks, where I work, practice continuous delivery. This basically means you can push the code to production with every commit. In practice it means updating software as and when you need it and not having to wait.The benefits seem obvious but I can understand why developers and companies are reluctant to perform continuous delivery. Often time a mistake looks worse than a delayed delivery. Looking internally, you’re more likely to get fired if you deliver something that doesn’t work than if you are late and can blame a string of processes and developers down the chain. Looking externally, what does 5 mins of downtime matter to customers when your service is providing them with what they need now? Delivering before your competitors is equally advantageous (if not more so) than a sturdy service. As long as you can quickly deploy a fix (again, continuous delivery) you should be happy to go to production as often as possible. You have to ensure, however, that there is a warning system for when things break. Which brings me to my next point.

Watching Metrics

My team are the blue line above. We lost. One of the main reasons for this is we did not have someone early on watching the graphs and watching the games play out. We used Ruby whereas the other teams used strongly typed languages (C# and C++). What we did not realise is we were sending the wrong type to the API. It was not until we looked at the plays and started putting out logs that we realised this. It would also have helped if we went through the documentation. We were all developers and so we wanted to jump into the code base (which resulted in merge conflicts and delayed deploy as we were pushing faster than our logic dictated). Other teams split into a code pair and a business logic pair for the first iteration. This worked well. One thing I noted was one team had a quality analyst and his take home was not to concentrate so much on the quality of the code but more on the output of the code. How well was the bot doing? Especially since performance was related to the other bots. For a startup, you are in a competitor ecosystem. If you have tunnel vision on your own code/service, you will most likely miss a trick and this could be what sets you apart. That being said, the lesson for watching metrics brings me to my next hard lesson learned.

Team Communication and Cohesion

Very early on, it became apparent that team communication was the key. After the first iteration my team restructured our seating to work in a circle facing each other. We discussed very briefly what aspect we would be implementing and shouted out whenever we were going to push. For the first few iterations (starting to bet and implement some logic based on the card in your hand), the team which set a structure and communicated well had the upper-hand. It had very little to do with code or team knowledge. Having someone look into applying the logic, figuring out which baby steps to implement first, and ultimately guiding the programming team worked best in this scenario. That being said, it was important these people were able to understand the key is to getting functionality out the door asap and not to try to apply an advanced algorithm all at once, which brings me to my next lesson learned.

Not Overthinking

Looking at LeanPoker, one might think the smartest algorithm will win. This is not the case. My biggest take away was this, the simplest and quickest response to the game play is what will win. The dives my team and the C# team took were mostly owing to the introduction of bugs and failing code. Because of this, the battle for second place was between us. The winning team had no down time but also moved from implementing the pocket pair logic (very simply) to using an external resource for getting odds on the river much more quickly than anyone else. Their first implementation was basically a logic matrix translated into a giant if/elsif/else statement. But this got them what they needed such that they could move onto the logic on the river and watch the games to tweak betting strategies. This left the remaining teams fighting for second place where it came down to who was most aggressively betting on the pocket pair.

For me, this became a very interesting lesson in startup battles. It’s not just getting to market first but being able to constantly react to it. It also highlighted the importance of metrics and remediation time over test coverage. I learned a lot and would recommend everyone play Lean Poker.


Microservices


Craft Conference is a generalist conference and as such the talks could not be too specific. There was a very clear theme however and the was microservices. The interesting aspect was how this architectural technique is either a) changing development style and business structure or b) a result of changing development style and building structure. To tweet Josh Long from Pivotal Labs

An insightful snippet from him is how one can make software robust not by reducing downtime but by reducing the time to start back up.

This was enough to get me interested in microservices. My favourite part of the conference was Josh’s demo spinning up microservices using Java in the cloud.



However, Dan North wondered how far are we going to take microservices. Are we going to see a one character nanoservice? I’m interested in how the microservices ecosystem will develop as was noted at the conference:


Craftsmanship


One thing that surprised me about Craft Conference was how much focus there was on human to human interaction rather than human to machine interaction. Software development, as a huge money making industry, is limited by the people more so than the programme. Software craftsmanship involves not just programming but understand people and business value.

This applies to every industry. And as Josh rightly said:

Dan North also shed a very interesting light on the value of code noting code is not an asset. Until it is deployed and being used by customers it is a liability.

Therefore,

Another interesting point for me, someone just starting in development, is the importance of having devops skills. It is a big ask for long time developers but with the popularisation of microservices the label “full-stack” is not enough. A developer should be able to build a piece of software all the way to business value.

Charity Majors gave a very colourful talk on why developers need to know devops. Even if it is not their speciality they need to know what happens to their code once it is deployed.

Something that was of particular interest to me was when the speakers talked about building skills. How making sure your developers build devop skills is a skill in itself. How to manage an environment of experimentation and constant learning. Charity gave the harsh truth, most managers just expect people to overwork.

This gives rise to imposter syndrome, you can never be good enough. Yet by thinking you should be better and striving to get better, that’s what makes you a good programmer.


Diversity


It was clear the conference organisers cared about diversity. The numbers were announced at the start.

In attendance was a male colleague whose first tech conference was Craft Conference. He was shocked at how low the numbers were for attendance and yet Craft had made a huge effort. It highlighted to me how much the issue can be highlighted and yet the reality is not clear until you step outside your own small circle and look at the larger picture.

One thing I really liked, besides the amount of female speakers, was the fact that the keynote speaker was aware of the issue even in his talk.

Systers Are Doing It For Themselves

Learning something new is always daunting. Entering a new field having just learnt a new skill is intimidating. How do you sell yourself when you feel you’re just a prototype, an MVP? I don’t know exactly how I am going to do this, but luckily I have my Systers to help.

A couple of days ago I attended a Systers meetup at Thoughtworks. It was run by the wonderful ladies from the US team. I had heard of Systers, the Anita Borg Institute and the Grace Hopper Celebration from my Twitterers across the pond. I had always assumed it was a US-centric thing. But not for much longer!

It looks like they are breaking out of the US and forming local groups to support systers world-wide. What excites me about this move is the inclusion of not just programmers or women in the tech industry but women in STEM. It’ll be great to get advice from women in many fields and at different stages of their career. It is exactly what I need right now.

A major benefit of being in the systers circle is knowing which companies value women in the workplace by partnering with them. For me, that’s a great place to start when deciding where to begin my career as a fully fledged programmer. Companies like Google, Microsoft, Facebook and Thoughtworks have signed up to work with the systers network and it looks like they will be hosting events.

Follow me on Twitter and I will post them.

JavaScript is an unruly child

This week was JavaScript week at MakersAcademy. After working with solely classical languages, moving to prototypal was like a vulcan mind meld. 

So a classical language is like traditional architecture. You build foundations and this determines what you can build on top. The structure on top determines what you can build inside, etc. A prototypal language is like building with Lego. Each piece is fairly similar. So you can build and extend on the fly without predetermining what can be built next as each piece will fit on top of another.

In a metaphorical way that is how I see it. In term of using a classical language like Python and Ruby to a prototypal language like JavaScript another metaphor can be invoked. Ruby is a well behaved child. You have to give it instructions but once you do it is pretty good at carrying them out as you have asked. JavaScript is an unruly, stubborn-minded, unwieldy child.

You need to be disciplined in managing JavaScript but too disciplined and you will end up in a confrontation. Try to be too strict and it’s JavaScript’s way or undefined. It has its own creative ways of doing things and if you cajole it just right you can be privy to it. 

My first JS project involved building a thermostat. During the process of taking a function outside of another function I forgot to take the variable assignment with it. Which means it should break. But it didn’t. It’s a strange bug when something works which should not. It turns out that the JS in browsers is doing something very strange.

Create this html page and pull it up in your browser:

<!doctype html>
<html>

  <head>
    JavaScript the unruly child
  </head>

  <body>
    <div id="wtf">
      Why is the browser setting this as a variable?
    </div>

  </body>

</html>

Now go into your console and type wtf. Just that. No var or anything. Yes, your browser creates a variable from your ids and sets it to the html element it is attributed to. 

 photo Screen Shot 2015-07-10 at 10.16.34 PM_zpstnmtf6st.png

This won’t be the last time I find JS has a mind of its own but I think I can learn to love JavaScript. The way I see it, Steve Jobs, Elon Musk, Ada Lovelace; they were never the  good, do-as-you-are-told child. They were the unruly child who had a mind of their own. No “good” child grows up to be “great”. But for the parent, years of toil before the hard work pays off.

My journey continues…

It’s All About Attitude And Very Little To Do With Aptitude

So last week was database week at MakersAcademy. This is when, if you haven’t already broken, you are expected to break. This is the week where hair is pulled out and laptops are flung out windows.

I rather enjoyed it. I nearly pulled out my own teeth trying to get the password to update using DataMapper. A validation meant I could not update unless I added a password confirmation even if the user did not provide it. I probably could have brute forced my way into the database and change it there with less effort. 

But at the end of the day, there was nothing a tactical combination of guess work, error reading and brute force could not solve. There had to be a a reason for the computer not doing what I asked of it. The reason is always that I am not asking it correctly. So think through logically everything it has been told to do and you’ll get there in the end.

What you should never do is panic. This, I believe, is the difference between those who are struggling and those who are completing the coursework. It is not about aptitude. Everyone, especially the women, are well capable of executing the challenges. 

At the end of the day it is not about having a fully functioning programme. It is getting a full understanding of that corpus of functionality, no matter how basic the application. I do not get further because I can “code better” but because I am regimented in my process (MVP feature -> test -> red -> green -> refactor -> git commit and repeat), I don’t attack my logic when a test fails but read through the error and the code very carefully (it is usually a typo) and I make sure I am building the functional domain of everything I have written in my head as I go along.

With this approach no one should be worried if they are a “good” coder. They should concern themselves with having the right attitude to problem solving and the patience to learn. I was talking to a woman recently who wants to do a course like Makers. She is really concerned about being “good at coding”. She wants to spend a year teaching herself first. This is totally the wrong attitude to have if you want to be a “good coder”. Feeling you need to know everything and have a lot of experience before you can even try to apply yourself is the enemy of “good coding”. 

A lot of the women I talk to have patience, a regimental work ethic and smarts enough to work at any tech giant. The problem, as I see it, is they tend to let the problem get the better of them. Instead of attacking the problem they attack themselves. They panic and they think they are not any good and they cannot do it. 

Generations of social psychology have brought males up with aggression as a positive characteristic and females with passivity as a positive characteristic. Coding requires neither extreme. A lot of men I have paired with over attack a problem. They charge into changing the logic when it is usually a typo. The women I have paired with have a better attitude towards attacking a problem but sometimes lack the stamina, turning on themselves before they have given enough time to figuring out the solution. When you are learning to programme you will take a long time to find a solution. But as you progress, the skill you are gaining above all else is reducing that time, not negating it.

I have the stamina to problem solve. I have thrown myself into new environments and have had to get things done on the job I had no idea I could do. This is not a result of having a “male characteristic brain” or being “not girly” as some men have assumed. It is because I am the second generation literate on my maternal side. My grandmother was never educated. She never went to school. She never learnt to read or write. When her husband died she begged in order to afford school books for her daughters so they could get the opportunities she never had.

I know now that, because of her strength, I will not break during this course. And I will not leave any woman behind. 

My journey continues…

Create Stable Fluid Code

Ugh, titles for blogs on programming read like mulched up cardboard taste. What I’m trying to get at is the concept of creating functionality whose logic holds sound but whose application is not so rigid.

This came to the fore last week at MakersAcademy where we were building our first web app; the game Battleships. Previously I had built some of the backend implementation but ended up using a gem for this web app. It was my first venture into web development (although very basic using the Sinatra framework), feature tests and Behaviour Driven Development. It was thoroughly enjoyable and I felt comfortable using the skills I had gained to build Rock, Paper, Scissors.

I banged out the backend pretty quickly. Seeing as an extension of the assignment was to implement the Rock, Paper, Lizard, Spock version:

I thought I shouldn’t hard code the options Rock, Paper, Scissors into a method (most people would use case statements). I wanted a method that would work out the logic using the three and the five options. So I decided to use a class constant and write the method to use the mathematical logic of the system. My code looks like 

OPTIONS = ["rock", "paper", "scissors"]

  def choice_to_number choice
    OPTIONS.index(choice)
  end

  def rock_paper_scissors player_choice, opponent_choice

    your_number = choice_to_number(player_choice)
    opponents_number = choice_to_number(opponent_choice)

    (your_number - opponents_number) % OPTIONS.count > 0 and (your_number - opponents_number) % OPTIONS.count <= OPTIONS.count / 2

  end
  

If all options are ordered such that, when wrapped circularly, each option beats half the remaining elements counter clockwise and loses to the other half clockwise then the logic states that (your choice - opponents choice) modulus the number of choices is greater than 0 and less than or equal to the number of choices divided by two. Thus, if the last line of the method rock_paper_scissors is true then you have won.

It meant that I was able to extend the game to include the Spock and Lizard options in the controller whilst using the same game logic. My code in the controller was very simply this:

def extend_lizard_spock
    (Game::OPTIONS).insert(1, "spock")
    (Game::OPTIONS).insert(3, "lizard")
  end
  

By putting the options and the rules of the games into array constants, it meant I could add these to the views from the controller, showing the user the rules of the game they decided to play. I know I should not be changing constants and in this instance I even used a global variable for the instance of game (sacrilege!) but this is owing to the fact that we have yet to learn to use databases.

My journey continues…

Forget What You Know, Prototype The Functional Domain

Ok, so choosing a title isn’t easy as I am trying to explain a rather abstract concept.

In week 2 of my MakersAcademy journey I made a functional version of the back end of the game Battleships. At first I tried going down a complicated hash with array keys to make the grid to represent a board. This did not go well. At one point I managed to make a hash with all the pairs having the same key! (I thought Ruby would not allow this). I was setting an array of coordinates (e.g. [2,3] ) as a key, adding this key plus the an instance of Ship to the hash and then changing the array in place (my method was trying to add the ship in at all the coordinates it would be at given it’s starting position, size and orientation). But the array instance is the key so all the keys changed in place. I decided to dump the code and rewrite from scratch.

Luckily, MakersAcademy provided an MVP pill where no grid was ever specified in any iteration. So my pair and I proceeded down the no grid route. This proved to be much more fruitful. The “board” is an array containing ships and it knows its right and bottom boundaries. Thus, a representation of 2D space is given solely by a set of coordinates. The x coordinate is a letter and the y coordinate a number e.g. C4. The “board” has a default size of 10 (“boards” are set to be square). The right boundary is defined by the last letter coordinate (for a “board” of dimension 10 this is J) and the bottom boundary is defined by the last number coordinate (for a “board” of dimension 10 this is 10). 

To check if a ship is outside the dimensions of our “board” we check the last position of the ship (logic dictates that if the last position is outside of the boundaries then the ship is off the “board” and if any other earlier part is off the “board” then so is the last position) has a coordinate letter following the right boundary, in this case J, or it has a coordinate number following the bottom boundary, in this case 10. Thus a grid need never be made. I found this implementation much more elegant. In refactoring an implementation with a grid I found this grid-less logic resulted in less functional dependency on the Board class and allowed for much simpler method implementation.

My conclusion is not to model “real life”. In “real life” we need a board to function as a coordinate giver for the ships because the “real life”plastic models cannot know their position. But if we think about, battleships the game is just trying to model “real world” battles at sea. Is the sea a board? No it is not. We have created abstract “coordinates” latitude and longitude (these are not physical things) which the ship is responsible for knowing. In code I can model these abstract features better than “real life” representations as they are limited to three spatial dimensions and one time.

So my lesson this week is: forget what you know, do not try and model real life. Model the functional domain - the abstract over the real.

My journey continues…

Test Driving Ruby

So I’ve taken the plunge and signed up for a development boot camp: Makers Academy. Yes, I can code. I know many women (and those non-computer science trained coders) have imposter syndrome. Women who code should own up to it and not think everyone out there is better at it. In fact, my first week has proven to me how much of a coder I already am.

In our first week we have pair-programmed, working TDD style through a tutorial setting up a simplified Boris bike system. For the first day I was paired with someone who is doing computer science. And we were on the same level, understanding at the same pace and even working in tandem to figure out functionality. Coding really is for everyone regardless of who you are and what you do. It is a frame of mind and having taught myself Python I know I have it.

I am a Pythonista but am also going to be a Rubyist. I learnt Python to deconstruct websites and to work with data. I write Python scripts to take apart. Now I’m hoping my mind will switch to Ruby for the opposite functionality. To build. This requires a different set of coding skills and coding mindsets. TDD helps with this. And as the course progresses I’m sure my mind will meld to the new rubric.

I love programming because it is continuous learning. Everyone who codes is in a state of learning. From the first week it is clear that there is no one better, no one more real a programmer than you. As with all walks of life, there are people who have learnt what you are currently learning. Thankfully with programming, many of them want to help you on your journey.

Mine continues next week….

We’re told we don’t ‘do’ enough — we should ‘lean in,’ we should speak at conferences, we should go to hackathons, we should give back through programs that teach girls to code, we should be mentors in our workplaces — all while doing our day jobs, continually learning more skills on the side, raising families and occasionally sleeping. These are all positive things, but one wonders if men are held to the same measuring stick; I know very few men who do all of these things, yet they seem to keep rising in the workplace without all the ‘extras’ — yet they often seem to be prerequisites for a female tech leader.
blog comments powered by Disqus