Thursday, 31 May 2018

25 pages a day - April 2018*

The Intelligent Investor: The Definitive Book on Value Investing

*More like almost 25 pages a day, and a week or two of May included.
I've discussed some parts of this book in my first post here, and there's more to it. Graham mentions another significant difference; between the defensive and the enterprising investor. The difference being not much money one puts in compared to the other, but how much time they spend researching and picking their investments. The defensive investor would stick to low-cost index funds balanced with government bonds, while the enterprising counterpart may risk individual stock selection, but not before carefully wading through at least a few years of the financial statements of the companies. He warns about earning figures inflated by recent revenues and shady accounting practises, suggesting one use average figures (.e.g for earnings per share) over past few years instead to determine if a stock is worth buying. "There is no good or bad stocks, only cheap and dear ones."
The efficient market hypothesis states that securities would more or less be perfectly priced (trading at fair value), and price disparities would not remain unexploited for too long. This theory is also mentioned in a few places, along with counterexamples from not too long ago. The market is not perfect, and will probably never be as long as emotion drives the decisions of a considerable chunk of its participants.
There's a short primer on evaluating financial statements, which tells you what to look at: stability and growth of earnings, historical records of dividends paid, size of the company, management etc. There's also actual values for "acceptable" P/E ratio, earnings per share, and price-to-book ratios, but I'm not sure how relevant these are today (since the book was last updated in the 70s). The latter half of the book is filled with tons of examples, comparing companies, discussing irrational market behaviour, and stories of exceptional returns achieved by people known to the author. If you only read one book about investing, this one wouldn't be a bad choice.

Friday, 13 April 2018

25 pages a day - March 2018


Dragons of Eden

Carl Sagan describes the evolution of man and other creatures and speculates a bit on some unanswered questions. What makes us more intelligent than other species? Are we the result of competing ancestral species? He ponders over life and evolution on other planets, suggesting intelligence developed outside of Earth (or the solar system) might look very different (literally and biochemically), while still having to comply with the same laws of physics. Machines might have a role to play in the next big step in intelligence, computers being good at many things that we aren't very good at, and vice versa. He also discusses the purpose of dreams, something that is observed only in mammals, and more common in predators rather than prey (go figure). The asymmetry in the hemisphere of our brains, the purpose each serves, the progress of language, are among the several other things Sagan takes us through the history of. The best part about this book is the cosmic calendar at the start, which puts down the entire history of the Universe (as we know it) in a single year. Fascinating to know how insignificant we are in the grand scheme of things, but also of the outstanding progress made by humans in relatively short time.


Zero to One

Peter Thiel in this book defines the attributes of a successful startup. He focuses on the concept of going from zero to one; change of an order of magnitude– a fundamental shift from how existing companies approach and solve a problem. He shares his thoughts on monopolies, capitalism, and competition among companies, and what makes them successful. One of my favorite pieces of advise for a startup, also something that I came across in the book, is about doing one thing and doing it well. When the odds are against you, as they are in a startup, you only make it harder for yourself by focusing on half a dozen things with the same small team. This is a good book overall and a must read for founders and employees, for it teaches you how to avoid the most common mistakes which prevent an enterprise from succeeding.


Prelude to Foundation

Fiction, for a change. The first one in the Foundation and Empire series of books, but the last to be published. Set in the distant future where humans inhabit millions of worlds and faster-than-light travel, Asimov takes us through the adventures of a paranoid mathematician who is convinced (by someone else) that his mostly theoretical paper could have a practical application, possibly making him the most important person in the galaxy. A fun read, will probably pick up the rest of the books in the series as well. Not much to write about without spoiling the story.

Sunday, 11 March 2018

25 pages a day - Feb 2018

This month's list

When Genius Failed: The Rise and Fall of Long-Term Capital Management


This was recommended in the footnotes of An Intelligent Investor which I was reading last month (January, 2018). The author provides a window into the secretive lives and ballsy albeit short adventures of the partners in the hedge fund Long Term Capital Management.

LTCM, which comprised of Nobel laureates and other geniuses, made a whole lot of money with a lot of leverage and then lost it all, almost bringing down several banks and the financial system along with it in a span of 4 years. I like the way the author gives a little bit of background on John Meriwether, the man at the centre of it all, and some of the partners, before going into the details of the fund itself.

It's an enthralling read, and it could be better, I feel, if I had better knowledge on the basics of financial markets and the instruments they deal in. The author makes it a point to explain, in simple language, several of the terms and concepts (such as arbitrage, swaps, spreads, etc) when first mentioning them, but I think it would be a better read if these terms and concepts were second nature to me. The more you understand, the more you appreciate.


The Toyota Way


I mentioned this one last month, having read a small part of it. I may have been quick to judge. I've heard words of praise for Toyota from a car enthusiast friend and this book provides the explanation. Every organisation takes about culture and core principles, but few put their money where their mouth is. Toyota has been doing it for decades. The founders and top personnel believed in a set of principles, ways of getting things done, and made sure everyone around them did the same. Promoting from within, they made sure their successors believed and followed these principles as much as they did. Rinse and repeat. What you end up with is a global organisation with astounding manufacturing efficiency and reputation for being one of the most reliable car manufactures on the planet. More important than the principles themselves is the ability to stick with them through thick and think.

The author mentions other organisations attempting to copy the processes Toyota follows, without making it a part of their culture, without buy-in from top management, in hopes to achieve the same gains in efficiency. It doesn't work, even if it does it doesn't stay that way for long. Sooner or later, they are back to square one. If you work in manufacturing and have even the slightest influence on the floor, this book can prove to be of great benefit.

I work in a startup, one that provides software based services. I read this book hoping to find something to help ship quality products on schedule. What I learned is that blindly attempting to apply these principles will not work, even if you do it well. I will need to start from scratch, picking those that apply to me, modifying them to fit this specific industry. I don't believe software is much more complicated than hardware. I feel the industry is relatively young and slightly undisciplined overall, and perhaps in half a century's time, whoever still maintains the quality they have today, will have an interesting story to tell.


Bargaining with the Devil: When to Negotiate, When to Fight 


I found this one also in the footnotes of one of my favourites from last month - Getting To Yes, by Roger Fisher, who is one of the co-founders of the Harvard Negotiation Program. The author of this book, Robert Mnookin, can be said to be his successor, and the current chair of the same program. This book is a great lesson in history, logical reasoning, and human relationships. The author provides a framework at the start of the book, one that will assist you in making the decision of whether or not you should negotiate. He discusses traps, which can be described as ways of thinking, that can lead, confuse, distort your thinking into leaning towards either of the ends (to negotiate and not).

The author then describes several stories where the protagonist (or a group of people) figure out how to "deal with the devil", if at all. The stories include that of Anatoly Sharansky and the Soviets, Rudolf Katzner and the Nazis, Churchill and the War Cabinet, IBM and Fujitsu, Nelson Mandela, the ANC, and the South African Government, musicians and management of the San Francisco Symphony, and a few more of personal disputes including divorce, estate settlement, etc. The author is personally involved in a few of them, and ends each story with an assessment of whether the characters involved were right in choosing to negotiate (or not) with their counterparts, and what he would do differently, providing ample reasoning. This books answers some of the questions at the end of the "Getting To Yes" in much more detail.

Sunday, 4 February 2018

25 pages a day - Jan 2018




What follows is my experience with reading (at least) 25 pages a day, and mini-reviews of the books I've read through it in January 2018. I find books to be a good way to learn something new and the easiest way to get more perspective on everyday things. It turned out to be a good "new year's resolution" and I intend to write a short summary of the books I cover each month.

Autopilot: The Art & Science of Doing Nothing

This short book attempts to explain what happens inside our brains whenever we get some downtime, when we are idle. Every time you "take a walk" or "sleep on it" before stumbling across a solution to the problem you're trying to solve, the brain behaves in a special way. There's a lot of historical and anecdotal evidence, based on the life and stories of poets and the teachings of philosophers. The author suggests we spend more time being idle, away from our devices and tasks, to boost our innovative capabilities which are enhanced when our minds are idle. An entire chapter, which feels more of rant, is dedicated to explaining why six-sigma stifles innovation in an organisation in the name of "process".

What I would have liked to see: Perhaps more focus on the scientific aspect of the subject.

Would I read it again? - Probably not anytime soon. Not because there's anything wrong with it, but the concept is simple and it drives home the point in one go. There isn't much to go back to. It was an entertaining read, and I now don't feel as bad spending more time lazing around.


Getting to Yes - Negotiating Agreement Without Giving In

A well-written book dense with information, tactics, and examles on getting the most out of negotiations. If you were ever involved in a social or professional setting where a decision was being made, you were in a negotiation and this book will prove plenty useful. The chapters are well structured, that start with describing the problem (of negotiation) itself and then a few core methods that one can use to tackle it effectively. One of the most important things that I took away from this book, that is (coincidentally) dealt with in more detail in the next book, is about treating the emotional aspect of problems, people itself, with utmost care and consideration. You can't "win" even if you're "right" if you don't think about the people involved. There's plenty of examples (hypothetical and real-world) that describe how these methods can be applied, and what successful application looks like. At the end of the book there's a list of useful question and answers for some scenarios .e.g on how you'd negotiate with Hitler, or with those much more powerful than you.

Would I read it again? - Definitely. Just browsing the table of contents was enough to refresh my memory (as it did at time of writing this), but there's a lot that I don't and would go back for.


How to Win Friends and Influence People

Guilty of judging a book by its cover, I always thought this one had a bookbait-y, almost cringeworthy title. Nothing could be farther from the truth. I've seen this recommended a few times on HN and thought I'd give it a go. This book has had a great impact when it comes to influencing behaviour and on how I think about and treat those around me. With examples that seem to be too good to be true, the author describes how adhering to a few logical principles we can achieve what the title says. But the basis for all, is sincerity and honesty. There's no trick or shortcut. It takes conscious effort to put it into practise. Unless you have a knack for it, your "normal" behaviour would probably go against a few of the things mentioned in this book. For me it is (or hopefully, was) frequent use of sarcasm or snark to put across a point (which the book will tell you, is one of the worst things you can do). It's hard to deviate from the norm, but it really does make a difference.

Would I read it again? - For certain. It would take me a few more readings to truly remember all that it has to offer.


The Quick and Easy Way to Effective Speaking

From the same author as How to Win Friends and Influence People, Dale Carnegie, in this book, describes how to get better at putting across your thoughts to your audience. Speaking is a two-way conversation in which the audience is as important as the one giving the talk. Just like the previous book, there are no shortcuts. "Preach what you practise" can be said to the principle behind several of the methods put forth in this book. Those who feel strongly about what they say, who speak from the heart, from experience, are more likely to get themselves heard than the ones who don't. Giving examples that the audience can relate to, speaking from personal experience, using visual aids, and being prepared are some of things that this book describes in detail.

Would I read it again? - Yes. Just like the previous book, it would take another reading or two to get it all in.



Below are a few books that I started reading but didn't finish.




The Toyota Way

This one has a preachy, slightly repetitive tone, but the examples talk of astounding gains in manufacturing efficiency achieved by applying the principles that Toyota has. One of the first thing it describes in detail is around eliminating everything not necessary (aka waste) in a process, and there's a lot more to that than I would have thought. I think this one has more to offer, but perhaps not as succinctly as some of the other books.

Structure and Interpretation of Computer Programs

A refreshing approach to programming! I haven't spent more time on this primarily because the exercises (to be done at a terminal or on piece of paper) are not as convenient to go through when commuting, where most of my reading takes place.

The Intelligent Investor: The Definitive Book on Value Investing

