↓ Skip to main content

Good execution of a project through consensus instead of leadership

Question
#

How can a project be well executed through consensus instead of leadership?

Answer
#

To properly execute a project without a leader that makes important decisions, time is one of the most critical components. Without enough time, decisions are not consensus but decisions made by the individuals available at the time the decision is required. It is also important not to rush things as it will simply lead to bigger and bigger mistakes happening more and more quickly. At one point a few or many team members will realize they’ve moved too far too fast and many of the necessary pieces are missing, which makes the work they’ve done so far either irrelevant or of low value.

The team members also need to know each other well enough to know their strengths and weaknesses. Without this knowledge, weaknesses are often ignored because they are the weaknesses of everyone.

Decisions need to be reviewed regularly to ensure consistency. Since there is no single leader that keeps the project in their head and wants to see it to completion, it is necessary to ensure that the work that is planned and executed is consistent towards a common vision. Not doing so can lead the team to work on features that go in opposite directions, features that are not aligned with the users the project targets. Acceptable moments to review those decisions are during the planning sessions and the review/demo sessions.

Team members should often work in pairs with a different individual in the team to ensure that their understanding of the project gets discussed with different individuals with different positions. This avoids working with the same person that shares your opinion of the work to be done, while some other individuals may completely disagree with this opinion. Surfacing such differences of opinion early in the development process is critical since it can lead to work that is not aligned with the project.

Overall, we want to reduce as much as possible the time between the moment an individual or group of individuals have an incorrect understanding of the project’s goals and the correction of their understanding.

Reference
#


Measuring success

Question
#

How will you measure your success over the next year?

Answer
#

Over the past few years success for me has been defined less by goals and more by being able to work continuously on a process. For example, I might want to get better at writing. My goal is not something like “write one technical book by the end of 2020” but rather “write technical content daily”. This decreases the pressure and the need to perform while allowing me to do what I want.

I feel happier and more successful when I can keep doing the same thing over and over, even though I may have no motivation. It shows me that it’s possible to accomplish pretty much anything, as long as you’re willing to put in the effort.

Because I evaluate success this way, it is easy for me to track if I’m successful. I use the Loop Habit Tracker (an android app) to track whether I’ve worked on something I told myself I wanted to improve. My list started small and contained very mundane things such as “Bed is done”, “Empty table”, “No dirty dishes” and started including more and more habits, such as “Read 1 wikipedia article”, “Answer 1 problem” and “Answer 1 question”.

Being able to keep a good habit is what defines success to me. With the help of the app I’m able to add more and more habits without forgetting the previous ones since I’m reminded to do them at the desired weekly frequency.


Visual Studio Code Run Me extension

Problem
#

I frequently run the same commands with different parameters but I have a terrible memory. I also use Visual Studio Code a lot.

Solution
#

I developed an extension in 2018 called Run Me whose goal is to allow you to define commands that you can customize through a form, which is a series of questions that will be asked to you, before launching the command with the parameters you provided.

I’ve used it to do all kinds of things, from launching OBS to resetting the Windows 7 visuals when it lowers them down due to low memory. I also use it to automate various tasks such as creating new articles using a template, opening my buffer document that I use on a daily basis to write notes and more.

Here’s an example of my configuration file which I use to start OBS and to reset the Windows 7 visuals.

"run-me": {
	"commands": [
		{
			"identifier": "start_obs",
			"description": "Start OBS x64",
			"command": "\"C:\\Program Files (x86)\\obs-studio\\bin\\64bit\\obs64.exe\"",
			"working_directory": "C:\\Program Files (x86)\\obs-studio\\bin\\64bit"
		},
		{
			"identifier": "reset_visuals",
			"description": "Reset W7 visuals",
			"command": "sc stop uxsms & sc start uxsms"
		}
	]
}

Reference
#


Productive meetings

Question
#

What does a productive meeting look like?

Answer
#

There are a few people invited, less than 6 ideally. Everyone invited knows why they are in the meeting and will contribute to the discussion.

An agenda for the meeting has been set, with a pre-determined amount of time for each item on the agenda. One person is responsible to make sure that the agenda is followed and that the time is respected.

Notes are taken by the different individuals that are part of the meeting.

Items that appear to require more discussion than anticipated are noted and the involved individuals may spend additional time outside of the meeting to make their point, either through another meeting or by writing a document explaining their position.

A list of actionable items is defined at the end of the meeting and responsibles are assigned to those items. Deadlines are also assigned to those items so that people can expect those items to be completed by the defined date.

References
#


Knowing what your users need without having users

Problem
#

I need to know what the users of my library need, but I don’t have any users yet. What should I do?

Solution
#

When you are defining who your target audience is, it can be rather difficult to decide who your users will be. If you’ve been building capabilities in a certain domain for a while and can solve specific problems with those capabilities, then you will likely want to look for users that may have those problems. You may even end up creating personas or prototypical users who have the problems that your library might solve.

Once you’ve established those prototypical users, you should try to find them in person and confirm your assumptions. You do not want to be building features that they don’t need. In the event you cannot get access to any real users, you can still make use of user proxies. User proxies are people that can somewhat act as the true end-users, but are not the true end-users, so that you have to be careful about what they tell you they need since it is likely to be biased by their actual position. Some potential user proxies are:

  • The users’ manager
  • Salespeople
  • Domain experts
  • Former users
  • Customers
  • Trainer and technical support
  • Business or system analysts

