mirror of
https://github.com/balkian/balkian.github.com.git
synced 2025-08-24 12:42:20 +00:00
Deploying to gh-pages from @ balkian/balkian.github.com@2b54cecdab 🚀
This commit is contained in:
33
categories/programming/index.html
Normal file
33
categories/programming/index.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!doctype html><html lang=en-us dir=ltr><head><meta charset=utf-8><meta name=viewport content='width=device-width,initial-scale=1'><meta name=description content="Posts related to programming languages"><title>Category: Programming - J. Fernando Sánchez</title><link rel=canonical href=https://balkian.com/categories/programming/><link rel=stylesheet href=/scss/style.min.2882a282de220283d6a6763f309d88473c8c934a66d2f8fcb45ce0bfac2af61a.css><meta property='og:title' content="Category: Programming - J. Fernando Sánchez"><meta property='og:description' content="Posts related to programming languages"><meta property='og:url' content='https://balkian.com/categories/programming/'><meta property='og:site_name' content='J. Fernando Sánchez'><meta property='og:type' content='website'><meta property='og:updated_time' content=' 2025-07-20T02:30:43+02:00 '><meta name=twitter:title content="Category: Programming - J. Fernando Sánchez"><meta name=twitter:description content="Posts related to programming languages"><link rel=alternate type=application/rss+xml href=https://balkian.com/categories/programming/index.xml><link rel="shortcut icon" href=/img/favicon.ico></head><body><script>(function(){const e="StackColorScheme";localStorage.getItem(e)||localStorage.setItem(e,"auto")})()</script><script>(function(){const t="StackColorScheme",e=localStorage.getItem(t),n=window.matchMedia("(prefers-color-scheme: dark)").matches===!0;e=="dark"||e==="auto"&&n?document.documentElement.dataset.scheme="dark":document.documentElement.dataset.scheme="light"})()</script><div class="container main-container flex on-phone--column extended"><aside class="sidebar left-sidebar sticky"><button class="hamburger hamburger--spin" type=button id=toggle-menu aria-label="Toggle Menu">
|
||||
<span class=hamburger-box><span class=hamburger-inner></span></span></button><header><figure class=site-avatar><a href=/><img src=/img/me_hu_57f477f2a0e68f7e.png width=300 height=300 class=site-logo loading=lazy alt=Avatar>
|
||||
</a><span class=emoji>💭</span></figure><div class=site-meta><h1 class=site-name><a href=/>J. Fernando Sánchez</a></h1><h2 class=site-description>My ramblings and reflections</h2></div></header><ol class=menu-social><li><a href=https://github.com/CaiJimmy/hugo-theme-stack target=_blank title=GitHub rel=me><svg class="icon icon-tabler icon-tabler-brand-github" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M9 19c-4.3 1.4-4.3-2.5-6-3m12 5v-3.5c0-1 .1-1.4-.5-2 2.8-.3 5.5-1.4 5.5-6a4.6 4.6.0 00-1.3-3.2 4.2 4.2.0 00-.1-3.2s-1.1-.3-3.5 1.3a12.3 12.3.0 00-6.2.0C6.5 2.8 5.4 3.1 5.4 3.1a4.2 4.2.0 00-.1 3.2A4.6 4.6.0 004 9.5c0 4.6 2.7 5.7 5.5 6-.6.6-.6 1.2-.5 2V21"/></svg></a></li><li><a href=https://git.sinpapel.es/balkian target=_blank title=gitea rel=me><svg viewBox="0 0 640 640" width="32" height="32"><path d="m395.9 484.2-126.9-61c-12.5-6-17.9-21.2-11.8-33.8l61-126.9c6-12.5 21.2-17.9 33.8-11.8 17.2 8.3 27.1 13 27.1 13l-.1-109.2 16.7-.1.1 117.1s57.4 24.2 83.1 40.1c3.7 2.3 10.2 6.8 12.9 14.4 2.1 6.1 2 13.1-1 19.3l-61 126.9c-6.2 12.7-21.4 18.1-33.9 12" style="fill:#fff"/><path d="M622.7 149.8c-4.1-4.1-9.6-4-9.6-4s-117.2 6.6-177.9 8c-13.3.3-26.5.6-39.6.7v117.2c-5.5-2.6-11.1-5.3-16.6-7.9.0-36.4-.1-109.2-.1-109.2-29 .4-89.2-2.2-89.2-2.2s-141.4-7.1-156.8-8.5c-9.8-.6-22.5-2.1-39 1.5-8.7 1.8-33.5 7.4-53.8 26.9C-4.9 212.4 6.6 276.2 8 285.8c1.7 11.7 6.9 44.2 31.7 72.5 45.8 56.1 144.4 54.8 144.4 54.8s12.1 28.9 30.6 55.5c25 33.1 50.7 58.9 75.7 62 63 0 188.9-.1 188.9-.1s12 .1 28.3-10.3c14-8.5 26.5-23.4 26.5-23.4S547 483 565 451.5c5.5-9.7 10.1-19.1 14.1-28 0 0 55.2-117.1 55.2-231.1-1.1-34.5-9.6-40.6-11.6-42.6M125.6 353.9c-25.9-8.5-36.9-18.7-36.9-18.7S69.6 321.8 60 295.4c-16.5-44.2-1.4-71.2-1.4-71.2s8.4-22.5 38.5-30c13.8-3.7 31-3.1 31-3.1s7.1 59.4 15.7 94.2c7.2 29.2 24.8 77.7 24.8 77.7s-26.1-3.1-43-9.1m300.3 107.6s-6.1 14.5-19.6 15.4c-5.8.4-10.3-1.2-10.3-1.2s-.3-.1-5.3-2.1l-112.9-55s-10.9-5.7-12.8-15.6c-2.2-8.1 2.7-18.1 2.7-18.1L322 273s4.8-9.7 12.2-13c.6-.3 2.3-1 4.5-1.5 8.1-2.1 18 2.8 18 2.8L467.4 315s12.6 5.7 15.3 16.2c1.9 7.4-.5 14-1.8 17.2-6.3 15.4-55 113.1-55 113.1" style="fill:#609926"/><path d="M326.8 380.1c-8.2.1-15.4 5.8-17.3 13.8s2 16.3 9.1 20c7.7 4 17.5 1.8 22.7-5.4 5.1-7.1 4.3-16.9-1.8-23.1l24-49.1c1.5.1 3.7.2 6.2-.5 4.1-.9 7.1-3.6 7.1-3.6 4.2 1.8 8.6 3.8 13.2 6.1 4.8 2.4 9.3 4.9 13.4 7.3.9.5 1.8 1.1 2.8 1.9 1.6 1.3 3.4 3.1 4.7 5.5 1.9 5.5-1.9 14.9-1.9 14.9-2.3 7.6-18.4 40.6-18.4 40.6-8.1-.2-15.3 5-17.7 12.5-2.6 8.1 1.1 17.3 8.9 21.3s17.4 1.7 22.5-5.3c5-6.8 4.6-16.3-1.1-22.6 1.9-3.7 3.7-7.4 5.6-11.3 5-10.4 13.5-30.4 13.5-30.4.9-1.7 5.7-10.3 2.7-21.3-2.5-11.4-12.6-16.7-12.6-16.7-12.2-7.9-29.2-15.2-29.2-15.2s0-4.1-1.1-7.1c-1.1-3.1-2.8-5.1-3.9-6.3 4.7-9.7 9.4-19.3 14.1-29-4.1-2-8.1-4-12.2-6.1-4.8 9.8-9.7 19.7-14.5 29.5-6.7-.1-12.9 3.5-16.1 9.4-3.4 6.3-2.7 14.1 1.9 19.8z" style="fill:#609926"/></svg></a></li><li><a href='https://scholar.google.com/citations?user=JLNusZ8AAAAJ&hl=en' target=_blank title="Google scholar" rel=me><svg aria-label="Google Scholar" role="img" viewBox="0 0 512 512"><rect width="512" height="512" rx="15%" fill="#4285f4"/><path fill="#fff" d="M213 111l-107 94h69c5 45 41 64 78 67-7 18-4 27 7 39-43 1-103 26-103 67 4 45 63 54 92 54 38 1 81-19 90-54 4-35-10-54-31-71-23-18-28-28-21-40 15-17 35-27 39-51 2-17-2-28-6-43l45-38-1 16c-3 2-5 6-5 9v103c2 13 22 11 23 0V160c0-3-2-7-5-8v-25l16-16zm58 141c-61 10-87-87-38-99 56-11 83 86 38 99zm-5 73c60 13 61 63 10 78-44 9-82-4-81-30 0-25 35-48 71-48z"/></svg></a></li></ol><ol class=menu id=main-menu><li><a href=/><svg class="icon icon-tabler icon-tabler-home" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><polyline points="5 12 3 12 12 3 21 12 19 12"/><path d="M5 12v7a2 2 0 002 2h10a2 2 0 002-2v-7"/><path d="M9 21v-6a2 2 0 012-2h2a2 2 0 012 2v6"/></svg>
|
||||
<span>Home</span></a></li><li><a href=/search/><svg class="icon icon-tabler icon-tabler-search" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="10" cy="10" r="7"/><line x1="21" y1="21" x2="15" y2="15"/></svg>
|
||||
<span>Search</span></a></li><li><a href=/links/><svg class="icon icon-tabler icon-tabler-link" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><path d="M10 14a3.5 3.5.0 005 0l4-4a3.5 3.5.0 00-5-5l-.5.5"/><path d="M14 10a3.5 3.5.0 00-5 0l-4 4a3.5 3.5.0 005 5l.5-.5"/></svg>
|
||||
<span>Links</span></a></li><li><a href=/cheatsheet/><svg class="icon icon-tabler icon-tabler-infinity" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><path d="M9.828 9.172a4 4 0 100 5.656A10 10 0 0012 12a10 10 0 012.172-2.828 4 4 0 110 5.656A10 10 0 0112 12 10 10 0 009.828 9.172"/></svg>
|
||||
<span>Cheatsheets</span></a></li><li><a href=/projects/><svg class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 15"/></svg>
|
||||
<span>Projects</span></a></li><li><a href=/archives/><svg class="icon icon-tabler icon-tabler-archive" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><rect x="3" y="4" width="18" height="4" rx="2"/><path d="M5 8v10a2 2 0 002 2h10a2 2 0 002-2V8"/><line x1="10" y1="12" x2="14" y2="12"/></svg>
|
||||
<span>Archives</span></a></li><li><a href=/about/><svg class="icon icon-tabler icon-tabler-user" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="12" cy="7" r="4"/><path d="M6 21v-2a4 4 0 014-4h4a4 4 0 014 4v2"/></svg>
|
||||
<span>About</span></a></li><li class=menu-bottom-section><ol class=menu><li id=dark-mode-toggle><svg class="icon icon-tabler icon-tabler-toggle-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="8" cy="12" r="2"/><rect x="2" y="6" width="20" height="12" rx="6"/></svg>
|
||||
<svg class="icon icon-tabler icon-tabler-toggle-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="16" cy="12" r="2"/><rect x="2" y="6" width="20" height="12" rx="6"/></svg>
|
||||
<span>Dark Mode</span></li></ol></li></ol></aside><aside class="sidebar right-sidebar sticky"><form action=/search/ class="search-form widget"><p><label>Search</label>
|
||||
<input name=keyword required placeholder="Type something...">
|
||||
<button title=Search>
|
||||
<svg class="icon icon-tabler icon-tabler-search" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="10" cy="10" r="7"/><line x1="21" y1="21" x2="15" y2="15"/></svg></button></p></form><section class="widget archives"><div class=widget-icon><svg class="icon icon-tabler icon-tabler-infinity" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><path d="M9.828 9.172a4 4 0 100 5.656A10 10 0 0012 12a10 10 0 012.172-2.828 4 4 0 110 5.656A10 10 0 0112 12 10 10 0 009.828 9.172"/></svg></div><h2 class="widget-title section-title">Archives</h2><div class=widget-archive--list><div class=archives-year><a href=/archives/#2025><span class=year>2025</span>
|
||||
<span class=count>5</span></a></div><div class=archives-year><a href=/archives/#2023><span class=year>2023</span>
|
||||
<span class=count>2</span></a></div><div class=archives-year><a href=/archives/#2021><span class=year>2021</span>
|
||||
<span class=count>2</span></a></div><div class=archives-year><a href=/archives/#2019><span class=year>2019</span>
|
||||
<span class=count>2</span></a></div><div class=archives-year><a href=/archives/#2016><span class=year>2016</span>
|
||||
<span class=count>1</span></a></div><div class=archives-year><a href=/archives/#2015><span class=year>More</span></a></div></div></section><section class="widget tagCloud"><div class=widget-icon><svg class="icon icon-tabler icon-tabler-hash" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><line x1="5" y1="9" x2="19" y2="9"/><line x1="5" y1="15" x2="19" y2="15"/><line x1="11" y1="4" x2="7" y2="20"/><line x1="17" y1="4" x2="13" y2="20"/></svg></div><h2 class="widget-title section-title">Categories</h2><div class=tagCloud-tags><a href=/categories/linux/ class=font_size_3>Linux
|
||||
</a><a href=/categories/programming/ class=font_size_3>Programming
|
||||
</a><a href=/categories/reflections/ class=font_size_1>Reflections</a></div></section><section class="widget tagCloud"><div class=widget-icon><svg class="icon icon-tabler icon-tabler-tag" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><path d="M11 3l9 9a1.5 1.5.0 010 2l-6 6a1.5 1.5.0 01-2 0L3 11V7a4 4 0 014-4h4"/><circle cx="9" cy="9" r="2"/></svg></div><h2 class="widget-title section-title">Tags</h2><div class=tagCloud-tags><a href=/tags/python/ class=font_size_8>Python
|
||||
</a><a href=/tags/linux/ class=font_size_5>Linux
|
||||
</a><a href=/tags/git/ class=font_size_3>Git
|
||||
</a><a href=/tags/github/ class=font_size_3>Github
|
||||
</a><a href=/tags/keyboard/ class=font_size_3>Keyboard
|
||||
</a><a href=/tags/logitech/ class=font_size_3>Logitech
|
||||
</a><a href=/tags/apache/ class=font_size_2>Apache
|
||||
</a><a href=/tags/javascript/ class=font_size_2>Javascript
|
||||
</a><a href=/tags/snippet/ class=font_size_2>Snippet
|
||||
</a><a href=/tags/arch/ class=font_size_1>Arch</a></div></section></aside><main class="main full-width"><header><h3 class=section-title>Categories</h3><div class=section-card><div class=section-details><h3 class=section-count>3 pages</h3><h1 class=section-term>Programming</h1><h2 class=section-description>Posts related to programming languages</h2></div></div></header><section class=article-list--compact><article><a href=/p/bridging-rdf-json-ld-and-dataclasses/><div class=article-details><h2 class=article-title>Bridging RDF, JSON-LD and Dataclasses</h2><footer class=article-time><time datetime=26007-02-26T23:22:59+01:00>26 Feb 2025</time></footer></div></a></article><article><a href=/p/uv-one-rust-tool-to-rule-all-pythons/><div class=article-details><h2 class=article-title>uv - One rust tool to rule all pythons</h2><footer class=article-time><time datetime=17007-02-17T23:02:47+01:00>17 Feb 2025</time></footer></div><div class=article-image><img src=/img/uv.png loading=lazy alt="Featured image of post uv - One rust tool to rule all pythons"></div></a></article><article><a href=/cheatsheet/python/><div class=article-details><h2 class=article-title>Python</h2><footer class=article-time></footer></div><div class=article-image><img src=/img/python.png loading=lazy alt="Featured image of post Python"></div></a></article></section><footer class=site-footer><section class=copyright>©
|
||||
2012 -
|
||||
2025 J. Fernando Sánchez</section><section class=powerby>Built with <a href=https://gohugo.io/ target=_blank rel=noopener>Hugo</a><br>Theme <b><a href=https://github.com/CaiJimmy/hugo-theme-stack target=_blank rel=noopener data-version=3.30.0>Stack</a></b> designed by <a href=https://jimmycai.com target=_blank rel=noopener>Jimmy</a></section></footer></main></div><script src=https://cdn.jsdelivr.net/npm/node-vibrant@3.1.6/dist/vibrant.min.js integrity="sha256-awcR2jno4kI5X0zL8ex0vi2z+KMkF24hUW8WePSA9HM=" crossorigin=anonymous></script><script type=text/javascript src=/ts/main.1e9a3bafd846ced4c345d084b355fb8c7bae75701c338f8a1f8a82c780137826.js defer></script><script>(function(){const e=document.createElement("link");e.href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap",e.type="text/css",e.rel="stylesheet",document.head.appendChild(e)})()</script></body></html>
|
242
categories/programming/index.xml
Normal file
242
categories/programming/index.xml
Normal file
@@ -0,0 +1,242 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Programming on J. Fernando Sánchez</title><link>https://balkian.com/categories/programming/</link><description>Recent content in Programming on J. Fernando Sánchez</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Wed, 26 Feb 2025 23:22:59 +0100</lastBuildDate><atom:link href="https://balkian.com/categories/programming/index.xml" rel="self" type="application/rss+xml"/><item><title>Bridging RDF, JSON-LD and Dataclasses</title><link>https://balkian.com/p/bridging-rdf-json-ld-and-dataclasses/</link><pubDate>Wed, 26 Feb 2025 23:22:59 +0100</pubDate><guid>https://balkian.com/p/bridging-rdf-json-ld-and-dataclasses/</guid><description><p>In the RDF world, data is expressed as a collection of triples.
|
||||
These triples can contain IRIs that may or may not be accessible or valid.
|
||||
And the use of these IRIs may or may not adhere to a vocabulary.
|
||||
Checking the validity of the IRIs and the semantics of the triples is an additional step.</p>
|
||||
<h2 id="the-rdflib-way">The <code>rdflib</code> way
|
||||
</h2><p><code>rdflib</code> only models IRIs, values and namespaces.
|
||||
Developers need to be cognisant of the URIs they are using, and the vocabularies being used.
|
||||
Prior to version 2.0, senpy followed a very similar model.
|
||||
It had a base class to represent a generic node.
|
||||
Each instance then gets its own automatically generated id, and will act like a normal dictionary, whose keys and values will be serialized as a JSON-LD dictionary.
|
||||
Multiple subclasses were also included to model specific types of node, mostly to provide convenience methods for the given subtype.
|
||||
Here is an example of a subclass, <code>Entity</code>.</p>
|
||||
<div class="highlight"><div class="chroma">
|
||||
<table class="lntable"><tr><td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||||
</span><span class="lnt">2
|
||||
</span><span class="lnt">3
|
||||
</span><span class="lnt">4
|
||||
</span><span class="lnt">5
|
||||
</span></code></pre></td>
|
||||
<td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">entry</span> <span class="o">=</span> <span class="n">Entry</span><span class="p">()</span>
|
||||
</span></span><span class="line"><span class="cl">
|
||||
</span></span><span class="line"><span class="cl"><span class="n">entry</span><span class="p">[</span><span class="s1">&#39;vocab:property&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="mi">25</span>
|
||||
</span></span><span class="line"><span class="cl">
|
||||
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">entry</span><span class="o">.</span><span class="n">jsonld</span><span class="p">())</span>
|
||||
</span></span></code></pre></td></tr></table>
|
||||
</div>
|
||||
</div><p>Would print something like this:</p>
|
||||
<div class="highlight"><div class="chroma">
|
||||
<table class="lntable"><tr><td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||||
</span><span class="lnt">2
|
||||
</span><span class="lnt">3
|
||||
</span><span class="lnt">4
|
||||
</span><span class="lnt">5
|
||||
</span></code></pre></td>
|
||||
<td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;@id&#34;</span><span class="p">:</span> <span class="s2">&#34;:Entry_202505....&#34;</span><span class="p">,</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;@type&#34;</span><span class="p">:</span> <span class="s2">&#34;prefix:Entity&#34;</span><span class="p">,</span>
|
||||
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;vocab:property&#34;</span><span class="p">:</span> <span class="mi">25</span>
|
||||
</span></span><span class="line"><span class="cl"><span class="p">}</span>
|
||||
</span></span></code></pre></td></tr></table>
|
||||
</div>
|
||||
</div><p>Producing correct triples using this model requires using the vocabularies and URIs properly, with little to no tooling to enforce it.
|
||||
This poses a big problem for a tool like Senpy, which aims to make it easier for professionals without a background in RDF to build and consume semantic NLP ser
|
||||
If an attribute is not a URI and is not included in the global JSON-LD context, it will not generate a triple in the final graph.
|
||||
Moreover, there is way to enforce that the vocabularies and the</p>
|
||||
<p>Pros:</p>
|
||||
<ul>
|
||||
<li>Flexible/extensible</li>
|
||||
<li>Lightweight. This is mostly JSON-LD in Python&rsquo;s clothing.</li>
|
||||
<li>Naturally maps to both <code>rdflib</code> and writing <code>json-ld</code></li>
|
||||
</ul>
|
||||
<p>Cons:</p>
|
||||
<ul>
|
||||
<li>Discoverability. Documentation and examples are needed to know which attributes to use</li>
|
||||
<li>Error-prone. It is easy to misuse a property, or introduce typos</li>
|
||||
<li>Tight coupling with semantics/RDF. One needs to know a thing or two about RDF, especially if new vocabularies or annotations need to be used.</li>
|
||||
</ul>
|
||||
<h2 id="the-object-oriented-way">The object-oriented way
|
||||
</h2><p>An obvious alternative to this problem in an object-oriented language like python is to use classes to represent our data model.
|
||||
These classes can define the specific attributes available, and typing annotations can serve both as a guide for the developer, and as a means to automatically
|
||||
validate objects at runtime.
|
||||
There are tools like <a class="link" href="https://pydantic.dev/" target="_blank" rel="noopener"
|
||||
>pydantic</a> that make this process very simple.
|
||||
Then, we only need to define how your models should be serialized into JSON-LD.
|
||||
We can thoroughly test this serialization to ensure that the resulting object is correct and produces the right RDF graph.
|
||||
Going back to our previous example, we could define an Entry class as a dataclass, and define all the possible types of annotations as attributes.</p>
|
||||
<p>This model works great when all the possible attributes are known ahead of time.
|
||||
But it starts to break when the model provided is not comprehensive enough, or customers of your library need to provide their own ad-hoc annotations / attribut
|
||||
es.
|
||||
This could be solved by encouring consumers of our library to define their own subclasses whenever they need to add new attributes.
|
||||
This works perfectly fine for serialization, but it breaks if your library needs to automatically deserialize these subclasses.
|
||||
It also breaks if different parts of the code need to add their own attributes on the same data at the same time.
|
||||
This was precisely the case of <code>senpy</code>, where entities are annotated by different plugins, each providing a different set of annotations.</p>
|
||||
<p>Pros:</p>
|
||||
<ul>
|
||||
<li>Discoverability. All possible attributes are known ahead of time, including their possible types.</li>
|
||||
<li>Decoupling from RDF. Developers only need to know about the dataclasses provided. The mapping to the RDF world is already encoded in the dataclass.</li>
|
||||
</ul>
|
||||
<p>Cons:</p>
|
||||
<ul>
|
||||
<li>Rigidity. Adding new types of annotations requires modifying the models, in the main module.</li>
|
||||
<li>Polymorphism.</li>
|
||||
</ul>
|
||||
<h2 id="a-hybrid-approach">A hybrid approach
|
||||
</h2><p>Whichever solution is chosen in the end, it needs to:</p>
|
||||
<ul>
|
||||
<li>Make it easy and error-proof to add the most common types of annotations</li>
|
||||
<li>Allow for additional annotations/attributes to be added</li>
|
||||
<li>Allow for upgrades in the future. i.e., converting the most common custom annotations into built-in ones</li>
|
||||
<li>Allow for deserialization of custom types</li>
|
||||
<li>Allow multiple consumers to add their own annotations</li>
|
||||
</ul></description></item><item><title>uv - One rust tool to rule all pythons</title><link>https://balkian.com/p/uv-one-rust-tool-to-rule-all-pythons/</link><pubDate>Mon, 17 Feb 2025 23:02:47 +0100</pubDate><guid>https://balkian.com/p/uv-one-rust-tool-to-rule-all-pythons/</guid><description><img src="https://balkian.com/img/uv.png" alt="Featured image of post uv - One rust tool to rule all pythons" /><p>Long story short: I&rsquo;m now using <a class="link" href="https://github.com/astral-sh/uv" target="_blank" rel="noopener"
|
||||
>uv</a>, and so should you.
|
||||
It is a great replacement for pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.</p>
|
||||
<h2 id="context">Context
|
||||
</h2><p>For years, my strategy to manage python projects has been a mix of a custom <code>setup.py</code>, several hand-crafted <code>requirements.txt</code> files (through <code>pip freeze</code>), a custom virtualenv per project, and multiple tools to upload to PyPI.
|
||||
Although this works, this setup has many drawbacks:</p>
|
||||
<ul>
|
||||
<li>It requires user intervention (creating a venv, sourcing it, handling new deps). This isn&rsquo;t ideal if you want new (probably inexperienced) users to use your projects.</li>
|
||||
<li>On a similar note, the whole process needs to be well documented if you want other users to contribute or maintain the code.</li>
|
||||
<li>Pinning dependency versions is finicky, and I&rsquo;ve run into problems beause of that.</li>
|
||||
<li>Creating a new project involves a template, or copying files from an older project.</li>
|
||||
</ul>
|
||||
<p>Of course, this is nothing new.
|
||||
There is a whole site dedicated to <a class="link" href="https://packaging.python.org/en/latest/" target="_blank" rel="noopener"
|
||||
>packaging your Python project</a>.
|
||||
A plethora of different projects have come and go, with varying degrees of success.</p>
|
||||
<h2 id="alternatives-poetry">Alternatives (poetry)
|
||||
</h2><p>About a year before trying <code>uv</code>, I tried to catch up with the ecosystem and get to know the <code>blessed new way</code>.
|
||||
However, the task proved to be a little more difficult, as the landscape is filled with a myriad of alternatives, each with their own set of drawbacks and detractors.
|
||||
Packaging has historically been a weak spot, in ironical contradiction to the Zen of Python&rsquo;s &ldquo;There should be one&ndash; and preferably only one &ndash;obvious way to do it&rdquo;,</p>
|
||||
<p>I eventually settled on <a class="link" href="https://python-poetry.org/" target="_blank" rel="noopener"
|
||||
>poetry</a>.
|
||||
Mostly because it seemed like the most popular alternative.</p>
|
||||
<p>There are many things I liked about it.
|
||||
First of all, having a convention for dependencies (<code>pyproject.toml</code>) and a tool that properly handles them was nice.
|
||||
It also removed the need to remember specific incantations to build and publish my Python projects.
|
||||
Lastly, I mixed it <code>poetry2nix</code> to create reproducible python environments using nix.
|
||||
This makes for a very powerful experience.</p>
|
||||
<p>However, there were multiple hiccups.
|
||||
First of all, it took me some time to figure out which specific fields to use (each tool can define ad-hoc properties in a the <code>pyproject.toml</code> file), and some of them seemed redundant with the more generic ones.
|
||||
Full disclosure, this specific point might be a mistake on my side, and I do not remember the details.
|
||||
The second one is speed.
|
||||
(Re-)creating an environment took a non-negligible amount of time.</p>
|
||||
<h2 id="enter-light-uv">Enter <del>light</del> <code>uv</code>
|
||||
</h2><p>According to its repository, <code>uv </code>can replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
|
||||
Not only that, but it also claims to do that 10-100 times faster than pip.
|
||||
I must admit that it being written in rust was a another selling point for me, as I&rsquo;m looking for excuses to collaborate in a decently-sized rust projejct.</p>
|
||||
<p>Installing it is dead simple: simply download the binary (e.g., with curl) or run <code>pip install uv</code>.
|
||||
You won&rsquo;t need much more: <code>uv</code> seems to just do the right thing out of the box.
|
||||
And it does it really, really fast.
|
||||
The rest of the time it gets out of the way.</p>
|
||||
<p>My only gripe so far is that I don&rsquo;t seem to find a built-in command to drop into a shell, but that is nothing that <code>uv run $SHELL</code> cannot fix.</p>
|
||||
<h2 id="common-operations">Common operations
|
||||
</h2><h3 id="initialize-a-repository">Initialize a repository
|
||||
</h3><div class="highlight"><div class="chroma">
|
||||
<table class="lntable"><tr><td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||||
</span></code></pre></td>
|
||||
<td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">uv init
|
||||
</span></span></code></pre></td></tr></table>
|
||||
</div>
|
||||
</div><h3 id="adding-dependencies">Adding dependencies
|
||||
</h3><div class="highlight"><div class="chroma">
|
||||
<table class="lntable"><tr><td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||||
</span></code></pre></td>
|
||||
<td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">uv add senpy
|
||||
</span></span></code></pre></td></tr></table>
|
||||
</div>
|
||||
</div><h3 id="running-commands-inside-the-environment">Running commands inside the environment
|
||||
</h3><div class="highlight"><div class="chroma">
|
||||
<table class="lntable"><tr><td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code><span class="lnt">1
|
||||
</span><span class="lnt">2
|
||||
</span><span class="lnt">3
|
||||
</span><span class="lnt">4
|
||||
</span></code></pre></td>
|
||||
<td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">uv run &lt;COMMAND&gt;
|
||||
</span></span><span class="line"><span class="cl">
|
||||
</span></span><span class="line"><span class="cl"># e.g., run a shell using your python version and dependencies
|
||||
</span></span><span class="line"><span class="cl">uv run $SHELL
|
||||
</span></span></code></pre></td></tr></table>
|
||||
</div>
|
||||
</div><h3 id="dependency-tree">Dependency tree
|
||||
</h3><div class="highlight"><div class="chroma">
|
||||
<table class="lntable"><tr><td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
|
||||
</span><span class="lnt"> 2
|
||||
</span><span class="lnt"> 3
|
||||
</span><span class="lnt"> 4
|
||||
</span><span class="lnt"> 5
|
||||
</span><span class="lnt"> 6
|
||||
</span><span class="lnt"> 7
|
||||
</span><span class="lnt"> 8
|
||||
</span><span class="lnt"> 9
|
||||
</span><span class="lnt">10
|
||||
</span><span class="lnt">11
|
||||
</span><span class="lnt">12
|
||||
</span><span class="lnt">13
|
||||
</span><span class="lnt">14
|
||||
</span><span class="lnt">15
|
||||
</span><span class="lnt">16
|
||||
</span><span class="lnt">17
|
||||
</span><span class="lnt">18
|
||||
</span><span class="lnt">19
|
||||
</span></code></pre></td>
|
||||
<td class="lntd">
|
||||
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">uv shell
|
||||
</span></span><span class="line"><span class="cl">Resolved 44 packages in 1ms
|
||||
</span></span><span class="line"><span class="cl">my-project v0.1.0
|
||||
</span></span><span class="line"><span class="cl">├── fastapi[standard] v0.115.8
|
||||
</span></span><span class="line"><span class="cl">│ ├── pydantic v2.10.6
|
||||
</span></span><span class="line"><span class="cl">│ │ ├── annotated-types v0.7.0
|
||||
</span></span><span class="line"><span class="cl">│ │ ├── pydantic-core v2.27.2
|
||||
</span></span><span class="line"><span class="cl">│ │ │ └── typing-extensions v4.12.2
|
||||
</span></span><span class="line"><span class="cl">│ │ └── typing-extensions v4.12.2
|
||||
</span></span><span class="line"><span class="cl">│ ├── starlette v0.45.3
|
||||
</span></span><span class="line"><span class="cl">│ │ └── anyio v4.8.0
|
||||
</span></span><span class="line"><span class="cl">│ │ ├── exceptiongroup v1.2.2
|
||||
</span></span><span class="line"><span class="cl">│ │ ├── idna v3.10
|
||||
</span></span><span class="line"><span class="cl">│ │ ├── sniffio v1.3.1
|
||||
</span></span><span class="line"><span class="cl">│ │ └── typing-extensions v4.12.2
|
||||
</span></span><span class="line"><span class="cl">│ ├── typing-extensions v4.12.2
|
||||
</span></span><span class="line"><span class="cl">│ ├── email-validator v2.2.0 (extra: standard)
|
||||
</span></span><span class="line"><span class="cl">│ │ ├── dnspython v2.7.0
|
||||
</span></span><span class="line"><span class="cl">...
|
||||
</span></span></code></pre></td></tr></table>
|
||||
</div>
|
||||
</div></description></item><item><title>Python</title><link>https://balkian.com/cheatsheet/python/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://balkian.com/cheatsheet/python/</guid><description><img src="https://balkian.com/img/python.png" alt="Featured image of post Python" /><h2 id="interesting-libraries">Interesting libraries
|
||||
</h2><h3 id="tqdm"><a class="link" href="https://github.com/tqdm/tqdm" target="_blank" rel="noopener"
|
||||
>TQDM</a>
|
||||
</h3><p>From tqdm&rsquo;s github repository:</p>
|
||||
<blockquote>
|
||||
<p>tqdm means &ldquo;progress&rdquo; in Arabic (taqadum, تقدّم) and an abbreviation for &ldquo;I love you so much&rdquo; in Spanish (te quiero demasiado).</p></blockquote>
|
||||
<p><img src="https://raw.githubusercontent.com/tqdm/tqdm/master/images/tqdm.gif"
|
||||
loading="lazy"
|
||||
alt="TQDM in action"
|
||||
></p>
|
||||
<h2 id="tools">Tools
|
||||
</h2><h3 id="uv"><a class="link" href="https://github.com/astral-sh/uv" target="_blank" rel="noopener"
|
||||
>uv</a>
|
||||
</h3><p>🚀 A single tool to replace pip, pip-tools, pipx, poetry, pyenv, twine, virtualenv, and more.
|
||||
⚡️ 10-100x faster than pip.</p>
|
||||
<ul>
|
||||
<li>Provides comprehensive project management, with a universal lockfile.</li>
|
||||
<li>Runs scripts, with support for inline dependency metadata.</li>
|
||||
<li>Installs and manages Python versions.</li>
|
||||
<li>Runs and installs tools published as Python packages.</li>
|
||||
<li>Includes a pip-compatible interface for a performance boost with a familiar CLI.</li>
|
||||
<li>Supports Cargo-style workspaces for scalable projects.</li>
|
||||
<li>Disk-space efficient, with a global cache for dependency deduplication.</li>
|
||||
<li>Installable without Rust or Python via curl or pip.</li>
|
||||
<li>Supports macOS, Linux, and Windows.</li>
|
||||
</ul></description></item></channel></rss>
|
1
categories/programming/page/1/index.html
Normal file
1
categories/programming/page/1/index.html
Normal file
@@ -0,0 +1 @@
|
||||
<!doctype html><html lang=en-us><head><title>https://balkian.com/categories/programming/</title><link rel=canonical href=https://balkian.com/categories/programming/><meta name=robots content="noindex"><meta charset=utf-8><meta http-equiv=refresh content="0; url=https://balkian.com/categories/programming/"></head></html>
|
Reference in New Issue
Block a user