#プログラミング原体験

blog.utgw.net

papix.hatenablog.com

小中高と家に家族共用のパソコンはあったのだけれど、プログラミングはしようと思っていなかった。 だいたいPCでやることは、近所の本屋のPCコーナーに売ってある「サルでもわかるDVDコピー」とか、PSPエミュレーターの動かし方、PSPの改造の方法を調べるのと、Flashゲームをやりつつエロサイトを見ることだった。

プログラミングをしようと思っていなかった原因はいろいろあり、当時は電気工事士になりたかったこと*1や、プログラムはコンピュータも含めて人間が作ったものだから、人間が理解出来るという中2的な発想があったことなどがある。それより大きかったのは、「そもそもプログラミングは高度に教育を受けた研究者がなんか火花をちらしている研究室で、めちゃくちゃ高い機械で行っている」という印象があったため。近所の本屋でもPCコーナーに売ってるのはプログラミングの本ではなくて、DVDコピーとかWinnyの本だらけだった。今だと検索すればいいじゃんで終わるが、そもそも検索しても出てこないと思っていたので検索しようという発想がなかった。

高校自体はいろいろつらく*2、文転して民俗学を勉強したかったが、学校のクラス的に文転ができず、理系で興味がゆいつあった情報工学科がある琉大に進学した。ここでMacBookを指定で買い、講義を受けることになる。

初めてやった課題は谷口先生のC言語のReport1で、*を使って好きな図形を書きましょうというのだった。 大学初年度と言えど精神年齢が小5から進化していないので、💩のAAを作って喜んでいた覚えがある。

このときのレポートは紙に印刷して提出だった。そういえば筆記体の練習とかもした気がする。

後半ではfor文とか鬼門のポインタとかやっていた。ポインタはよくわからんかったが、for文では尊師マーチを出力するプログラムを書いて喜んでいた覚えがある。

後期は山田先生のJavaだったのだが、課題という課題もなかったのでRobocodeを動かした覚えしか無い。よくわからんが壁伝いのWallロボットが最強だった気がする。Javaのコードが全然読めなくてパラメーターを変えただけだったっぽい。

この時期はなんか自分で母国語みたいなのが欲しくてScalaをやってみようとしていた。冷静に考えるとJavaも関数型もオブジェクト指向もわからんこの段階でScalaは完全に失敗だった気がする。

2年生になるとプログラミングの講義自体は無いが、プログラミングを要求される課題がいくつか増える。 実験といういろいろな先生が持ち回りで1,2週担当する講義があって、ここのnal先生の担当のシェルスクリプトプログラミングがめちゃくちゃ面白かった。 今までCとかしか書いたことなかったので、なんか書きやすくて面白かった。特にcurl/wgetでwebの情報を撮ってこれるというのは自分の中で革命的だった。nal先生は冗談が通じると個人的に思っていたので、DMMのグラビアアイドルカテゴリからランキングを取得するシェルスクリプトを書いた。当時の実験受講者でトップだったのでレポートが公開されたのは思い出に残っている。

今みたらGitHubに上がっていた。 github.com

後期には河野先生が担当しているOSという講義があって、なかなか難易度が高い講義として知られている。 この講義でPerlを使うということを聞いていて、たまたま琉大でPerl入学式を開催するという話を聞いたのでそこに参加した。東京からきたやばいエンジニアがいるということで、恐る恐るid:papixさんに懇親会で話しかけたのが思い出深い。

Okinawa.pmでPerlを母国語にしたいと宣言してからはや数年、なんとなく日常会話は出来るようになった気がする。

C言語は得意でもなく苦手でもなかったが、2年生のコンピュータシステムとかコンピュータアーキテクチャとかで、アセンブラやCPUって結構面白いなぁとか思っていた。 そして2年生後期でOSを受けて、そのOSの中にあった「Linuxのkernelをデバッグビルドしてコードを読む課題」がめちゃくちゃ面白くて、当時のクリスマスはひたすらLinux のKernelをビルドしていた。これは小学生の頃から持ち続けていた「OSって高い機械でバチバチしながら開発している」とイメージしていたものが、手元のMacBookで見れるようになったというのが大きい気がする。

