Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

65 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

marc

About

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

Python

Install

pip install marc

Quickstart:

frommarcimportMarkovChainplayer_throws="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"sequence= [throwforthrowinplayer_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
letplayerThrows="RRRSRSRRPRPSPPRPSSSPRSPSPRRRPSSPRRPRSRPRPSSSPRPRPSSRPSRPRSSPRP"letsequence= playerThrows.map{String($0)}letchain=MarkovChain(sequence)
chain.update("R","S")print(chain["R"])
// [("P", 0.5), ("R", 0.25), ("S", 0.25)]
letplayerLastThrow="R"letplayerPredictedNextThrow= chain.next(playerLastThrow)!
letcounters=["R":"P","P":"S","S":"R"]letcounterThrow=counters[playerPredictedNextThrow]!
print(counterThrow)
// "S"

For more inspiration see the swift/Examples/ directory

API/Comparison

PythonSwift
Importfrom marc import MarkovChainimport Marc
Initialize Achain = MarkovChain()chain = MarkovChain<String>()
Initialize Bchain = MarkovChain(["R", "P", "S"])let chain = MarkovChain(["R", "P", "S"])
Update chainchain.update("R", "P")chain.update("R", "P")
Lookup transitionschain["R"]chain["R"]
Generate nextchain.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

LikeDislike
defaultdict !!Clunky setup.py packaging
random.choice !Setting up and working with environments
Dictionary comprehensions + sorting__init__.py and directory issues

Swift

LikeDislike
Package.swift and packaging in generalDictionary performance sucks... (surprising!!)
Don't have to think about environmentsNeed randomness? Too bad. Go roll it yourself
XCTest is nicer/easier than unittest/pytestPlaygrounds 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

About

Markov chain generator for Python and/or Swift

Resources

Stars

66 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages