Problem-based research

 Suatu ketika, sekitar tahun 2015, seorang kolega dosen (yang beberapa tahun kemudian menjadi kepala jurusan) ditanya oleh istrinya: Yang, apa sih yang kamu lakukan ketika menjalani S3. Sang suami berpikir sebentar, kemudian menjawab. Sederhananya begini: Saat S3 aku membuat-buat masalah sendiri, kemudian berusaha memecahkannya sendiri. Ketika aku bisa memecahkan masalah tersebut, aku mendapat gelar S3.

Jawaban sang istri mengejutkan: Nek gawe masalah dewe, terus diselesekno dewe, aku yo iso. Lapo adoh-adoh sekolah S3. Nek ngono iku ae yo gak perlu PhD.

Terinspirasi oleh dialog suami-istri tersebut, saya mencari ide penelitian berdasarkan masalah nyata. Bukan masalah yang dibuat-buat. Apakah itu “problem-based research”? Berdasarkan referensi [1], kriterianya adalah sebagai berikut:  

1. Masalahnya adalah masalah “umum”, bukan berdasarkan opini personal. Artinya, banyak orang menganggap “masalah” tersebut adalah benar-benar masalah, bukan hanya peneliti saja.

2. Bukan berdasarkan perbandingan dua data(set) saja. Artinya, tidak membandingkan (atau mencari) bahwa di dua data tersebut ada permasalahan, tapi permasalahannya benar-benar “general”, ada di dataset yang lain. Dari kriteria ini, sebaiknya riset memakai setidaknya tiga dataset. Atau, jika hanya dua dataset (minimum), ditunjukkan bahwa permasalahan ada juga di dataset yang lain meski tidak dievaluasi (berdasarkan referensi).   Contoh lainnya adalah membandingkan data sebelum dan sesudah “treatment”. Ini juga hanya pembuktian metode, bukan sebuah riset berbasis masalah.  

3. Riset berbasis masalah juga bukan karena ada korelasi antara A dan B. Lagi, apa masalahnya? Jika memang ada masalah, misalnya di A, dan solusinya ada di B, bisa jadi ini akan menyelesaikan masalah. Tapi jika ingin mengetahui korelasi A dan B, misalnya tingkat penghasilan dan konsumsi belanja, ini bukan masalah, dan hanya mencari-cari masalah saja.

4. Tujuan riset berbasis masalah bukan “Ya” dan “Tidak”, tapi menyelesaikan masalah. Misal penelitian untuk menyelesaikan masalah XXX. Tujuan penelitian bukan untuk membuktikan metode AAA bisa menyelesaikan masalah XXX, tapi untuk mengetahui mengapa dan bagaimana metode (AAA) yang diusulkan bisa menyelesaikan XXX. Bedanya, jika ternyata metode AAA belum bisa menyelesaikan masalah XXX, peneliti akan mencari metode lain yang bisa menyelesaikan XXX. Intinya, cara pandang agar sebuah masalah selesai, bukan hanya metode penelitian saja.

Referensi:  

[1] T. J. Ellis and Y. Levy, “Framework of problem-based research: A guide for novice researchers on the development of a research-worthy problem,” Informing Sci., vol. 11, pp. 17–33, 2008, doi: 10.28945/3288.

from Blogger https://ift.tt/mK2zXwF
via IFTTT

Dua tipe riset: Curiosity-driven vs. Mission oriented

Ketika membaca panduan membuat proposal yang dibuat oleh JSPS, saya menemukan pembagian tipe riset yang sangat menarik: curiosity-driven vs. mission-oriented. Pembagian ini menurut saya lebih jelas daripada pembagian yang lain (misalnya pure vs applied research). Lebih jauh, Ichiro Kanazawa menjelaskan keduanya sebagai berikut.

If we try to
identify the types of researches (to be granted), it is not promising for us to find any
resolution or settlement which can be accepted from any point of views. Under such
a circumstance, I think that the categorization (originally in English) proposed by
JSPS, i.e. “curiosity-driven researches” and “mission-oriented researches”, are
relatively plain and practical. But once we try to translate those two English
categories into Japanese, those might be “researches driven by curiosities” and
“researches to fulfill the clearly defined missions”. Then the first one, which could
be easily be transformed into “researches to gratify researchers’ curiosities”, might
then easily be recognized as researches which researchers carry on as their
pleasures. Contrary to this case, the second one could be easily accepted because of
their clear targets. Therefore, I prefer not to recommend to translate those into
Japanese. Based on this situation, I would really like to warn that we must to foster
“curiosity-driven researches”, and I am seriously worrying that, if not, no young
people of our next generation will be born, who should take over not only sciences in
Japan, but also society itself in Japan. This is my principle standpoint regarding the
Grant-in-Aid.

 

