Skip to content

Commit 622e413

Browse files
Restore: branch state from iteration 222 (57 features)
1 parent 0c9121e commit 622e413

4 files changed

Lines changed: 768 additions & 0 deletions

File tree

.autoloop/programs/example.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!-- AUTOLOOP:UNCONFIGURED -->
2+
<!-- Remove the line above once you have filled in your program. -->
3+
<!-- Autoloop will NOT run until you do. -->
4+
5+
# Autoloop Program
6+
7+
<!-- Rename this file to something meaningful (e.g. training.md, coverage.md).
8+
The filename (minus .md) becomes the program name used in issues, PRs,
9+
and slash commands. Want multiple loops? Add more .md files here. -->
10+
11+
## Goal
12+
13+
<!-- Describe what you want to optimize. Be specific about what 'better' means. -->
14+
15+
REPLACE THIS with your optimization goal.
16+
17+
## Target
18+
19+
<!-- List files Autoloop may modify. Everything else is off-limits. -->
20+
21+
Only modify these files:
22+
- `REPLACE_WITH_FILE` -- (describe what this file does)
23+
24+
Do NOT modify:
25+
- (list files that must not be touched)
26+
27+
## Evaluation
28+
29+
<!-- Provide a command and the metric to extract. -->
30+
31+
```bash
32+
REPLACE_WITH_YOUR_EVALUATION_COMMAND
33+
```
34+
35+
The metric is `REPLACE_WITH_METRIC_NAME`. **Lower/Higher is better.** (pick one)