コンパイラに興味を持ったのは、これも河野先生の講義があったB3からなのだけど、OSと同様にわけわかんない存在だったのが以外とコードが読めるというのが楽しくて、以降は触っていた。当時はいろいろあったので、周辺の人々が触っていないニッチなところをやろうと思っていたのもあると思う。

後は低レイヤーとかPerlとかに興味を持って今に至る感じ。僕もpapixさんと同じで大学に入って始めた口なので、小中とかでやってる人を見るとすげーっと思ったりするけど、まぁ今も十分楽しいのでいいかなぁと最近思っています。

*1:父の職業に憧れがあった

*2:3年間同じクラスで同じ担任だったが、全てに置いてうまく行かなかった

singularityを使ったLaTeXのビルド環境を学科GitLabに構築した

自分がubuntuに作業環境を変えたこともあるのだけれど、最近の新入生のMacBookの容量が125GBとMacTeXをいれるには心もとない状態だったので、GitLabのCI/CDでLaTeXのビルドをしようとしていた。

paperist/alpine-texlive-jaにパッチをあたものを使っていたのだけれど、GitLab CIでLaTeXをビルドしようとする場合、 生成したPDFがroot権限になってしまうという問題がある。

su-execとか使ってどうにかしようとしたのだけど、ちょっとめんどくさいしidをdocker runの時に渡さないと行けないのが解りやすくないので厳しい気持ちになっていた。

学科システムでは別のコンテナランタイムとしてsingularityを使っている。

singularityはなんとuid/gidが実行時ユーザーと同じ状態で実行されたり、自動でホームディレクトリがマウントされるなど、今回のようなlatexのコマンドをコンテナから使う環境としてはぴったし。 ということでDockerfileをもとにsingularityのdefファイルを作った。

defファイル

gitlab.ie.u-ryukyu.ac.jp

dockerからの変更点

基本的にDocker時代のものをそのまま利用すれば良いのだけれど、singularityならではの変更点がいくつかある。

  • singularityの場合/tmpにファイルを書き出してbuildするのはNG

    • /tmpはホストの/tmpとマウントされてしまう
    • 今回はLaTeXのインストールスクリプトを置く場所を/latex以下にすることで回避
  • %environmentはビルド時に解決されない

    • PATHをいじってビルドしようとする場合は問題が生じる
    • %postの中で明示的にexportすることで解決

他にはepsを含めたいのでgostscriptを、makeしたいのでmakeをインストールするようにしている。 あまり関係ないが、CTANもミラーサーバーに向けているなどの違いがある。

あとはsingularity run latex.sif uplatex hoge.texとかしたいので、%runscriptで引数をexecするように書く。

%runscript
  exec "$@"

ビルド

singularity build --fakeroot latex.sif latex.def

使い方

sungularity runでも良いのだけれど、sifファイルにはシェバングが埋め込まれていて、自動でsingularity run出来る。

なのでこんな感じで使える。

$latex.sif latexmk
$latex.sif make

gitlab ciの設定は別のエントリで

合わせて読みたい

ie.u-ryukyu.ac.jp

ubuntuでdf: /run/user/1000/doc: Operation not permitted とか怒られる

なんかdfするとdf: /run/user/1000/doc: Operation not permittedとか怒られる。

$ df       
df: /run/user/1000/doc: Operation not permitted
Filesystem     1K-blocks      Used Available Use% Mounted on
tmpfs            3214652      2404   3212248   1% /run
/dev/nvme0n1p2 959863856 160878272 750157376  18% /
tmpfs           16073244    116640  15956604   1% /dev/shm
tmpfs               5120         4      5116   1% /run/lock
tmpfs               4096         0      4096   0% /sys/fs/cgroup
/dev/nvme0n1p1    523248      7984    515264   2% /boot/efi
tmpfs            3214648       136   3214512   1% /run/user/1000