– Ichiro Kanazawa

JSPS membagi pendanaannya juga berdasarkan dua tipe riset di atas dan dua jenis pembiayaan: competitive research fund dan basic funds. Lihat gambar di bawah ini untuk lebih detailnya.

researh and fund

 Gambar tersebut menjelaskan jenis pendanaan riset berdasarkan dua sudut pandang:

  • Sumbu atas (horizontal): jenis riset

    • Kiri: Riset ilmiah berbasis ide kreatif peneliti (curiosity-driven research).

    • Kanan: Riset dan pengembangan (R&D) berbasis kebijakan/target pemerintah (mission-oriented research).

  • Sumbu kiri (vertikal): jenis pendanaan

    • Atas: Dana kompetitif (dipilih melalui open call dan review).

    • Bawah: Dana dasar (dana rutin untuk operasional dan pengelolaan institusi).

Dari kombinasi ini, ada empat kategori utama:

1️⃣ Dana Kompetitif + Riset Berbasis Ide Peneliti

👉 Research supported by Grants-in-Aid for Scientific Research (Kakenhi)

Ini adalah skema hibah kompetitif untuk riset yang lahir dari ide peneliti sendiri.

  • Peneliti mengusulkan topik bebas.

  • Proposal diseleksi melalui proses review.

  • Fokus pada pengembangan ilmu pengetahuan dasar.

Contoh di Jepang: Kakenhi (Grant-in-Aid for Scientific Research).

2️⃣ Dana Kompetitif + Riset Berbasis Misi Pemerintah

👉 Research funded by open call sesuai misi kementerian

  • Pemerintah atau kementerian menentukan tema atau target tertentu.

  • Peneliti mengajukan proposal sesuai tema tersebut.

  • Tetap melalui seleksi kompetitif.

Biasanya terkait isu strategis seperti AI, energi, kesehatan, dll.

3️⃣ Dana Dasar + Riset Berbasis Ide Peneliti

👉 Riset di universitas dan institut riset antar-universitas

  • Dibiayai dari dana operasional rutin universitas.

  • Tidak selalu melalui kompetisi proposal besar.

  • Mendukung kebebasan akademik dan riset jangka panjang.

4️⃣ Dana Dasar + Riset Berbasis Misi Pemerintah

👉 Proyek nasional yang dipimpin pemerintah

  • Proyek strategis tingkat nasional.

  • Dipromosikan dan dikelola oleh pemerintah atau badan R&D nasional.

  • Biasanya berskala besar dan jangka panjang.

Inti Pesan Gambar

Sistem pendanaan riset dibagi berdasarkan:

  1. Siapa yang menentukan arah riset?

    • Peneliti (bottom-up)

    • Pemerintah/kebijakan (top-down)

  2. Bagaimana dana diberikan?

    • Kompetitif (melalui seleksi proposal)

    • Dana dasar (alokasi rutin institusi)

Dengan memahami peta ini, kita bisa melihat posisi suatu riset:
Apakah itu murni ide akademik? Apakah mengikuti agenda nasional? Apakah didanai oleh hibah kompetitif atau dana institusi?

Untuk peneliti di Jepang, memahami struktur ini penting agar bisa menentukan strategi pendanaan yang tepat untuk risetnya. Berbeda dengan Ichiro Kanazawa-sensei di atas, saya justru mengusulkan riset  “mission-oriented”, khususnya untuk negara berkembang. Karena riset mission-oriented, jelas luaran dan tujuannya.  

from Blogger https://ift.tt/5W8r1HQ
via IFTTT

Numpy Tingkat Lanjut

Ada beberapa perintah untuk menaikkan skill pemrograman Python Numpy (dan Scipy) ke level lanjut. Jika Anda (termasuk saya) paham dan bisa menginterpretasikan output perintah tersebut, maka kita sudah siap naik ke level Numpy selanjutnya. Beberapa perintah tersebut adalah sebagai berikut.

