Skip to main content
marc

About

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

Python

Install‡

pip install marc

Quickstart:

from marc import MarkovChain

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

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

chain["R"]
# {'P': 0.5, 'R': 0.25, 'S': 0.25}

player_last_throw = "R"
player_predicted_next_throw = chain.next(player_last_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

Swift

SPM:

dependencies: [
    .package(url: "https://github.com/maxhumber/marc.git", .upToNextMajor(from: "22.5.0"))
]

Quickstart:

import Marc

let playerThrows = "RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"
let sequence = playerThrows.map { String($0) }

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

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

let playerLastThrow = "R"
let playerPredictedNextThrow = chain.next(playerLastThrow)!

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

For more inspiration see the swift/Examples/ directory

API/Comparison

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 chain.next("R") chain.next("R")!

Why

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:

meme

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:

Python

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

Swift

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.

Warning

‡ marc 22.5+ is incompatible with marc 2.x

Metadata

Release files for marc 22.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for marc 22.5.1
File Size Uploaded Provenance Actions
marc-22.5.1.tar.gz 4.6 kB Without provenance Details for marc-22.5.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for marc 22.5.1
File Interpreter ABI Platform Actions
marc-22.5.1-py3-none-any.whl Python 3 none any Details for marc-22.5.1-py3-none-any.whl

Total release size: 9.5 kB

Release files / marc-22.5.1.tar.gz

Download URL marc-22.5.1.tar.gz
Size 4.6 kB
Tags Source
SHA-256 checksum
How to use checksums
d4b5cc1f9ca89267c789fa2f85f86ef05c7649027d092c8613c10ee51fd52b11
BLAKE2b-256 checksum
How to use checksums
b6e30eafea128cf145624261bf65f1d0276fcd5c54562c9401d755ff9c3a0ef8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.9.13

Release files / marc-22.5.1-py3-none-any.whl

Download URL marc-22.5.1-py3-none-any.whl
Size 4.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d3e6755a151c9a448dae50fa72082060b19feae2931de01f8a490d216bea1da7
BLAKE2b-256 checksum
How to use checksums
e29e53fa2923a8089a636b252ac75ad7103dd248f9e137f6ea8513f4847f07f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.0 CPython/3.9.13

Security for marc 22.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page