ググったとことdfのバグとか、flatpackのバグとか主張しているサイトが見つかったが、ubuntuの場合はxdg-document-portalを止めればいいらしい。

$ systemctl --user stop xdg-document-portal.service

問題なさそう。ちなみにディレクトリは消せなかった。

$ df
Filesystem     1K-blocks      Used Available Use% Mounted on
tmpfs            3214652      2416   3212236   1% /run
/dev/nvme0n1p2 959863856 160933308 750102340  18% /
tmpfs           16073244    377076  15696168   3% /dev/shm
tmpfs               5120         4      5116   1% /run/lock
tmpfs               4096         0      4096   0% /sys/fs/cgroup
/dev/nvme0n1p1    523248      7984    515264   2% /boot/efi
tmpfs            3214648       140   3214508   1% /run/user/1000

askubuntu.com

Ubuntuのdiscordアプリのフォントを変える

Ubuntuのdiscrodのフォントが奥ゆかしいことになっており、変更してみた。

BetterDiscordのインストール

Discordアプリをいい感じに編集できるBetterDiscordをインストールする。 linuxの場合はgistを読んでコマンドを打つ。

gist.github.com

$curl -O https://raw.githubusercontent.com/bb010g/betterdiscordctl/master/betterdiscordctl
$chmod +x betterdiscordctl
$sudo mv betterdiscordctl /usr/local/bin

discord自体はsnapでいれているので、snapオプションをつけてinstallする

$betterdiscordctl install --snap

フォントの変更

ユーザー設定-> Custom CSSから

* { font-family: "Noto Sans CJK JP" !important;
-webkit-font-smoothing: subpixel-antialiased;
}

参考資料

ch.nicovideo.jp

Ubuntuで撮影したスクショを日付順に整理するコマンドかいた

自分しか使わなさそうツールです。

Ubuntuではスクショを取ると、~/PicturesScreenshot from 2021-01-03 08-28-12.pngみたいな名前でスクショが保存されます。 放置しているとスクショが溜まって大変なので、年/月/日でディレクトリを切って、そこに移動させるスクリプトを書きました。 Perlでファイル操作するときは最近はPath::Tinyが以上に便利でいいですね。

#!/usr/bin/env perl
use strict;
use warnings;
use Path::Tiny;

my $pictures_path = shift // $ENV{"HOME"}."/Pictures";
my $pictures_dir = path($pictures_path);

my $screenshot_reg = qr/Screenshot from (\d{4})-(\d{2})-(\d{2}) (\d{2}-\d{2}-\d{2}\.\w+)/;
#Screenshot from 2021-01-03 08-28-12.png

for my $file ($pictures_dir->children(qr/Screenshot from/)) {
  if ($file !~ /$screenshot_reg/) {
    print "[ERRPR] failed parse", $file->[0],"\n";
  }

  my $year         = $1; #2021
  my $month        = $2; #01
  my $day          = $3; #03
  my $picture_name = $4; #08-28-12.png

  my $new_picture = path("$pictures_dir/Screenshot/$year/$month/$day/$picture_name");
  $new_picture->touchpath;
  $file->move($new_picture);
}

おそるべきプログラミング入門サイトExercismをやってみた

Twitterで見かけたのでやってみました。

exercism.io

触った感じだと、Progate的なwebブラウザでプログラミングするタイプではなくて、truckに近く、コマンド経由でローカルに課題をダウンロードし、コマンド経由で回答を提出するという感じのプログラミング入門サイトです。これで無料なのはすごい気がする。

会員登録はGitHubAuthが使えるのでそれでしました。 特に何も打つ必要がないので便利。

課題のダウンロード/提出にはexercismというコマンド経由で行う必要があり、今はubuntuユーザーなのでsnapでinstallしました。

$sudo snap install exercism

exercismをインストールしたら、トークンを設定する必要がある。

$exercism configure --token=<トークンを貼る>

