Noratetsu Lab

動じないために。

2023年2月

2023/02/23

NTA-DIY:1ヶ月目⑧~ScrapboxのUserScriptを作ってみる~

 ブックマークレットが作れるようになったので、今度はScrapboxのUserScriptに挑戦することにしました。


 ScrapboxのUserScriptは私がJavaScriptを習得したいと思った動機のひとつです。是非とも作りたい何かがあったわけではありませんが、コーディングできる人が自由にカスタマイズして便利にしている一方、そのコードをすっかり公開までしてくれているのに自分はそれを参考にすることもできないのが少し悔しかったのです。
 一応作ろうと思えば作れるようになった今となっては、逆に「別に作ろうとしなくても構わないな」という結論に至っているのですが、やりたくてもやれないのとやれるけどやらないのとでは心持ちが違いますね。

 さて、UserScriptでできることというのは色々あります。その可能性の広さがどのくらいのものか私はまだ全然わかりませんが、私が思いつくだけでも方向性は様々です。
 当初は処理の実行タイミングのコントロール(つまりイベントの設定)がよくわからなかったので、まずPage Menuのボタンを作る形を試しました。自分でイベントリスナーやsetInterval、あるいはUserScript Eventsを設定できるようになれば自由にイベントを発火させられることになりますが、その域に行くのは当分先のことです(私の場合は)
 Page Menuのボタンクリックで動かすとして、そこでやれるのは例えば次のようなことです。

  • 予め用意した文字列などをalertで表示する
  • どれかのページのコードブロックの内容を取得して表示する
  • 自分のプロジェクトのページデータを取得し特定の条件に合うページを抽出して何かする
  • DOM操作でclassを付け外ししてCSSを変更する
  • DOM操作でstyle要素を付け外ししてCSSを変更する

 他にも数多の可能性があります。今挙げたのは1ヶ月目の時点で私が実際にやってみたことです。つまり簡単な処理です。
 Pege Menuの作り方の細かい説明はここではしませんが、一番下にいくつかリンクを貼ったので必要な方はご参照ください。

 まずPage Menuのメニュー追加の書き方を知るためにalertを表示するだけのコードを書きました。
https://gist.github.com/nora-tetsu/c3cec884219f1ba75768063a5c92bac2
 実際には、当時ブログ記事をScrapboxで書くことがあったので、記事を書く際の組み立てのヒントを表示するようにして使っていました。

 次は特定のページのコードブロックの内容の取得です。この処理には「FetchAPIを使ってScrapboxAPIを叩く」という工程が必要です。当時はAPIも非同期処理もよくわからなかったので見様見真似でやりました。
https://gist.github.com/nora-tetsu/68cabe5bbf8e7e2d51a2a247eefc83ec

 今度はScrapboxAPIの別のプロパティを使い、自分のプロジェクト内のページの中から特定のキーワードをタイトルに含むページを抽出して、リンクを一覧にして今開いているページに追記することを試みました。
https://gist.github.com/nora-tetsu/8a47788d0740443eb9fdf98cb4c95cb8

 DOM操作によってCSSをコントロールすることもできます。まずUserCSSに予めスタイルを書いておいてclassで切り替える方法です。daiizさんのコードを参考にさせていただきました(新書モード - daiiz)。例えばコードブロックのフォントを切り替えるとしたらこう書けます。
UserCSS
https://gist.github.com/nora-tetsu/7f1d938a56db34f702c0dcf9fd85fa9f
UserScript
https://gist.github.com/nora-tetsu/bac49dbc95d7c6e8366c5867b7d36275

 UserCSSは使わずにstyle要素の追加と除去で切り替える方法もあります。こちらはページの背景をリーガルパッド風にするUserScript - Scrapbox研究会を参考にしています。例えば以前作った、関連リンクを左列に持ってくるUserCSSのオン・オフを切り替えるとしたらこうなります。
https://gist.github.com/nora-tetsu/aef2d3f5833eebcfe0358de3a8e191da

 Scrapboxの公開プロジェクトには当時作ったコードが色々置いてありますが、今となってはあまりよろしくない書き方があちこちにあります(直すのも面倒で…)。なので参考にしてくださいとはちょっと言えませんが、自分が振り返る分には「手探りで頑張っていたなあ」と懐かしく思い出されます。なお今回記事内に載せたコードは当時のものを適宜直しています。

 まだ単純なことしかできていないわけですが、「自分でメニューを増やして、自分が作ったコードを何かしら実行できる」という体験をしたことにより、UserScriptへの漠然とした憧れはこれで大方解放されました。特にCSSの切り替えについては、UserCSSで設定した状態に固定されてしまうことに不都合を感じていたので、それを解消できたことでかなりの達成感がありました。
 ずぶの素人がUserScriptをJavaScriptの勉強のための実験場として使うのはちょっと危なく感じられたこともあり、UserScriptについてはそこそこにして、ここからいよいよHTML・CSS・JavaScriptの三点セットでツールの自作に挑んでいくことになります。

参考

当時の咀嚼

 

2023/02/21