In User Stories Applied: For Agile Software Development, Mike Cohn suggests to use more than one user proxy to mitigate the bias from any specific user proxy. Make sure that the user proxies are of different types. This technique is comparable to using ensembling in machine learning.

Reference
#


AST in python

Problem
#

I want to analyze a python script to extract something from it. How do I do that?

Solution
#

Python has an abstract syntax tree like most programming language.

You can use the ast module to parse a string that contains the code you want to analyze.

A simple example is as follow. It will read a file defined in the file variable, use ast to parse it, returning a tree that can then be traversed using the visitor pattern. Defining visitors lets you separate the responsibility of each of them, making the code that analyzes code easier to understand.

import ast

class ClassVisitor(ast.NodeVisitor):
	def visit_ClassDef(self, node):
		# Do some logic specific to classes
		self.generic_visit(node)

class FunctionVisitor(ast.NodeVisitor):
	def visit_FunctionDef(self, node):
		# Do some logic specific to functions
		self.generic_visit(node)

visitors = [
	ClassVisitor(),
	FunctionVisitor()
]

with open(file, "r") as f:
	code = f.read()

	tree = ast.parse(code)

	for visitor in visitors:
		visitor.visit(tree)

Reference
#


Working on the most important task

Question
#

Why aren’t we always working on the most important task?

Answer
#

For bad reasons:

  • We don’t want to work on the most important task.
  • The most important task feels overwhelming.
  • The most important task seems too risky.
  • The most important task doesn’t seem fun to work on.
  • We want to work on fun tasks, not hard tasks.
  • We want to work on what interests us, not what provides the most value.
  • We think that the task we’re working on is more important, but it isn’t.
  • We don’t know how to solve the most important task.

For acceptable reasons:

  • We don’t know what is the most important task at the moment.
  • We don’t understand what is important to our clients.

For good reasons:

  • The most important task has prerequisites that need to be completed before it can be done.
  • The most important task is being done by someone else already.
  • The importance of tasks is likely to change soon due to a change in objectives.

When to abandon pull requests

Question
#

When is it appropriate to abandon a pull request?

Answer
#

Assuming that this is in a business context, you should abandon working on a pull request if getting the pull request merged is taking away too much time from others and it requires a lot of additional changes, creating a lot of back and forth between the creator and the reviewers.

You should abandon it if the feature/bug it fixes is not important enough compared to other more important ones. One should always work on the most important task rather than to work on tasks of lower importance. Furthermore, working on low importance pull requests will also “force” your coworkers to review those low importance pull requests, reducing the overall productivity. As such, always think of the impact you will have on others.

Many developers often think that bugs are of the utmost importance and should be fixed as soon as possible. However, implementing a good fix might require a lot of effort on the part of the person that will fix the issue, as well as a good amount of effort on the part of the reviewers which could have spent their time on features or bugs that are more important. Like anything else, bugs should be prioritized based on how important they are, not just that they are a bug.


Reinventing the wheel

Question
#

Why do we reinvent the wheel?

Answer
#

It is very common for developers to want to develop things themselves instead of reusing existing code. They prefer to know how it works so that if they need to make changes to the code, they know where to do it since they wrote it themselves. If they are lucky, they’ve been given a narrow set of initial requirements that could be fulfilled by a more complex/complete library, but they think that they can do it themselves or do it better. Thus they build themselves a square wheel.

One of the positive sides of developing something that already exists is that you can get a good understanding of what is required without having to consider all the other parts which may be required for other use cases. You’re also free to explore the aspect of the problem that you find interesting or challenging.

One of the negative sides is that if you work on your own square wheel for a while, you never end up learning a library that might prove more useful. You also do not acquire the skill of learning new libraries and their strengths/weaknesses, as well as how you could help to improve them. Sometimes however by reading an existing library you will come to the conclusion that fixing said library is likely to take you more time than writing a new one.

In my experience, the main reason that has led me to write something from scratch even though I had access to code that partially did what I wanted was because:

  • the library wasn’t able to sell me on the reasons I should use it instead of doing it myself, while I considered implementing the solution myself to be somewhat easy.
  • the code (organization, style) was so messy that fixing it would require more time than rewriting it after understanding the core concepts.
  • the library was not maintained anymore.
  • using the library would make my workflow slower.

References
#


Billionaire's life

Question
#

If I were a billionaire, how would I live my life?

Answer
#

I would invest a good chunk of my money in doing research in the fields I’m interested in, namely biology, genetics, computer science, software engineering, machine learning and artificial intelligence. I would spend my time trying defining what is the most important thing I could be working on given our current understanding and constraints in order to reach certain objectives. I would want to get informed by the advice of the smartest people I can get. I would pay others to help me get to my goals faster. I would avoid having to deal with hardware constraints by simply purchasing more hardware. I would try to trade the money I have to remove as much friction as possible in my work. I would like to consider working on different things as having a variety of hobbies and not a variety of jobs. I would avoid spending my time commuting. I would eliminate the time I spend on cooking and cleaning. I would maximize the effectiveness of my time, from the moment I wake up to the moment I go to sleep. I would try to find ways to increase the number of people (or machines) that can help me. I would try to find ways to make the fact that I’m a billionaire irrelevant to the accomplishment of everything I’ve stated here.