ちなみにいきなり動かそうとするとエラーがでて、トークンを発行するURLが案内される。

$ exercism download --exercise=hello-world --track=raku
Error:

    Welcome to Exercism!

    To get started, you need to configure the tool with your API token.
    Find your token at

        https://exercism.io/my/settings

    Then run the configure command:

        /snap/exercism/5/exercism configure --token=YOUR_TOKEN

exercismは他にいろいろ設定できるみたいで、作業用ディレクトリも設定可能。 初期設定だと$HOME/snap以下が作業ディレクトリとなってしまうので、今回は自分で作ったworkspaceディレクトリを設定した。 自分で作ったworkspaceにcdした状態で次のコマンドを実行。

$exercism configure -w=$PWD

これで初期設定が終わるので、あとは問題で指定されているコマンドを打って課題をローカルにダウンロードする。 課題はいろいろな言語があるのだけれど、今回はRaku(Perl6)を選んでみました。

$exercism download --exercise=hello-world --track=raku

今回はrakuの下にhello-worldというディレクトリが作られていました。

$ pwd
/home/anatofuz/workspace/exercism/raku/hello-world
$ls
HelloWorld.rakumod  hello-world.rakutest  README.md

あとはここで課題に応じてプログラムをしたり、テストを動かしたりすれば良さそう。 僕はRakuだったので、とりあえずRakuでテストをいい感じに動かすprove6をインストールした。

$zef install App::Prove6

テストを確認するとこんな感じ。Hello, World!と返すhello関数を作ればいい。

+kajika+anatofuz$ cat hello-world.rakutest
#!/usr/bin/env raku
use Test;
use lib $?FILE.IO.dirname; #`[Look for the module inside the same directory as this test file.]
use HelloWorld;
plan 1; #`[This is how many tests we expect to run.]

# Run the 'is' subroutine from the 'Test' module, with three arguments.
is(
  hello,           # Run the 'hello' subroutine, which is imported from your module.
  'Hello, World!', # The expected result to compare with 'hello'.
  'Say Hi!'        # The test description.
);

ということでHello.modを編集

$ cat HelloWorld.rakumod
#`(
  This is a 'stub' file. It's a little start on your solution.
  It is not a complete solution though; you will have to write some code.
)
unit module HelloWorld;

sub hello is export {
    return "Hello, World!";
}

prove6でテストを実行。通ってる。

+kajika+anatofuz$ prove6 .
hello-world.rakutest .. ok
All tests successful.
Files=1, Tests=1,  0 wallclock secs
Result: PASS

ここまで出来ると課題提出が可能。submitで提出。

$exercism submit ./HelloWorld.rakumod

通っているとターミナル側でURLが生成されるので、それを開いて答えがあってるかの確認とかを行う。 答えがあってる場合は、自分の回答を公開するかどうかとかを聞かれるのでそのあたりに答えると次の課題がアンロックされる感じでした。

所感

1問くらいしか動かしてないですが、就活でのコーディング面接の雰囲気を知るとかの意味でも結構おすすめです。 全部英語なので読むのは大変かもしれませんが、わかりやすい英語ですし、テストコード見ればだいたい雰囲気がわかる感じなので、暇なときにやってみましょう。

snapでVLCをインストールする

ubuntuでよく使われているパッケージツールのsnapを使って動画再生ソフトのVLCをインストールする。

snapはGUIも持っていて「ubunntu software」からアクセスすることが出来る。 雑にVLCで検索すると、なんか2つ出てくる。

f:id:anatofuz:20210107173322p:plain

違いは何かというと、下のopen sorceとか書かれていないVLCはinstallして使うと、音声は流れるけど動画が流れないなどの仕様になっている。 あとファイルアクセスのAPIGNOMEのものを使ってなさそうなので、上にでてきた方を入れると使用可能。

使ってみたところwindows/macとほぼ同じ雰囲気で使えたので良かった。ubuntuにはもともとビデオアプリが入っているのだけれど、どっちがいいのかはまだわからない。