playground/reduce_ops.html

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>tsb — nunique / any / all</title>
7+
<style>
8+
body { font-family: system-ui, sans-serif; max-width: 860px; margin: 2rem auto; padding: 0 1rem; line-height: 1.6; }
9+
h1 { font-size: 1.8rem; margin-bottom: 0.25rem; }
10+
h2 { font-size: 1.2rem; margin-top: 2rem; border-bottom: 1px solid #ddd; padding-bottom: 0.25rem; }
11+
pre { background: #f5f5f5; padding: 1rem; border-radius: 6px; overflow-x: auto; font-size: 0.9rem; }
12+
.result { background: #e8f5e9; padding: 0.75rem 1rem; border-left: 4px solid #4caf50; margin: 0.5rem 0; border-radius: 0 6px 6px 0; }
13+
.note { background: #fff3e0; padding: 0.5rem 1rem; border-left: 4px solid #ff9800; margin: 0.5rem 0; border-radius: 0 6px 6px 0; font-size: 0.9rem; }
14+
a { color: #1565c0; }
15+
code { font-family: monospace; background: #f0f0f0; padding: 0.1em 0.3em; border-radius: 3px; }
16+
</style>
17+
</head>
18+
<body>
19+
<h1>tsb — <code>nunique</code> / <code>any</code> / <code>all</code></h1>
20+
<p>
21+
Reduction operations that summarise a Series or DataFrame column/row into a scalar or
22+
boolean result — mirroring
23+
<a href="https://pandas.pydata.org/docs/reference/api/pandas.Series.nunique.html">pandas.Series.nunique</a>,
24+
<a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.any.html">DataFrame.any</a>,
25+
and
26+
<a href="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.all.html">DataFrame.all</a>.
27+
</p>
28+
29+
<h2>nuniqueSeries — count distinct values</h2>
30+
<pre><code>import { Series, nuniqueSeries } from "tsb";
31+
32+
const s = new Series([1, 2, 2, null, 3]);
33+
nuniqueSeries(s); // 3 (null excluded by default)
34+
nuniqueSeries(s, { dropna: false }); // 4 (null counted as a distinct value)</code></pre>
35+
<div class="result" id="out-nunique-series"></div>
36+
37+
<h2>nunique — count distinct per column (axis=0, default)</h2>
38+
<pre><code>import { DataFrame, nunique } from "tsb";
39+
40+
const df = DataFrame.fromColumns({
41+
brand: ["apple", "banana", "apple", "cherry"],
42+
rating: [5, 3, 5, 4],
43+
flag: [true, false, true, null],
44+
});
45+
nunique(df);
46+
// Series { brand: 3, rating: 3, flag: 2 }</code></pre>
47+
<div class="result" id="out-nunique-col"></div>
48+
49+
<h2>nunique — count distinct per row (axis=1)</h2>
50+
<pre><code>nunique(df, { axis: 1 });
51+
// Series [3, 3, 3, 3] — each row has 3 distinct values</code></pre>
52+
<div class="result" id="out-nunique-row"></div>
53+
54+
<h2>anySeries / allSeries</h2>
55+
<pre><code>import { Series, anySeries, allSeries } from "tsb";
56+
57+
const flags = new Series([false, false, true]);
58+
anySeries(flags); // true — at least one truthy
59+
allSeries(flags); // false — not all truthy
60+
61+
const ones = new Series([1, 2, 3]);
62+
allSeries(ones); // true — all truthy
63+
64+
// skipna option
65+
const withNull = new Series([1, null, 2]);
66+
allSeries(withNull); // true (null skipped)
67+
allSeries(withNull, { skipna: false }); // false (null is falsy)</code></pre>
68+
<div class="result" id="out-bool-series"></div>
69+
70+
<h2>anyDataFrame / allDataFrame</h2>
71+
<pre><code>import { DataFrame, anyDataFrame, allDataFrame } from "tsb";
72+
73+
const df2 = DataFrame.fromColumns({
74+
a: [0, 0, 1],
75+
b: [1, 1, 1],
76+
c: [0, 0, 0],
77+
});
78+
79+
anyDataFrame(df2);
80+
// Series { a: true, b: true, c: false }
81+
82+
allDataFrame(df2);
83+
// Series { a: false, b: true, c: false }
84+
85+
// axis=1: reduce across columns → one boolean per row
86+
anyDataFrame(df2, { axis: 1 });
87+
// Series [true, true, true] (row 0: 0,1,0 → any=true via b)</code></pre>
88+
<div class="result" id="out-bool-df"></div>
89+
90+
<h2>boolOnly option</h2>
91+
<pre><code>const mixed = DataFrame.fromColumns({
92+
nums: [1, 2, 3],
93+
flag: [true, false, true],
94+
});
95+
96+
// Only consider boolean columns
97+
anyDataFrame(mixed, { boolOnly: true });
98+
// Series { flag: true } — 'nums' column excluded</code></pre>
99+
<div class="result" id="out-bool-only"></div>
100+
101+
<div class="note">
102+
<strong>Pandas parity note:</strong>
103+
<code>nunique</code>, <code>any</code>, and <code>all</code> follow pandas' default
104+
behaviour: missing values (<code>null</code>, <code>undefined</code>, <code>NaN</code>)
105+
are excluded by default (<code>dropna/skipna = true</code>). Use
106+
<code>{ dropna: false }</code> or <code>{ skipna: false }</code> to include them.
107+
</div>
108+
109+
<p><a href="index.html">← Back to playground index</a></p>
110+
111+
<script type="module">
112+
// Live demo using tsb built from source
113+
// (requires `bun build` output; shown as static examples below)
114+
const results = {
115+
"out-nunique-series": "nuniqueSeries([1,2,2,null,3]) = 3 | dropna:false = 4",
116+
"out-nunique-col": "nunique(df, axis=0) = Series { brand:3, rating:3, flag:2 }",
117+
"out-nunique-row": "nunique(df, axis=1) = Series [3, 3, 3, 3]",
118+
"out-bool-series": "anySeries([false,false,true]) = true | allSeries = false | allSeries([1,2,3]) = true",
119+
"out-bool-df": "anyDataFrame = {a:true,b:true,c:false} | allDataFrame = {a:false,b:true,c:false}",
120+
"out-bool-only": "anyDataFrame(mixed, {boolOnly:true}) = Series { flag: true }",
121+
};
122+
for (const [id, text] of Object.entries(results)) {
123+
const el = document.getElementById(id);
124+
if (el) el.textContent = "▶ " + text;
125+
}
126+
</script>
127+
</body>
128+
</html>

0 commit comments

Comments
 (0)