<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SATNAM</title>
    <description>The latest articles on DEV Community by SATNAM (@probotisop).</description>
    <link>https://dev.to/probotisop</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4239976%2F72037b91-429c-41b0-9817-d403caea0920.jpg</url>
      <title>DEV Community: SATNAM</title>
      <link>https://dev.to/probotisop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/probotisop"/>
    <language>en</language>
    <item>
      <title>I open-sourced GOD HAND: a local-first tool for exploring tabular data</title>
      <dc:creator>SATNAM</dc:creator>
      <pubDate>Wed, 11 Nov 2026 23:30:21 +0000</pubDate>
      <link>https://dev.to/probotisop/i-open-sourced-god-hand-a-local-first-tool-for-exploring-tabular-data-899</link>
      <guid>https://dev.to/probotisop/i-open-sourced-god-hand-a-local-first-tool-for-exploring-tabular-data-899</guid>
      <description>&lt;p&gt;Today I'm releasing &lt;strong&gt;GOD HAND OF STATISTICS&lt;/strong&gt; as open source under the &lt;strong&gt;Apache-2.0&lt;/strong&gt; licence.&lt;/p&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://github.com/ProbotisOP/GodHandOFStatistics" rel="noopener noreferrer"&gt;github.com/ProbotisOP/GodHandOFStatistics&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;A local web app for exploring tabular data. You drop in files, and it profiles, cleans and connects them, searches for patterns, and &lt;strong&gt;shows only the patterns that survive statistical checks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It runs entirely on your machine (server bound to &lt;code&gt;127.0.0.1&lt;/code&gt;). No account, no API key, no cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why
&lt;/h2&gt;

&lt;p&gt;Automated exploration tests hundreds of hypotheses, and some will "pass" by chance. On a file of pure random numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;$ uv run python examples/noise_challenge.py
  naive testing, p &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; 0.05 one at a &lt;span class="k"&gt;time&lt;/span&gt; : 10 &lt;span class="s1"&gt;'significant'&lt;/span&gt; of 230 tests  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;- all &lt;span class="kc"&gt;false&lt;/span&gt; alarms
  GOD HAND, 231 hypotheses on the ledger : 0 patterns reported
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GOD HAND is built so that the second line is the normal outcome.&lt;/p&gt;

&lt;h2&gt;
  
  
  Highlights
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Statistics you can trust&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every hypothesis is registered on a &lt;strong&gt;ledger&lt;/strong&gt; before it is tested; the ledger is the only source of p-values&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Benjamini–Hochberg&lt;/strong&gt; false-discovery control across the whole search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sealed 30% holdout&lt;/strong&gt; (≥ 2,000 rows) or cross-fitting (300–2,000 rows), with the candidate list frozen first&lt;/li&gt;
&lt;li&gt;Permutation tests (Besag–Clifford), effect sizes with intervals (Spearman ρ, Cliff's δ), design-effect correction for repeated rows&lt;/li&gt;
&lt;li&gt;Evidence &lt;strong&gt;grades A–E&lt;/strong&gt;, explained in plain language without causal claims&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Finds what matters&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Relationships, group differences, segments, interactions, Simpson's paradox, change points, differences between files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exact formula detection&lt;/strong&gt;, e.g. &lt;code&gt;Revenue = Avg_Spend × Daily_Customers × 0.03&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Near-copy columns merged, so findings aren't duplicated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qfqcgjrf9a0o8y0tcuk.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qfqcgjrf9a0o8y0tcuk.gif" alt="The Data Universe" width="600" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Works with your files&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CSV, TSV, Excel, Parquet, JSON&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microsoft Access&lt;/strong&gt; (&lt;code&gt;.mdb&lt;/code&gt;, &lt;code&gt;.accdb&lt;/code&gt;), &lt;strong&gt;SQLite&lt;/strong&gt;, &lt;strong&gt;DuckDB&lt;/strong&gt;, &lt;strong&gt;dBase&lt;/strong&gt;, all read-only and detected by their file signature&lt;/li&gt;
&lt;li&gt;Multi-file joins and appends, with warnings for row inflation and unit mismatches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Clean and export&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Green / yellow / red health light per table&lt;/li&gt;
&lt;li&gt;One-click fixes, exported as cleaned &lt;strong&gt;CSV/Parquet&lt;/strong&gt; plus a &lt;strong&gt;Python (polars) or SQL&lt;/strong&gt; recipe&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Explore&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interactive &lt;strong&gt;Vega-Lite&lt;/strong&gt; charts: zoom, pan, hover, isolate a series, export PNG/SVG/CSV&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;three.js Data Universe&lt;/strong&gt;: columns are stars, findings are beams coloured by direction, and clicking shows the evidence&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stack
&lt;/h2&gt;

&lt;p&gt;Python 3.12–3.13 (polars, numpy, scipy, scikit-learn, FastAPI) · React 19 + TypeScript + Vite · three.js · Vega-Lite · tested with pytest, Hypothesis and Playwright.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get started
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/ProbotisOP/GodHandOFStatistics &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; GodHandOFStatistics
uv sync
&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; apps/web &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm install &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build&lt;span class="o"&gt;)&lt;/span&gt;
uv run python -m godhand.server        &lt;span class="c"&gt;# http://127.0.0.1:8000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Requires &lt;a href="https://docs.astral.sh/uv/" rel="noopener noreferrer"&gt;uv&lt;/a&gt; and Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Status
&lt;/h2&gt;

&lt;p&gt;This is release &lt;strong&gt;0.1&lt;/strong&gt;. Known limits: runs are kept in memory, very large scatter plots are slow, and password-protected Access files aren't supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coming next:&lt;/strong&gt; drift watch (re-test findings on new data), a local AI copilot answering only from the ledger, and persistent runs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get involved
&lt;/h2&gt;

&lt;p&gt;Try it on a real dataset and tell me what it found, what it missed, and where it got the statistics wrong. Issues, ideas and pull requests are welcome. See &lt;a href="https://github.com/ProbotisOP/GodHandOFStatistics/blob/main/CONTRIBUTING.md" rel="noopener noreferrer"&gt;CONTRIBUTING.md&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;⭐ If it's useful, a star helps others find it: &lt;strong&gt;&lt;a href="https://github.com/ProbotisOP/GodHandOFStatistics" rel="noopener noreferrer"&gt;github.com/ProbotisOP/GodHandOFStatistics&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>python</category>
      <category>showdev</category>
      <category>datascience</category>
    </item>
  </channel>
</rss>