NTA-DIY:1ヶ月目⑦~DOMとAmazonブックマークレット~

 前回、Scrapboxのページに文字列を追記するブックマークレットの話をしました。
 現在日時や開いているタブのタイトル・URLの取得を覚えたので、次はWebページの内容をScrapboxにクリップするブックマークレットを作ってみることにしました。手始めにAmazonの書籍情報です。


 いきなりゼロからでは何もできないので、先人の知恵を借りることにしました。教材はこちらです。

 Webページから情報を取得する際に必要なのはDOM(Document Object Model)の概念の知識です。要するにJavaScriptを通してHTML要素を指定したり操作したりする方法を知る必要があるわけです。
 JavaScriptのキモはDOM操作にあると思いますが、DOMはJavaScriptがHTMLやSVGなどを操作できるようにするためのAPIであって、JavaScript言語の中に含まれているものではないので、JavaScriptの基本を勉強する時にはすぐには登場しない場合も多いのではないかと思います。(DOMはあくまでAPIだ、ということはコードを書いている中ではほとんど意識しません。JavaScriptが当然に持っている機能かのように扱うことになると思います。というか、あくまでAPIだとか言われても初学者にはなんのこっちゃでしょう。)
 NTA-DIY(ノートテイキングアプリのDIY)に於いてはDOM操作がチョー重要でゴリゴリ多用することになります。逆に言うと必要に迫られるのですぐ覚えます。最初の一歩を踏み出せれば後はその都度調べてどうにかなるでしょう。
 その最初の一歩として、Amazonから情報を取得するブックマークレットを理解することは大いに役立ちました。「DOMの基本を順を追って学ぶ」というやり方だとまっさらなHTMLにひとつひとつ自分で要素を作っていくところから始めることになると思いますが、ブックマークレットの解体を通してWebページとの関連を理解することは、既に出来上がっている立派なWebページを解釈することから始まるので、実用的な知識と感覚が早く身につくのではないかと個人的には思っています。

 Webページをクリップする系のブックマークレットに必要なのは、基本的に「この要素の中身のこの文字列を取り出す」ということだと思います。「この要素」をどうやって指定して、そのうちの「この文字列」をどう絞り込むか、がまず覚えるべきことです。
 「この要素」の指定のために使うメソッドは、最低限「document.querySelector()」、「document.querySelectorAll()」を覚えれば用は足ります。他のメソッドとは「指定した後に更新された場合にそれが反映されるかどうか(動的か静的か)」「処理速度が速いか遅いか」で使い分けが発生しますが、クリップするにあたっては実行した時点のデータを取得できればいいので、静的な一方で指定方法が柔軟なquerySelector/querySelectorAllは初学者にはありがたいメソッドです。特にCSSに慣れている人はセレクタの指定方法が同じなのでわかりやすいでしょう。
 便利な反面、処理速度は少し遅くなります。大量に処理する場合には影響が生じる可能性があるので、「document.getElementById()」「document.getElementsByClassName()」などを使えた方が後々楽ということになります。
 私は今のところ、id指定の時は「document.getElementById()」、それ以外はわかりやすい「document.querySelector()」「document.querySelectorAll()」を使うことが多いですが、多分動的なgetElementBy系のメソッドをちゃんと使ってもっとうまく指定した方がいいのだろうと考えているところです。(静的なquerySelector系だけでも素人の趣味ならそれほど支障はないということでもあります。)
 さてgetElementByにしろquerySelectorにしろ、それだけでは要素全体を取得するだけでそこに含まれる文字列を取得することはできません。「この文字列」を指定するには、「textContent」か「innerText」というプロパティを使う必要があるわけです(この二つは似ていますが少し違います)。そしてこれらは子要素まで含めて取得することにも留意が必要です。場合によっては正規表現を使うことにもなります。(この記事は体験記であって説明記事ではないので詳しくは解説しません。)

 慣れれば目的の要素・目的の文字列をズバッと指定できるようになりますが、最初は取得を試みても何をどう取得したことになっているのかがよくわかりませんでした。
 そこで、対象の指定がうまくいっているかを確認するために活躍したのがコンソールと「console.log()」メソッドでした。コンソールとはWebブラウザのデベロッパーツールを開くと表示される欄で、consoleメソッドの結果が書き込まれている場所です。コードを書いてEnterすればその場で実行することもできます。
 そのコンソールでquerySelectorなどを試し、その結果をconsole.logで確認します。最初は理解が追いついていないので闇雲にならざるを得ず、とにかくうまくいくまで試しました。うまくいったらそれをブックマークレットに反映させます。console.logがいつ役に立つのかそれまでピンと来ていなかったのですが、DOM操作の試行錯誤のために繰り返し使ったのでコンソール上でもコード内でも「console.logで確認する」という習慣がすっかり身につきました。

 Amazonに関して作ったブックマークレットが以下のものです。なお挙動は当初の通りですが、コードそのものはこの記事を書くにあたって改めました。
https://gist.github.com/nora-tetsu/3294ef2b1db728cb1b239913cf89c45f
 これは冒頭で紹介したお手本の理解に挑みながら、少しのチャレンジを試みています。具体的には、手本にはないHTML要素からの文字列の取得と、選択範囲の取得です。その他の部分はほぼ手本のコピペになっています。
 このブックマークレットは手本をちょっと弄った程度のものですが、この他にGooglePlayや他の出版社からクリップするブックマークレットを作りました。上述の悪戦苦闘はそちらに挑んだ時のことです。
 一連のブックマークレット作りによって、デベロッパーツールを用いてHTML要素を探してDOM操作するということが身につき、自分のツールを一から作る土台ができたと思います。
 

2023/02/19

自分のブログを持つということ

 こちらのオンライン対談を拝聴しました。
【編集版】ライフハック研究会Online第9回「今個人がBlogで情報発信を行う意義」


 興味深い話が色々あって面白かったです。最後のあたりの、beckさんが昔やっていたことのお話は聞いていてわくわくしました。行動力がすごい。開けっぴろげという意味でオープンだけどその界隈にしか知られることはないという意味である程度クローズドだった時代が、気持ちの面では一番自由だったのかもと思います。

 以下、この対談を聞いて考えたことをちょっと書いておこうと思います。

noteと個人ブログの違い

 noteと個人ブログの違いはどこにあるのか、というお話がありました。対談に出てきたことと私が考えるところを合わせて書き出してみます。なおここでの「個人ブログ」とはアフィリエイトを主目的としたブログは含みません。

  • 読者のスタンス
    • 知名度がなくてもある程度読まれやすいのがnote、読まれるようになるまでが大変なのが個人ブログ
    • 作者読みが比較的されにくいのがnote、比較的されやすいのが個人ブログ
    • 数字(スキ数)で評価されるのがnote、(はてブを見なければ)数字の評価は見えにくいのが個人ブログ
    • 下の世代が「この中から探す」と考える場所がnote、上の世代にとって自分で探し集めるものなのが個人ブログ
  • 手間
    • エディタが簡単なのがnote、場合によっては難解なのが個人ブログ
  • デザイン・個性
    • 記事のデザインが画一的なのがnote、やろうと思えば多様にできるのが個人ブログ
    • 場を自分で作る意識が相対的に弱いのがnote、相対的に強いのが個人ブログ
    • 自分の趣味を反映させる余地があまりないのがnote、自分の趣味で自己満足を追求する余地があるのが個人ブログ
    • 筆者の人となりの判断が難しいのがnote、筆者の人となりを知って親しみを持ちやすいのが個人ブログ
  • 記事の所在
    • 自分の記事がnoteというサイトの1コンテンツになるのがnote、自分の記事はあくまで自分の場の1コンテンツであるのが個人ブログ
    • プラットフォームが終了したら全部なくなってしまうのがnote、自分でサーバーを用意するなら永続するのが個人ブログ

 私のこのブログはGoogleのBloggerというサービスを使ったものなので、GoogleがBloggerをやめてしまえば場としては消滅してしまいます。でもエクスポート機能があるので引っ越しは多分簡単でしょう。HTMLも概ね自由に弄れることから、感覚としては「自分のもの」と思ってこのブログを運営しています。
 さて私も一応noteに時たま投稿していますが、途中からnoteはツールやコードの話だけにして、個人的なことを書くのはやめてしまいました。理由としては色々ありますが、核の部分を一言で言うと、誰に向かって言っているのかわからなくなってしまったからです。私がやりたかったのは、倉下さんが仰っていたように自分なりの「メディア」を作ることで、「情報発信」ではなかったということです。
 私という存在を表現しようとした時、noteの雰囲気、構造、評価システム、SNSでの扱われ方などが、私のやりたいことにはマッチしていないように感じられました。noteは確かに読まれやすいでしょう。そしてそれはつまり、「noteなら読まれやすい」ことを前提にして書いているんだろう、と読み手が思って読むことも意味していると思います。つまり「全世界に向けて言っている」ということを前提として捉えられてしまうのです。そうなると必然的に悪し様に言われる確率もいくらか高まりそうです。人間性や倫理観、常識の度合い、知識の深さ、頭の程度を測ってなんだかんだと言われるわけです。全世界に向けて言うのに相応しい内容かどうかを四方八方からチェックされる、という印象です。私自身の経験ではありませんが、そんな大した話ではなかったのにうっかりバズったせいで面倒くさいことになってしまった記事を幾度も見かけました。はてな匿名ダイアリーと同じようなものです。
 個人ブログならそのリスクはゼロになるかというと別に全然そんなことはないのですが、望まない層にリーチする確率が下がれば面倒事の発生確率も下がることは確かに思えます。もちろんバズる確率も下がりますが、バズりたくないので全然構いません。そもそもバズるようなことを書いてもいないので、別にnoteに投稿したからと言って取り沙汰されることはないでしょうが、私が直接面倒事に巻き込まれるかどうかもさることながら、そういうことが発生しているタイプの場なのかどうかが私にとっては重要です。なぜなら、真剣に文章を書くということができるかどうかが、私の中ではその点にかかっているからです。書きたい内容の都合上、「読まれなくては意味がない」の前に「納得できる形で書けなくては意味がない」と感じています。
(とはいえ、パーセンテージにすればごく小さい事象に対して恐れすぎている面はあります。)

noteは文章版Pixiv

 ブログに書いているのに「是非noteで書いてください」と言われたという話を聞いて、イラストに於けるPixivみたいだなということを思いました。
 私自身、Pixivがイラスト界を席巻してからというもの、何かを見たくなったらPixivの中だけを探して終わりにするようになってしまいました。数度の騒動によってPixivから出ていった人が沢山いるのは知っていますが、それでも「じゃあ投稿者それぞれの投稿先を追って見に行こう」とはなりません。去っていく投稿者たちのほとんどがPixiv上で「これからはこっちでやります」というアナウンスをまともにやってくれないこともあって、Pixivの外でどれだけの活動が行われているのかもはや全然わからないのです。
 ここ数年は、画像の複数枚投稿が可能になって久しいTwitterがイラストや漫画の投稿先として隆盛を極めているように思えます。そしてTwitterにはリツイートがあるので、自分の趣味に合うものを流してくれるアカウントをキュレーターとしてフォローしておけば、作家を個別に追うことなしに次々タイムラインに流れてきます。どんどん入ってくるので、一体何という名前のどんな為人の作家が描いたものなのかもまともに意識しないことが増えています。
 PixivにしろTwitterにしろ、個人サイトをリンク集、同盟、サーチサイトで探し回っていた頃と比べると、個々の作者に対する思い入れは無きに等しいものになっています。投稿も交流も昔とは比べ物にならないほど簡便になった反面、「つくっているということ」「つくる人がいるということ」に対してはありがたみを感じにくくなっているように思えます。すごいものを目にしやすくなり「おお、すごい」と感動する頻度は増した気がするのに、そのすごい人にその先も関心を持ち続けることというのは割合的に少なくなりました。出会いが多すぎるからでしょう。もはや飢えていないのです。その分だけ、私は情けなくも怠惰になってしまいました。
 かつてはWeb上に発表している人がいるだけでありがたいことだったのに、今や「神絵師」「神字書き」など「神」的存在になってようやく人々から継続的に関心を持たれるようになるわけです。

 何か文章を読みたくなったらnoteから探す、ということが当たり前になると、noteに投稿しなければ存在を認識してもらうことすらなくなります。noteしか見ない人にとっては、noteの外にある文章は存在していないのと一緒でしょう。
 その一方で、noteに投稿している限り、余程飛び抜けなければありがたみを感じてもらうこともないように思えます。「役に立つ」部分だけ齧られて終わりになるかもしれません。何しろ投稿数が膨大です。
 noteは「場」を独自のものにはできません。「その人の総合的な世界観」みたいなものに惚れることは難しくなっています。Pixivでもそのことを強く感じました。そうなると、個々の作品の出来の勝負になってしまいます。作品単位で判定して、相対的に評価が高いものが残り、相対的に劣るものが関心から外れていく。そういう淘汰がともすると自分の中に起こってしまうのです。
 といって、「noteの中しか読まないような人」を自分の場に引き込む必要があるかどうかは微妙だなと感じています。しかし、本来そうではないけど昨今の潮流からなんとなくnoteを読んでいる、という人がいた場合に、そういう人を自分の場に誘導できたら良いことがあるかもしれない……と対談を聞いていて思いました。