So far, this book has taught me a very importance difference. The one between actual and speculative investments. It explains the various investments instruments available in the U.S. (which are not much use to me, but the ones everywhere else are not vastly different) and how they have performed over the past. It tells you that to be a decent investor, you need to make the least amount of mistakes. To not let emotion influence your judgement. To be confident in what you pick, so much so that you'd stick with it if the market shut down for a decade, or if you could not see the ticker everyday. I don't expect to get exceptional returns after following everything in the book, but I do hope to identify and avoid investment mistakes.

Sunday, 31 December 2017

Year in Review 2017 - Startup Engineering

I'm Kedar, and I work as an Engineer at a startup. This post is inspired by patio11's tweet and his posts on the same topic. It's a summary of thing's I've learnt over the past year working on PaySense's platform.

Shipping on time and quick iterations matter. Time now is more valuable then money later. Below are a few (opinionated) engineering practises I've found to be useful.

Keep complexity low

Whether this be the tooling or deployment, the simpler it is to understand, the better it is to manage. Unless you've got a large team, utilise resources where they matter (shipping product).

Don't solve all the problems

The best problems are the ones you don't have to solve, those that you can avoid altogether. Buy or outsource your way out of ones you think are not important (but may be urgent). If it can be put off until later, do so.
For those that you're not so sure about, spend some time figuring out. If you need an hour to figure out if something (that will take +10 man-hours) really needs solving, do it! Even if you're wrong 8 times out of 10, you will be better off. At times you may be also be able to find other solutions, from your investigation, that don't take as long.
The better you know the ins and outs of critical systems, where data is stored and how it flows through your systems, the more effective you can get at problem-solving.

Make it work, make it right, make it fast

Make it work - Handle 90% of the use cases, show value, serve the customer first. This is your "MVP".
Make it right - Keep refactoring code, adding tests, ensure and improve the base level of quality.
Make it fast (if you really have to) - This one's highly opinionated, but I believe you should solve performance issues when they become a problem. This is difficult to get right, since you must keep an eye on run-times (does it increase day by day) and side-effects (does it subtly impact other systems), but will save you time and resources that you can deploy elsewhere.

Bugs and prioritisation

Not all bugs are created equal. Define them by how many customers they impact, and at what stage in the funnel. Prioritise those that appear later in your on-boarding funnel first. Customers at the end of the funnel are more likely to put off (and may also end up complaining, making noise on social media) than those at the beginning.
If you're spending too much time fixing bugs and/or they keep cropping up, it's probably a sign of bigger issues.

Monoliths and Microservices

