In this blog post I want to share my experience learning how to snowboard as a skier. I go skiing every year or so but I never snowboarded and I thought now would be the perfect time to learn it. I love learning and learning how to learn and I thought that this would be a great time for me to learn a new skill.
I prepared like anyone would prepare for anything: by watching a lot of YouTube videos.
Yup. That’s all I did. Here’s a sample of my notes.
I think the biggest thing that I learned from skiing that transferred to snowboarding is that you should really commit to the turn.
If you go, you go for it, no half-assing. With skiing this means that you must take some speed down and then push through to finish the turn. With snowboarding this means that you should lean into the turn and trust the snowboard to grip the edge.
All this watching of Youtube videos really paid off and I was able to do a red slope on my first day of snowboarding which was pretty neat. I’m not going to say it was pretty, but I got down the slope with some turns.
As a bonus picture here is me falling in some powder snow.
I guess I did not commit enough to the turn!
In this blog post I want to share a piece of text I found in Elon Musk’s biography. How much of it is true, I don’t know, but I like the idea of so I’m sharing it.
“One reason was that rocket components were subject to hundreds of specifications and requirements mandated by the military and NASA. At big aerospace companies, engineers followed these religiously.
Musk did the opposite: he made his engineers question all specifications. This would later become step one in a five-point checklist, dubbed “the algorithm,” that became his oft-repeated mantra when developing products:
In this tweet we see how people initially disliked the now historic Wright brother’s initial flight. It’s easy to be negative and to be an armchair critic. No matter what you do, if it is of any significance you will find people that are critical. So best expect it and be ready for it.
Product: That being said, criticism can also be used as a tool to refine ideas and to make them stronger by having them stand up to scrutiny. There will always be some criticism, but maybe you can use it to make your ideas stronger and more resilient.
Org: Organizations must make decisions. Oftentimes this can be done in a democratic way in a group setting, but sometimes a leader must make bold and unpopular decisions. Then it is your choice. Do you listen to the criticism or do you continue regardless of what others say?
What is more important? The current behaviour of the system (functionality) or the ability of the system to change (architecture)? This is the trade-off that software architects have to keep in mind with every decision both big and small.
People from the business will often tell you that current function and behaviour is more important because it delivers added user value right now. But if you always relent to this pressure then you are failing at your job of being a software architect.
Whatever you do there will always be more and more requests from the business to respond to changing market conditions, but if you don’t draw a line in the sand and if you keep giving in, then at some point all chose changes make the system so hard to change that everything will grind to a halt. Then people from the business will look and you, scoff, and think: he did a terrible job for not saying no more often to us.
It’s your responsibility to both (a) make the required changes but even more importantly (b) keep the system in such a healthy state that it is possible to do (a). That is the principal task of a software architect. This means sometimes saying no to requests from the business in order to protect the long-term integrity of the system.
Successful collaboration relies on shared interfaces.
Currently, I’m part of a project in my organisation involving three teams: the mlops team (my team), the data team, and the dashboard team.
The data team creates the model, we handle hosting it in our infrastructure, and the dashboard team takes care of visualisation. To make this collaboration work, we need to interact with both teams, consuming and hosting the model, and providing its output to the dashboard team.
The only real way of making this collaboration go smoothly is by establishing a clear interface. We need to align with both teams (the data team and the dashboard team) in what we expect to give them and what we expect in return.
For example, one such agreement could look something like this:
s3://{env}-{region}-service/foo/bar/things.json
things.json
being valid json
with the following format: {String<Name>: String<<List[Int]>>}
.Agreeing on this interface provides a clear point of separation, allowing both teams to work in parallel because you can pretend you get the output agreed upon in the interface (mock it, fake it, whatever). The important thing is that your interface need not be perfect from the start, but agreeing on one is the first step in decoupled collaboration.
I have been reading this paper Programming as Theory building (1985) by Naur and I have to say it is very interesting.
What I like about this paper is that it puts programs and code in a new perspective for me. Before reading this paper I always thought that code was the most sacred thing and the objective truth that we could all agree on. Now that I’ve read this paper I am starting to think a bit differently.
The main premise of the paper is that it is not the program (the code) that is central, but that it is the theory (sort of like the mental model) of the programmers writing the program (code) that is actually central.
All that programmers do is solve real world problems with code. What this means is that programmers have a theory (mental model) of the problem in their head and how to solve it. The code is merely an expression of this mental model. To write good code and to have others write good code is then an exercise in trying to shape, agree, and collaborate on this theory.
I use the word theory quite casually here, but it has a very subtle meaning that I honestly can not fully explain. But what I got from the paper is that the theory that is mentioned here means that one has an idea, a sort of mental model, about the world which allows you to reason with it, to change it, to modify it, to play around with it. In that sense it is a bit more broader and abstract than say some physics laws.
The important piece of this theory is that it allows you to intuit where to change a system if a change is required. One thing that the paper states (back in 1985) is that the real only constant thing is change. The world changes constantly and so programs are forced to change as well. The programmers then working on the code must also know how to change the program in ways. This is the key benefit of having this theory in mind over just looking at the code. Having this theory in mind allows you to understand how you should change the code if future requirements come in.
It’s like the joke about the plumber who just whacks a pipe with a hammer to fix a clog and charges 200 dollars. the client protests, saying he should only charge 5 for such a simple fix. the plumber itemizes the bill - 5 for hitting the pipe, 195 for knowing where to hit it.
You’re not paying for the labour of the plumber, but for his theory (mental model) that allows him to understand where to modify the system (whack a pipe)
FIGURE 1.11.The Designer’s Model, the User’s Model, and the System Image. The designer’s conceptual model is the designer’s conception of the look, feel, and operation of a product. The system image is what can be derived from the physical structure that has been built (including documentation). The user’s mental model is developed through interaction with the product and the system image. Designers expect the user’s model to be identical to their own, but because they cannot communicate directly with the user, the burden of communication is with the system image.
It’s the designers job to try and create a shared understanding through with the user through clever design. This is like collaborating on a project but on hard mode. The user can only see the product and documentation and needs to build a theory with just that.
I found this example in The Design of Everyday Things by Don Norman.
The last example that I want to give is about the saying “The map is not the territory.” In a sense a map is literally a projection of the territory, but it is not the same. Only when the generals all understand the map and how the actual territory diverges from the map, it can really be useful. Would it be possible to state, in more general terms that, the program is not the solution? The map (projection) is not the territory (reality). The program (projection) is not the solution (reality)? Maybe.
I’m more and more convinced that Python developers should steal this great convention from Rust developers.
I talked briefly about colocating source code and test code in this previous blog post and in that blog post I mentioned someone on Reddit who mentioned Rust. Coincidentally, it just so happens that I’ve been reading up a bit about Rust and I found the official documentation talking about this and this is what they write.
Under the header Unit Tests the book writes:
The purpose of unit tests is to test each unit of code in isolation from the rest of the code to quickly pinpoint where code is and isn’t working as expected. You’ll put unit tests in the src directory in each file with the code that they’re testing. The convention is to create a module named tests in each file to contain the test functions and to annotate the module with cfg(test).
Under the header Integration Tests the book writes:
In Rust, integration tests are entirely external to your library. They use your library in the same way any other code would, which means they can only call functions that are part of your library’s public API. Their purpose is to test whether many parts of your library work together correctly. Units of code that work correctly on their own could have problems when integrated, so test coverage of the integrated code is important as well. To create integration tests, you first need a tests directory.
In summary, colocate the unit tests and source code and act like integration tests are tests external to your library and hence they should stay in a separate tests directory.
This is a vacation photo of me (in the middle). You might see us three and Mount Fuji in the background and you might think “nice picture”.
But when I look at this photo what I remember is that we were in Hakone and that it was almost autumn. I remember that we made a gamble on which day we would take this hike because of the weather. I remember that we had to get up really early at 5am to start this long hike and that the reward was so worth it. When we got to the top we were surprised that it was so quiet there and that there were only two other people with us. The fact that they were a bit old impressed us even more because the climb up was quite steep.
Of course, if you look at this picture that would be literally impossible for you to know because you weren’t there. I remember it because I was there.
For better or worse, this is exactly how documents produced in agile teams work as well. They make sense if you were there, and often they make less sense if you weren’t.
These documents created together make a lot of sense for the people that were there at the time of creation. But you will most likely share it with someone that was not there, and then it will make a lot less sense to him. There’s not really a lot that you can do other than getting together and trying to retell the story the same way that I used the photo above to tell you my story.
This blog post is a remix and might contain some literal words of a chapter of User Story mapping by Jeff Patton. I want to share this because I deeply and fundamentally agree with the point that he’s making and I want to link it to the programming paper “Programming As Theory Building (1985)” by Naur at some point.
Giving and receiving feedback is incredibly important. Here I want to share with you a simple framework that will make giving feedback a lot easier.
First things first. A guiding principle should be that you should always give feedback on things that people can change. It doesn’t make sense to give feedback on the colour of someone’s eyes because they can’t change that, but it does make sense to give feedback on something that someone did that you found commendable.
The framework I want to share is the SBI framework which stands for Situation, Behaviour, and Impact.
The framework has three simple steps:
Putting it all together this is the final feedback that you could give for example:
Hey I just wanted to give some feedback. In yesterday’s meeting with leadership I noticed that you were standing up straight and talking with a confident voice and demeanour. Seeing this made me feel really great because you rocked that presentation and I know that this is a goal that we have been working on together and it really shows that you’re improving. Keep it up!
Giving and receiving feedback is hard, so let’s try to get all the help we can.
Speed in and of itself can be a feature, see ruff for example. Here’s a list of tricks that I’ve found useful to speed up your code.