A State Machine Datastore in the Wild
Richard Crowley
Betable operations
Richard Crowley
Betable operations
Gambling-as-a-service
Licensed and regulated so game developers don’t have to be
Single-player
Single-event
Against the house
Easy to model as a REST API
Multi-player
Single-event, sort of
Against the house
Time dimension didn’t fit into REST
Roulette is but the first of a new class of game mechanic
Most events are asynchronous from a player’s perspective
Most events are temporally localized from the house’s perspective
Player presence
Server-to-client broadcasts and messages
Timeouts in case of player inaction
www.ietf.org/rfc/rfc6455.txt
Beginning to see widely-deployed support
Providing useful semantics on top of WebSockets would be an interesting talk in its own right
WebSockets out front
Internal REST APIs in between
Storage underneath
All Cassandra, all the time
N=3
R=2
W=2
(quorum reads and writes)
Naturally, we tried this first
Correctly enforced domain-specific constraints
Serializable updates
Audit trail
High concurrency
Sell 1000 bingo cards “instantly”
Don’t sell more than 1000
Don’t sell more than 4 to any player
Don’t sell any after the first ball is drawn
Conservatively 200 kB, mutated slightly 1000 times
Cards only semi-independent due to domain-specific constraints
Enough thinking, let’s hack!
Doubly-linked list
Optimistic concurrency control
Two column families: entries
and pointers
(with LongType
columns)
Death by roundtrip
Write new tail to entries
and include the previous tail’s row key
Write to the previous tail’s row in pointers
with a timestamp and the new tail’s row key
Read the previous tail’s row in pointers
to see if our write won the append race
Consistent hashing of entities to processes
Locked read-modify-write over the network
Also death by roundtrip
At this point, why even use Cassandra?
Lacks expressiveness
(read: Turing-completeness)
Basically used it like a filesystem
Also also death by roundtrip
Enforce complex constraints on data
Efficient in terms of network I/O
Distributed, for some value of distributed
Scale horizontally
1000 bingo card strawman
Existing storage engines lack expressiveness
Small scale makes a custom solution plausible
YAGNI versus nothing more permanent than a temporary solution
Arbitrary size and structure
Unit of atomicity
Unit of distribution
Examples: RouletteTable
, RouletteRound
, but not RouletteBet
type Table struct { ID string GameID string RoundID string Players []Player NextTransition time.Time // ... }
Mechanism of all reads and writes
Analogous to stored procedures
Apply to (at most) one entity
Examples: CreateRouletteTable
, CreateRouletteRound
, CreateRouletteBet
, and ResolveRouletteRound
type CreateTable struct { TableID string // ... } func (ct *CreateTable) Prepare(pc PrepareContext) error { return nil } func (ct *CreateTable) Apply(ac ApplyContext) (*Table, error) { t := &Table{ ID: ct.TableID, // ... } if err := ac.Store(t.ID, t); nil != err { return nil, err } return t, nil }
Dispatch other transitions
Generate data
Mutate the transition
PrepareContext
has Dispatch
, Load
, and more but not Store
, LoadExcl
, or StoreExcl
func (ct *CreateTable) Prepare(pc PrepareContext) error { r, err := pc.Dispatch(&CreateRound{ // ... }) if nil != err { return err } ct.RoundID = r.ID return nil }
Cross-entity operations
No transactional guarantees
Efficient for humans and networks
Transition written to write-ahead log
Enforce domain-specific constraints
Update a stored entity
ApplyContext
has Load
, Store
, LoadExcl
, StoreExcl
, and more
GetEntity
reads an entity given a type and a key
GetIndex
reads a secondary index given its name and a secondary key
UpdateEntity
could theoretically update fields in any entity but we haven’t needed it
Atomicity: entity writes are as atomic as you want
Consistency: weak guarantees since transitions contain arbitrary code
Isolation: within an entity when requested
Durability: fsync(2)
the write-ahead log
Consistency: no stale reads
Availability: requests hashed to non-failing coordinators respond but no second-choice coordinators
Partition tolerance: unreachable coordinators don’t make reachable coordinators unavailable
Atomicity of entity-spanning operations
Locality of any two entities
Pat Helland’s Life beyond Distributed Transactions: an Apostate’s Opinion in CIDR 2007
Transitions declare a distribution key
Distribution key conventionally identifies an entity
Consistent hash function maps transitions to a coordinator process
Command-line flags easily configured by Puppet
Declare peers on your consistent hash ring
Declare masters from which to replicate
Master-slave
Master-master
Next N-1
peers
One listening socket per process
Clients connect to any process
Peers proxy transitions to their coordinator
Clients can embed the consistent hashing algorithm as an optimization
Asynchronous
Loosely inspired by MySQL
Replicate transitions, which are small, not entities, which may be very large
Prepare
not called when replicating
Slave sends a BeginReplication
transition with an Index
and Offset
Master streams transitions from the initial Index
and Offset
forward
Slave atomically logs the cursor with each replicated transition
Addr
of master, Index
of and Offset
into master’s write-ahead log
Log rotation copies the last cursor in the previous log file into the next log file
Recovery requires reading the most recent log and accepting the last cursor found
type Table struct { ID string `index:"-"` GameID string `index:"GameID_TableID"` // ... }
Declare a primary key for the entity
(does not have to be the distribution key)
Declare entity fields to be indexed
An index maps a secondary key to a list of primary keys
Secondary indexes automatically updated during Store
and StoreExcl
Eventually consistent via asynchronous replication
Optimistic: not atomic with entity storage
Query(index, key)
with a PrepareContext
or an ApplyContext
False positives and negatives possible
Objects and blobs
ObjectStore
and BlobStore
interfaces
Load
, Store
, LoadExcl
, and StoreExcl
Layered implementations
BSONObjectStore
serializes and stores objects in a BlobStore
The key is prefixed with the object’s type
FileBlobStore
stores blobs on the filesystem
Store
and StoreExcl
are atomic via rename(2)
LoadExcl
and StoreExcl
use flock(2)
Pathnames contain an epoch to support snapshot backups
An IndexingObjectStore
has an ObjectIndex
and an ObjectStore
Calls Index
and then Store
or StoreExcl
Delegates Query
, Load
and LoadExcl
DirObjectIndex
builds secondary indexes on the filesystem
+---------+----------+----------+---------+ | | | | | | version | flags | length | type | | (uint8) | (uint16) | (uint16) | (UTF-8) | | | | | | +---------+----------+----------+---------+ +----------+----------------+ | | +------------+ | | length | | transition | | | (uint32) | | (BSON) | | | | +------------+ | +----------+----------------+
Naming the type outside of the JSON facilitates deserialization
Naive and expensive
It’s easy to create protocol buffer-like versioning and extensibility by being careful with BSON
go-bson
nicely mirrors encoding/json
go-bson
actually feels more naturally Go than goprotobuf
+---------+----------+----------+----------+---------+ | | | | | | | version | nonce | flags | length | type | | (uint8) | (uint32) | (uint16) | (uint16) | (UTF-8) | | | | | | | +---------+----------+----------+----------+---------+ +----------+----------------+ | | +------------+ | | length | | transition | | | (uint32) | | (JSON) | | | | +------------+ | +----------+----------------+
Naming the type outside of the JSON facilitates deserialization
Java: even fluent Java tastes bad to us
Scala: scary, C++-like amount of syntax
C: it’s a nice hammer to have in a pinch
Go: all but garbage collector maturity
Always google it as “golang”
Approaching four years old
Thompson, Pike, Cox, Griesemer
Statically typed
Not classically object-oriented
CSP primitives as syntax
One service spread across two Git repositories
No one had ever worked with stored procedures, much less ones with this much power
Both top-down and bottom-up
Neither top-down nor bottom-up
I tried to preserve engineers’ artistic freedom
I needed a more formal process
Protocol designed to allow non-request-oriented workloads
That never panned out
If it were HTTP, I think people would use it as an application platform, not a database
Can test each side of distribution/replication as units
Start 3 services in one Go process and sleep a bit to test together
Jump through hoops to test network errors
Sporadic timeouts that didn’t show up in metrics
Very busy lock in a metrics.Registry
Fixed the bug in go-metrics
Used to allow Dispatch
in Apply
methods
Prevent double-applying in replication
Non-deterministic replication
Eliot Moss’s Nested Transactions: An Approach to Reliable Distributed Computing
go-metrics
and Graphite
apply-transition
and get-entity
hd(1)
Budget half your time for admin tools
(not kidding)
We’re backing more and more services with this storage engine every day
High-availability coordinators
Next-generation secondary indexes
Native HTTP via soon-to-be open-sourced Go HTTP service framework


Preparation time
30 mins to 1 hour
Cooking time
1 to 2 hours
Serves
Serves 10-12
Dietary
Filled with colourful chunky vegetables and large enough to serve a crowd, this would make a decorative addition to an Easter feast. Roasting the vegetables, and including Gruyère with its distinctive flavour, ensures that it is very moreish too.
For this recipe you will need a 28cm/11in loose-bottomed fluted tart tin and some baking beans.
Put the flour and butter in a food processor and pulse until they take on the texture of bread crumbs. (Or place in a mixing bowl and rub the butter into the flour with your fingertips). Add the egg and 1 tablespoon cold water and pulse until combined and a dough forms (or mix by hand).
Roll the dough on a lightly floured, cold work surface into a circle large enough to line the tart tin and roughly 3mm thick, leaving a generous edge to allow for shrinking in the oven. Lay the pastry in the tin and push it gently into the corners where the base meets the sides. Prick the base and sides of the pastry with a fork and chill in the fridge for 15 minutes.
Preheat the oven to 180C/160C Fan/Gas 4.
Line the chilled pastry with baking paper and fill with baking beans. Bake for 10 minutes. Remove the beans and paper and put the pastry case back in the oven for another 10-15 minutes. Remove from the oven and set aside to cool.
Increase the oven temperature to 200C/180C Fan/Gas 6.
Put the onions and courgettes in a large sandwich bag, drizzle with olive oil and season generously with salt and pepper and shake the bag to coat. Tip onto a large baking tray. Roast for 30–40 minutes, turning the vegetables over halfway through cooking, until tender and golden-brown. Remove from the oven. Reduce the oven temperature to 180C/160C/Gas 4.
Meanwhile, bring a small amount of water to the boil in a wide lidded pan. Once boiling add the spinach, clamp down the lid and turn off the heat. After 5 minutes, drain the spinach and leave to cool. Gather the spinach into a ball and using a clean tea towel squeeze as much water out as possible. Once the spinach is as dry as you can get place it on a chopping board and roughly chop. Whisk together the cream, eggs and half the cheese and season well with salt and pepper.
Once the vegetables are roasted you are ready to assemble the quiche. Sprinkle the remaining cheese onto the base of the pastry case. Pile in the vegetables, spreading them out so that they are evenly distributed, and pour over the cream mixture.
Bake the quiche for 25–35 minutes or until the filling is set and golden-brown on top. Take out of the oven and leave to cool slightly before removing from the tin and transferring to a serving plate. Serve warm.


Shruti Haasan Soon To Fly Off For UK Following Her Upcoming Musical Concerts
This year, Shruti starred in her first international series, "Treadstone", which released a few months back.
by IANSActress-singer Shruti Haasan has the Tamil film “Laabam” and an untitled Telugu project coming up, and is also focussing on her musical journey. She will head to the UK later this month for her latest gigs.
Shruti, who had toured the UK earlier this year, will be doing another set of concerts there in November and December. The gigs will start from November 28.
“I’ve really enjoyed performing in the UK and the response has been great. I’m also meeting some really accomplished musicians who I hope to collaborate with in the near future,” she said.
This year, Shruti starred in her first international series, “Treadstone”, which released a few months back. She plays the recurring character Nira Patel in the action drama series.
Shruti is looking forward to the release of “Frozen 2“. She is the voice of Elsa in the Tamil version of the Hollywood film.
Apart from her film commitments, Shruti plans to release her debut album as well.


Python Documentation¶
Documentation is absolutely essential to anyone seeking to use your software. The easiest and most reliable way to produce this documentation is by using a tool that examines the source itself and develops the document directly from the programs. By using cleverly formatted Python docstrings, we can augment that analysis with easy-to-understand descriptions.
In the case of Python, there are several tools for extracting documentation from the source. The most popular one is Sphinx, http://sphinx.pocoo.org/.
We can use pydoc, also. This is part of Python. It doesn’t cope well with files in UTF-8 encoding. You need to include the following comment in any files that have Unicode characters.
# -*- coding: utf-8 -*-
In Documentation Development we’ll look at how we can use Sphinx to create complete, accurate, and nice-looking documentation for our application.
In Using Sphinx we’ll look at a aspects of using Sphinx.
In order to use either tool, we’ll need to write using ReStructuredText (RST.) In Basic RST Markup we’ll look at the foundations of using RST.
In Interpreted Text, or Inline Markup we’ll look at inline markup that produces things like emphasis and strong text.
We’ll look at how we can provide details of function arguments and return values in RST Field Markup. This is primarily focused on Sphinx.
We’ll look at more complex RST markup in Directives
In Standard Paragraphs we’ll look at boilerplate like “see also”, and “warning” sections that are often marked with special icons aor distinctive layout.
We’ll show a large example in Class Example.
Documentation Development¶
Generally, the workflow has the following outline.
Develop the skeleton class.
Develop unit tests for most features.
Rework the class until it passes the unit tests. This may involve adding or modifying tests as we understand the class better. This also involves writing docstrings for modules, classes and methods.
Revisit the modules, classes and methods, finishing each description using the ReStructured Text (RST) markup language. We won’t cover all of this language, just enough to provide a sense of how the tool is used to make clean, professional API documentation.
Run the documentation tool (i.e. sphinx-build) to create the documentation. Fix any errors in your docstring markup. Also, rework the documentation as necessary to be sure that you’ve capture important information about the class, the methods, the design decisions.
Using Sphinx¶
When you install Sphinx, it creates a script that you can use.
Generally, you’ll run the $ sphinx-quickstart script to create an empty documentation directory.
$ sphinx-quickstart
This interactive script will ask a number of questions, allowing you to pick sensible directories and file names.
You’ll need to include two extensions to enable Sphinx to create your API documentation.
autodoc
will create module documents based on the RST markup in the docstrings.autosummary
will create summaries of packages and modules.
You’ll then add content to your index.rst
file. This file is the root for
the documentation. It can be very simple, or or it can do include other files
to break a large document into manageable pieces.
The most important commands are the following.
To run Sphinx, you’ll use a command similar to the following.
$ sphinx-build -b html sourcedir builddir
Basic RST Markup¶
We write our module, class and method docstrings using the RST markup language. RST is one of many structured text markup languages, where indentation and formatting rules are used to interpret your documentation. These formatting rules help the tools deduces the structure of your document (sections, list, etc.) and the presentation (bold, italic, or font changes.) Some of these markup rules have been used in plain text documents since documents were first stored on computers.
Fundamentally, the RST formatting rules are implemented by a module named
docutils
. For additional documentation on RST, see
the Sphinx web site (http://sphinx.pocoo.org) and the
Docutils web site (http://docutils.sourceforge.net/).
In addition to document structure, deduced from the layout, RST also uses explicit directives and interpreted text (or “inline”) markup.
Document Structure. Generally, you must write in paragraphs. A blank line is the end of one paragraph and the beginning of another. Also, different indentation will signal paragraph changes. The indent rule is handy for making bullet lists or numbered lists.
A line that is indented and begins with -
is a bulleted list.
A line that starts with digits and periods is a numbered list. Lists can nest within each other.
If you need to have sections and subsections (you’ll almost always do
this in the docstring for a module or package), you “underline” the
title with lines of ===
, ---
or ~~~
.
To include code code samples and doctest, you’ll use either the ::
marker. Or the explicit .. code-block::
directive.
Generally, the first paragraph must be a pithy summary of the material to follow. This paragraph will often be used in overviews and index pages.
Example testCard Module. For example, our module document might look like this.
#!/usr/bin/env python
"""The testCard module includes a number of unit tests for the Card
and Deck classes in the card module.
Overview
========
This module tests the following classes:
- Card
- Deck
Card Tests
----------
.. autoclass:: TestCards
Deck Tests
----------
.. autoclass:: TestDeck
Usage
=====
This module uses the standard text runner, so it can be executed
from the command line as follows::
python testcard.py
"""
We started with an overview paragraph. It summarizes the module in a single sentence.
We have an underlined section heading. In this document, the highest level of the outline is underlined with
=
’s. The second level is underlined with-
.RST is very flexible with the underlining rules.
We have a bullet list. Simply indent, and begin the paragraph with
-
. Lists can be nested, the RST processor will work this out based on the indentation of the various sublists.We used the
.. autoclass::
directive to gather docstring documentation from the class docstring and include it in the overall module docstring.We included a literal block of code after a paragraph which ends with
::
. The following material is indented to show what should be formatted specially.
Interpreted Text, or Inline Markup¶
In addition to basic document structure rules, RST includes a way to show that a span of characters should be interpreted specially. This is sometimes called Inline Markup because it is within the structural markup.
*words*
will render the words in italic. This can also be done with:emphasis:`words`
.**words**
will render the words in bold. This can also be done with:strong:`words`
.``words``
will render the words in afixed
font to indicate that it is a code sample. Literal programming text can also use:literal:`words`
.Code samples can also be done with
:samp:`word {replaceable}`
. In this case, the material enclosed in{}
is displayed in italics:word replaceable
.
Additionally, there are several cross-reference inline markup formats available for code elements.
Here’s an example of a paragraph using some inline markup to make some characters italic, other bold, and still others a fixed-width find that makes them look like code.
This method computes the square root of a number, *n*.
It returns a value, *r*, such that :samp:`r**2 == n`.
**Note**. Square root of a negative number will raise a ``TypeError`` exception.
RST Field Markup¶
RST Field markup is primarily used to tie your documentation directly
to Python language structures. Field markup is a separate paragraph of the form
:tag arg: body
. We won’t cover all of the tags, just
enough to produce basic documentation.
Field markup also provides several standard kinds of standard “formal paragraphs” within your document. We’ll look at these separately.
The following tags are used to define detailed features of a method function.
:param p: description
A description of the parameter, p, for a function or method.:return: description
A description of the return value from the function or method.:keyword k: description
A description of the keyword parameter, k, for a function or method.
Here’s an example of a method function docstring that uses @param
tags.
def __init__( self, rank, suit ):
"""Build a card with a given rank and suit.
:param rank: numeric rank, ace is 1, 2-13 for 2 though King.
:param suit: String suit, use one of the module constants.
"""
self.rank= 14 if rank == 1 else rank
self.suit= suit
The following tags are used to define specific variables in a module or class.
:ivar v: description
A description of the an instance variable of a class. Generally, this will be in the class level docstring, and will refer to one of the class’sself.
variables.:var v: description
A global variable of a module. Generally, this will be in the module docstring, and will refer to one of the global variables created by the module.
Here’s an example of a class definition docstring that uses :ivar:
tags.
class Card:
"""A single playing card, suitable for Blackjack or
Poker. While a suit is retained, it doesn't figure into
the ordering of cards, as it would in Bridge.
**Reminder**. The internal rank of an Ace is 14. The constructor,
however, expects a value of 1.
:ivar rank: the numeric rank of the card. 2-13, with ace as 14.
:ivar suit: the string suit of the card.
"""
Directives¶
RST has a number of useful directives available for structuring the documentation. Sphinx uses all of the basic RST directives and adds a large number of additional directives.
A directive is an RST markup command starts with a special ..
line,
and may include a number of lines indented within the directive. One of the
common ones is the .. code-block::
directive. The ::
is
an essential part of the directive syntax.
It looks like this.
Example. .. code-block:: python def fact(n): if n == 0: return 1 return n*fact(n-1) More Text.
The directive starts with the ..
line and continues through the
indented section. The directive content ends with the end of the indentation.
Epydoc uses the :tag:
syntax; it doesn’t define new RST directives.
Because of this, there are two styles for
some of the more advanced markup: an Epydoc tag style and a Sphinx directive
style.
Standard Paragraphs¶
There are several kinds of standard paragraphs that are part of any well-written document set. These include things like
Related Topics.
Epydoc usess the
:seealso:
tag to generate a “Related Topics” paragraph with references to other documents.Sphinx uses the
.. seealso::
directive line to generate additional references.Admonitions (Notes, Warnings, etc).
Epydoc uses tags like
:note:
,:attention:
,:bug:
, and:warning:
tags to generate standard types of admonition paragraphs.Sphinx uses directives like
.. note::
,.. attention::
, and.. warning::
directives to generate standard types of admonition paragraphs. Other admonitions include “caution”, “danger”, “error”, “hint”, “important”, “tip”.Status. You can track the development and deployment status of your programs. Tags like
:version:
,:todo:
,:deprecated:
,:since:
,:status:
, andchange:
are used by both Epydoc and Sphinx.Bibliographic Information. You can provide standard publication information. Tags like
:author:
,:organization:
,:copyright:
,:license:
and:contact:
can be used.
Class Example¶
Here’s an example of a module with detailed class documentation.
blackjack.py
#!/usr/bin/env python3
"""
Building Skills in Object-Oriented Design V4
The blackjack module includes the Suit class and Card class hierarchy.
:author: S. Lott
:license: http://creativecommons.org/licenses/by-nc-nd/3.0/us/
"""
from typing import Any
import enum
class Suit(enum.Enum):
"""Enumerated suit names and values."""
Clubs = u"\N{BLACK CLUB SUIT}"
Diamonds = u"\N{WHITE DIAMOND SUIT}"
Hearts = u"\N{WHITE HEART SUIT}"
Spades = u"\N{BLACK SPADE SUIT}"
class Card:
"""A single playing card, suitable for Blackjack or
Poker. While a suit is retained, it doesn't figure into
the ordering of cards, as it would in Bridge.
.. note:: Aces and Facecards.
Ace and Facecards are separate subclasses.
.. attribute:: rank
The numeric rank of the card. 2-13, ace has an effective
rank of 14 when used in Poker.
.. attribute:: suit
The string suit of the card. This should be from the
named constants (Clubs, Diamonds, Hearts, Spades).
At the class level, there are four constants that can
make code look a little nicer.
:var: Jack
:var: Queen
:var: King
:var: Ace
"""
Jack = 11
Queen = 12
King = 13
Ace = 1
def __init__(self, rank: int, suit: Suit) -> None:
"""Build a card with a given rank and suit.
:param rank: numeric rank, 2-10. Aces and FaceCards are separate.
:type rank: integer in the range 2 to 10 inclusive.
:param suit: suit, a value from the Suit enum
:type suit: Suit
"""
assert isinstance(suit, Suit)
self.rank = rank
self.suit = suit
self.points = rank
def hardValue(self) -> int:
"""For blackjack, the hard value of this card.
:returns: int
"""
return self.points
def softValue(self) -> int:
"""For blackjack, the soft value of this card.
:returns: int
"""
return self.points
def __eq__(self, other: Any) -> bool:
"""Compare cards, ignoring suit.
>>> from blackjack_doc import Card, Suit
>>> Card(2, Suit.Diamonds) == Card(2, Suit.Spades)
True
>>> Card(2, Suit.Diamonds) == Card(10, Suit.Spades)
False
"""
return self.rank == other.rank
def __lt__(self, other: Any) -> bool:
"""Compare cards, ignoring suit.
>>> from blackjack_doc import Card, Suit
>>> Card(2, Suit.Diamonds) < Card(3, Suit.Spades)
True
>>> Card(10, Suit.Diamonds) < Card(10, Suit.Spades)
False
"""
return self.rank < other.rank
def __le__(self, other: Any) -> bool:
return self.rank <= other.rank
def __gt__(self, other: Any) -> bool:
return self.rank > other.rank
def __ge__(self, other: Any) -> bool:
return self.rank >= other.rank
def __str__(self) -> str:
"""
>>> from blackjack_doc import Card, Suit
>>> str(Card(2, Suit.Diamonds))
' 2♢'
"""
return f"{self.rank:2d}{self.suit.value}"
def __repr__(self) -> str:
"""
>>> from blackjack_doc import Card, Suit
>>> repr(Card(2, Suit.Diamonds))
"Card(rank=2, suit=<Suit.Diamonds: '♢'>)"
"""
return f"{self.__class__.__name__}(rank={self.rank!r}, suit={self.suit!r})"
We’ve included a module-level docstring, class-level docstrings, and even some method-level docstrings. The idea is to provide enough information so that the automatic documentation produced by Sphinx is complete and useful.
Example Sphinx Automodule¶
This shows how the documentation looks when .. automodule::
is used.
Building Skills in Object-Oriented Design V4
The blackjack module includes the Suit class and Card class hierarchy.
- author
Lott
- license
-
class
blackjack_doc.
Card
(rank: int, suit: blackjack_doc.Suit)¶ A single playing card, suitable for Blackjack or Poker. While a suit is retained, it doesn’t figure into the ordering of cards, as it would in Bridge.
Note
Aces and Facecards. Ace and Facecards are separate subclasses.
-
rank
¶ The numeric rank of the card. 2-13, ace has an effective rank of 14 when used in Poker.
-
suit
¶ The string suit of the card. This should be from the named constants (Clubs, Diamonds, Hearts, Spades).
At the class level, there are four constants that can make code look a little nicer.
- Var
Jack
- Var
Queen
- Var
King
- Var
Ace
-
__eq__
(other: Any) → bool¶ Compare cards, ignoring suit.
>>> from blackjack_doc import Card, Suit >>> Card(2, Suit.Diamonds) == Card(2, Suit.Spades) True >>> Card(2, Suit.Diamonds) == Card(10, Suit.Spades) False
-
__ge__
(other: Any) → bool¶ Return self>=value.
-
__gt__
(other: Any) → bool¶ Return self>value.
-
__init__
(rank: int, suit: blackjack_doc.Suit) → None¶ Build a card with a given rank and suit.
- Parameters
rank (integer in the range 2 to 10 inclusive.) – numeric rank, 2-10. Aces and FaceCards are separate.
suit (Suit) – suit, a value from the Suit enum
-
__le__
(other: Any) → bool¶ Return self<=value.
-
__lt__
(other: Any) → bool¶ Compare cards, ignoring suit.
>>> from blackjack_doc import Card, Suit >>> Card(2, Suit.Diamonds) < Card(3, Suit.Spades) True >>> Card(10, Suit.Diamonds) < Card(10, Suit.Spades) False
-
__repr__
() → str¶ >>> from blackjack_doc import Card, Suit >>> repr(Card(2, Suit.Diamonds)) "Card(rank=2, suit=<Suit.Diamonds: '♢'>)"
-
__str__
() → str¶ >>> from blackjack_doc import Card, Suit >>> str(Card(2, Suit.Diamonds)) ' 2♢'
-
__weakref__
¶ list of weak references to the object (if defined)
-
hardValue
() → int¶ For blackjack, the hard value of this card.
- Returns
int
-
softValue
() → int¶ For blackjack, the soft value of this card.
- Returns
int
-
-
class
blackjack_doc.
Suit
¶ Enumerated suit names and values.
Looking Forward¶
In these first few chapters we’ve done several things:
Identified the problem we’re going to solve,
Installed the tools to help build a trustworthy Python application,
Made sure we can write unit tests for our code,
Started down the path of producing useful documentation.
In the next chapter, we’ll start the journey of building a simulation for the Roulette game. The first chapter has a close look at the game. After that, we’ll look at the kind of solution we’ll build, and in the remaining chapters, we’ll look at the individual classes required.


Balancing city growth and sustanability is always a tedious task for the city management. Sustainable city growth is always critical for all round developement of the city. This dashboard helps city management and service providers to track and maintain the city growth. Dashboard comes with the Stops congestion and heat map with useful analytics to tackle the city traffic.


The Link Control allows Module and Page Editors to select a link to a URL, a page on this site, a file that has been uploaded to the Digital Asset Management module (Admin > File Management), or the profile of a registered user. The Link Control can also be used to disable a link field on a module, such as the Announcements module. The Link Control is displayed on the add and edit page of many modules including the Links, Announcement, Documents, Events, Media and Vendors module.
Optional Settings:
The Link Control as displayed on the Edit page of the Links module
Related Topics:


Localization Settings for Existing Pages
How to set the Localization setting for pages on the Page Settings page.
The Localization section is only displayed when content localization is enabled on the site. See "Enabling Localized Content"
Page editors and translators for any language.
- Select Page Localization from the Edit Page menu on the ControlBar.
- Select the Localization tab.
- At Page Culture, the culture of the current page is displayed. In the below example, the page is "Neutral Culture" which means that the same page will be used across all cultures on the site.
Next Steps:
- Make Page Translatable
-
Notify Translators


This SRFI defines basic hash tables. Hash
tables are widely recognised as a fundamental data structure for a wide
variety of applications. A hash table is a data structure that:
- provides a mapping from some set of keys to
some set of values associated to those keys
- has no intrinsic order for the (key, value)
associations it contains
- supports in-place modification as the
primary means of setting the contents of a hash table
- provides key lookup and destructive update
in amortised constant time, provided that a good hash function is
used.
This SRFI aims to accomplish these
goals:
- to provide a consistent, generic and widely
applicable API for hash tables
- to improve code portability by providing a
standard hash table facility with guaranteed behaviour
- to help the programmer by defining utility
routines that account for the most common situations of using hash
tables.


HTML means HyperText Markup Language
Because I want to know how to make websites.
I can learn at my own pace.


Control Flow: if, when, for, while
If Expression
In Kotlin, if is an expression, i.e. it returns a value. Therefore there is no ternary operator (condition ? then : else), because ordinary if works fine in this role.
// Traditional usage
var max = a
if (a < b) max = b
// With else
var max: Int
if (a > b) {
max = a
} else {
max = b
}
// As expression
val max = if (a > b) a else b
if branches can be blocks, and the last expression is the value of a block:
val max = if (a > b) {
print("Choose a")
a
} else {
print("Choose b")
b
}
If you're using if as an expression rather than a statement (for example, returning its value or
assigning it to a variable), the expression is required to have an else
branch.
See the grammar for if.
When Expression
when replaces the switch operator of C-like languages. In the simplest form it looks like this
when (x) {
1 -> print("x == 1")
2 -> print("x == 2")
else -> { // Note the block
print("x is neither 1 nor 2")
}
}
when matches its argument against all branches sequentially until some branch condition is satisfied. when can be used either as an expression or as a statement. If it is used as an expression, the value of the satisfied branch becomes the value of the overall expression. If it is used as a statement, the values of individual branches are ignored. (Just like with if, each branch can be a block, and its value is the value of the last expression in the block.)
The else branch is evaluated if none of the other branch conditions are satisfied. If when is used as an expression, the else branch is mandatory, unless the compiler can prove that all possible cases are covered with branch conditions (as, for example, with enum class entries and sealed class subtypes).
If many cases should be handled in the same way, the branch conditions may be combined with a comma:
when (x) {
0, 1 -> print("x == 0 or x == 1")
else -> print("otherwise")
}
We can use arbitrary expressions (not only constants) as branch conditions
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
We can also check a value for being in or !in a range or a collection:
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}
Another possibility is to check that a value is or !is of a particular type. Note that, due to smart casts, you can access the methods and properties of the type without any extra checks.
fun hasPrefix(x: Any) = when(x) {
is String -> x.startsWith("prefix")
else -> false
}
when can also be used as a replacement for an if-else if chain. If no argument is supplied, the branch conditions are simply boolean expressions, and a branch is executed when its condition is true:
when {
x.isOdd() -> print("x is odd")
x.isEven() -> print("x is even")
else -> print("x is funny")
}
See the grammar for when.
For Loops
for loop iterates through anything that provides an iterator. This is equivalent
to the foreach
loop in languages like C#. The syntax is as follows:
for (item in collection) print(item)
The body can be a block.
for (item: Int in ints) {
// ...
}
As mentioned before, for iterates through anything that provides an iterator, i.e.
- has a member- or extension-function
iterator()
, whose return type- has a member- or extension-function
next()
, and - has a member- or extension-function
hasNext()
that returnsBoolean
.
- has a member- or extension-function
All of these three functions need to be marked as operator
.
To iterate over a range of numbers, use a range expression:
fun main(args: Array<String>) {
//sampleStart
for (i in 1..3) {
println(i)
}
for (i in 6 downTo 0 step 2) {
println(i)
}
//sampleEnd
}
A for
loop over a range or an array is compiled to an index-based loop that does not create an iterator object.
If you want to iterate through an array or a list with an index, you can do it this way:
fun main(args: Array<String>) {
val array = arrayOf("a", "b", "c")
//sampleStart
for (i in array.indices) {
println(array[i])
}
//sampleEnd
}
Alternatively, you can use the withIndex
library function:
fun main(args: Array<String>) {
val array = arrayOf("a", "b", "c")
//sampleStart
for ((index, value) in array.withIndex()) {
println("the element at $index is $value")
}
//sampleEnd
}
See the grammar for for.
While Loops
while and do..while work as usual
while (x > 0) {
x--
}
do {
val y = retrieveData()
} while (y != null) // y is visible here!
See the grammar for while.
Break and continue in loops
Kotlin supports traditional break and continue operators in loops. See Returns and jumps.


Coronation Street SPOILERS: Kel is questioned by police TONIGHT!
Kel groomed Paul Foreman when he was a teenager
by Charlotte RodriguesIt looks like the net is closing in on Kel in tonight's Coronation Street (November 25 2019).
In a preview for the episodes shared on the soap's official Twitter account, Kel has been arrested for the burglaries, but the police start questioning something else found in his apartment.
Despite Kel's solicitor telling him that he should reply "no comment" to the questions, Kel completely denies knowing anything about the burglaries.
When the police tell him they're sending an officer to search Kel's home, the security guard claims he's been set up and if any stolen objects are found at his place, they would have been planted there.
But the officer quickly changes the subject and shows Kel a photo and asks if they're his Polaroids.
Surprisingly Kel doesn't deny it and nods, knowing full well the photos belong to him.
The paedophile begins to get nervous and the policeman tells him they're forensically searching the laptop found at his flat which belongs to Daniel.
He then says to Kel: "I wonder what we'll find on yours?"
Kel is clearly worried at what the police will find. Has he finally been caught?
Viewers know Kel sexually abused Paul Foreman when he was a teenager.
Read More: Coronation Street star Beverley Callard shares adorable new photo of her grandson
Kel, who was in a relationship with Paul's mum Bernie, groomed the young boy into believing they were in a relationship.
A couple of months ago, Kel got back in contact with Bernie and Gemma and he made his way back into their lives. But they had no idea what Kel had done to Paul.
In Friday night's episodes (November 22 2019) Bernie and Gemma broke into Kel's house suspicious that he was behind the robbery at Daniel's flat.
Read More: Coronation Street's Fiona Middleton 'could return with Christmas bombshell for Emma'
But when they were searching his home, they were horrified to find not just Daniel's missing laptop, but inappropriate pictures of Paul and other young boys.
They later asked Paul about the pictures and he told his mum and sister about Kel's abuse.
Gemma pleaded with Paul to go to the police but he didn't want to go over what happened again.
However, Bernie reported Kel to the police for burglaries and for the pictures.
Coronation Street airs on Mondays, Wednesdays and Fridays at 7.30pm and 8.30pm on ITV.
Leave us a comment on our Facebook page @EntertainmentDailyFix and let us know what you think!


There was the pilot
F-50 Air Jet
One direction
She made the assessment
The assessment for what's right
She knew what to do
Enginees engaged
The sound hit the stomach of the earth
The place as home
Opened the arms
And the pilot was ready
For the attack
The childrens staring in the street
The dogs barking in an empty building
The cheer of hope
Swelling the homes
But the pilot was blind
It had no time
For peripherical vision
The orders were clear
And those were
Not her friends
Not her family
Not her house
Not her home
Those were
Her unknown enemy
And so she did
Shee pushed the buttoms
Technical precision
The most efficient
No margin of error
And there it watched
The fire burning
Cleaning sensation
The Kerosene
Melting homes
Melting faces
And in so she found relief in the soul
A warrior of her own freedom
A hero for modernity
She could already see her medal
Her recognition
The cover of a magazine
The soldier of the year
She couldn't hide the smile
So much satisfaction
She indeed was sparkling
For two and a half seconds
Until the sound came
Slowly it came
As a thunder
It was more than an explosion
It was a shout from the universe
A yell from the humanity
From thedeepest of guts
And there she heard
The innocence of children
The simplicity of families
The love in streets and homes
The sound went
But it stayed
Reverbarating in the chamber of her soul
It had nowhere to go
And there it stayed
From life to eternity
With no measures to circumsize
No methods of operation
It burned her skin off
And she tried everything
And the best she could was a prothesis
The perfect cover
For others
And the mirror at least
She could say it was the game of choice
Of not having a choice
And she served beautifully
She did what she had to
A Patriot of Freedom
And the applauses would not cease to exist
The acceptance
The claps
The idolization
Would make it seem as if it were worth it
But as every night came
And the words went quieter
She faced herself
The whispers of gods would blow
Alone
And as such
The guardians of her mind
They had themselves openly
And she had to see the moving skin
The damage
The sound still running from head to toes
Boiled gas
Would melt away her hand and feet
And
Still
Sne saw
She pictured
She remembered
The purity
The naivete
The genuinity
The uniqueness
She would try to run
There was no button
DELETE
The writer was stubborn
In his own certainty and omniscience
It was all carved
By God himself
In the heart of her soul.


| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| AccessToken.js | 100% | 5/5 | 100% | 0/0 | 100% | 1/1 | 100% | 5/5 | |
| Account.js | 42.62% | 26/61 | 10% | 3/30 | 30.77% | 4/13 | 42.62% | 26/61 | |
| AccountStoreMapping.js | 68.57% | 24/35 | 50% | 8/16 | 50% | 3/6 | 68.57% | 24/35 | |
| ApiKey.js | 23.68% | 9/38 | 0% | 0/12 | 0% | 0/6 | 23.68% | 9/38 | |
| Application.js | 32.28% | 92/285 | 13.13% | 21/160 | 13.04% | 6/46 | 32.62% | 92/282 | |
| ApplicationAccountStoreMapping.js | 57.14% | 8/14 | 0% | 0/2 | 33.33% | 1/3 | 57.14% | 8/14 | |
| AuthenticationResult.js | 67.86% | 19/28 | 30% | 3/10 | 60% | 3/5 | 67.86% | 19/28 | |
| CollectionResource.js | 46.84% | 89/190 | 48.48% | 32/66 | 36.07% | 22/61 | 47.31% | 88/186 | |
| CustomData.js | 48.15% | 26/54 | 0% | 0/12 | 42.86% | 6/14 | 48.15% | 26/54 | |
| Directory.js | 33.85% | 22/65 | 4.17% | 1/24 | 16.67% | 2/12 | 33.85% | 22/65 | |
| DirectoryChildResource.js | 45.45% | 15/33 | 25% | 3/12 | 33.33% | 2/6 | 45.45% | 15/33 | |
| Group.js | 31.03% | 9/29 | 0% | 0/8 | 0% | 0/6 | 31.03% | 9/29 | |
| GroupMembership.js | 43.75% | 7/16 | 0% | 0/4 | 0% | 0/3 | 43.75% | 7/16 | |
| InstanceResource.js | 35.48% | 11/31 | 0% | 0/12 | 75% | 3/4 | 35.48% | 11/31 | |
| Organization.js | 47.62% | 10/21 | 0% | 0/4 | 20% | 1/5 | 47.62% | 10/21 | |
| OrganizationAccountStoreMapping.js | 50% | 7/14 | 0% | 0/2 | 0% | 0/3 | 50% | 7/14 | |
| Provider.js | 83.33% | 5/6 | 100% | 0/0 | 0% | 0/1 | 83.33% | 5/6 | |
| ProviderData.js | 83.33% | 5/6 | 100% | 0/0 | 0% | 0/1 | 83.33% | 5/6 | |
| RefreshToken.js | 100% | 5/5 | 100% | 0/0 | 100% | 1/1 | 100% | 5/5 | |
| Resource.js | 88.89% | 16/18 | 60% | 6/10 | 100% | 3/3 | 88.89% | 16/18 | |
| ResourceFactory.js | 94.44% | 17/18 | 75% | 6/8 | 100% | 1/1 | 94.44% | 17/18 | |
| Tenant.js | 54.69% | 35/64 | 16.67% | 4/24 | 41.67% | 5/12 | 54.69% | 35/64 |


Module kweditor
source code
Imports:
wx,
grid,
ChangeCellValue,
ClearArea,
PasteArea,
DeleteRows,
AddRows,
CommentRows,
InsertCells,
DeleteCells,
UncommentRows,
Undo,
Redo,
RenameKeywordOccurrences,
ExtractKeyword,
AddKeywordFromCells,
MoveRowsUp,
MoveRowsDown,
ExtractScalar,
ExtractList,
TipMessage,
RideGridCellChanged,
RideItemStepsChanged,
RideSettingsChanged,
PUBLISHER,
RideEventHandler,
PopupMenu,
PopupMenuItems,
SETTINGS,
Variable,
GridEditor,
GridToolTips,
UserKeywordNameDialog,
ScalarVariableDialog,
ListVariableDialog,
ExpandingContentAssistTextCtrl,
Colorizer,
ColorizationSettings,
Usages,
RenameProgressObserver


Explanation of Foobar.
A glossary entry name can consist of multiple words. The inventory loader must take that into account.


Photographs
The following photographs may cause your mind to begin a process called "imagination". We suggest to
suppress your imagination while observing these images. Too much imagination may cause nostalgia or
The following photographs may cause your mind to begin a process called "imagination". We suggest to
suppress your imagination while observing these images. Too much imagination may cause nostalgia or