Start with a single system and database. This keeps operational complexity low.
Microservices arise for several reasons, identify poor ones: .e.g hype-driven (BIGCO is using it), for sake of using another language, engineer(s) wanting free reign, "solutions seeking problems", over optimising (primary intention is of "make it fast") right from the start.
Develop in "modules" instead that you can pull out (these won't exist from day one, but you can factor them in when "making it right").

Team and Hiring

Use languages, tools, and frameworks that you and your team are comfortable and experienced with.
Hire people who are comfortable with your team. Make use of references, trust but verify.

Ship early, ship often.

Ship as early as you can. Validate ideas before it gets to the customer. If you can experiment without building it out completely, do it!
Better to "make it work" in a month, than ship with a "right & fast" product in 3. Because when you launch after 3 months, it's likely you'll scrap or end up redoing most of what you did. More time it takes to ship, the more factors you need to consider: e.g. market change, competition.


All of these might seem obvious at first, but I've come to learn and appreciate as they've allowed me to become better at what I do.

Saturday, 12 August 2017

Django tips #3 - Subquery expressions

This post describes a common quirk observed when performing joins against multiple tables in an SQL query, and a solution to it using a new feature (Subquery expressions) of the Django ORM.

A common problem


Consider the following models in Django.

from django.db import models


class Account(models.Model):
    name = models.CharField(max_length=32, unique=True)


class Credit(models.Model):
    account = models.ForeignKey(Account)
    amount = models.DecimalField(max_digits=12, decimal_places=2)


class Debit(models.Model):
    account = models.ForeignKey(Account)
    amount = models.DecimalField(max_digits=12, decimal_places=2)


Let's add some accounts, and also a few credit and debit entries against them. This is what the tables look like now:

# Accounts
+------+--------+
|   id | name   |
|------+--------|
|    1 | FOX    |
|    2 | SNAKE  |
|    3 | DOG    |
+------+--------+


# Credits
+----------------+-----------------+
| account_name   |   credit_amount |
|----------------+-----------------|
| FOX            |           100.0 |
| SNAKE          |            50.0 |
| SNAKE          |            20.0 |
| DOG            |           300.0 |
+----------------+-----------------+

# Debits
+----------------+----------------+
| account_name   |   dedit_amount |
|----------------+----------------|
| FOX            |           40.0 |
| SNAKE          |           30.0 |
| DOG            |           12.0 |
| DOG            |           23.0 |
+----------------+----------------+


Now, we want to answer a simple question: "What is the current balance of each account?". The balance of an account is defined as the sum of all credits minus the sum of all debits.

Seems pretty straightforward, right?

This is how one would do it using the Django ORM (A simple group-by and aggregate, which I described in one of the previous posts: https://mixedquantum.blogspot.in/2015/01/python-django-tips.html)

Account.objects.values('id').annotate(
    credit_sum=Sum('credit__amount'),
    debit_sum=Sum('debit__amount'),
    balance=F('credit_sum') - F('debit_sum')
).values_list('name', 'balance')

"""
[('FOX', Decimal('60.00')),
 ('SNAKE', Decimal('10.00')),
 ('DOG', Decimal('565.00'))]
"""


The balance for FOX looks okay (100 - 40). But what's happening with SNAKE, and DOG? Their balance amount isn't correct.
Printing the individual sums of credits and debits might help us figure out what's happening.

+--------+--------------+-------------+-----------+
| name   |   credit_sum |   debit_sum |   balance |
|--------+--------------+-------------+-----------|
| FOX    |        100.0 |        40.0 |      60.0 |
| SNAKE  |         70.0 |        60.0 |      10.0 |
| DOG    |        600.0 |        35.0 |     565.0 |
+--------+--------------+-------------+-----------+

The sum of debits is double what is should be for SNAKE, and the sum of credits is twice of what it should be for DOG.
The "twice" comes from the fact that there are two entries of credit for SNAKE, and two entries of debit for DOG.

An intermediate representation might help explain this better. This is the data on which the aggregates (SUM) are applied.

+--------+-------------+-----------------+------------+----------------+
| name   |   credit_id |   credit_amount |   debit_id |   debit_amount |
|--------+-------------+-----------------+------------+----------------|
| FOX    |           1 |           100.0 |          1 |           40.0 |
| SNAKE  |           4 |            20.0 |          2 |           30.0 |
| SNAKE  |           3 |            50.0 |          2 |           30.0 |
| DOG    |           5 |           300.0 |          3 |           12.0 |
| DOG    |           5 |           300.0 |          4 |           23.0 |
+--------+-------------+-----------------+------------+----------------+

The INNER JOIN is applied before the aggregate (SUM in this case). We need it the other way round.

The solution


In Postgres, this can be done using a WITH query (Common Table Expression):

WITH credits AS (
    SELECT account_id, sum(amount) AS credit_sum
        FROM core_credit
    GROUP BY account_id
), debits AS (
    SELECT account_id, sum(amount) AS debit_sum
        FROM core_debit
    GROUP BY account_id
)

SELECT a.name, credit_sum - debit_sum AS balance
    FROM core_account a
        INNER JOIN credits c
            ON c.account_id = a.id
        INNER JOIN debits d
            ON d.account_id = a.id;

Which gives us the correct balance of each account:

+--------+-----------+
| name   |   balance |
|--------+-----------|
| FOX    |      60.0 |
| SNAKE  |      40.0 |
| DOG    |     265.0 |
+--------+-----------+


Common Table Expressions don't seem to be supported in Django, but subqueries, which can be used to achieve the same output, were recently added in Django 1.11.

This is how we can use Subquery expressions to get the same result:

from django.db.models.expressions import Subquery, OuterRef
from django.db.models import F, Sum

from core.models import Account, Credit, Debit

credits = Credit.objects.filter(
    account=OuterRef('pk')).values('account_id').annotate(sum_credits=Sum('amount'))
debits = Debit.objects.filter(
    account=OuterRef('pk')).values('account_id').annotate(sum_debits=Sum('amount'))

Account.objects.annotate(
    credit_sum=Subquery(credits.values('sum_credits')),
    debit_sum=Subquery(debits.values('sum_debits')),
    balance=F('credit_sum') - F('debit_sum')
).values_list('name', 'balance')

"""
[('FOX', Decimal('60.00')),
 ('SNAKE', Decimal('40.00')),
 ('DOG', Decimal('265.00'))]
"""


It's not the most intuitive of code, but to someone who spends a lot of time using the ORM, it's just a matter of getting used to.

You can read more about Subquery expressions here: https://docs.djangoproject.com/en/1.11/ref/models/expressions/#subquery-expressions

The Django ORM has come a long way in terms of things it makes possible, reducing the need to resort to raw SQL queries even for some not-so-straightforward use cases.

Tuesday, 13 December 2016

Notes on database versioning

This post contains links to external resources that discuss database versioning or related concepts. I've also added a description for some of the links (which may not be a summary, but contains relevant points discussed in the resource).

By database versioning, I am referring to versioning of data stored in the database, and not schema versioning or migration. An application of database versioning is audit logging.

Basics


A good starting point is this Wikipedia article: Slowly Changing Dimensions (SCD)

Various techniques (Type 0, Type 2, Type 6..) of versioning (referred to as SCD management methodologies) are specified. They are discussed against a particular example, but may be applied to other use cases (such as audit logging) as well.

… For historical sales reporting purposes it may be necessary to keep a record of the fact that a particular sales person had been assigned to a particular regional office at an earlier date, whereas that sales person is now assigned to a different regional office.

Log Trigger is a technique that deals with SCD. The MS-SQL server example is most concise, describing an implementation using database triggers. (One can use functions (in Postgres) or equivalent routines for better organization and structure within triggers).

If the use case doesn't require a start_date and an end_date (audit logging). One can do away with the end_date, and rename start_date to created_at. To get the latest version, one would look at the row in the history table with the largest value of created_at.

When it comes to foreign keys, one may or may not want the referential integrity in the history table as in the base table.

Foreign keys may be kept if the referenced table rows are not deleted, or use ON DELETE SET NULL instead of  ON DELETE CASCADE (for example) to not lose the entire row. The choice would depend on your use case, and when the use case is audit logging, neither method provides an accurate audit log.

If the referenced table also makes use of a history table to store versions, one can use Foreign Keys to the history table (instead of Foreign Keys to the base reference table) for better comprehensiveness.

Better History Tables


This post from database-programmer suggests copying all values from the base table into the history table is a naive approach. It recommends storing only the fields that you care about, and storing "deltas" in cases where the value is numeric. The advantage of storing deltas is highlighted by a specific query (computing balance at a point in time) for a specific use-case (ordering system).

Security of history tables can be dealt with by restricting operations (disallow UPDATES, limit INSERTS to only database triggers, and allow DELETES only by privileged users for purging the tables to reduce size on disk).

While it makes sense to only save columns you need, storing deltas will probably depend on your use case. Good points on security and access control being implemented at the lowest level (the database) rather than application code.

Branching Model


Another technique I came across was self-referencing history or version tables that can be used to maintain multiple versions (branches) of a record. Useful when you need to keep track of the source or hierarchy of changes, or need to store incremental changes (or work on such changes individually).

Vendor-specific solutions


Change Data Capture (CDC) in SQL Server and Oracle.



There are several implementations, and several more combinations of various implementations that one can go with. Whatever the choice, one needs to maintain the versioning implementation, be it in code or in the database (as triggers or stored procedures).

Schema changes may require changes to the history tables. If schema changes frequently or involves major structural updates, making relevant changes to the history tables incurs a proportionately higher overhead (which might not be worth it).