Metadata-Version: 2.4
Name: dalang
Version: 0.6.4
Summary: Dalang (Data Analytics LANGuage): bahasa analisis data yang mudah dibaca, dengan konteks perhitungan yang selalu tertulis di kode. MODEL dan measure, EXPLAIN dan TEST, peramalan dan regresi, modul .dal, serta ekspor ke DAX (Power BI) dan SQL.
Author: Tim Dalang
License-Expression: Apache-2.0
Keywords: data analytics,language,dax,power bi,sql,duckdb,bahasa indonesia
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Intended Audience :: Education
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: Indonesian
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Compilers
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: duckdb>=1.1
Provides-Extra: grafik
Requires-Dist: matplotlib>=3.7; extra == "grafik"
Provides-Extra: excel
Requires-Dist: openpyxl>=3.1; extra == "excel"
Provides-Extra: semua
Requires-Dist: matplotlib>=3.7; extra == "semua"
Requires-Dist: openpyxl>=3.1; extra == "semua"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: matplotlib>=3.7; extra == "dev"
Requires-Dist: openpyxl>=3.1; extra == "dev"
Dynamic: license-file

# Dalang (Data Analytics LANGuage)

Dalang adalah bahasa analisis data yang mudah dibaca, untuk analis data dan pengguna Excel serta Power BI, dari pemula sampai mahir. Konteks setiap perhitungan tertulis di kode, sehingga setiap angka bisa dijelaskan. Pesan kesalahan dan format angka memakai bahasa Indonesia.

```basic
LET sales = LOAD CSV "penjualan.csv"

MODEL Toko
    TABLES sales
    CALENDAR sales.tanggal
    MEASURE Omzet = SUM(sales.nilai)
    MEASURE Growth = (Omzet - Omzet PREVIOUS YEAR) / Omzet PREVIOUS YEAR
END MODEL

SHOW Omzet, Growth BY kota WHERE YEAR = 2025
EXPLAIN Growth AT kota = "Jakarta", YEAR = 2025
```

```text
kota     Omzet  Growth
-------  -----  ------
Bandung    100  100,0%
Jakarta    290   70,6%
Growth = 70,6%
  ← (Omzet - (Omzet PREVIOUS YEAR)) / (Omzet PREVIOUS YEAR)
  ← Omzet = 290
  ← Omzet PREVIOUS YEAR = 170
  ← filter: kota = "Jakarta"   (dari AT)
  ← filter: YEAR = 2025        (dari AT, lewat CALENDAR sales.tanggal)
```

## Pemasangan

Dalang membutuhkan Python 3.10 atau lebih baru.

```bash
pip install dalang
dal --version
```

| Tambahan | Perintah | Untuk |
|---|---|---|
| `grafik` | `pip install "dalang[grafik]"` | menyimpan grafik `PLOT` sebagai PNG |
| `excel` | `pip install "dalang[excel]"` | `LOAD EXCEL` dan `SAVE … AS EXCEL` |
| `semua` | `pip install "dalang[semua]"` | keduanya |

## Perintah `dal`

| Perintah | Kegunaan |
|---|---|
| `dal run laporan.dal` | Menjalankan program. `--set nama=nilai` mengisi `PARAMETER`, `--show-python` menampilkan hasil terjemahan ke Python. |
| `dal check laporan.dal` atau `dal check .` | Memeriksa program tanpa menjalankannya: ejaan, nama kolom dari file data, aturan MODEL, dan modul. |
| `dal test .` | Menjalankan semua blok `TEST` tanpa mencetak `SHOW`. Kode keluar 1 bila ada yang gagal. |
| `dal fmt .` atau `dal fmt --check .` | Merapikan huruf besar dan indentasi tanpa mengubah arti program. |
| `dal parse laporan.dal` | Menampilkan cara Dalang membaca program, dengan setiap ekspresi berkurung. |

Contoh pesan kesalahan dari `dal check`:

```text
Kesalahan di analisis.dal baris 3:
    SHOW SUM(sales.nilia)
                   ^^^^^
Kolom "nilia" tidak ada di tabel "sales". Mungkin maksud Anda: "nilai"? Kolom yang tersedia: tanggal, kota, kode, nilai

[GAGAL] analisis.dal: 1 kesalahan
```

## Fitur

