#!/usr/bin/env python3 """Reproduce Scholar4AI's current-window comparison, using Python's standard library. Download /data/research-patterns-input.json and run: python research-patterns.py research-patterns-input.json > research-patterns.csv Each OpenAlex work counts once; multiple names on one work do not inflate totals. """ import csv import io import json import sys from collections import Counter def aggregate(snapshot): seen, buckets = set(), {} for category in snapshot['categories']: buckets[category['name']] = dict(category, papers=0, with_datasets=0, with_equations=0, with_both=0, with_abstract=0, with_fulltext=0, dataset_names=Counter(), equation_names=Counter()) for paper in snapshot['papers']: key = paper['id'] if key in seen: continue seen.add(key) row = buckets[paper['category']] datasets, equations = set(paper['datasets']), set(paper['equations']) row['papers'] += 1 row['with_datasets'] += bool(datasets) row['with_equations'] += bool(equations) row['with_both'] += bool(datasets and equations) row['with_abstract'] += bool(paper['has_abstract']) row['with_fulltext'] += bool(paper['has_fulltext']) row['dataset_names'].update(datasets) row['equation_names'].update(equations) return list(buckets.values()) def as_csv(rows): out = io.StringIO(newline='') fields = ['name', 'slug', 'papers', 'with_datasets', 'with_equations', 'with_both', 'with_abstract', 'with_fulltext'] writer = csv.DictWriter(out, fieldnames=fields, extrasaction='ignore', lineterminator='\n') writer.writeheader() writer.writerows(rows) return out.getvalue() if __name__ == '__main__': with open(sys.argv[1], encoding='utf-8') as source: sys.stdout.write(as_csv(aggregate(json.load(source))))