passive-experiment-csv-header-preview 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Passive Experiment (Chad Darcy)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: passive-experiment-csv-header-preview
3
+ Version: 0.1.0
4
+ Summary: Preview ASCII header renames and collisions before using CSV Cleanup. Offline Python, original names visible; no file writes.
5
+ License-Expression: MIT
6
+ Project-URL: CSV Cleanup Kit, https://passiveexperiment.gumroad.com/l/osmloi?utm_source=pypi&utm_medium=sample&utm_campaign=mkt10-csv-cleanup-kit
7
+ Keywords: csv,data-cleaning,cli
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Dynamic: license-file
12
+
13
+ # CSV header preview
14
+
15
+ Preview the header-renaming step from the CSV Cleanup Kit before touching any CSV data. The script shows original and proposed ASCII snake_case names by position, including duplicate suffixes. Python 3.10+ only; no dependencies, account, network or file writes.
16
+
17
+ ```sh
18
+ python3 csv_header_preview.py ' Client Name ' 'Client-Name' '名'
19
+ ```
20
+
21
+ This fictional example proposes `client_name`, `client_name_2` and `column`. Non-Latin text, accents, punctuation and currency distinctions can be lost; compare every proposal with the original. Renaming does not prove compatibility with any receiving system. The sample accepts header strings only. It does not read CSVs, clean cells, remove duplicates, convert dates, neutralize formulas or validate financial records.
22
+
23
+ The code is a bounded sample of the existing reviewed tool's header logic, created with AI assistance and checked with fictional cases. No outcome, security or compatibility guarantee; do not pass personal/client data in a public example or support request. This is not the paid kit or a hosted service.
24
+
25
+ The optional [CSV Cleanup Kit](https://passiveexperiment.gumroad.com/l/osmloi?utm_source=github&utm_medium=sample&utm_campaign=mkt10-csv-cleanup-kit) is USD9 on Gumroad and includes the full offline cleanup script, JSON change report, fictional before/after exercise and printable Plan/Check/Handoff sheets in A4/US Letter. The paid kit retains its single-business licence; no worksheet or paid archive is included here. This is the seller's sample and paid offer, not independent endorsement or verified demand.
26
+
27
+ Released under the MIT licence (see LICENSE). The licence covers this sample only, not the paid kit.
@@ -0,0 +1,15 @@
1
+ # CSV header preview
2
+
3
+ Preview the header-renaming step from the CSV Cleanup Kit before touching any CSV data. The script shows original and proposed ASCII snake_case names by position, including duplicate suffixes. Python 3.10+ only; no dependencies, account, network or file writes.
4
+
5
+ ```sh
6
+ python3 csv_header_preview.py ' Client Name ' 'Client-Name' '名'
7
+ ```
8
+
9
+ This fictional example proposes `client_name`, `client_name_2` and `column`. Non-Latin text, accents, punctuation and currency distinctions can be lost; compare every proposal with the original. Renaming does not prove compatibility with any receiving system. The sample accepts header strings only. It does not read CSVs, clean cells, remove duplicates, convert dates, neutralize formulas or validate financial records.
10
+
11
+ The code is a bounded sample of the existing reviewed tool's header logic, created with AI assistance and checked with fictional cases. No outcome, security or compatibility guarantee; do not pass personal/client data in a public example or support request. This is not the paid kit or a hosted service.
12
+
13
+ The optional [CSV Cleanup Kit](https://passiveexperiment.gumroad.com/l/osmloi?utm_source=github&utm_medium=sample&utm_campaign=mkt10-csv-cleanup-kit) is USD9 on Gumroad and includes the full offline cleanup script, JSON change report, fictional before/after exercise and printable Plan/Check/Handoff sheets in A4/US Letter. The paid kit retains its single-business licence; no worksheet or paid archive is included here. This is the seller's sample and paid offer, not independent endorsement or verified demand.
14
+
15
+ Released under the MIT licence (see LICENSE). The licence covers this sample only, not the paid kit.
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env python3
2
+ """Preview CSV Cleanup's ASCII header renaming without reading or writing files."""
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import re
8
+
9
+
10
+ def snake(header: str) -> str:
11
+ text = re.sub(r"[^0-9a-zA-Z]+", "_", header.strip()).strip("_").lower()
12
+ return text or "column"
13
+
14
+
15
+ def preview_headers(headers: list[str]) -> list[dict[str, str | int]]:
16
+ """Return original/proposed names by position; never change caller data."""
17
+ names: set[str] = set()
18
+ result = []
19
+ for position, raw in enumerate(headers, start=1):
20
+ name, n = snake(raw), 2
21
+ while name in names:
22
+ name, n = f"{snake(raw)}_{n}", n + 1
23
+ names.add(name)
24
+ result.append({"position": position, "original": raw, "proposed": name})
25
+ return result
26
+
27
+
28
+ def main(argv: list[str] | None = None) -> int:
29
+ parser = argparse.ArgumentParser(description=__doc__)
30
+ parser.add_argument("headers", nargs="+", help="Quote each literal header as one argument")
31
+ args = parser.parse_args(argv)
32
+ print(json.dumps({"warning": "ASCII renaming can lose accents, non-Latin text and currency distinctions; review every proposed name. No CSV or data cells were read or changed.", "headers": preview_headers(args.headers)}, ensure_ascii=False, indent=2))
33
+ return 0
34
+
35
+
36
+ if __name__ == "__main__":
37
+ raise SystemExit(main())
@@ -0,0 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: passive-experiment-csv-header-preview
3
+ Version: 0.1.0
4
+ Summary: Preview ASCII header renames and collisions before using CSV Cleanup. Offline Python, original names visible; no file writes.
5
+ License-Expression: MIT
6
+ Project-URL: CSV Cleanup Kit, https://passiveexperiment.gumroad.com/l/osmloi?utm_source=pypi&utm_medium=sample&utm_campaign=mkt10-csv-cleanup-kit
7
+ Keywords: csv,data-cleaning,cli
8
+ Requires-Python: >=3.10
9
+ Description-Content-Type: text/markdown
10
+ License-File: LICENSE
11
+ Dynamic: license-file
12
+
13
+ # CSV header preview
14
+
15
+ Preview the header-renaming step from the CSV Cleanup Kit before touching any CSV data. The script shows original and proposed ASCII snake_case names by position, including duplicate suffixes. Python 3.10+ only; no dependencies, account, network or file writes.
16
+
17
+ ```sh
18
+ python3 csv_header_preview.py ' Client Name ' 'Client-Name' '名'
19
+ ```
20
+
21
+ This fictional example proposes `client_name`, `client_name_2` and `column`. Non-Latin text, accents, punctuation and currency distinctions can be lost; compare every proposal with the original. Renaming does not prove compatibility with any receiving system. The sample accepts header strings only. It does not read CSVs, clean cells, remove duplicates, convert dates, neutralize formulas or validate financial records.
22
+
23
+ The code is a bounded sample of the existing reviewed tool's header logic, created with AI assistance and checked with fictional cases. No outcome, security or compatibility guarantee; do not pass personal/client data in a public example or support request. This is not the paid kit or a hosted service.
24
+
25
+ The optional [CSV Cleanup Kit](https://passiveexperiment.gumroad.com/l/osmloi?utm_source=github&utm_medium=sample&utm_campaign=mkt10-csv-cleanup-kit) is USD9 on Gumroad and includes the full offline cleanup script, JSON change report, fictional before/after exercise and printable Plan/Check/Handoff sheets in A4/US Letter. The paid kit retains its single-business licence; no worksheet or paid archive is included here. This is the seller's sample and paid offer, not independent endorsement or verified demand.
26
+
27
+ Released under the MIT licence (see LICENSE). The licence covers this sample only, not the paid kit.
@@ -0,0 +1,10 @@
1
+ LICENSE
2
+ README.md
3
+ csv_header_preview.py
4
+ pyproject.toml
5
+ passive_experiment_csv_header_preview.egg-info/PKG-INFO
6
+ passive_experiment_csv_header_preview.egg-info/SOURCES.txt
7
+ passive_experiment_csv_header_preview.egg-info/dependency_links.txt
8
+ passive_experiment_csv_header_preview.egg-info/entry_points.txt
9
+ passive_experiment_csv_header_preview.egg-info/top_level.txt
10
+ tests/test_csv_header_preview.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ csv-header-preview = csv_header_preview:main
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "passive-experiment-csv-header-preview"
7
+ version = "0.1.0"
8
+ description = "Preview ASCII header renames and collisions before using CSV Cleanup. Offline Python, original names visible; no file writes."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ dependencies = []
13
+ keywords = ["csv", "data-cleaning", "cli"]
14
+
15
+ [project.urls]
16
+ "CSV Cleanup Kit" = "https://passiveexperiment.gumroad.com/l/osmloi?utm_source=pypi&utm_medium=sample&utm_campaign=mkt10-csv-cleanup-kit"
17
+
18
+ [project.scripts]
19
+ csv-header-preview = "csv_header_preview:main"
20
+
21
+ [tool.setuptools]
22
+ py-modules = ["csv_header_preview"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,50 @@
1
+ import importlib.util
2
+ import io
3
+ import json
4
+ import contextlib
5
+ import unittest
6
+ from pathlib import Path
7
+
8
+ spec = importlib.util.spec_from_file_location('header_sample', Path(__file__).resolve().parents[1] / 'csv_header_preview.py')
9
+ module = importlib.util.module_from_spec(spec)
10
+ spec.loader.exec_module(module)
11
+
12
+ class HeaderPreviewTests(unittest.TestCase):
13
+ def test_cli_runs_without_writing_files(self):
14
+ import subprocess
15
+ import sys
16
+ import tempfile
17
+ with tempfile.TemporaryDirectory() as directory:
18
+ result = subprocess.run([sys.executable, str(Path(module.__file__).resolve()), ' A ', 'a'], cwd=directory, text=True, capture_output=True, check=True)
19
+ self.assertEqual(json.loads(result.stdout)['headers'][1]['proposed'], 'a_2')
20
+ self.assertEqual(list(Path(directory).iterdir()), [])
21
+
22
+ def test_collision_order_matches_existing_tool(self):
23
+ values = ['a', 'a', 'a_2', 'a', ' A ']
24
+ original = values.copy()
25
+ actual = module.preview_headers(values)
26
+ self.assertEqual([x['proposed'] for x in actual], ['a', 'a_2', 'a_2_2', 'a_3', 'a_4'])
27
+ self.assertEqual([x['original'] for x in actual], original)
28
+ self.assertEqual(values, original)
29
+ self.assertEqual([x['position'] for x in actual], [1, 2, 3, 4, 5])
30
+
31
+ def test_lossy_and_empty_names_are_visible(self):
32
+ result = module.preview_headers(['', '名', 'é', 'USD $', 'USD €'])
33
+ self.assertEqual([x['proposed'] for x in result], ['column', 'column_2', 'column_3', 'usd', 'usd_2'])
34
+ self.assertEqual(result[1]['original'], '名')
35
+
36
+ def test_cli_valid_json_and_warning(self):
37
+ stream = io.StringIO()
38
+ with contextlib.redirect_stdout(stream):
39
+ self.assertEqual(module.main([' Client Name ', 'Client-Name']), 0)
40
+ result = json.loads(stream.getvalue())
41
+ self.assertIn('can lose', result['warning'])
42
+ self.assertEqual(result['headers'][1]['proposed'], 'client_name_2')
43
+
44
+ def test_cli_requires_headers(self):
45
+ with contextlib.redirect_stderr(io.StringIO()), self.assertRaises(SystemExit) as error:
46
+ module.main([])
47
+ self.assertEqual(error.exception.code, 2)
48
+
49
+ if __name__ == '__main__':
50
+ unittest.main()