10 Feb 2020

AST in python

History / Edit / PDF / EPUB / BIB / 1 min read (~193 words)
Problems Software development Python

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

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)

When is it appropriate to abandon a pull request?

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.

Why do we reinvent the wheel?

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.

07 Feb 2020

Billionaire's life

History / Edit / PDF / EPUB / BIB / 2 min read (~235 words)
Questions

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

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.

Is it better to spend a lot of time designing a great software solution or to implement an acceptable one?

In software development, the further you go down the development pipeline, the more expensive it is to change things. Once a solution is established and is being used by other parts of the code, replacing it becomes more expensive. Thus it would make sense to spend as much time as possible planning what you're going to develop before you develop it. Sometimes you however do not have enough information to make an informed design decision upfront and you actually need to implement something to explore and understand what will be needed to solve the problem. The exploratory implementation you do may end up being satisfactory enough that you do not see the need to redesign your solution.

When you implement a solution you generally have an idea of the use cases you need to support, but sometimes certain use cases are less common and require a lot more effort to support. As such, you have the choice between implementing a solution that would support both common and uncommon use cases but would require more time, or you could implement a solution that covers the common cases. Depending on the field you are in, you will have to choose between this tradeoff.

In the domains I've worked (game development, web development, machine learning), it has been more valuable to implement an acceptable solution that could be shown as providing value to the client vs designing a great solution until it was proven to be necessary.

Always make wise use of your time and assess whether quality or quantity is needed for your software project.