1. Blok Memory (np.nbytes)

Sering kali kita hanya fokus pada bentuk (shape) array, namun melupakan “berat”nya. Perintah `np.nbytes` menginformasikan berapa banyak memori RAM yang sebenarnya kita pakai.  Seseorang yang paham bahwa mengubah tipe data (dtype) dari float64 ke float32 bisa memangkas konsumsi memori hingga 50%, yang berarti mempercepat proses komputasi secara drastis. Di sini, kita belajar bahwa array bukan sekadar wadah angka, tetapi blok memori yang harus dikelola secara efisien.
Contoh: 
import numpy as np

a = np.zeros((1000, 1000), dtype=np.float64)
print(a.nbytes)
# Karena float64 = 8 byte, maka total memori:
# 1000 x 1000 x 8 byte = 8.000.000 byte (~8 MB)
Konsep penting:
  • Ukuran memori = jumlah elemen × ukuran tipe data.
  • Mengganti float64 ke float32 langsung mengurangi memori setengahnya.
  • Pada skala besar (misalnya deep learning atau audio processing), ini sangat krusial.
Jika kita tidak sadar ukuran memori, kita akan mudah “membunuh” RAM sendiri.

2. Stride

Jika nbytes adalah beratnya, maka stride adalah cara kita melangkah di atas memori tersebut. Stride menentukan berapa byte yang harus “diloncati” komputer untuk menuju ke elemen berikutnya di setiap dimensi. Stride adalah jarak (dalam byte) yang harus dilompati untuk berpindah ke elemen berikutnya pada setiap dimensi. Konsep inilah yang menjawab misteri mengapa operasi transpose pada array besar bisa sangat cepat. Karena Numpy tidak benar-benar memindahkan data di memori; ia hanya mengubah pola langkah (stride) tersebut. Memahami stride berarti memahami bagaimana komputer “melihat” data array secara linear di dalam RAM.

Contoh:

a = np.arange(12).reshape(3, 4)  
print(a.strides)  
# Jika dtype=int64 (8 byte), kemungkinan output:
(32, 8)

Artinya:

  • Untuk pindah ke baris berikutnya → lompat 32 byte (4 kolom × 8 byte).
  • Untuk pindah ke kolom berikutnya → lompat 8 byte.

Ini penting karena:

  • Operasi transpose (a.T) sering tidak membuat copy data, hanya mengubah stride.
  • Pemahaman stride membantu kita tahu kapan NumPy membuat copy atau hanya view. 
  • Dalam optimasi performa, akses memori yang kontigu jauh lebih cepat. 

Stride adalah jembatan antara konsep matematis array dan realitas fisik memori.

3. Broadcasting

Broadcasting adalah seni “mengada-ada” secara efisien. Broadcasting memungkinkan operasi antara array dengan ukuran yang berbeda tanpa perlu menyalin data secara fisik untuk menyamakan ukurannya. Misalnya, menjumlahkan array (3,3) dengan vektor (3,) secara otomatis. Seorang programmer biasa mungkin akan melakukan looping atau padding manual, tetapi level “Dewa” membiarkan Numpy melakukan broadcasting internal yang jauh lebih cepat karena terjadi di level C. Kita hemat memori, kita hemat waktu.
Contoh:
a = np.array([[1], [2], [3]])
b = np.array([10, 20, 30])

c = a + b

Secara mental:

  • a bentuk (3,1)
  • b bentuk (3,)
  • NumPy “membentangkan” dimensi agar cocok → hasil (3,3)

Tanpa broadcasting, kita harus membuat array besar secara manual. Dengan broadcasting:

  • Kode lebih ringkas
  • Lebih hemat memori
  • Lebih cepat

Kunci memahami broadcasting:

  • Dimensi dibandingkan dari kanan ke kiri
  • Ukuran cocok jika sama atau salah satunya 1

Kalau ini sudah bisa kita prediksi tanpa menjalankan kode, berarti otak kita sudah mulai “NumPy-native”.

4. Fancy Indexing

Fancy indexing adalah indexing menggunakan array atau list indeks. Berbeda dengan slicing biasa yang menghasilkan view (tampilan tanpa menyalin data), Fancy Indexing selalu menghasilkan copy (data baru). Memahami perbedaan ini krusial agar kita tidak membludakkan memori secara tidak sengaja saat memproses data besar.