いっそHTML打って作ってしまえ

 対談の最後の方にもありましたが、ブログというのは読む側としても過去記事にアクセスしにくいという難点があるのを常々感じています。ちょうどこの対談の何日か前に、このブログのサイドメニューを整理しました。前はラベルを機械的に並べていましたが、分類を作って「つまりどんなものがあるブログか」が多少わかりやすくなるように試みたつもりです。
 あとは前に記事を書きましたNoratetsu Lab Dict.が、Scrapboxの公開プロジェクトをブログの補助として使うことにしました(Noratetsu Lab Dict.)。ブログの記事内で他の記事の内容とリンクさせるのは難しく、またリンクを貼られても読者がそれを読みに行こうと思いそうにないので、記事ではなく単語にジャンプできるようにしたわけです。単語ページに関連する記事へのリンクを貼っているので、Scrapbox上で一応記事同士の関連性も表現しています。
 これはそもそも自分の書きにくさの解消を目的としてやっていることなので、読者にとってどのくらい嬉しいことかはわかりませんが、自分のブログに関するWiki的なものをScrapboxで作るのはブログの欠点を補うひとつの手なのではないかと感じています。(ちなみに「ブログではなくScrapboxに文章を公開する」というのは個人的にやりたい形態ではないので候補から外しています。)

 このブログをブログの形で守った上での工夫としてそういうことをちょこちょこ始めてはいるのですが、しかしそもそもの話、倉下さんが仰るようにもうHTMLでサイト作っちゃえばいいんじゃないの、という気持ちも大きくなっています。コンテンツとして記事一覧がドワーッと並んでいたほうが圧巻な感じがして格好良いんじゃないかとも思います。
 私は最近GitHub Pagesを利用してHTMLをちらほら公開するようになりました。HTMLサイト全盛期を「作る側」としては経ていないので、私にとっては今がはじめてのHTML期です。そもそもサイトの公開をしたくてWeb技術を学んだわけでもなく、いろいろできるようになったんだから今更だけどHTMLサイトを作ったら面白いのかも?と思い始めた段階にあります。
 このブログを書いていても、これ日記じゃないんだから時系列順に並ぶ必要ないんじゃないかと感じることがあります。シリーズものはラベルでピックアップするんじゃなくて、普通に記事一覧があってずらっと並んでいて赤字の「NEW!」なんかがついていたほうが良いような気もします。個人的には「洗練された新しいデザイン」みたいなものにはもう慣れきって憧れも褪せてきています。

 どうするかはまだ考え中です。なんにしても、訪問者と私自身が楽しい場を作れたらいいなと思っているところです。
 

2023/02/19

NTA-DIY:1ヶ月目⑥~実作:簡単なブックマークレット~

 基礎の基礎を一通り勉強したところで、次はブックマークレットの作成に挑みました。Scrapboxのページに書き込むものです。
 というのも、Scrapboxの特定のページに追記する(またはページを新規作成する)にはURLに文字列をくっつけて開けばいいと知ったので、それなら「ブックマークレットの書き方」さえ解ればすぐ実用的なプログラムができるだろうと思ったからです。


 それがどのくらい簡単なことかというと、最終的にwindow.open('https://scrapbox.io/:project/:page?body=:textの形の一文を実行できればいいのです。そのために必要なのは:textの部分の文字列を用意することだけです。書き込みたい文字列を作って、この一文に入れて実行させる。それだけなら全然難しいことはないわけです。
 なおブックマークレットは、JavaScriptで即時関数(読み込むと同時に実行する関数)を作って頭に「javascript:」をつけ、ブックマークのURL欄に設定することでクリック時に実行できるようになります。
 例えば以下の一文を登録して実行すれば動作の確認はできます。「:project」の部分には書き込みたいプロジェクトのURLを入れてください。「test」というページに「abc」と書き込まれます。「test」というページが既にあって編集日時が更新されると困るというような場合は、適当な英数字に変えて試してください。
javascript:(function(){window.open("https://scrapbox.io/:project/test?body=abc")})()
 ブラウザによってはポップアップのブロックで動かない場合があります。その場合は「https://scrapbox.io」のポップアップとリダイレクトを許可すれば動くと思います。(Chromeの場合→Chrome でポップアップをブロックまたは許可する - パソコン - Google Chrome ヘルプ
 これは、「window.open(url)」というメソッドを「(function(){ })()」で囲って即時関数にし、頭に「javascript:」をつけてブックマークレットにしているわけです。
 なおこの例では半角英数のみなので単純にURLを入れていますが、日本語や記号などはそのまま入れることができず、エンコードが必要です。エンコードは「encodeURIComponent()」というメソッドを使います。基本的に常にこのメソッドを通して設定することになります。
javascript:(function(){window.open("https://scrapbox.io/:project/"+encodeURIComponent("テスト")+"?body="+encodeURIComponent("本文"))})()
 これをブックマークに登録すると(:projectの部分は変えてください)、クリックするたびに「テスト」というページに「本文」が追記されます。

 実用的なブックマークレットを作成するにあたっては、ページタイトルと本文部分について、window.open()の手前に処理を加えて希望の内容を作ることになります。その処理によってブックマークレット実行時に自動で文字列を生成し、複雑な内容のページをScrapboxにワンクリックで作ったり、または既存ページに追記したりできるようになるわけです。
 例えば、今日の日付のページにダイアログボックスを通じて文字列を追記するとすればこんなふうになります。
https://gist.github.com/nora-tetsu/ace95fcf7d15612b4f1a23339dbf5f45
 一番下のコメントアウトされている部分がブックマーク登録用のものです。登録して実行すると、まずプロジェクトURLの入力を求められ、次に文字列の入力をすることになります。(自分で使うにはプロジェクトURLの入力は煩わしいですが、例として誰でも使えるようにするために入力する形にしています。)
 同様に今日の日付のページに、今度は現在開いているページを追記するなら以下のようになります。選択範囲があれば引用記法で追記されます。
https://gist.github.com/nora-tetsu/5f649fa7eef9dbb4042ab68c1ce64659

 JavaScriptに詳しくなればブックマークレットによって相当複雑なことができるようになりますが、最初のうちはそんな高度なことはできません。(私は現時点でも大したことはできません。)
 Scrapboxへのページ追加は、最低限ブックマークレットとして動かすために必要なことが非常に少ないので、練習にはうってつけでした。本文部分の文字列を作るコードを少しずつ複雑にしていくことで、データの扱いや各種メソッドを覚えていったのです。
 そして、Scrapboxの特定のページの作成・追記だけでも色々可能性は広がると思います。何より、UIに沿って手動で行うアナログな入力に縛られずに「プログラムで動かす」という経験をすることは、少し大袈裟に言えば世界の色が変わるような体験です。それ以上のことを実際にするかどうかは別として、「やろうと思えば色々できそう」と感じることは心を豊かにすると感じています。
 

2023/02/14

NTA-DIY:1ヶ月目⑤~小さいチャレンジ集~

 JavaScriptの勉強のごく初期は、単元ごとにその時点で知っていることを使って何かしらの極小プログラムを色々作りました。


 今となってはなぜわからなかったのかわからないところであちこち悪戦苦闘していたわけですが、どうにかもがいてひねり出してを繰り返して前に進んだのだなと思い出されます。
 当時書いたコード(をちょっと直したもの)なので誰かの役に立つとは思えませんが、思い出として記録しておきたいと思います。

四則計算する関数

function operation(x, y) {  
 return {  
 和: x + y,  
 差: x - y,  
 積: x * y,  
 商: Math.floor(x / y),  
 余: x % y,  
 };  
};  
console.log(operation(2, 3));  

 関数とオブジェクト(連想配列)の理解のために作ったものだったと思います。
 最初はオブジェクトもなんとなく掴めなかった、というか、「連想配列」という語でちょっと混乱したのですが、何がどう曖昧だったのかはもはやわかりません。

四桁の乱数生成

// 最小値x、最大値yの乱数を作る  
function random(x, y) {  
 return Math.floor(Math.random() * (y - x + 1)) + x;  
}  
  
// 四桁の乱数を表示する  
const n = random(0, 9999); // 乱数を用意する  
if (n < 10) { // 1桁の時  
 alert("000" + n);  
} else if (n < 100) { // 2桁の時  
 alert("00" + n);  
} else if (n < 1000) { // 3桁の時  
 alert("0" + n);  
} else { // 4桁の時  
 alert(n);  
};  

 乱数とIf分岐と数字を文字列として連結する練習のために作りました。
 当時はこれ以上すっきりさせる手段がわかりませんでしたが、今ならこう書きます。

const random = (x, y) => Math.floor(Math.random() * (y - x + 1)) + x;  
alert(('000' + random(0, 9999)).slice(-4));  

二桁×二桁計算クイズ

// 最小値x、最大値yの乱数を作る  
const random = (x, y) => Math.floor(Math.random() * (y - x + 1)) + x;  
  
// 問題の数を設定する  
const n = 5;  
  
// 繰り返す  
for (var i = 1; i < n + 1; i++) {  
 const a = random(11, 99);  
 const b = random(11, 99);  
 alert(`第${i}問(全${n}問)\n${a}×${b}は?`); // 問い  
 alert(`${a}×${b}=${a * b}`); // 答え  
}  

 乱数でできることが何かないかと探していて作ったものです。当初はもっと野暮ったい書き方でしたがちょっと直しました。
 最初の頃は、乱数というのが「プログラミングやってる感」の象徴みたいに思えて、とにかく乱数を使った何かを作りたい気持ちが強かったのを覚えています。
 alert()がクイズに便利だと思い、この形でクイズやゲームをあれこれ色々作っていました。もっと後の回で触れますが、何ヶ月か後ではダイアログを使ったゲームとして神経衰弱や簡易ポーカーを作ったりもしました。

Scrapboxに年リンクをまとめて作る

let t = '';  
for (let i = 2025; i > 1949; i--) {  
 t += `[${i}]\n`;  
}  
const body = encodeURIComponent(t);  
const projectName = 'hoge'; // 自分のScrapboxプロジェクト  
const title = 'temp'; // 書き込むページのタイトル  
window.open(`https://scrapbox.io/${projectName}/${title}?body=${body}`);  

 確かfor文を降順で作ってみることを目的に書きました。ついでに実用可能なものにしようと思ってScrapboxへの書き込みを活用。
 最初はブックマークレットもUserScriptも当然わからないので、どれかのページのコンソールかオンラインエディタで実行したのだったと思います。

 他に、Dateオブジェクトのことを知らなかった頃(勉強を開始して数日の、変数と配列とオブジェクトを学んだばかりの時点)、自力で年月日のデータを作り、ダイアログに情報を知りたい日付を入力すると、それがその年の何日目の何曜日で残り何日でその日生まれの星座は何で、その年は元号と十二支十干が何で閏年かそうでないか五輪があるのかないのかを表示できるプログラムを作ったりしました。
 それはかなり長期にわたり手を入れて、リファクタリングを繰り返して徐々に洗練させていきました。自力で年月日のデータを作ろうなんていうことに熱意を傾けられたのは初学者ゆえだと思いますが、たまたま年月日はDateオブジェクトがあるからやらなくてもよかったことであるにしても、その回り道で獲得した経験値はかなり大きなものだったと思います。
 そのコードは貼らないんかい、というツッコミがあるかもしれませんが、結構長いのと、あからさまに「やらなくていいことをやっている」感があってちょっと見せるには気が引けるので割愛致します。まあでも、Dateオブジェクトを最初から知っていても単に「ループ処理で配列を作りたい」という気持ちによって同じことをやっていたような気もします。当時も別に日付のデータが欲しかったのではなく、そういうデータを自分で作ることにこそ意味があったのです。

 最初の頃、分厚い解説本を読み込むとかいうことはしないでずっと手を動かしていました。ちゃんとした解説本はそこそこわかるようになってから読んだのですが、「もっと早く読んでおけば」と思ったかというと、正直全然そうは思いませんでした。
 逆に「ここまで来てから本を手にとってよかった」と感じたので、趣味でやるならそういう非体系的で場当たり的な学びもありだと私は思います(とはいえ基礎の基礎は初心者向けの解説本かサイトかアプリの力を借りるべきです)。個人の感想に過ぎないところではありますが、プログラミングに関しては空回りも無意味ではないということを強く感じています。
 

2023/02/13

NTA-DIY:1ヶ月目④~for文を解らないまま使う~

 プログラミングでは繰り返し処理(ループ処理)が非常に重要です。どんなツールを作るのでも避けては通れないことではないかと思います。
 そもそもの話、同じことの繰り返しを手でやらなくて済む、というのがコンピューターの最大の利点でしょう。


 ループさせるには、「どこからどこまで、どういう条件のもと繰り返すのか」ということを指定する必要があります。それがわからないとコンピューターとしては処理しようがないので当たり前のことなのですが、これがなかなか曲者です。
 JavaScriptでn回繰り返したいという時はfor文を使います。

for (let i = 1; i < 10; i++) {   
 console.log(i + "回目のループ");   
}  

 こうすると、コンソールに「1回めのループ」「2回めのループ」…「9回めのループ」と表示されます。同じ処理を9回繰り返したことになります。
 このfor文はプログラミングらしいことを実行するには必須なので、早い内に習得する必要がありますが、しかし構造としてはかなり複雑な形をしているように見えます。括弧の中の「let i = 1; i < 10; i++」ってなんやねん、と。括弧の中身はセミコロンで区切られた3つの文が含まれていますが、こういう形で書くものというのはfor文くらいでは?と思いますし、いきなりイレギュラーな形式と直面することになるのです。
 この文はつまりこういうことになります。

for (  
 let i = 1; // 初期化式(ループ開始前に実行する式)  
 i < 10; // 条件式(ループの継続条件を示す式)  
 i++ // 変化式({}内が実行される度に実行する式)  
) {   
 console.log(i + "回目のループ");   
}  

基本形は「iを初期化(i=0が一般的)」「iの条件を指定」「i++でカウントアップ」となりますが、こうでなければいけないわけではなく、無限ループに気をつければ色々複雑にすることも可能です。可能ですが、最初にfor文と出会った時には急に三種類の式の話をされても圧倒されるばかりで、応用なんてできる状態にはありませんでした。括弧内に文が複数入っている、という意味がまずもってわかりません。
 ではどうするか。「for (let i = 0; i < hoge.length; i++) {}」という形を単語登録(あるいはエディタのスニペット機能に登録)して、「弄るのはhoge.lengthの部分だけ」と決めてしまいました。よくわからんがhoge.length回繰り返すことがわかればそれでいい、ということです。つまり、理解するのをとりあえず諦めました。(そのように片付けて次に進むのは少数派ではないだろうと思います。)
 ちなみに、iを使ったループの内側でまたfor文のループをする際にはi以外の文字を使いたいので、「for (let j = 0; j < hoge.length; j++) {}」「for (let k = 0; k < hoge.length; k++) {}」も登録していました。コーディングのレベルが上がるにつれてこれらを使うことはなくなっていきましたが、最初は「ループの中でループ」という構造を形にしようとするだけでも精一杯なのでよく活用しました。

 繰り返し処理は他にも色々なやり方があります。それぞれに特徴があり使い分ける必要がありますが、最初のうちは学習コストが高いですし理解するより動く何かを作りたかったので、馬鹿の一つ覚えを決め込んでfor文+if分岐のゴリ押しでいきました。ループの仕方はどうあれここからここまでこれを繰り返せればいいのだ、ということです。慣れてきて「なんかfor文連発はダサいな」と感じたら他のやり方を覚える良いタイミングだなと思っています。
 なお一年が経ち一応理解はしても、敢えてfor文を複雑にしてループさせたいタイミングというのはありませんでした。ただ他の人が書いたコードを読むにあたってはfor文が捻って使われていることがしばしばあるので、そういうコードを見た時にはやはり「ちゃんとわからないと駄目だ」という気分にはなりました。
 理想はその都度理解して適切なものを選択することです。ですがプログラミングが得意なわけでもなく現実はそうスムーズにはいかないので、回り道万歳と思ってやるのが良いと思っています。楽しんでいさえすれば、いずれ「そもそもこれってどういう意味なんだろう」と気になってくるように思います。
 そしてこのことは、あらゆる勉強に於いて同じではないかなと思います。
 

2023/02/12

NTA-DIY:1ヶ月目③~おみくじいろいろ~

 プログラミング学習の定番におみくじプログラムの作成があります。乱数と条件分岐を使うので、おみくじを作れるようになればすなわち他にもできることがぐっと増えるというわけです。


 このシリーズは私の体験記として書いているので、良い手本を見せようというのでもなければ懇切丁寧な解説をしたためるのでもありません。しかし、実際何をやったかを書いておくことには多少の意味があると思うので、コードをちょこちょこ書いておくことにします。
 おみくじとして成立するためには、「乱数を生成する」「生成した乱数に応じて結果を表示する」の二点が必要です。乱数の生成にはバリエーションはそんなにありませんが、乱数に対応する結果の呼び出し方にはいくつか方法があります。私が勉強に使った記事ではひとつの方法だけ例として書いてありましたが、これでもできるんじゃないかと自分で他の方法を考えて試しました。
 捻りも何もないコードですが、自力でチャレンジしたい方もいらっしゃるかもしれないので折り畳んでおきます。

①基本のif分岐 ```js const r = Math.random() * 5; // 0以上5未満の乱数を生成する if (r < 1) { console.log('大吉です'); } else if (r < 2) { console.log('中吉です'); } else if (r < 4) { console.log('吉です'); // 吉の出る確率を高く設定 } else { console.log('凶です'); } ```
②わかりやすいswitch文 ```js const r = Math.floor(Math.random() * 5); // 0以上5未満の整数の乱数を生成する let result = ''; switch (r) { case 0: result = '大吉'; break; case 1: result = '中吉'; break; case 2: case 3: result = '吉'; // 吉の出る確率を高く設定 break; default: result = '凶'; } console.log('運勢は' + result + 'です'); ```
③配列ですっきり ```js const r = Math.floor(Math.random() * 5); // 0以上5未満の整数の乱数を生成する const fortune = ['大吉', '中吉', '吉', '吉', '凶']; // 配列を用意する(吉の出る確率を高く設定) console.log('運勢は' + fortune[r] + 'です'); ```
 具体的にどう書いたのかというのはおまけなので、細かく見なくていいです。検索すると他のやり方も色々出てくるだろうと思います。  何かひとつ新しいことを覚えた時、それを使って何ができるのか可能性を考えるのが楽しく感じました。たとえその先に出てくることでさらっとやれてしまうことなのだとしても、今知っていることだけでどうにかできるかもと考えていくわけです。  ツールづくりに入ってからも、便利な組み込みメソッドが既にあることに気付かず、同じ挙動のものを自分で関数にしていたというのがいくつかあります。一言で言うとアホですが、本人は「やはりこれは一般的に多用される処理なのだ!」と思ってむしろテンションが上がりました。学習効率としては非効率なのかもしれませんが、気持ちの面では独学でマイペースにやっているがゆえのボーナスと感じました。それに、気分の良さがブーストになるのだとすれば、非効率イコール遠回りとも限りません。  コンピューターは寛容です。エラーにならなければなんでもやってくれます。思いつく限り試せるものは何でも試すというのが、主体的な楽しさを維持できる姿勢だと思います。

 ところで、1ヶ月目は覚えたことや気付きが多いので、記事の本数としては12ヶ月で均等ではなく1ヶ月目に偏って多くなると思います。もうしばらく初期の話にお付き合いください。
 

2023/02/11

NTA-DIY:前日譚②~JavaScriptを書けると何が嬉しいの?~

 JavaScriptの勉強を始める前、数ヶ月かけてCSSを勉強していました。CSSもなかなか一筋縄ではいかないもので今でも自由には使えませんが、ある程度は想定した通りの見た目を作れるようになりました。
 人が作ったものをただ取り入れるのではなく自分でカスタマイズすることで、アプリケーションは全く違った使用感になる、ということをCSSの習得を通じてひしひしと感じました。


 しかしながら、それならJavaScriptを覚えたら劇的に豊かになる――と思えていたかというと、そういうイメージは全然持てていませんでした。JavaScriptを使えるようになると何が嬉しいのか、少しも想像できなかったのです。何が嬉しいんでしょうかと人に尋ねたこともありましたが、説明されてもなおピンと来ていませんでした(「はあ、なるほど?」という感じでした)
 知らないものなのだから想像できないのは当たり前、ということはあるでしょう。たとえばサービスについての英語の説明などで、そのものの定義ではなく「それで生活がどう変わるか」というようなことばかりを書かれ、かえって不親切に感じることがよくあります。そのものについての知識が全然増えていかないからです。(だからそういう説明は駄目だ、という主張ではありません。大抵はどう説明されても結局使ってみなければわからないのです。)
 そしてそれまでプログラミングをほぼやらずに生きてきたわけですから、プログラミングというものなしに自分の世界は完結していました。プログラミングが自分の生活に含まれていないことに、何か不足を感じていたわけではないのです。コンプレックスはあれど、なくても何も困っていませんでした。
 今となっては、当時悩みの種になっていたことはプログラミングの力で様々解決できるものだったとわかりますが、その時点ではそんなことはわからないので、プログラミングができればあれもこれも解決するのになあ、なんて思うことはなかったのです。

 私にとって幸い突破口になったのが、「HTMLを使ってブックマークを管理したい」という思いでした。詳しいことは別途書きますが、HTMLに自分好みの見た目でリンク集を作りたいと考えた時に、「ベタ打ちはつらいからCSVの中身を表示できたら嬉しい」と思いました。多分それはJavaScriptの出番ってことだろうと想像し、なんとか望みのものを作った時に、「じゃあこれができるんじゃないか、あれができるんじゃないか」と思い巡らすことができるようになったのです。
 その時私が獲得したイメージというのは、「JavaScriptを使えば、Excelのような表データに好きな見た目をつけられる」というものでした。今はCSVではなくJSONを使っていますが、ともかく、データに見た目を用意する手段を自分で作れるのがJavaScriptなのだと気がついた時、私の中でプログラミング脳になるスイッチがカチッと押されたのだと思います。
 

2023/02/10

NTA-DIY:1ヶ月目②~感動したもの勝ち~

 さてJavaScriptの勉強の話に入っていきます。
 プログラミング教育を受けていない且つプログラミングに苦手意識が強い大人たちに宛てたような文章です。


 ごくごく簡単なものですがコードを含むので、JavaScript未経験でちょっと試してみたいという方はJSFiddleというオンラインエディタを使ってみるとよろしいかと思います。

画像

 JavaScriptの勉強を始めて最初にやるのは「console.log("Hello world!");」または「alert("Hello world!");」でしょう。Hello worldというのはプログラミングをスタートする際のお決まりの文句です。console.logはコンソールという領域にログを記述するもので、alertはダイアログを表示するものです。
 実行して「おお、Hello worldできたぞ」と思ったら、今度は「console.log("こんにちは世界");」とでも書き換えて実行します。すると当然「こんにちは世界」と表示されます。「おお、できたぞ」と思うわけです。
 次に変数を勉強することになるでしょう。

var a = "あいうえお";   
console.log(a);  

でコンソールに「あいうえお」と表示されます。「おお、できたぞ」と思います。今度は別な文字列や数字などでやってみます。
 文字列を連結することも覚えるでしょう。

var n = "のらてつ";   
console.log("私は" + n + "です");  

で「私はのらてつです」と表示されます。「おお、できたぞ」と思います。今度は複数の変数を連結させてみます。

 とにかく、何かをやる度に「おお、できたぞ」と感動するわけです。捻りがあるわけでもないのでできるのは当たり前なのですが、当たり前でも「おお、できたぞ」と。 私たちは日々さまざまなことを行い、そして学びますが、「そうなって当然」のものに「おお」と感動するのはなかなか難しいものです。そもそも「これでオッケーなんだ」とはっきり答えを得られるとも限りません。 プログラミングでは正しいか正しくないかが明快です。正しいか、正しくないか、のふたつにひとつなのです。そして個人でやっている分には、正しくなくても誰にも迷惑はかかりません。誰にも怒られません。逆にしょぼいことに喜んでも誰にも笑われません。「1+1=2」という計算と同レベルの超初歩のコードに「おお」と思っても構わないのです。
 更に、コードは綺麗でなくともコンピューターが読めれば「正しい」ことになります。ダサくてもいいのです。恥ずかしいなら他人に見せなければいいだけで、コンピューターは「だっさwww」とか言ってきません。変な迂回をすると処理に時間がかかってしまうケースはありますが、大規模なデータを扱わなければ支障が出るほどにはなりません。気づいた時にひとつひとつ直していけばいいのです。
 たとえ変なエラーを出しても、コンピューターは「おかしいところがありますよ」と知らせてくれるだけで、「馬鹿だなあ」とか言ってきません。「うまくいくまで手当り次第に試す」という力技でゴリ押ししてもコンピューターが堪忍袋の緒を切らすことはありません。そういう試し方をするとまずい領域というのはありますが、初学者の勉強の過程にはそういうものはそんなにないと思います。(ただしScrapboxのUserScriptとかは気をつけた方が良いです。力技の行使は大事なデータと繋がりがない場所に限るが吉でしょう。)

 何をそんなに強調しているかといえば、勉強の敵は他者の評価だという個人的な経験則です。例えば日本人の英語の下手さの何割かは他者の目があることによると思っています。他者に対する背伸びによって成長が促進される部分と、望んでもない評価でやる気を削がれる部分とがあり、それは慎重に天秤にかける必要があります。
 勉強の成果をリアルタイムで公開とかすると、腕に覚えのある先輩プログラマーから「なんでそう書くの? こうしたらいいのに」とか言われて「うっ」となることもあるでしょうから、積極的に助言を得たいのでなければひとりでこっそりやっていてもいいと思います。自分のペースに合わない助言は時に負担となります。
 もちろん、むしろどんどん言ってもらえた方が近道だしありがたい、という人は公開した方が良いと思います。

 私が考える、初学者に於いて最も重要なことは、「おお、できたぞ」という感動です。うまくやれているかとか、よりモダンかとか、無駄がないかとか、そんなことは二の次三の次です。動けばいいのです。もちろん職業プログラマーになるなら別ですが、そういう志のある人はこんな記事は読んでいないでしょう。とにかく動けばいいのです。動かしているうちに勝手にうまくなりますしモダンにもなっていきますし無駄は減っていきます(最短ではないにしても)。とにかく動けばいいのです。そして「動く」ことに感動するのです。それは、そういう言語を誰かが作ってくれたことやコンピューターというものが自分の目の前にあることへの感謝も含めての感動とも言えるでしょう。
 そうやってとにかく動けばいいということにして「おお」「おおー」「おお~」と思いながらやった結果、多分自分としてはこれ以上速くならないんじゃないかなという速度でJavaScriptを習得していったと思います。独学なので自分に必要なことだけやっており、学習内容は網羅的ではありませんが、苦手意識をなくすのには十分です。
 プログラミングというのは無邪気に楽しんだもの勝ちだと思っています。まだプログラミング二年生の分際ですが、私はそう思います。
 

2023/02/07

タスク管理の変遷語り

今月のテーマである「今日(こんにち/きょう)のタスク管理」について。自分のこんにちの形式に至るまでの経緯を振り返ってみたいと思います。フローの説明というより認識の変化の話になるのでちょっと長くなります。

管理人

アイコン画像

のらてつ Noratetsu

キーワード

このブログを検索

検索

ブログ アーカイブ

2025
2024
2023
2022
2021