Rough project size estimation
History / Edit / PDF / EPUB / BIB / 2 min read (~345 words)How do you estimate the size of a project roughly?
When I am asked to provide a rough estimate of the required effort on a project with a lot of requirements or user stories, I first want to make sure that my estimate is in the right order of magnitude. That means that I want to estimate a project that takes 1-10 weeks to be in that range, but not estimate less than a week or more than 10 weeks. Similarly, a project that takes one or more years should not estimated as a job of a few weeks.
My orders of magnitude are as follows:
- 1 day
- 1 week (5 days)
- 1 month (20 days)
- 1 quarter (60 days)
- 1 half-year (120/125 days)
- 1 year (250 days)
As such, when estimating a task, I will say that the task will either take 1 day, 1 week or 1 month. In general, any task that is estimated at 1 month long (or above) needs to be broken down into sub-tasks as it indicates that the task is hiding a lot of complexity.
With this kind of approach, one can estimate that a developer can do approximately 250 small tasks (1 day), 50 medium tasks (5 days) or 13 large tasks (20 days) per year.
Start by creating an estimate of the overall project without thinking about any of the underlying tasks. This is done to have a quick idea of the scale of the project.
Then list and estimate the tasks that will need to be accomplished to complete the project. You might be forgetting a few, but it is fine at that moment. Think mostly of the most important tasks and also the riskiest.
If the sum of the efforts you estimated is in the same order of your original project estimate, then you are done. If not, then you need to investigate and explain what led you to either over or under estimate. Did you forget to estimate some tasks? Did you ignore some tasks when you did your initial estimate? What were the assumptions you made that were right/wrong? Once you are satisfied with your explanation, you are done with estimating.
Visual Studio Code templates
History / Edit / PDF / EPUB / BIB / 2 min read (~314 words)I use VS Code and I'd like to insert templates into my documents. How do I do this?
In VS Code, the concept of templates is called snippets. It is fairly easy to create a snippet, so I won't go into the details. Here's an example of a snippet I use to insert the date and time quickly into my documents.
{
"Datetime": {
"scope": "",
"prefix": "dt",
"body": [
"$CURRENT_YEAR-$CURRENT_MONTH-$CURRENT_DATE $CURRENT_HOUR:$CURRENT_MINUTE:$CURRENT_SECOND"
],
"description": "Date time"
}
}
With this snippet, I only have to type dt
and then press TAB and dt
gets replaced by the current date and time.
I use snippets to create the template of my questions and problems articles. My current approach is to open a non-existent file by calling code /path/to/new/file
and VS Code opens the editor with this file. I can then write the content of this file, which will not automatically save until I manually save. Once I'm happy with the content of my article, I manually save, which means that in the future, any edit I make and then have the editor lose focus will be automatically saved and commit to git (my current workflow).
One of the things I don't particularly like with the current implementation of the snippets system is that the body needs to be a list of strings, where each item represents a new line. It is possible to create a single entry and use \n and \ to format the string, but that is not a clean approach. Those are limitations of jsonc. If it was possible to link to a file, then it would be "easy" to create a clean template.
How can I read more books?
Make it a priority to read books. Replace some of the existing habits you have with reading books instead.
If you like to spend time reading reddit or hackernews or watching videos on youtube, replace that with reading a book. Of course, it's easier said than done. The best way I've been able to transition from those activities to reading books was to progress slowly. Don't replace reading hackernews one day by reading a book instead. Instead, simply spend 5, 10, 15 minutes reading a book, and then the remainder of the time on reading hackernews. Spend the same amount of time every day reading a book for a week. When a week has passed, increase that amount of time slightly (e.g., go from 5 minutes per day to 10 minutes per day).
As you increase the amount of time you read, you will find it easier and easier to spend time reading instead of doing other activities you might consider harmful or less valuable.
How can you tell when you've reached the top of your job and that you won't find smarter people?
When people that challenge you bring arguments which you've already considered. When the suggestions of others are stale or not intriguing. When you don't find excitement in your work. When you aren't challenged anymore. When the problems you are facing are not solved elegantly by others. When the problems you are facing have become so niche that few people on Earth may be able to discuss them or help you solve them.
Improving the performance of a slow click CLI
History / Edit / PDF / EPUB / BIB / 2 min read (~372 words)My click CLI is slow, even just to show the help. How do I make it go faster?
In most cases, the reason your click CLI is slow is that you have large imports at the top of the files where you have declared your commands.
The typical pattern is as follows:
cli.py
from train import train
from predict import predict
@click.group()
def cli():
pass
cli.add_command(predict)
cli.add_command(train)
train.py
import click
import pandas as pd
import torch
@click.command()
def train():
pass
predict.py
import click
import pandas as pd
import torch
@click.command()
def predict():
pass
Notice that in both these files we import pandas
and torch
, which can account for a large chunk of script execution time simply due to importing them. You can verify that by simply running python -X importtime train.py 2>tuna.log
and using tuna (run tuna tuna.log
) to inspect the results and convince yourself.
The suggested pattern is to move the imports inside of the function itself, as such:
train.py
import click
@click.command()
def train():
import pandas as pd
import torch
pass
predict.py
import click
@click.command()
def predict():
import pandas as pd
import torch
pass
This will shave off a large amount of time spent importing those packages (pandas
and torch
). They will only be loaded when you need to run the command itself, not every time you invoke the CLI.
Another pattern which is more complicated is to move the logic of the functions in separate files. This is done to avoid the common mistake that will happen over time that developers will add more logic in those command files, adding imports at the top of the file and slowing the CLI again. By moving the complete implementation to a separate file, you can have the imports at the top of the file and it is not possible to make this mistake again.
train.py
import click
@click.command()
def train():
from train_implementation import train
train()
train_implementation.py
import pandas as pd
import torch
def train():
# Implementation is now here
pass