Contoh:

a = np.array([10, 20, 30, 40])
idx = [0, 2]
print(a[idx])
[10 30]

Perbedaan penting:

  • Slice (a[1:3]) → biasanya view (tidak copy)
  • Fancy indexing → selalu membuat copy

Ini sangat penting untuk:

  • Mengontrol penggunaan memori
  • Menghindari bug akibat modifikasi data yang tidak disengaja

Misalnya:

b = a[idx]
b[0] = 999

Di sini, a tidak akan berubah karena b adalah copy.
Kalau kita tidak memahami ini, kita bisa salah kaprah saat debugging.

5. Vectorization

Vectorization adalah teknik menghilangkan loop eksplisit (perulangan for di Python) dan menggantinya dengan operasi array tunggal. Loop Python lambat karena interpretasi per-baris, namun operasi vektor Numpy terjadi di level kompilasi C/Fortran yang sangat cepat. Ketika kita memahami Broadcasting, Stride, dan Memory, Vectorization menjadi senjata utama untuk membuat kode berjalan 10x hingga 100x lebih kencang.

Berikut contoh penggunaan vektorisasi untuk menggantikan perulangan for.
Perulangan for:

result = []
for x in a:
    result.append(x * 2)

Vektorisasi:

result = a * 2

Kenapa jauh lebih cepat? Loop Python berjalan di level interpreter (lambat). Operasi NumPy berjalan di C (cepat). Akses memori lebih efisien. Vectorization bukan sekadar “gaya”, tapi filosofi berpikir: Berpikir dalam bentuk operasi matriks, bukan iterasi elemen.

 

Perlu diingat, bagian terpenting adalah memahami konsep array dengan perintah di atas pada tataran level otak kita, bukan simulasi komputer. Artinya, kita bisa menebak output dari komputer (simulasi/Python Numpy) dengan otak kita dan memahaminya. Bukan asal mensimulasikan array, meskipun bisa menebak hasilnya. Inilah yang terpenting: ilmu sebelum beramal.

Referensi: 

from Blogger https://ift.tt/SDT6Gl2
via IFTTT

Interval walking di musim dingin

Interval Walking Training (IWT), atau yang dikenal sebagai teknik berjalan interval, merupakan cara sederhana namun sangat efektif untuk meningkatkan kesehatan: cukup bergantian antara jalan cepat (fast walking) dan jalan lambat (slow walking) dalam sesi sekitar 30 menit, misalnya 5 menit cepat lalu 5 menit lambat secara bergiliran. Berbeda dengan jalan biasa, metode asal Jepang ini telah dibuktikan secara ilmiah melalui berbagai studi besar—melibatkan ribuan partisipan—mampu mengontrol kadar gula darah pada penderita diabetes, menurunkan tekanan darah, mengurangi risiko stroke, serta memperbaiki kondisi hipertensi, gejala depresi, kualitas tidur, dan kekuatan fisik secara keseluruhan, termasuk peningkatan kapasitas aerobik serta kekuatan otot kaki yang lebih unggul dibandingkan jalan konstan. Kini, IWT semakin populer di seluruh dunia dan bahkan mulai diintegrasikan ke dalam program rehabilitasi jantung (cardiac rehabilitation) dengan pemantauan jarak jauh, menjadikannya solusi praktis, aman, dan mudah diikuti bagi siapa saja yang ingin hidup lebih sehat tanpa peralatan mahal atau gym. 

Bagaimana memanfaatkan IWT pada musim dingin? 

Secara tidak sengaja, saya “menemukan” metode IWT dengan memanfaatkan dinginnya musim dingin. Setiap hari ketika bekerja, saya butuh berjalan kaki ke tempat sholat, berpindah gedung. Nah, di saat keluar dari gedung saya dengan udara yang lebih dingin daripada di dalam gedung, saya mempercepat jalan saya, dengan harapan segera masuk ke gedung lain sekaligus menambah pergerakan agar badan lebih hangat. Ketika masuk gedung lain, saya memperlambat kecepatan jalan saya. Ini yang saya maksud dengan IWT di musim dingin. Singkatnya:

  • Indoor: jalan lambat
  • Outdoor: jalan cepat
Tidak hanya di musim dingin, IWT indoor (lambat)-outdoor (cepat) tersebut juga tidak sengaja saya praktekkan di musim yang lain. Mungkin sudah terbiasa. Suatu ketika teman saya berkata kalau di luar gedung jalan saya cepat sekali.

from Blogger https://ift.tt/gLSQAY9
via IFTTT

Fix Japanese garbled character

 To fix garbled Japanese characters, use the `nkf` command. You need to install it first since it is usually not available by default in most Linux platforms. Then, using the following command to convert its encoding (detected by default) to a readable one.   

$ nkf old_file.txt > new_file.txt 

An example of output is below.

from Blogger https://ift.tt/efxNAI6
via IFTTT

Permasalahan smartwach (The problem with smartwatch)

Saya menyukai memakai jam, dengannya saya bisa tahu waktu. Utamanya waktu untuk sholat dan melakukan aktivitas lainnya. Dengan adanya smartwatch, tidak hanya waktu saja informasi yang saya dapatkan, melainkan lama tidur, detak jantung, dan jumlah langkah (step tracker). Informasi itu sangat bermanfaat. Misalnya, dalam sehari saya menargetkan tidur tujuh jam, jika kurang dari itu (informasi dari smartwatch), saya bisa menambah jam tidur saya. Sebaliknya, jika siang/sore saya sudah tidur 1-2 jam, maka malamnya saya bisa tidur lebih singkat. 

Begitu juga untuk langkah kaki, kalau saya menargetkan tiap harinya harus berjalan 7000 langkah, jika kurang saya bisa menambahnya. Bahkan, saya bisa merangkum data-data itu, seperti yang saya jelaskan di sini: 

https://bagustris.blogspot.com/2021/05/data-jalan-kaki-tidur-dan-detak-jantung.html

Tapi ada satu permasalahan besar pada smartwatch. Apa itu? Sangat tidak masuk akal bagi saya jika saya harus mengisi daya (charge) smartwatch tersebut tiap minggu. Karenanya, dua smartwatch yang saya pakai sebelumnya berdaya tahan lama, Xiaomi Band 4 dan Amazfit Band 7. Keduanya memiliki rentang hidup (lifetime) selama kurang lebih tiga-empat minggu (21-28 hari) untuk sekali isi daya dengan mode power saver. 

Saat ini saya tidak memakai smartwatch lagi, hanya Casio yang memiliki fitur step tracker yang bisa bertahan 10 tahun tanpa diisi daya, cukup mengganti baterainya. Saat itu saya sedang dalam perjalanan selama tiga minggu, dan saya mengandalkan smartwatch untuk bisa bertahan sepanjang waktu itu. Ternyata kapasitasnya menurun, baru dua minggu sudah mati, dan saya tidak membawa kabel pengisian dayanya. Saat itu juga saya beralih ke jam tangan yang tidak perlu diisi daya, tahan lama, memiliki fitur step tracker, dual time, dan fitur-fitur lainnya.  

from Blogger https://ift.tt/9zSpZWm
via IFTTT

Khatam dalam 28 hari

 
Sejak menerapakan One Day One Juz (ODOJ) beberapa tahun terakhir, saya berusaha untuk mencari cara yang lebih efektif. Dengan “lebih efektif” yang saya maksudkan adalah konsistensi dalam beberapa hal, misalnya:

  • Memulai dan mengakhiri (khatam) pada hari tertentu, misalnya mulai pada hari Senin, khatam pada hari Sabtu (bukan dalam seminggu, setikdaknya pada saat ini)
  • Bisa membaca Al-Kahfi dan/atau Yaasin pada hari Jumat, tidak harus tiap Jumat.
Akhirnya, saya menemukan formula seperti gambar di bawah: khatam dalam dua puluh delapan hari (empat minggu pas). Mulai Juz 1 pada hari Sabtu, dan khatam pada hari Jumat di minggu ke empat. Dengan cara ini setidaknya dalam sebulan s(tepatnya empat minggu) saya membaca surah Al-Kahfi dan Yaasin pada hari Jumat setidaknya sekali. Biasanya saya membaca setelah subuh; jadi pada mingu ke dua saya membaca Al-Kahfi dan Yaasin di pagi hari. Terkadang saya membaca dua juz dalam sehari. Satu juz setelah subuh, dan satu juz menjelang tidur. Misalnya pada minggu ke dua di hari kamis, saya membaca juz 13 di pagi hari, dan juz 14 di malam hari. Begitu juga di hari Jumat minggu ke empat. Juz 29 setelah subuh, dan juz 30 sebelum tidur.
Semoga formula ini tidak hanya bermanfaat untuk saya, tapi  bisa diterapkan oleh orang lain.
Khatam 28 hari

