Double-entry bookkeeping as a directed graph

  • I find it a strange choice to explain double-entry bookkeeping with the example of "one entry for Alice, one entry for Bob". That's really not what it's about. It's obvious that a transaction with two parties could be recorded in two places, but to me the crucial point of double-entry bookkeeping is that it requires two entries for each party of the transaction. So if Alice buys book from Bob, four entries are made.

    I get that this is supposed to be a simplification for educational purposes, but I find this is simplification is an oversimplification, since it omits the key point.

  • I think people underestimate the beauty and impact of accounting.

    Just a tiny number of formulas (accounting identities [1]) and statements (P&L, balance sheet, etc.) can represent what's going on in any org in ways that can be roughly comparable. Reminds me of the "fundamental theorem of calculus" or "central dogma of biology".

    Accounting is also where we get math and written language [2] as ancient Mesopotamian civilizations initially kept track of commodities using specific "accounting tokens" [3] shaped like the thing represented, and that evolved into written language, imagine: hieroglyphics.

    Later, Al-Jajr [4] (aka algebra, literally "balancing") was invented by Al-Khwarizmi (origin of "algorithm") to solve Islamic inheritance law, whose rules of splitting up became a series of equations that led to the need to solve them quickly and correctly. Al-Khwarizmi's quadratic formula was the origin of why "algorithm" gets its name from him.

    [1] https://en.wikipedia.org/wiki/Accounting_identity

    [2] https://en.wikipedia.org/wiki/History_of_accounting

    [3] https://en.wikipedia.org/wiki/History_of_ancient_numeral_sys...

    [4] https://en.wikipedia.org/wiki/Al-Jabr

    [5] https://en.wikipedia.org/wiki/Al-Khwarizmi

  • Double-entry bookkeeping is very easy to understand once you ditch the ridiculous "credit" and "debit" terminology.

    Essentially, the goal is to keep the accounting equation true at all times. The equation is: Equity = Assets - Liabilities. Eventually, earnings (Income - Expenses) will become part of equity, so splitting that out, you have: Equity + Income - Expenses = Assets - Liabilities. Rearranging to get rid of the minus signs you get: Equity + Income + Liabilities = Assets + Expenses. This equation must be true or something has gone wrong - like money appearing or disappearing out of nowhere. To keep it true at all times, it should be clear that any time you add money to an account on the left side of the equation (say, to an Income account), you must either add the same amount to an account on the other side or subtract the same amount from the same side.

    For example, you sell a lemonade for $5. You add $5 to Sales (Income) and add $5 to Current Account (Assets).

    The "credit" and "debit" terminology is ridiculous because their definitions swap around depending on which account you're talking about, which is an utterly absurd (mis)use of language and the main reason people find this confusing.

  • > Definition 6: Credit An entry that represents money leaving an account.

    > Definition 7: Debit An entry that represents money entering an account.

    Not really, the meaning of debit and credit depends on the type of account: https://en.wikipedia.org/wiki/Debits_and_credits

    Maybe there's a reason why it takes more than one course to become a CPA (https://www.accounting.com/careers/cpa/how-to-become/).

  • I see a lot of consternation about credits and debits and the nomenclature.

    Something that makes this simpler to think about from a modern perspective is that accounting is older than the popular use of negative numbers. By a lot. If we were to invent accounting today, we'd probably use positive and negative accounts instead of debit and credit accounts.

    Algebra over addition is second nature to us at this point, but it would not have been obvious to the average merchant in 1604, and even then, negative numbers were viewed quite poorly.

    What is important is that there are always two sides to a transaction and that they are inverses of each other. This is all a credit and debit are. Inverse operations on a number.

    Therefore, we can make a rule that a transaction balances when credit = debit. (aka we didn't invent money as debit + credit = 0, but remember that we didn't like negative numbers when this system was invented, so this last fact is more of a happy coincidence that happens to ALWAYS WORK, for some reason, rather than the goal).

    What is then reasonable is to consider literal cash on hand to be the most positive (debit) kind of account there can be, and work backwards from there. If I want to handle an expense, then I need to invert the cash account somehow (credit it) and therefore have the opposite kind of entry for where the money went (debit it). So an expense account must have a generally debit (or positive) balance.

    But where did the cash come from? Well that comes from income and I want the cash to be debit-ey so the place it came from must be credit-ey otherwise I risk writing a transaction that doesn't balance (equal zero). So then income accounts must generally be credit accounts rather than debit account (aka they hold a typically negative balance or are "credit normal").

    What is really killer about this system, is it just so happens that every mundane transaction you could ever write will end up as balanced transactions and each of these possible transaction accounts end up having the same usual balance of credit or debit (negative or positive). I think that is just so elegant.

  • Still too complicated. It goes wrong with "Let’s add the Transaction column to our table."

    Don't store the account data. Instead store the transactions. Compute the accounts from that. The table "Transactions" should have the fields: Date, Amount, SourceAccount, TargetAccount, Description.

    That is how it becomes beautiful in my opinion. Unlearn this habit of thinking in accounts just because that is what you know from your bank statements. Think in cash flows.

    (Ok, this is too simple for the tax use case. Sometimes transactions have multiple sources or targets. So my schema above needs to be adapted for that. My point is that the thinking should still be different.)

  • Hi, all!

    I'm not an accountant but decided to study double-entry bookkeeping and basic accounting a while ago. I learned a lot from many places, including great threads here on HN, and wanted to give back to the community. In this article, I explain the mechanics of double-entry bookkeeping and how I came to realize it's a directed graph.

    I know there are many accounting nerds on HN so please feel free to criticize or suggest changes where I got things wrong!

  • Nice job on this. But, one has to be careful with redefining terms that have a generally accepted meaning. Changing Debit/Credit to Incoming/Outgoing smacks of jargon and will cause confusion. Any bookkeeper will understand what credit cash and debit expense means. Putting that in incoming and outgoing terms will not help the people who do the work, or have to explain the work. It's probably worth the effort of learning the nomenclature that's been useful for a few hundred years rather than falling back on what are metaphors.

  • David P. Ellerman has a mathematical approach to accounting based on what he refers to as the Pacioli group. A provisional element of the Pacioli group looks like x//y where x and y are non-negative integers and we form equivalence classes based on x//y and u//v being equivalent if the cross sums x+v and y+u are equal. The group operation is x//y + u//v = (x+u)//(y+v) and the inverse of x//y is y//x . The identity element is 0//0. For more info see, for example, https://ellerman.org/wp-content/uploads/2012/12/DEB-Math-Mag...

  • I think I'm missing something here. How does looking at transaction history as a directed graph help anything? Is it an improvement on the centuries-old "double-entry" practice?

    It seems to barely work with the toy example of couple transactions - imagine what the graph would look like with dozens or hundreds of edges between pairs of nodes. What use would there be for the typical algorithms that work with graphs?

    This feels a bit like using pliers as a hammer. Sure, you can, I guess -- but why?

  • My understanding of double-entry bookkeeping is that it does not care who Alice bought the book from, nor what their accounts look like.

    Instead, the "double entry" that complements the money leaving Alice's cash ledger is the entry of the value of the book into Alice's "book ledger", one decreases by $20, and the other increases by the same amount.

  • I always enjoy these explainers that use computer science terms.

    In this case, you can be more precise about the type of graph: double-entry accounting creates a Directed[0] Bipartite Graph[1] with Labelled Edges[2]. Every edge is between a Transaction and an Account nodes, which makes it bipartite, and the amounts are edge labels.

    [0] https://en.m.wikipedia.org/wiki/Directed_graph

    [1] https://en.m.wikipedia.org/wiki/Bipartite_graph

    [2] https://en.m.wikipedia.org/wiki/Graph_labeling

  • Double-entry bookkeeping is the original CRDT.

    Just by maintaining a local invariant -- debits and credits in a transaction sum to zero -- a distributed network of agents attending to their own ledger can reliably maintain a global consistent state (like, money is neither created nor destroyed), or heal it in the case of corruption.

  • I built a double-entry ledger for multiple different kinds of credit cards at redcarpetup. the way i like to primarily think of it technically is idempotency. Thinking of balances is the wrong way to model it :

    1. since you want the capability to recompute all balances using ledger entries. 2. there are not two balances. There's usually a lot more. you want to update reward points, dues, late fees, partner share, etc etc etc. a 2 balance double entry ledger is a simplification.

    once you set your mental model to think of it as a idempotency problem, there are multiple ways to model it. For e.g. a directed graph - traverse the entire subgraph to update balances. Or model it as a log database and re-run txns to arrive at balance computation.

  • There is one limitation of the graph visualization that's worth paying attention to: If you add a larger number of transactions to it, the graph will become tangled up and difficult to make sense of: You see which accounts trade with each other, but the order of the trades got lost, because all transactions share the same "account" nodes.

    Indeed, if you'd try to also track balances in the graph, you'd end up with the exact same limitations that the original, "mutable" account table had: You can only store a single "current" balance for each account and each time you add another transaction to the graph, the old balances of the accounts involved are lost.

    You could fix this shortcoming by redefining the meaning of the "round" nodes in the graph and essentially treating the graph as a ledger: Instead of a round node representing an account, make it represents an account at a specific point in time, i.e. between two transactions. Then new transactions can be added as new nodes and edges to e.g. the right side of the graph and the graph will become a long chain that grows from left to right and represents the exchange of money over time.

    (Another constraint has to be added that a transaction must never go "backwards in time", i.e. never go from a node to the right to one on the left and never have an "incoming" and "outgoing" edge pointing to the same round node)

    With many accounts and transactions, it might still get difficult to keep track, which transactions are close together in time and which are far apart. This could be made easier by introducing another container, let's call it a block, that groups all transactions together which share at least one "round" node in their "incoming" or "outgoing" edge. Because of the "no going back in time" property, the blocks will be non-overlapping and they will also have at least a partial ordering to them that follows the chronologial ordering of the transactions.

    If you want to make the graph extra pretty, pick one transaction in each block and use its timestamp to turn the partial into a total ordering.

    If you zoom out, your graph indeed looks like a chain of blocks, going from left to right in the direction of time, with each block containing the transactions that belong to the same slice of time. A blockchain, if you will...

  • Something's been bugging me about this article (besides the fact that it's explanation/examples of double entry ledgers are either bad, misleading, or wrong, depending on your perspective), and I wasn't able to put my finger on it until just now:

    There's a way easier way to explain double entry bookkeeping for the article's target audience, it's just statics for accounting.

  • I'm surprised that there are no mentions of a great hacker-friendly plain-text accounting software called `ledger` https://ledger-cli.org/ in this thread. It has amazing documentation when it comes to understanding basic principles of double-entry bookkeeping and goes through many typical situations and usecases. There are also several forks, most popular and advanced is `hledger` https://hledger.org/ (h is for Haskell), which provides some neat features out of the box, such as a simple web interface. All of them are very primitive compared to "professional" accounting software, but in return it offers great opportunities for hacking around while ensuring validity of your books.

  • Ten years in SAP working on FI, SD and AA. (not anymore, I'm done with that)

    The post triggered PTSD and I want to go home and cry. You created your double entry, cool, now let's split it (because of million reasons) and add taxes. So now we deal with a basic 25 line document where some lines are doing nothing but move funds through certain tax accounts. Oh, no, there is a typo, but we cannot just create the reversal because for some accounts, the transaction should stay reflected in turnovers, for some it should not and for most it depends on fiscal period and stuff.

    Don't forget that everything varies between countries. With all that let's create a financial statement for eg Walmart (who has every line item sold posted to SAP system when you buy things at store)

  • This helped me. In class now and the first ever accounting course I've taken. It's hard to wrap your head around without any background.

    Thank you!

  • Everyone should do their own accounts. I've been doing it for over 12 years and I'm so glad I've kept up with it.

    I don't bother keeping my ledger immutable, though. The point about immutability is that whatever happened is immutable (because it's in the past; it already happened!) and the ledger should just reflect that. So if I somehow made a mistake in my ledger I just correct it. I keep my ledger in git so that does record changes to the ledger itself, but I rarely, if ever, need to access these.

  • Interestingly I sort of went in the other direction at one point -- converting what was obviously a graph (build pipelines) into a from-to / credit-debit representation. On reflection it's just an edge list.

    My main problem with adapting the representation was in the incommensurability of different kinds of asset moving through the pipeline. How does one credit source code and debit a blob store? I thought about learning more about multi-currency accounting as a source for ideas but never followed it up.

    That effort inspired my thinking about a "Universal Asset Graph" for software[0] -- keeping track of not just containment but also movement and transformation of software. It's a partial but not complete inspiration for GUAC, which aims to capture software part relations for easy querying.

    [0] https://theoryof.predictable.software/articles/some-requirem...

    [1] https://guac.sh

  • I think it is a great article and graph representation would be very useful to have in accounting. There are a few things I would add:

    1. It may be beneficial to segregate ledgers (used to record transactions with customer accounts, i.e. with assets you do not own) vs. books (transactions recorded to present own assets and liabilities). Books are used to account for all possible types of assets and liabilities, while ledgers are usually strictly limited to reflection of cash movements. I think the article is about ledgers.

    2. Regarding the state of each account at each period in time, I think there is a lot of confusion between reflecting activity / transactions in the period and adjustments related to how prior transactions were recorded. I personally thought that adjustments could be better accounted for using something like a model with slowly changing dimensions where you can see history of each change. So it is not something you want to see on the directed graph by default, but something you want to be able to trace.

    3. There was one idea that I really don’t like because although it make sense on surface, it has really bad implications for accounting and analytics. The idea I am talking about is that you don’t need to have one debit and credit for transaction, rather you just need to make sure that total debits equal total credits. say, Bob has several types of accounts and multiple customer. Now Bob asks you to tell him, how much of the current balance of a specific account was generated from proceeds by customer. To answer it, you now have to solve many-to-many relationships between customers and Bob’s accounts. And sometimes it has no deterministic answer because we balanced multiple accounts in one entry. And accountant now have to use imagination and excel to prepare a manual report that uses multiple assumptions to answer this question.

  • Martin Kleppmann (author of Designing Data-Intensive Applications) has a great article in the same vein: https://martin.kleppmann.com/2011/03/07/accounting-for-compu...

  • This is my mental model and how I built the backend of a budgeting web app.

    Two types of accounts:

    - assets (you want your balance to be more than 0)

    - liabilities (you want your balance to be 0)

    Two types of entries:

    - debits (increase balances of assets, decrease balances of liabilities)

    - credits (increase balances of liabilities, decreases balances of liabilities)

    Rules:

    - A transaction represents a transfer of value between accounts.

    - Every transaction must have at least two entries. The balance of all entries the transaction holds should be 0, i.e., balance = debits - credits.

    You don't think about money leaving or entering an account before you nail down those definitions. The account representations can be anything that holds a numeric value, not just money.

    You can affect more than two accounts by adding additional entries with the condition of keeping the balance to 0.

  • Double-Entry Bookkeeping is great - I have learned it when started implementing ERP systems. This article is a bit overcomplicated and also, where is the Balancing Entry for the Opening Balances? It should be balanced against some Technical Account...

  • I work in the Carbon Accounting space where the accounting is used for carbon emissions.

  • Nothing of substance to add, I just wanted to say that I thoroughly enjoyed this post.

  • My personal observation is that where many people struggle the most mentally is across the three statements (balance sheet, income statement, and cash flows), 1) that that balance sheet is point in time and the other two are over some period, but 2) how a record entry effects each of the statements…e.g. if you sell an asset for a gain causing a change in the composition of the balance sheet (asset > cash, reversals of accumulated depreciation etc.) income statement (income in excess of basis) and cash flow (actual cash received)

  • Very cool! Well-written, and surprisingly real:

    Somewhere VERY close to this modeling patterns has always been an interesting use case for us is large-scale visual analysis of crypto investigations, where the ledger gets shown quite similarly. The bit on taxes is funny too, as that's the first thing to get filtered out because it makes the graph messy :) Often, balances aren't initially known, so a post whole-graph-compute step is done to algorithmically enrich nodes after.

    You can also do visual tricks here, like collapse 'multiedges' between the same accounts to get a summary of their p2p history. Analytically, this becomes an easy groupby on a ledger dataframe :)

    To a lesser extent, we also see fiat $ investigations here too, imagine correspondent banking. I wish more bigco AML forensic accounting did this internally (erp, credit cards, ..), especially as so much is digital now, but we don't see that as much.

    An interesting area becomes when you do things like add identity details to the graph, and can then start realizing the "A" and "Alice" and contra XYZ are all the same person. Another, which helps once you have a lot of data, is to start to be able to decloak transaction $1 "food" is a Costco hotdog, or funny buying patterns. Both are where "graph neural networks" come in, which have really advanced over the last few years. We see this kind of things in finance, like risk analysis. We find most folks are at the viz stage vs AI stage, and it's a multi-year relationship to get them from one to another, but a fun one!

    ---

    Edit: Another practical modeling aha here is that a transaction can involve multiple entities. Formally, that is a hyperedge: it's fine for edges to connect more than 2 nodes. (And why languages like datalog are neat here, even if rare.) Visually that's confusing, so a trick is to make the transaction a node and connect it to all the involved accounts. Keeping transactions as event edges between entities can be nicer when zoomed out as fewer nodes, but having the transaction node is nice when zoomed in, and in the limit, there are asymptomatically fewer nodes+edges when doing the transaction node as you replace strongly connected components (quadtratic in edges) with a hub&spoke, which is linear.

  • I believe double-entry bookkeeping needs more attention.

    I think double-entry bookkeeping is, at least to me, as fundamental to economics (and of course business) as logic to math. Even if some actors don't use it explicitly, it still holds. If I buy ten apples for 10 bucks, I have ten more apples in stock and ten bucks less.

    Many economic discussions (not only on HN) get out of hands because people don't try to see the full picture or deliberately choose to see one side. I've even seen a professor of economics claim in public that the world is too much in debt. Well, double-entry bookkeeping tells you that there are always two sides to consider.

    For example, in case of governmental debt they ignore the other side of that debt, which might be assets. Assets like airports, schools, bridges, etc. Usually, we call such things useful.

    Another typical example is the central bank "prints money". Well, double-entry bookkeeping tells us that it's not possible. If they hand out currency, the counterpart needs to trade something in (typically repurchase agreements with commercial banks). (Leaving aside here the idea of helicopter money, which could even go into neg. equity or a loss.)

  • A better way to do this would be to more closely model what is really happening, that is the transaction events which change state. The states being changed would be the account balance amounts input to and output from the transaction event. With the event, you can also track the system performing the function in the event. (All with rdf) https://graphmetrix.com/trinpod-server

  • Personally I find the model of a collection of immutable events that preserve assets= liabilities+ equity easier.

    Events being constrained to historical statements of fact.

  • This is a great write up, thank you! One thing I’m curious about is what properties/metrics of the graph mean for accounting. Spectral properties (eigenvalues, etc…) might have some insightful meaning for the financial system.

    Also I’m sure this is extremely well studied but I’m not super familiar — ML on accounting graphs could identify shapes that indicate illegal transactions, etc… Will dig for reading :)

  • Cool! Reminded me to this accounting explanation for CS folks (written by Designing Data Intensive Applications author) https://martin.kleppmann.com/2011/03/07/accounting-for-compu...

  • Double entry can track networth better. Instead of a single entry of recording 500$ paid for laptop, which decreases your networth by 500, in reality you still have 500$ worth of a laptop in your hand. You would also record the asset increase as a +500$ from gaining a laptop. Which reflects reality of your situation better.

  • I'm not sure that visualizing bookkeeping as a graph is helpful, it makes it really hard to tell what's going on and you lose the time dimension. What if you instead used a table to show movement of funds by transaction, and only used a graph to model the "aggregate result" of a set of transactions?

  • Is there any person who wants to test an old but currently in-development agpl licensed accounting software? Your help would be regarding testing the software, reporting bugs and maybe submit PRs to fix issues

    https://gnukhata.org/install/

  • I've been preaching to use a simpler accounting system for years and even built my own tool for it: https://github.com/ad-si/Transity

    But so far with little success. I think I’m the only active user of Transity.

  • I recently wrote my own bookkeeping software based on a budgeting spreadsheet my wife found a long time ago and used for years. It wasn’t until reading this (and some of these comments and other references) that I realized it’s actually a disguised double-entry bookkeeping system. No wonder it works so well!

  • It was 'cute' the first time it was posted (in this form: https://martin.kleppmann.com/2011/03/07/accounting-for-compu...), but I find pointless musing like this to be counterproductive sometimes. While I understand the tendency to fixate on 'nerdy' topics like, "How can I take <thing> people think about as <X> and shove it into math or computer science idea <Y>?" this (a) doesn't introduce any substantive ideas (in this particular instance) and (b) would completely fuck up your bookkeeping and result in you failing an audit if you completely ditched double-entry bookkeeping in place of a directed graph.

    Use the appropriate structure for the data. A graph is not appropriate as you lose information about time, which is important to the ledger. No, you can't add time as a value on your edges. If you did, you'd either have several dozen graphs, or they would look absurd.

  • The article is wrong in at least one important respect. Debits do not always increase the balance of an account. Accounts can have either a natural debit balance or a natural credit balance.

    Credits actually increase the revenue account, which is a pretty important one!

  • Well, in this case

    - balance = states

    - transactions = state transitions

    It is simply the representation of state transitions as a diagram, similar but not equivalent to that of a state machine.

  • Double-entry bookkeeping is inferior to N-entry bookkeeping, whereby a transaction generates N entries, that sum to zero. Multiple dual-entry transactions are needed to record a single N-entry transaction which is clumsy and harder to follow.

    Also, by the way, the whole debit/credit thing in English-language accounting is supremely idiotic: a credit is an increse in this account, but a decrease in this other type of account? What? It's purely for job security for accountants.

    There are accounts which represent outside interests/stakes in the company. Then there are accounts which represent what the company has.

    The outside interest accounts run negative (under normal conditions). An interpretation of that is that the company owes what it has to the outside interests.

    The sum of all the accounts is zero.

    The outside interest accounts go negative when the company grows. E.g. $100 added to cash (account representing what the company has) might be balanced by a -$100 into the owner's equity account. The company owes $100 more to the owner.

    If the $100 came from a bank, then rather than the equity account going down by $100, the account representing that bank or loan (outside interest) would go down by $100, more negative.

    If the company buys some equipment for $100 for cash, then -$100 goes into cash, and $100 into assets.

    When that asset depreciates, turning to $80 dollars a year later, -$20 goes into assets, and $20 into owner's equity, bringing it closer to zero.

  • Can one do accounting using Git commits, and would it be practical?

  • Block chain should solve any issues relating to accounting

  • Not a fan of people changing the terminology used in a domain. It confuses people in the domain (accounting) and makes their lives just slightly more harder. Keep in mind, sometimes the software you write is pushed hard by the incompetent CIO that “wAnTs To ReDuCe ToOlS” or gets a kickback from the vendor. That person doesn’t have to deal with it on a daily basis but the poor workers have to deal with this shite software.

    The impression of that poor software reflects poorly on the rest of us.

  • Nice graphical breakdown.

    I think the real winner isn't Bob or Alice though they each benefited from the exchange. The real winner is the credit card company that banked 10% of the transaction on Alice's side and 5% on Bob's side. Sounds like they both chose the least sensible option to handle payment.

    Maybe Bob should've made it clear that he accepted cash, money orders, cashier's checks, or personal checks, or even cryptocurrency so that Alice would not need to suffer a foreign currency conversion fee especially when you consider that they live in the same small town.

    Just kidding. I realize that the example transaction needed some massaging on the path to the end graph to illustrate handling of more complex, real-world transactions.

    Great job producing this intuitive break-down.

    There is one thing that I found interesting near the top of the tutorial. You make the statement "But money is meant to be spent." If money exists to be spent then why do so many people accumulate such vast sums that they could never spend all that they have managed to accumulate? Dumb question, I know. Money in the hand has indeterminate or no value until the bearer needs to acquire a product or service and then the value of the money in hand is set by the seller of the product or service they require. The global economy functions because at some point in time a traditional barter system where useful physical items were exchanged was replaced by the current system involving exchange of special artisan linen papers or conveniently portable metallic disks emblazoned with cartoon images celebrating historical events or personalities.

    Anyway, this was a good read and I enjoyed watching the transaction ledger complexity increase to account for real-world situations where there are more than two parties involved in a single transaction. Years ago when I was in high school we had a class that introduced us to checking and saving accounts and the goal of the class was to teach us how money moves through the system so that we could manage our own assets once we had real jobs and incomes. We had the introduction to the ledger book with one side handling credits and the other handling debits. It was all confusing at first but ended up being very useful.

    A long time after this class I found myself working as an independent consultant paid a negotiable hourly rate. All of that earlier instruction came in very handy when I needed to split project time and classify and categorize all the transactions that helped me understand where all that cartoon cash came from and where it all went. My spouse is a CPA/Auditor so having her level of knowledge and experience close to hand was also enormously useful in splitting everything so that the charts and graphs I assembled were most intuitive.

    Thanks! I enjoyed reading this.