Monday, June 22, 2015

Basic casino math

In a previous series of posts, I went over the models used by casinos to spin a wheel (spinning, manipulating the odds, clustering and near misses). I did not yet expand on the basic mathematical models that ensure a casino makes money.

Let's pretend we are spinning the wheel again. The wheel has 5 pockets, and just one of those is the winning one. Given we will be using an unmodified wheel, you win 1 out of 5 spins. Each bet costs you 1 euro. Looking at the true odds (1/5), the casino should pay out 4 euro for you to break even.

Respecting the true odds would not make the casino any money, they pay out less to ensure that the house has an edge on you. So instead of paying out 4 euro, it will be a tad less.

The house edge can be cast into a fairly simple formula.

In this example, the house edge is a whopping 20%, meaning statistically 20% of each bet will go to the casino. So the higher the house edge, the better?

Not really, if players constantly go through their bankroll in a matter of minutes, it's not very likely they will keep returning to your casino. The inverse to the house edge, and maybe even a more important number, is the payout percentage. When the house edge is 20%, the player's payout percentage will be 80%. For each bet you make, you will statistically see a return of 80%. As a player to get maximum value for money - to play as long as possible - you should aim to play in a casino that has the highest payout percentages.

Often misunderstood is that this does not mean you will get to keep 80% of your bankroll by the end of the night. The payout percentage relates to a single bet. The casino's hold, or money eventually left on the table, is several times the house edge, since players tend to circulate through the same money more than once. So the longer you play, the more the house edge will nibble at your bankroll.

Knowing the house edge, it's pretty simple for a casino to predict a customer's worth; multiply the house edge, the average stake and the number of games per hour.

Given we spin the wheel 60 times an hour for a stake of 1 euro, we will make the casino 12 euro an hour on average. The higher this number, the bigger your potential, the harder a casino will try to make you a regular.

Understanding how casinos make a living, it's safe to say casinos aren't the place to play for money, but to play with money.

Sunday, May 24, 2015

Consumed: Queries and projections (F#)

This is the third post in my series on porting a node.js application to an F# application.

So far, I've looked at parsing command line arguments, handling commands and storing events. Today, I want to project those events into something useful that can be formatted and printed to the console.

In the original application, I only had a single query. The result of this query lists all items consumed grouped by category, sorted chronologically

Handling the query is done in a similar fashion to handling commands. The handle function matches each query and has a dependency on the event store.

Where C# requires a bit of plumbing to get declarative projections going, F#'s pattern matching and set of built-in functions give you this for free.

We can fold over the event stream, starting with an empty list, to append each item that was consumed, excluding the ones that were removed later. Those projected items can then be grouped by category, to be mapped into a category type that contains a sorted list of items.

The result can be printed to the console using a more imperative style.

And that's it, we've come full circle. We can now consume items, remove items and query for a list of consumed items.

Compared to the node.js implementation, the F# version required substantially less code (two to three times less). More importantly, although I wrote tests for both, I felt way more confident completing the F# version. A strong type system, discriminated unions, pattern matching, purity, composability and a smart compiler makes way for sensible and predictable code.

Source code is up on Github.

Sunday, May 17, 2015

Consumed: Handling commands (F#)

As I wrote earlier, I've been working on porting a node.js web application to an F# console application. It's an application I wrote to learn node.js but still use today to keep track of all the things I consume.

The application is able to consume an item, to remove a consumed item and to query all consumed items.

In the previous post, I parsed command line arguments into typed commands and queries. Today, I'll look at handling the two commands.

I've refactored the command discriminated union to contain records with data that go along with the command - I found that this makes for more discoverable and refactor-friendly deconstruction later on.

Validation

Before we do anything with the command, we need to make sure it passes basic validation. The validate function takes a command, and returns a success or failure result. Validation can fail because an argument is empty, its structure is invalid or it's out of range. Inside the function we match the command discriminated union with each case, validate the data and return a result.

Producing events

Having validated the command, we can start thinking about doing something useful. I want the command handlers to be pure, to be able to focus on computation, without having to worry about side effects.

Since the node.js web application stores its data in the form of events, this one will too. I can now migrate the existing event store to a simple text file living in my Dropbox, for then to drop the existing Postgres database.

This means that command handlers will need to produce events.

Dependencies

Looking at the tests the command handlers need to satisfy, we know that a command handler depends on the system time and the eventstore.

The dependency on time is just a function that takes no arguments and returns a datetime.

An implementation could look like this.

Reading an event stream is a function that takes a stream name and returns an event stream.

Implementing a naïve event store takes more than one line on code.

An eventstore

This implementation stores events in a text file. When an event is stored, it gets serialized to JSON for then to be appended to a text file. When reading a stream it will read all events from disk, deserialize them to then filter by stream name before returning it as an event stream - it's not exactly web scale.

The signature for reading a stream doesn't satisfy the signature we defined earlier though. We can satisfy it by creating a partially applied function.

Handlers

Handlers focus on pure computation, they just need to return an event or a failure.

We can only consume an item once, and we can only remove items that exist. It shouldn't be possible to consume items that have been removed. There isn't much needed on the inside to cover these use cases.

We inject the event store and time dependencies by passing in the relevant functions - since I'm already using this function further on in program.fs, the compiler can infer the signatures, no need to explicitly state the signatures I defined earlier.

Side effects

So far we have been able to avoid intentional side effects - we did introduce functions that might have accidental side effects (reading from disk and reading the system time ). It would be nice to be able to restart the application without losing all state, so we need to take the result the command produced and persist it. A small function takes care of matching each result to invoke the relevant side effect. So far, we only want to store events. With this, we successfully isolated side effects to one small function.

Putting it all together

By now, we can validate commands, handle them and take care of their side effects. We can now compose those pieces together using Railway Oriented Programming and invoke the pipeline. The output gets matched, so we can print something relevant for the user to see.

Next time, we'll look at implementing queries.