from Blogger https://ift.tt/aVvnELb
via IFTTT

TODO after installing Ubuntu

This is to document what I must have done after Installing Ubuntu on new PC or laptop. I am an Ubuntu loyal user since 2009 and never changed to other OS. To be expert, you need to focus on one thing. This also applies when choosing operating system for your computer.

Recently, I received a PC with RTX5090 for work. I asked student to install Ubuntu 24.04. After it was installed, I need to make it to suit my workflow. Here is what I have done after installing Ubuntu 24.05.

TODO (as per December 2025), i.e., to Install; 

  1. VScode
  1. VSCode extensions: Python, Pylance, Copilot, Ampcode, etc.
  2. gh (Github CLI): sudo snap install gh 
  3. Swith default git editor to VIM 
  • Simplenote
  • Mendeley (install via flatpak)
  • Diodon (for clipboard management)
  • Gnome-sushi (for [audio] preview)
  • Optionals:  

    1. Multipass
    2. Mozc (to enable Japanese characters

    Previously when I installed Ubuntu on a new device, I make a lot of modifications: themes, icon, etc. (more complete list: http://bagustris.blogspot.com/p/download.html) . Now, default should be the best. If nothing work, then modification is needed. If there is no problem, no need to change default. Minimal installation, maximum speed.

    from Blogger https://ift.tt/7JBc1oE
    via IFTTT

    Kriteria memilih pekerjaan

    Dari diskusi dengan seorang teman, dia memiliki tiga kriteria untuk memilih pekerjaan. Ketiga kriteria tersebut adalah:

    1. Make sense
    2. Make money
    3. You love it!
    Pertama, pekerjaan kita haruslah masuk akal, logis. Artinya pekerjaan kita itu dibutuhkan dan kita benar-benar bekerja. Adakah pekerjaan yang tidak masuk akal? Ada, contohnya influencer abal-abal, youtuber sembarangan. Apa urgensinya pekerjaan itu?

    Kriteria kedua pekerjaan kita haruslah menghasilkan uang (yang cukup). Adakah pekerjaan yang tidak menghasilkan uang? Ada, semua yang berlabel “pro bono” tidak menghasilkan uang karena pekerjaan tersebut adalah voluntary.

    Ketiga adalah anda menyukainya. Ada peribahasa “If you are not doing what you love, you are wasting your time”. Pepatah ini benar adanya. Jika anda tidak menyukai pekerjaan anda sekarang, anda harus secepatnya mencari pekerjaan baru.

    Bagaimana dengan kriteria lain seperti “halal”? Otomatis, tidak mungkin (contohnya sebagai seorang muslim) anda menyukai pekerjaan yang tidak halal meskipun itu menghasilkan banyak uang.

    from Blogger https://ift.tt/cuPQ6Ud
    via IFTTT

    Filter emboss (dari PIL): kenapa bagian yang berwarna gelap tidak di-emboss

    Iseng-iseng, saya mencoba menggunakan filter emboss pada ijasah S1 (versi Inggris) saya. Di luar dugaaan, filter embos tidak muncul pada jas yang saya pakai.

    Kode yang saya gunakan:

    from PIL import Image, ImageFilter
    import matplotlib.pyplot as plt
    
    img = Image.open('/mnt/data/ijasah_s1_bta_eng.png')
    emboss = img.filter(ImageFilter.EMBOSS)
    
    plt.imshow(emboss)
    plt.axis('off')
    
    

    Hasil: 

    Alasan kenapa emboss tidak muncul:
    • Tinta berwarna (misalnya merah atau biru) dan warna jas memiliki nilai luminance yang hampir sama (fenomena color blending by luminance contrast);
    • Perbedaan kontrasnya sangat kecil (tinta menyerap cahaya secara berbeda, stempel tampak memudar atau bahkan “hilang”);
    • Emboss tidak dapat menonjolkannya;
    • Menunjukkan fenomena optik normal pada stempel di atas area gelap (optik‐low‐visibility).

    from Blogger https://ift.tt/qrloDHd
    via IFTTT