Skip to main content

Markov chain generator

Project description



marc is a Markov chain generator for Python and/or Swift



pip install marc


from marc import MarkovChain

sequence = [throw for throw in player_throws]
# ['R', 'R', 'R', 'S', 'R', 'S', 'R', ...]

chain = MarkovChain(sequence)
chain.update("R", "S")

# {'P': 0.5, 'R': 0.25, 'S': 0.25}

player_last_throw = "R"
player_predicted_next_throw =
# 'P'

counters = {"R": "P", "P": "S", "S": "R"}
counter_throw = counters[player_predicted_next_throw]
# 'S'

For more inspiration see the python/examples/ directory



dependencies: [
    .package(url: "", .upToNextMajor(from: "22.5.0"))


import Marc

let sequence = { String($0) }

let chain = MarkovChain(sequence)
chain.update("R", "S")

// [("P", 0.5), ("R", 0.25), ("S", 0.25)]

let playerLastThrow = "R"
let playerPredictedNextThrow =!

let counters = ["R": "P", "P": "S", "S": "R"]
let counterThrow = counters[playerPredictedNextThrow]!
// "S"

For more inspiration see the swift/Examples/ directory


Python Swift
Import from marc import MarkovChain import Marc
Initialize A chain = MarkovChain() chain = MarkovChain<String>()
Initialize B chain = MarkovChain(["R", "P", "S"]) let chain = MarkovChain(["R", "P", "S"])
Update chain chain.update("R", "P") chain.update("R", "P")
Lookup transitions chain["R"] chain["R"]
Generate next"R")"R")!


I built the first versions of marc in the Fall of 2019. Back then I created, and used, it as a teaching tool (for how to build and upload a PyPI package). Since March 2020 I've been spending less and less time with Python and more and more time with Swift... and so, just kind of forgot about marc.

Recently, I had an iOS project come up that needed some Markov chains. After surveying GitHub and not finding any implementations that I liked (forgetting that I had already rolled my own in Python) I started from scratch on a new implementation in Swift.

Just as I was finishing the Swift package I re-discovered marc... I had a good laugh looking back through the original Python library. My feelings about the code I wrote and my abilities in 2019 can be summarized in a picture:


Unable to resist a good procrasticode™ project, I cross-ported the finished Swift package to Python and polished up both codebases and documentation into this mono repo.

Honestly, I had a lot of fun trying to mirror the APIs as closely as possible while doing my best to keep the Python code "Pythonic" and the Swift code "Schwifty". The whole project/exercise was incredibly rewarding, interesting, and insightful. Crudely, here's how I found working on both packages:


Like Dislike
defaultdict !! Clunky packaging
random.choice ! Setting up and working with environments
Dictionary comprehensions + sorting and directory issues


Like Dislike
Package.swift and packaging in general Dictionary performance sucks... (surprising!!)
Don't have to think about environments Need randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytest Playgrounds aren't as good as Hydrogen/Jupyter

So why? For fun! And procrastination. And, more seriously, because I needed some chains in Swift. And then, because I thought it could be interesting to create a Rosetta Stone for Python and Swift... So if you, Dear Reader, are looking to use Markov chains in your Python or Swift project, or are looking to jump to or from either language, I hope you find this useful.


marc 22.5+ is incompatible with marc 2.x

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

marc-22.5.1.tar.gz (4.6 kB view hashes)

Uploaded source

Built Distribution

marc-22.5.1-py3-none-any.whl (4.9 kB view hashes)

Uploaded py3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page