### Data dan tabel

- `LOAD CSV`, `LOAD EXCEL … WITH sheet: "Juni"`, dan `LOAD PARQUET`. Pemisah CSV (`;`, `,`, tab, `|`) dan tipe kolom dikenali otomatis.
- `SAVE … AS CSV`, `AS EXCEL`, atau `AS PARQUET`.
- Operasi tabel: `WHERE`, `SELECT`, `SORT BY … DESCENDING`, `TOP n tabel BY kolom`, `RANK`, `JOIN … ON …`, `RENAME`, `REMOVE`, `FILL`, dan `APPEND`.
- Kolom baru atau kolom yang diganti: `LET sales.pajak = nilai * 0.11`, `LET sales.kota = TRIM(kota)`.
- Ringkasan: `SUM`, `MEAN`, `MEDIAN`, `MIN`, `MAX`, `COUNT`, `COUNTDISTINCT`, `STDEV`, dan `VARIANCE`, dengan `BY`, `WHERE`, `WITH totals: TRUE`, dan `WITH rows: n`.
- `PLOT … BY …`: grafik teks di terminal, ditambah PNG bila `dalang[grafik]` terpasang.

### MODEL dan measure

```basic
MODEL Toko
    TABLES sales, products
    RELATE sales.kode TO products.kode
    CALENDAR sales.tanggal
    MEASURE Omzet = SUM(sales.nilai)
    MEASURE Omzet_Minuman = Omzet WHERE products.kategori = "Minuman"
    MEASURE Per_Produk = MEAN(Omzet) FOR EACH ROW OF products
END MODEL
```

- Measure dihitung ulang di setiap konteks: `BY`, `WHERE`, dan `AT kota = "Jakarta", YEAR = 2025`.
- `WHERE` pada measure mengiris konteks, tidak menimpanya. Untuk melepas filter, tulis `IGNORE FILTER kota`.
- `AS SHARE OF kota` untuk porsi dari keseluruhan.
- `RELATE` mengalirkan filter dari tabel "satu" ke tabel "banyak". Filter dari tabel yang tidak terhubung menjadi pesan kesalahan, bukan total yang berulang.
- Total dihitung ulang, bukan dijumlahkan. Baris yang semua nilainya kosong disembunyikan, kecuali dengan `WITH show_empty: TRUE`.
- Hasil pembagian dua besaran sejenis otomatis ditampilkan sebagai persen.

### Waktu

- `CALENDAR` memberi dimensi `YEAR`, `QUARTER`, `MONTH`, `WEEK`, dan `DAY` tanpa tabel tanggal terpisah.
- Pengubah waktu: `PREVIOUS YEAR`, `LAST 3 MONTH`, dan `YEAR TO DATE`, `QUARTER TO DATE`, atau `MONTH TO DATE`.
- Pengubah waktu tanpa konteks waktu ditolak sebelum program berjalan.

### Memeriksa angka

- `EXPLAIN Omzet AT …` menunjukkan rumus, nilai setiap bagian, dan asal setiap filter.
- `TEST "nama" … EXPECT … END TEST` menjaga angka acuan, dan `dal test` menjalankannya sekaligus.

### Analitik

Semua dihitung dalam Python murni tanpa paket tambahan, dan hasilnya sudah dicocokkan dengan numpy.

- `STATS(kolom)` atau `STATS(tabel)`: statistik deskriptif. Kuartilnya sama dengan `PERCENTILE.INC` di Excel.
- `CORRELATE(a, b)`: korelasi Pearson, juga per kelompok dengan `BY`.
- `REGRESS target ON x1, x2, kota`: regresi linear dengan p-nilai. Kolom teks menjadi variabel dummy. Hasilnya punya `.r2`, `.koefisien`, `.p_nilai`, dan `.prediksi(5, 15, "Jakarta")`.
- `FORECAST Omzet BY MONTH NEXT 6 MONTH`: memilih Holt-Winters, Holt, atau pemulusan sederhana sesuai panjang data, lengkap dengan rentang (`WITH level: 0.8`), dan memberi peringatan bila data terlalu pendek untuk pola musiman.

### Pustaka Python

```basic
USE PYTHON "statistics" AS st
USE PYTHON "math" AS m
SHOW st.median(promo.omzet)                     ' kolom dikirim sebagai daftar
LET promo.log_omzet = m.log(omzet)              ' baris demi baris
MEASURE Median = st.median(sales.nilai)         ' di dalam MODEL: ikut BY, WHERE, AT, EXPLAIN
```

### Modul dan kerja tim

- `USE "toko.dal" AS toko` memakai data, MODEL, dan fungsi dari file lain. Isinya selalu dipanggil lewat alias: `toko.Omzet`, `toko.products`, `toko.Pajak(x)`.
- Modul hanya berisi definisi, sehingga memakai modul tidak pernah menampilkan atau menyimpan apa pun. `USE` yang saling memakai ditolak.

### Ekspor

- `EXPORT Toko TO DAX`: tabel kalender, relasi, dan measure untuk Power BI. `WHERE` pada measure menjadi `KEEPFILTERS`, dan pengubah waktu menjadi `DATEADD`, `DATESINPERIOD`, atau `DATESYTD`.
- `EXPORT Omzet BY kota, YEAR TO SQL`: satu kueri `SELECT … GROUP BY` yang berjalan sama di DuckDB dan PostgreSQL.
- Measure yang tidak bisa diterjemahkan ditulis sebagai komentar beserta alasannya.

Keamanan: nilai dari program tidak pernah disambung ke teks SQL. Semua nilai dikirim sebagai parameter kueri.

## Buku dan contoh

Buku *Analisis Data dengan Dalang: Panduan lengkap dari pemula hingga mahir* membahas semua fitur di atas dalam 17 bab, dari program pertama sampai studi kasus lengkap. Folder `examples/` berisi Program Target 1–9, kasus kesalahan E1–E6, data buku (`penjualan.csv`, `produk.csv`, `bulanan.csv`, `promo.csv`), contoh modul (`toko.dal`), dan studi kasus Bab 17 (`examples/kasus/`).

## Belum didukung

Fitur berikut memberi pesan yang jelas dan program tidak dijalankan sebagian:

- `EXPORT … TO PYTHON`, `ASK`, `USE R`, dan `USING R`;
- `SORT BY` pada `SHOW` yang berisi measure (gunakan `RANK`);
- `WHERE` di akhir perintah `EXPORT` (tulis syaratnya di measure: `EXPORT (Omzet WHERE YEAR = 2025) BY MONTH TO SQL`);
- fungsi Python atas kolom bersama `BY` di luar MODEL (gunakan `MEASURE`);
- pengubah waktu yang menggeser filter periodik seperti `WHERE MONTH = 3` (gunakan `BY MONTH` atau `WHERE YEAR = …`).

## Riwayat versi

Rincian lengkap ada di file `CHANGELOG.md` di dalam paket sumber.

| Versi | Isi utama |
|---|---|
| 0.6.4 | Perbaikan dari penulisan buku: kolom yang ada diganti di tempat, fungsi Python atas kolom dan di dalam measure, `FORECAST` atas measure modul, `TOP`/`RANK` atas tabel modul, SQL yang sama di PostgreSQL, dan `dal check` untuk folder |
| 0.6.3 | Filter dari tabel tanpa `RELATE` menjadi kesalahan, dan `TOP n kolom BY measure` |
| 0.6.2 | Urutan evaluasi pengubah, `LET … AS DATE`, dan tampilan tahun |
| 0.6.1 | `dal check` mengikuti `RENAME` dan `REMOVE` |
| 0.6.0 | `dal fmt` dan `dal test` |
| 0.5.0 | Modul `.dal` dan `EXPORT … TO SQL` |
| 0.4.0 | `FORECAST`, `REGRESS`, `STATS`, dan `CORRELATE` |
| 0.3.0 | `JOIN`, `RANK`, file Excel dan Parquet, dan `EXPORT … TO DAX` |
| 0.2.0 | `MODEL`: measure yang dihitung ulang di dalam konteks |
| 0.1.0 | Rilis pertama: `LOAD CSV`, `SHOW`, `PLOT`, alur program, dan `dal check` |

## Pengembangan

```bash
pip install -e ".[dev]"
pytest
```

Tes ada di folder `tests/`, dan program di `examples/` dipakai sebagai golden test.

## Lisensi

Dalang dirilis di bawah Apache License 2.0 (lihat file `LICENSE`).
