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.
This is to document what I must have done after installing Ubuntu on a new PC or laptop. I have been a loyal Ubuntu user since 2009 and never changed to another OS. To be an expert, you need to focus on one thing. This also applies when choosing an operating system for your computer.
Recently, I received a PC with RTX5090 for work. I asked the student to install Ubuntu 24.04. After it was installed, I needed to make it suit my workflow. Here is what I have done after installing Ubuntu 24.05.
Previously when I installed Ubuntu on a new device, I made a lot of modifications: themes, icons, etc. (more complete list: https://bagustris.blogspot.com/p/download.html) . Now, default should be the best. If nothing works, then modification is needed. If there is no problem, there is no need to change the default. Minimal installation, maximum speed.
Dulu saya pernah bertanya-tanya, adakah platform atau aplikasi note-taking yang sederhana, aplikasi tersebut hanya bersifat aplikasi (seperti word processor) namun filenya disimpan dalam file teks sederhana seperti text (TXT) dan markdown (MD)? Bukan menyatu dengan aplikasi seperti Google Keep atau Evernote (bukan app-over-file tapi file-over-app). Ternyata ada, dan saya pernah mencobanya. Dulu saya saya tidak melanjutkan mencobanya karena apa yang saya cari tersebut tidak ketemu, ternyata memang ada. Ketidaktahuan saya memblokade penggunaan aplikasi tersebut waktu itu. Aplikasi itu adalah Obsidian.
Setelah menggunakan evernote, kemudian pindah ke Google Keep, dan Simplenote, ada beberapa perubahan mendasar yang saya alami. Versi free dari evernote memiliki kemampuan terbatas. Google Keep kemudian mematikan versi luring (offline) sehingga saya tidak bisa melihat catatan saya lewat PC ketika tidak bisa konek internet. Simplenote menjadi second brain bagi saya, namun, ketika catatan saya bertambah banyak dan saya menginginkan catatan terstruktur (linked-notes, notes in note), simplenote menjadi terbatas. Saya pernah mencoba Obsidian sekitar beberapa tahun yang lalu, namun apa yang saya cari (sync dan structured notes) tidak saya temukan karena ketidaktahuan saya.
Organisasi Obsidian (vaults)
1. Diary -- untuk catatan harian
2. Fiksi -- untuk mencatat kisah fiksi, seperti draft cerpen atau novel
3. Non-fiksi -- untuk catatan non-fiksi
4. Google keep -- archive dari Google Keep yang saya export ke Obsidian
5. Pengajian -- catatan pengajian dll., ada plugin Quran juga.
Demikian, Obsidian telah menjadi otak keempat saya setelah simplenote dan Standard Notes.
Akhirnya, ada platform offline dan online dalam satu portal. Dan platform itu ternyata sudah ada sejak lama. Namanya Standard Notes. Bisa diinstal via snap dengan perintah berikut di Ubuntu.
sudo snap install standard-notes
Saya suka menulis blog, baik itu di blogger, wordpress, medium, atau tumblr. Masalahnya, sejauh pengetahuan saya saat itu, belum ada platform digital yang bisa berlaku baik untuk offline dan online. Misalnya, saat saya punya ide, saya menuliskannya di editor, word processor, atau note taking app. Kemudian saat saya ingin mempublikasikannya, saya salin tulisan offline tadi ke platform blog yang bersangkutan, misalnya Blogger. Sampai saya menemukan platform/aplikasi Standard Notes yang menyatu dengan listed.to.
Dengan platfom ini saya bisa menulis blog on-the-go secara luring, kemudian mempublikasikannya dari perangkat tersebut tanpa harus menyalin dan menempelnya ke internet. Cukup sekali-dua kali klik. Bagi anda yang belum tahu caranya, berikut cara publikasi blog lewat Standard Notes and Listed (www.listed.to).
1. Buka Stantard Notes app atau web app 2. Klik ikon Preferences in sisi kanan bawah 3. Buka seksi Listed 4. Pilih Create New Author
Untuk publikasi dari Standard Notes ke Listed (lihat gambar di bawah). 1. Klik kanan judul note yang akan dipublish 2. Pilih "Listed action" kemudian pilih "Publih to Blog"
Voilla, sekarang catatan datam Standard Notes tersebut telah terpublish dalam Listed.to.
Karena kemudahan itu, besar kemungkinan saya akan mengeblog di Listed. Blog di blogspot ini mungkin akan dormant, wallahua'lam. Saya belum tahu pastinya, mungkin topik-topik professional akan saya taruh disini, catatan harian di Listed, dan quotes di Tumblr.
Dengan demikian, Standard Noted menjadi otak ketiga saya setelah simplenote.
Are you interested in visualizing live audio data from your microphone? Do you want to see the waveform of your voice or any other sound in real time? In this blog post, we’ll explore a Python script that utilizes Matplotlib to plot live microphone signals. This script is a useful tool for understanding and analyzing audio input in real time.
Before we begin, make sure you have sounddevice, Matplotlib, and NumPy installed. If not, you can install them using the following command:
pip install matplotlib numpy sounddevice
Now, let’s dive into the code and see how it works.
The Code
#!/usr/bin/env python3"""Plot the live microphone signal(s) with matplotlib.Matplotlib and NumPy have to be installed."""import argparseimport queueimport sysfrom matplotlib.animation import FuncAnimationimport matplotlib.pyplot as pltimport numpy as npimport sounddevice as sd
The script starts with the usual shebang (#!/usr/bin/env python3) and a brief docstring explaining the purpose of the code. It also imports the necessary modules: argparse, queue, sys, FuncAnimation from matplotlib.animation, plt (alias for matplotlib.pyplot), numpy, and sounddevice.
Next, the code defines two helper functions and two main functions.
def int_or_str(text):"""Helper function for argument parsing."""try:returnint(text)exceptValueError:return textdef audio_callback(indata, frames, time, status):"""This is called (from a separate thread) for each audio block."""if status:print(status, file=sys.stderr)# Fancy indexing with mapping creates a (necessary!) copy: q.put(indata[::args.downsample, mapping])
The int_or_str function is a helper used for parsing command-line arguments. It tries to convert the input text to an integer and returns it if successful; otherwise, it returns the input text as it is.
The audio_callback function is called for each audio block received from the microphone. It receives indata (the audio data), frames (the number of frames), time (the timestamp of the audio data), and status (the status of the audio stream). It prints any status messages to the standard error and puts a copy of the audio data (filtered using downsampling and channel mapping) into a queue (q) for processing later.
def update_plot(frame):"""This is called by matplotlib for each plot update. Typically, audio callbacks happen more frequently than plot updates, therefore the queue tends to contain multiple blocks of audio data. """global plotdatawhileTrue:try: data = q.get_nowait()except queue.Empty:break shift =len(data) plotdata = np.roll(plotdata, -shift, axis=0) plotdata[-shift:, :] = datafor column, line inenumerate(lines): line.set_ydata(plotdata[:, column])return lines
The update_plot function is called by Matplotlib for each plot update. It retrieves audio data from the queue (q) and shifts the existing data to accommodate the new audio block. The function then updates the y-data of the lines on the plot with the new audio data.
if__name__=="__main__":# ... (continued in the next code block)
The script uses the standard Python if __name__ == "__main__": guard to ensure that the following code is only executed when the script is run directly, not when it’s imported as a module.
parser = argparse.ArgumentParser(add_help=False) parser.add_argument('-l', '--list-devices', action='store_true',help='show list of audio devices and exit') args, remaining = parser.parse_known_args()if args.list_devices:print(sd.query_devices()) parser.exit(0)
The code sets up an argument parser with argparse to handle command-line arguments. It allows the user to list available audio devices and exit the program without running the main functionality. If the user specifies the --list-devices flag, the script will print a list of audio devices using sd.query_devices() and then exit.
parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter, parents=[parser]) parser.add_argument('channels', type=int, default=[1], nargs='*', metavar='CHANNEL',help='input channels to plot (default: the first)') parser.add_argument('-d', '--device', type=int_or_str,help='input device (numeric ID or substring)') parser.add_argument('-w', '--window', type=float, default=200, metavar='DURATION',help='visible time slot (default: %(default)s ms)') parser.add_argument('-i', '--interval', type=float, default=30,help='minimum time between plot updates (default: %(default)s ms)') parser.add_argument('-b', '--blocksize', type=int, help='block size (in samples)') parser.add_argument('-sr', '--samplerate', type=float, default=16000, help='sampling rate of audio device') parser.add_argument('-n', '--downsample', type=int, default=1, metavar='N',help='No downsample (default: %(default)s)') args = parser.parse_args(remaining)
The script creates another argument parser, this time with a description based on the script’s docstring. It defines several command-line arguments:
channels: The channels to plot. If not specified, it will default to the first channel.
device: The input audio device to use. It can be specified either by a numeric ID or a substring of the device name.
window: The visible time slot in milliseconds. This controls how much of the audio history is displayed on the plot.
interval: The minimum time between plot updates in milliseconds.
blocksize: The block size (number of samples) for audio processing. If not specified, the default block size of the audio stream will be used.
samplerate: The sampling rate of the audio device. If not specified, it will default to 16000 Hz.
downsample: The factor by which the audio data is downsampled. By default, no downsampling is applied.
The parse_args method is called to parse the remaining command-line arguments (remaining) after handling the --list-devices option.
ifany(c <1for c in args.channels): parser.error('argument CHANNEL: must be >= 1') mapping = [c -1for c in args.channels] # Channel numbers start with 1 q = queue.Queue()
The code checks if any of the specified channels are less than 1. If so, it raises an error with an appropriate message. It then creates a mapping list for the channel indices, as the channel numbers in args.channels start from 1.
Full code is listed below. Actually, it is based on an example from sounddevice documentation [1].
#!/usr/bin/env python3
"""Plot the live microphone signal(s) with matplotlib.
Matplotlib and NumPy have to be installed.
"""
import argparse
import queue
import sys
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
import numpy as np
import sounddevice as sd
def int_or_str(text):
"""Helper function for argument parsing."""
try:
return int(text)
except ValueError:
return text
def audio_callback(indata, frames, time, status):
"""This is called (from a separate thread) for each audio block."""
if status:
print(status, file=sys.stderr)
# Fancy indexing with mapping creates a (necessary!) copy:
q.put(indata[::args.downsample, mapping])
def update_plot(frame):
"""This is called by matplotlib for each plot update.
Typically, audio callbacks happen more frequently than plot updates,
therefore the queue tends to contain multiple blocks of audio data.
"""
global plotdata
while True:
try:
data = q.get_nowait()
except queue.Empty:
break
shift = len(data)
plotdata = np.roll(plotdata, -shift, axis=0)
plotdata[-shift:, :] = data
for column, line in enumerate(lines):
line.set_ydata(plotdata[:, column])
return lines
if __name__ == "__main__":
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument(
'-l', '--list-devices', action='store_true',
help='show list of audio devices and exit')
args, remaining = parser.parse_known_args()
if args.list_devices:
print(sd.query_devices())
parser.exit(0)
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[parser])
parser.add_argument(
'channels', type=int, default=[1], nargs='*', metavar='CHANNEL',
help='input channels to plot (default: the first)')
parser.add_argument(
'-d', '--device', type=int_or_str,
help='input device (numeric ID or substring)')
parser.add_argument(
'-w', '--window', type=float, default=200, metavar='DURATION',
help='visible time slot (default: %(default)s ms)')
parser.add_argument(
'-i', '--interval', type=float, default=30,
help='minimum time between plot updates (default: %(default)s ms)')
parser.add_argument(
'-b', '--blocksize', type=int, help='block size (in samples)')
parser.add_argument(
'-sr', '--samplerate', type=float, default=16000, help='sampling rate of audio device')
parser.add_argument(
'-n', '--downsample', type=int, default=1, metavar='N',
help='No downsample (default: %(default)s)')
args = parser.parse_args(remaining)
if any(c < 1 for c in args.channels):
parser.error('argument CHANNEL: must be >= 1')
mapping = [c - 1 for c in args.channels] # Channel numbers start with 1
q = queue.Queue()
try:
if args.samplerate is None:
device_info = sd.query_devices(args.device, 'input')
args.samplerate = device_info['default_samplerate']
length = int(args.window * args.samplerate / (1000 * args.downsample))
plotdata = np.zeros((length, len(args.channels)))
fig, ax = plt.subplots()
lines = ax.plot(plotdata)
if len(args.channels) > 1:
ax.legend([f'channel {c}' for c in args.channels],
loc='lower left', ncol=len(args.channels))
ax.axis((0, len(plotdata), -1, 1))
ax.set_yticks([0])
ax.yaxis.grid(True)
ax.tick_params(bottom=False, top=False, labelbottom=False,
right=False, left=False, labelleft=False)
ax.text(0.01, 0.99, f'Sample rate: {args.samplerate/args.downsample} Hz', transform=ax.transAxes, va='top', ha='left')
fig.tight_layout(pad=0)
stream = sd.InputStream(
device=args.device, channels=max(args.channels),
samplerate=args.samplerate, callback=audio_callback)
ani = FuncAnimation(fig, update_plot, interval=args.interval, blit=True)
with stream:
plt.show()
except Exception as e:
parser.exit(type(e).__name__ + ': ' + str(e))
Save it as sd_plot_input.py (or whatever name.py) and run it with the following commands. See the video above for the sample output.
Setelah upgrade ke kernel 5.19, terjadi masalah "screen flickering" pada Laptop (kantor) saya, Dell XPS 9320. Padahal laptop ini adalah certified hardware, Link: https://ubuntu.com/certified/202112-29761. Hanya saja Canonical sudah berdalih, karena saya membelinya dengan pre-installed Windows (11), bukan Ubuntu.
...Standard images of Ubuntu may not work well, or at all. (https://ubuntu.com/certified/202112-29761)
Karena menyebabkan sakit mata jika screen flickering ini dibiarkan, saya mencari solusinya. Biasanya ini adalah permasalahan yang disebabkan karena update kernel, dan benar saja AskUbuntu memberikan jawaban yang serupa:
Untuk mengecek kernel di Ubuntu, saya menggunakan perintah berikut.
$ uname -a
Linux bagus-XPS-9320 linux-image-5.19.0-46-generic #6-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 24 18:24:09 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Permasalahannya ada di kernel 5.19 yang saya gunakan tersebut.
Untuk melihat list kernel yang tersedia bisa dengan cara berikut (bisa juga lewat Advanced options saat booting).
Solusinya adalah mengganti kernel. Cara pertama untuk mengetes solusi ini adalah reboot dan masuk ke Advanced options dan memilih kernel lain (dalam hal ini 6.1) dan cek apakah screen flickering masih terjadi.
Cara kedua adalah dengan mengganti kernel 5.19 menjadi 6.1 by-default secara otomatis. Ini adalah yang saya gunakan, tapi carannya beda dengan cara yang diterangkan oleh AskUbuntu di atas (tapi didapat dari AskUbuntu lainnya [2]).
Pertama back-up file grub.
sudo cp /etc/default/grub /etc/default/grub.bak
Kedua edit `LINUX_DEFAULT=0` menjadi kernel yang dituju. Dalam hal ini saya menggunakan menu "Advanced options for Ubuntu" dan kernelnya, digabung dengan tanda ">". Berikut isi grub saya. Perhatikan dua baris teratas, baris pertama adalah konfigurasi lama (dikomen) dan baris kedua adalah konfigurasi baru.
$ sudo vim /etc/default/grub
#GRUB_DEFAULT=0
GRUB_DEFAULT="Advanced options for Ubuntu>Ubuntu, with Linux 6.1.0-1006-oem"
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX=""
#GRUB_CMDLINE_LINUX_DEFAULT="i915.enable_dc=0 intel_idle.max_cstate=2"
Terakhir adalah update-grub
$ sudo update-grub
Dan reboot laptop. Setelah sekian lama mengetik tulisan ini, screen flickering tidak terjadi.
Multipass is a game changer. It looks like a virtual environment for python or a virtual box for OS, but for Ubuntu instances only (the hosts can be Windows and MacOS). This short writing documented my effort to enable the installation of TexLive 2022 for adding IEEE header and footer for camera-ready APSIPA 2022.
$ wget https://www.apsipa2022.org/APSIPA_ASC_2022_Template.zip
$ sudo apt install unzip
$ unzip APSIPA_ASC_2022_Template.zip
$ cd APSIPA_ASC_2022_Template/Latex
$ pdflatex PaperSample_Guideline_tex.tex
...
Output written on PaperSample_Guideline_tex.pdf (3 pages, 126525 bytes).
Transcript written on PaperSample_Guideline_tex.log.
That's all. For 20.04, it will throw to an infinite recursion loop due to the lower fancy version. The only solution is to install newer Latex on Ubuntu 22.04 under multipass. For real cases, you may need to mount your local directory (which contains TEX files) to an instance with `multipass mount`.
Setelah sekian lama ingin mencoba docker, kali ini saya benar-benar mencobanya. Selama ini saya bisa menghindari docker karena venv dan conda tidak pernah gagal. Karena kali ini conda gagal mendukung GPU di tensorflow 1.15, maka mau tidak mau Docker menjadi solusi terbaik.
Gambar 1. Diagram alir ketika venv gagal, berlanjut ke conda, berlanjut ke docker. Selama venv berhasil membuat environment yang diinginkan saya akan memakainya sebagai pilihan pertama, jika tidak baru mencoba conda dan docker, secara bertahap.
Docker Untuk Menginstall Software (Paket/Library) Baru
Sampai saat ini saya masih memakai Ubuntu 16.04 untuk laptop-laptop pribadi dan Ubuntu 20.04 untuk laptop-laptop kantor. Permasalahan pada OS lama adalah kegagalan untuk menginstall software versi baru. Kasus saya adalah menginstall paket opensmile python versi terbaru (versi 2.4.1) yang membutuhkan library glibc di atas versi 2.31. Library glibc ini tidak bisa diupate. Pernah sekali saya mengupdatenya dan system saya (Centos 7) langsung rusak dan harus install ulang. Docker adalah solusinya.
# asumsi docker sudah terinstall
$ docker run -it ubuntu bash
# jika ada masalah permission, lakukan: sudo chmod 666 /var/run/docker.sock
$ apt update
$ apt install python3
$ apt install python3-pip
$ python3 -m pip install opensmile
$ apt install libsndfile1 libsndfile1-dev
$ apt install sox
$ apt insalll ffmpeg
root@6e7dd3cbfee1:/# python3
Python 3.8.10 (default, Mar 15 2022, 12:22:08)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import opensmile
>>> opensmile.__version__
'2.4.1'
>>> exit()
root@6e7dd3cbfee1:/# ldd --version ldd
ldd (Ubuntu GLIBC 2.31-0ubuntu9.7) 2.31
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
Menyimpan file docker dengan commit
Docker tidak didesain untuk menyimpan file, untuk menyimpan file (dan perubahan/update) dari docker
yang sedang berjalan dan docker-docker sebelumnya gunakan perintah commit berikut.
Format:
docker commit CONTAINER_ID IMAGE
$ docker ps -a # bisa juga dengan ps -l untuk docker yang sedang berjalan
$ dokcer commit ef7d7090e3c7 ubuntu:opensmile
Docker Untuk Menginstall Software Lama (Tensorflow 1.15 dengan GPU support)
Skenario:
Saya ingin menjalankan kode di repository berikut: Efficient Bigan, dengan GPU RTX 3090, yang
saat itu (saat repo itu dibuat dengan tensorflow 1.15) belum diproduksi.
Solusi:
# asumsi docker belum terinstall
$ sudo apt install docker.io
$ curl https://get.docker.com #install curl jika belum ada
$ sudo systemctl --now enable docker
$ distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
&& curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | sudo apt-key add - \
&& curl -s -L https://nvidia.github.io/libnvidia-container/$distribution/libnvidia-container.list | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
$ sudo apt update
$ docker images # list images docker
REPOSITORY TAG IMAGE ID CREATED SIZE
nvcr.io/nvidia/tensorflow 22.04-tf1-py3 8b2abbd886f0 2 years ago 9.51GB
$ docker run --gpus all -it --rm nvcr.io/nvidia/tensorflow:22.04-tf1-py3
$ git clone https://github.com/houssamzenati/Efficient-GAN-Anomaly-Detection.git
$ cd Efficient-GAN-Anomaly-Detection
$ python3 main.py gan mnist run --nb_epochs=10 --label=0
______ _____ _____ ____
|_ `.|_ _| / ___ `. .' '.
| | `. \ | | |_/___) | | .--. |
| | | | | | _ .'____.' | | | |
_| |_.' /_| |__/ | / /_____ _| `--' |
|______.'|________| |_______|(_)'.____.'
[09:48:37 INFO @AnomalyDetection] Running script at gan.run_mnist
2022-03-30 09:48:37.916727: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudart.so.11.0
[09:48:37 WARNING @tensorflow] Deprecation warnings have been disabled. Set TF_ENABLE_DEPRECATION_WARNINGS=1 to re-enable them.
[09:48:38 WARNING @tensorflow] From /TA/demo/Efficient-GAN-Anomaly-Detection/gan/run_mnist.py:4: The name tf.ConfigProto is deprecated. Please use tf.com
pat.v1.ConfigProto instead.
...
2022-03-30 09:48:44.229713: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcublas.so.11
2022-03-30 09:48:44.683684: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library libcudnn.so.8
[09:48:51 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 0 | time = 7s | loss gen = 0.7218 | loss dis = 1.3530
[09:48:54 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 1 | time = 3s | loss gen = 0.7747 | loss dis = 1.2383
[09:48:57 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 2 | time = 3s | loss gen = 0.8793 | loss dis = 1.0877
[09:49:01 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 3 | time = 3s | loss gen = 1.0170 | loss dis = 0.9235
[09:49:04 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 4 | time = 3s | loss gen = 1.1724 | loss dis = 0.7746
[09:49:07 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 5 | time = 3s | loss gen = 1.3378 | loss dis = 0.6493
[09:49:11 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 6 | time = 3s | loss gen = 1.5056 | loss dis = 0.5522
[09:49:14 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 7 | time = 3s | loss gen = 1.6597 | loss dis = 0.4744
[09:49:17 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 8 | time = 3s | loss gen = 1.7992 | loss dis = 0.4116
[09:49:21 INFO @GAN.train.mnist.fm.0] Epoch terminated
Epoch 9 | time = 3s | loss gen = 1.8616 | loss dis = 0.3848
[09:49:21 WARNING @GAN.train.mnist.fm.0] Testing evaluation...
[09:54:19 INFO @GAN.train.mnist.fm.0] Testing : mean inference time is 1.5292
Testing | PRC AUC = 0.7183
Me-mount direktori
Alih-alih membuat commit setiap kali kita mengedit, kita bisa memount direktori saat memanggil docker.
Skenario: Mengedit file diluar docker, mengeksekusi file (misal python) didalam docker.
Caranya adalah sebagai berikut.
$ docker run --gpus all -it --mount type=bind,source=/TA,target=/TA tf1.15:py3
Dimana `source` adalah sumber direktori, dan `target` adalah target direktori. Image docker sebelumnya sudah saya commit menjadi `tf1.15` dengan tag `py3`.
Menambahkan docker ke sudoers
Ketika membuka docker, terlihat bahwa tanda di baris kiri terminal adalah sharp #, ini menandakan kita masuk sebagai super user (sudo). Karenanya ada error saat membuka docker pertama kali (harus chmod 666 dulu). Solusi ini hanya berjalan sementara, untuk solusi permanen kita bisa menambahkan docker ke grup sudoers sebagai berikut.
# menambahkan grup baru bernama docker
$ sudo groupadd docker
# menambahkan $USER ke grup docker
$ sudo usermod -aG docker $USER
# merefresh grup
$ newgrp docker
Demikian tutorial singkat docker ini, semoga bermanfaat.
`history` itu penting. Dengannya kita bisa mencari perintah-perintah apa saja yang telah kita panggil. Berikut contohnya.
$ history
# output
..
1978 cd
1979 cd github/CSS
1980 cd github/CCS/
1981 git pull
1982 cd scripts/
1983 ls
1984 cp create_csv_split.py create_csv_split_ccs.py
1985 code create_csv_split_ccs.py
1986 python3.8 -m IPython
1987 cd
1988 ls /groups/gac50538/
1989 cd github/CSS/
1990 ls
1991 cd ..
1992 ls
1993 cd CCS/
1994 ls
1995 code csv/train_dataset_ccs.csv
1996 python3 -m IPython
1997 python3 -m IPython
1998 ssh 192.168.244.64
1999 history
Lebih mudah lagi, perintah `history` bisa kita panggil dengan jalan pintas Ctrl-R. Kita bisa menggunakan Ctrl-R lagi untuk berputar (cycle) ke `history` selanjutnya.
FZF
FZF membuat `history` terlihat usang. Atau bisa saja dikatakan memambah kemampuan `history` agar lebih bertenaga lagi: "fuzzy search". Perhatikan potongan video berikut.
sudo apt install fzf
fzf
# Ctrl-R
Untuk bisa menggunakan fitur tersebut, yakni mengganti Ctrl-R dari `history` ke `fzf`. Kita perlu tambahkan dua baris berikut ke .bashrc.
This is my second experience using a pen tablet on Ubuntu (which works wonderful). Everything works out the box using the previous Digimend v10 installation. The only change I made is to copy Huion H950p configuration to the following content.
#!/bin/sh
# huiowh1409.sh: configuration file for WH1409 on Ubuntu 20.04, run as: $ ./huionwh1409.sh
#Change DVI-I-1 to what monitor you want from running command: xrandr
MONITOR="DP-1"
# Get pad name, use "lsusb" or "xsetwacom list devices"
PAD_NAME='HUION Huion Tablet'
# get stylus ID
ID_STYLUS=$(xinput | grep "$PAD_NAME stylus" | cut -f 2 | cut -c 4-5)
# map pad to first monitor
xinput map-to-output $ID_STYLUS $MONITOR
# Pad button mapping for Xournal
xsetwacom set "$PAD_NAME Pad pad" button 1 key Ctrl z # undo
xsetwacom set "$PAD_NAME Pad pad" button 2 key Ctrl y # redo
xsetwacom set "$PAD_NAME Pad pad" button 3 key Ctrl shift d # default
xsetwacom set "$PAD_NAME Pad pad" button 8 key Ctrl shift p # pen
xsetwacom set "$PAD_NAME Pad pad" button 9 key Ctrl shift e # eraser
xsetwacom set "$PAD_NAME Pad pad" button 10 key Ctrl 1 # shape recognizer
xsetwacom set "$PAD_NAME Pad pad" button 11 key Ctrl 4 # arrow
xsetwacom set "$PAD_NAME Pad pad" button 12 key Ctrl 5 # coordinate
xsetwacom set "$PAD_NAME Pad pad" button 13 key Ctrl c # copy
xsetwacom set "$PAD_NAME Pad pad" button 14 key Ctrl v # paste
xsetwacom set "$PAD_NAME Pad pad" button 15 key Ctrl shift r # select rect
xsetwacom set "$PAD_NAME Pad pad" button 16 key Ctrl d # new page after
exit 0
All 12 pad buttons work without any further configuration! Both USB cable and bluetooth connection also work seamlessly. This WH1409 tablet has a smoother pen (PW500 pen) compared to H950P (with PW100 pen). So far, I am very satisifed by its performance, particularly on Linux-based PC.
Langkah di atas hanya bekerja pada Ubuntu 20.04 dengan Python 3.8. Untuk Ubuntu 16.04, anda harus menginstall tesseract-ocr (engine pengenalan teks) terbaru, yakni versi 4.1 via ppa. Program tesseract-ocr yang ada di repo 16.04 adalah versi lama (3.0.4) dan menyebabkan terjadinya error pada instalasi normcap di Ubuntu 16.04.
Ikuti langkah-langkah di sini untuk instalasi tesseract-ocr baru di Ubuntu 16.04. Meski sudah menginstall tesseract-ocr terbaru dan menambah data train (tessdata) di /usr/share/tesseract-ocr/tessdata/, saya masih gagal menginstall normcap di Ubuntu 16.04. Pesan errornya seperti ini.
...
AttributeError: type object 'tesserocr.OEM' has no attribute 'LSTM_ONLY'
Catatan ini akan diupdate bila ada informasi baru.
Solusi:
Berdasarkan komentar pembuatnya, berikut solusi instalasi normcap di Ubuntu 16.04:
As a scientist or researcher or a lecturer, writing paper in Latex is a must. To make it easy writing in Latex, I used VScode with Latex Workshop extension. For non native English speaker, there is another extension called ltex (based on "language tool") to check spelling and grammar. This is a perfect combination for writing paper in Latex: VScode+Latex Workshop+Ltex.
However, since I used Ubuntu 16.04 as my OS, there is a difficulty on installing the latest Ltex version (v9.0.0) in Ubuntu 16.04, which required java-11. Here, I documented my steps to tackle the problem.
Download openjdk from this link: https://github.com/AdoptOpenJDK/openjdk11-binaries/releases/download/jdk-11.0.10%2B9/OpenJDK11U-jdk_x64_linux_hotspot_11.0.10_9.tar.gz
Extract the downloaded file.
Copy extracted file to /usr/local: sudo cp -r jdk-11.0.10+9/ /usr/local
Set ltex java path to: /usr/local/jdk-11.0.10+9
Finish
The last step, step 4 (before finish), can be shown below.
Now Ltex is ready, as shown below. It checks your spelling and grammar errors aumatically, for free.
Another trick
I used another PC with also 16.04 version, but I don't need to follow these tricky steps with leaving "Ltex Java path" blank.
Belajar kanji bisa dilakukan secara otomatis. Bagaimana bisa? Bisa. Dengan kata lain, kita bisa "terpaksa" belajar kanji (ini yang saya maksud secara otomatis) karena melihat wallpaper PC (komputer). Begini caranya.
OS: Ubuntu
Cara yang saya coba terangkan di sini bisa diterapkan dengan mudah pada Ubuntu. Pada OS lain bisa, tapi perlu penyesuaian, khususnya aplikasi untuk mengubah wallpaper setiap sekian waktu. Pada Ubuntu, aplikasi ini sudah tersedia secara default. Aplikasi tersebut adalah "Shotwell Photo Manager" yang biasa digunakan untuk membuka file foto.
Materi Kanji
Pertama, download (git clone) wallpaper kanji (dari N3 ke N5) dari github berikut.
Simpan direktori tersebut pada tempat (direktori) di mana ingin menyimpan file kanji.
Langkah-langkah (dicoba pada Ubuntu 16.04):
Buka aplikasi shotwell
Import direktori file kanji (misal: /home/bagus/JLPT-one-kanji-a-day-wallpaper-set) dengan cara File >> Import
Set sebagai background dengan cara, Ctrl+A semua file wall paper kanji, kemudian File >> Set as desktop background (Set as desktop slideshow)
Konfigurasi waktu untuk berganti wallpaper, misal (default) satu jam
Selesai!
Konfigurasi ganti wallpaper setiap satu jam pada Shotwell
Berikut adalah tampilan setelah proses import selesai.
Tampilan awal, kanji tampak ter-"zoom"
Nah, kanji sudah terpasang sebagai wallpaper. Masalahnya, by default, tidak ada konfigurasi untuk wallpaper tersebut atau wallpaper ditampikan dalam keadaan ter-zoom, seperti gambar di bawah. Untuk mengganti konfigurasi "zoom" ke "scaled", agar sesuai dengan ukuran monitor, gunakan perintah berikut
gsettings set org.gnome.desktop.background picture-options "scaled"
Cara di atas (mengganti "zoom" ke "scale") bisa memakai GUI bila ada di setting (Setting >> Appearance >> Look), seperti gambar di bawah tangkapan layar berikut.
Tampikan wallpaper seteleah di "scale"
Nah sekarang, ukurannya tinggal pas. Selanjutnya tinggal mengganti warma background di belakang kanji, lewat setting di bawah. Hasilnya adalah gambar di bawahnya.
Ekstensi pdf sangat fleksibel, baik digunakan secara independen maupun ketika di "embedd" ke dalam file lain, misalnya Latex. Gambar yang baik (resolusinya) kebanyakan bukan dalam format pdf, tapi (contohnya) SVG. Konversi yang cepat (dalam hitungan detik) dibutuhkan agar kita tidak perlu membuka program berbasis grafis (seperti InkScape atau Adobe Illustration) untuk konversi dari SVG ke PDF. Berikut solusinya.
# install program jika belum terinstall
$ sudo apt-get install librsvg2-bin
$ rsvg-convert -f pdf -o output.pdf input.svg
Cara ini menghemat waktu sekitar 10 menit dari cara konvensional (berbasis grafis). Selain itu, aplikasi berbasis grafis sering "mend-distract" kita untuk mengerjakan sesuatu yang lain di aplikasi tersebut.
Di musim pandemi seperti sekararang ini, banyak seminar/konferensi dialihkan menjadi online/virtual. Tulisan ini akan membahas teknik presentasi online/virtual berbasis perangkat lunak gratis, khususnya yang berjalan di sistem operasi berbasis Linux.
Perangkat yang dibutuhkan/digunakan antara lain: Beamer atau Impress atau Google Slide, SimpleScreenRecorder atau OBS Studio, ffmpeg dan audacity. Jadi setidaknya kita menggunakan empat perangkat, misal Beamer > OBS > ffmpeg > Audacity, atau, Impress > SimpleScreenRecorder > ffmpeg > Audacity. Diagram alir dari langkah-langkah yang dilakukan dapat digambarkan pada gambar di bawah ini.
Diagram alir proses peremakan presentasi virtual
Di akhir tulisan, saya akan demokan dua hasil perekaman dengan teknik yang saya jelaskan di artikel ini.
Hari ini saya iseng mencari-cari aplikasi yang bisa menampilkan Al-Quran di command line alias terminal. Apa manfaatnya? (1) Ketika disebutkan surat dan ayatnya, misal 7:37, kita segera tahu arti ayat tersebut (dalam bahasa inggris); (2) Ketika membaca Quran (yang tidak ada terjemahannya), kita juga bisa langsung tahu artinya. Ternyata ada aplikasi ini Github. Langsung cus saya coba. Berikut tutorial singkatnya.
Tes signifikansi digunakan untuk menilai apakah dua hal (benar-benar) berbeda. Menggunakan logika penalaran (logical reasoning), kita tidak bisa menilai dua hal secara subyektif. Misal, A dan B itu berbeda, karena tidak sama persis. Tidak demikian. Kita harus berbicara berdasarkan data. Nah bagaimana menunjukkan kalau A dan B itu berbeda dengan data? Tes signifikansi-lah salah satu caranya.
Perlu dicatat, sebelum saya lanjutkan tulisan ini, banyak kritik atas penggunaan tes signifikansi. Salah satunya adalah tulisan ini. Sebagai solusinya, penulis artikel tersebut menyarankan penggunaan confidence level. Saya tidak akan membahas hal tersebut (meskipun saya setuju). Prinsip saya, mempelajari apa yang sedang digunakan (meski dianggap salah atau tidak layak), tetap bermanfaat sehingga kita tahu kekurangannya.
Paired t-test
Ada beberapa macam t-test: paired, two samples with equal variance, dan two samples with unequal variance. Kali ini saya akan membahas paired t-test, karena itu yang saya pakai. Pair t-test digunakan untuk mengecek dua proses (misal sebelum dan sesudah improvement), Asumsi yang dipakai adalah bahwa bahwa perbedaan rataannya 0. Paired t-test baik dipakai jika:
Proses/metode yang berbeda pada subyek yang sama
Tidak ada data outlier
One-tail vs Two-tail dan p-value
Analisis One-tail vs Two-tail dilihat dari kurva distribusinya. Perhatikan gambar di bawah ini. Jika memakai two-tail (ini yang akan dipakai) kita memakai dua sisi-nya. Jika memakai satu-sisi maka hanya dipakai setengah sisinya. Memakai two-tail, dengan confidence level 95% maka significance leevel-nya adalah 5% atau 0.05. Inilah batas nilai p-value (asserting p-value=0.05). Jika nilai p-value di bawah nilai batas tersebut, maka null hypothesis kita tolak dan alternatif hypothesis kita terima (artinya: perbedaan yang kita dapatkan signifikan).
Saya menggunakan "ssh" untuk mengakses desktop, dimana hampir semua proses komputasi saya lakukan di PC tersebut, bukan di laptop. Keuntungannya, selama saya bisa konek ke jaringan kampus (apato, perpus, dll) saya tetap bisa mengakses desktop, menjalankan simulasi, merubah variabel, dll. Jika berada diluar kampus, saya menggunakan TeamViewer. Untuk memudahkan menggunakan terminal dengan ssh, saya menggunakan perangkat "byobu", sebuah utilitas yang dibuat untuk menjembatani tmux atau screen, perangkat lain untuk memudahkan menggunakan terminal di Linux yang "membisakan" penggunaan terminal dalam beberapa sesi, beberapa jendela, dan menutupnya tanpa harus menghentikan proses yang sedang berjalan (ini penting ketika mengeksekusi perintah di terminal).
Berikut beberapa shortcut penting ketika menggunakan byobu via ssh:
Ctrl A, D : keluar dari ssh tanpa menghentikan proses (=F6)
F2: membuat jendela baru
Alt + Panah Kanan/Kiri: berpindah jendela
Ctrl + F6: keluar dari jendela, split
Fn + F7: enable scroll
Ctrl + C: keluar (dari enable scroll)
Alt + F6: menghentikan ssh dari komputer lain kecuali yang dipakai
F9: menampilkan help (gunakan tab untuk berpindah menu, =Shift+F1)
Ctrl+F6 atau ketik 'exit': keluar dari sesi
Beberapa shortcut lainnya seperti "Shift+F2" (membagi jendela secara horizontal), "Ctrl + F2" (membagi jendela secara vertikal), tidak saya masukkan karena saya jarang membagi jendela terminal menjadi beberapa bagian (kecuali terpaksa). Jika itu dilakukan, maka untuk berpindah fokus ke jendela samping atau atas/bawah gunakan "Shift+Panah". Selain shortcut di atas saya menggunakan perintah berikut: