プログラム

ブクログのエクスポート機能で出力されたCSVファイルから特定期間に読了した本のMarkdownテーブルを出力する

タイトル通り。

今日書いたエントリーで使った様なテーブルをブクログのエクスポート機能で得られるCSVファイルからGoogle App Script で作成する方法。
実行するとシートの末尾にMarkdownが出力される。

function generateMarkdownTable() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();
  var markdown = "| タイトル | 作者名 | 出版社名 |\n| --- | --- | --- |\n";

  for (var i = 1; i < data.length; i++) {
    var row = data[i];
    var completionDate = new Date(row[10]); // 読了日の列インデックスを仮定(例:11列目)
    var startDate = new Date("2023/01/01");
    var endDate = new Date("2023/12/31");
    var itemID = row[1]; // アイテムIDの列インデックスを仮定(例:2列目)

    if (completionDate >= startDate && completionDate <= endDate) {
      var title = row[11]; // タイトルの列インデックスを仮定(例:12列目)
      var author = row[12]; // 作者名の列インデックスを仮定(例:13列目)
      var publisher = row[13]; // 出版社名の列インデックスを仮定(例:14列目)
      var titleLink = "https://www.amazon.co.jp/dp/" + itemID;

      markdown += "| [" + title + "](" + titleLink + ") | " + author + " | " + publisher + " |\n";
    }
  }

  // 最後の行にMarkdownテーブルを追加
  var lastRow = sheet.getLastRow();
  sheet.getRange(lastRow + 1, 1).setValue(markdown);
}

ChatGPTと会話してGoogle Apps Scriptのスクリプトを組み立てる

仕事で使っているあるスプレッドシートをソースとしてある分析をしたいと思ったときにChatGPTのcode interpreterを利用して分析してもらおうと一瞬思ったのだけれども、そのソースのスプレッドシートのサイズがある程度の大きさだったり、そもそも扱っているデータの兼ね合いもあるので、ChatGPT側で処理をするのではなくて以下の様な手順でGoogle Apps ScriptをChatGPTに組んでもらった。やり方は...

  1. ChatGPTに目的とする分析結果を得るための手法を3つ提案してもらう
  2. 提案してもらった中から現状のデータセットを鑑みて試してみたいと思う手法を1つ選ぶ
    1. で選んだ解析をGoogle Apps Scriptで実装してほしいと伝える。その際にスプレッドシートの仕様を添える (1行目はラベルで2行目以降にデータがセットされており1列目は識別子で2列目は... といった具合でデータの諸元となるシートの仕様を箇条書きにして伝える)
  3. ChatGPTから出力されるGoogle Apps Scriptをスプレッドシートにセットする
  4. スクリプトを実行する
  5. 実行した結果を確認する

といった流れ。4.から6.を繰り返してブラッシュアップしていくのだけれども30分くらいのやりとりで120-130行くらいでかなりスマートな(と自分には見え、少なくとも自分には書けない)スクリプトを出力してくれて、これを現時点での自力で書いてたらもっと時間かかっていただろうなと思うのと、こういったやり方が引き続き実現できるのであれば30代までにエンジニアとしてコードを書くことを生業にしていたことが違う形で活かすことができて面白いなと思った。
出力されるコード自体が所望の動きをするものかは確認しないといけないのだけれども、それも

  • ログを入れてほしい
  • 出力結果の検証をしたいのだけれどもどういったログを確認するとよいか

といったコミュニケーションをChatGPTと取っていたら、各処理の開始と終了、データをパースする際の先頭と最後をログ取る様にするのでそれが意図した挙動の出力になっているか確認するとよいと思うと言われ、ではそれで確認するのでスクリプトをアップデートしてほしい。といった一連のやりとりでスクリプトは更新されていくのであった。
そして、それで確認すると変なところでセル内の数値の加算の処理がスクリプトでは文字連結されているのに気づいたり、集計時のハッシュのキーが誤っていたりと不具合に自分が気づき、再びそれをフィードバックすると... という具合で自分が望むスクリプトが組み上がっていくのは二人組になってペアプログラミングしている様な感覚。

もう少しこのあたり自分なりに体系化してみたい気もする。

ブクログで表示中のページからアイテムページのURLを抽出する

タイトル通りのメモエントリー。

月に一度、読んだ本のまとめをブクログで抽出してそれをこのブログのエントリとしてまとめていて、以前は貼り付け用のコードが公式から提供されていたのだけれども廃止になったので温かみのある手作業でアイテムページのURLをコピペしていた。同じことを3回やったら自動化できないか考えたほうがみたいなことを普段は棚上げ力を発揮して発言していたのだけれども、いい加減一発で取得できる様にしようということでChatGPTに教えてもらった。

以前だったらこういうのなんとなくこういう感じでコード書くんだろうな。あれ、この正規表現のときどうだっけ...と調べながら書いてたのがスッと出てくるのは生産性劇的に違うなと実感する。

いや、このくらいだったらChatGPTに聞かづとも出てくるでしょうという指摘は甘んじて受けます...。

let htmlContent = document.documentElement.innerHTML;
let regexPattern = /https:\/\/booklog\.jp\/item\/1\/[A-Za-z0-9]{10,13}/g;
let extractedStrings = htmlContent.match(regexPattern);

if (extractedStrings !== null) {
  extractedStrings = [...new Set(extractedStrings)];
  extractedStrings.forEach(url => console.log(url));
} else {
  console.log("No matching URLs found.");
}

通院, OpenAI APIと戯れる – 2023年3月19日

午前中は通院などあって付添のため外出。移動中には先日から読み始めた「シャープ 再生への道」を読む。

自宅に戻ってから、先週来からのChatGPTの盛り上がりを受けてOpenAI APIを介した実装に興味が湧いてきたのでシンプルにhttps://github.com/hideack/slack-cli-streamのコマンドとして実装をしてみた。
OpenAI API向けのAPIクライアントのNode.js実装は公開されているものがあるのでサンプルに従って実装したらすぐ呼び出しまで行えた。コマンドとして試したものはSlackの時系列を眺めるなかでふと気になったことがあったら同プログラムのコマンドラインから

> gpt おいしいカレーの作り方を教えてください

といった形で対話の文字列を与えることでAPIに渡せることができてその応答がSlackなどの発言に混ざって帰ってくるもの。

https://github.com/hideack/slack-cli-stream から OpenAI API呼び出しの様子

gpt + 質問文字列 でOpenAI APIを介してリクエスト

どちらかというと久しくコードを書いておらず、VSCodeを開いてvimプラグインを入れてみるなどのテスト勉強になると突然机の周りを整理しだす学生かの如く、開発環境に手を入れ始めてしまい、その中で先のプラグインを入れたときにキーを押しっぱなしにしてもカーソルが動かず、その原因を調べる中で更に深みにはまり... といったことにも時間を使ってしまった。でも、こういうところも含めてコードを書くのは楽しいと思ったのだけどこういった行為もAIとの対話の中でどういった位置づけになるのだろうとふと考えたりした。
なお、このvimプラグインを入れたときの問題は以下のサイトで示されている解決策で解決した。先に書いておくとVSCodeのコンソールから以下の設定を入れた。

defaults write com.microsoft.VSCode ApplePressAndHoldEnabled -bool false # For VS Code
defaults write com.microsoft.VSCodeInsiders ApplePressAndHoldEnabled -bool false # For VS Code Insider

MiniMagickで画像の文字を重ね合わせて新たに画像を作る – 2022年2月13日

この週末三連休の自由研究(?)の一環。
Rubyでテンプレートになる画像を読み込み、その画像の上に文字を重ね合わせ画像ファイルとして書き出すまでの一連の流れは以下の様な形で試すことができたというメモ。

require 'mini_magick'
image = MiniMagick::Image.open("template.png")

image.combine_options do |config|
  config.font "font.ttf"
  config.pointsize 64
  config.fill "#ff0000"
  config.gravity "center"
  config.annotate "0,0", "ここにメッセージを入れる"
end

image.write "#{SecureRandom.hex}.png"

久しぶりに試行錯誤しながらプログラムを書いて動かした。

Railsチュートリアル 第6版 をはじめた

最近、コード書いたりめっきりできてないなと思ったところもあったので、改めてRailsチュートリアルを課金して改めて頭からやってみることにした。目標はカラーミーショップAPIを使ったRailsアプリを1アプリ作ってみることにしてみる。

少し脱線するけども、自分がどういう役割や職位であっても根はエンジニアであり続けたいと思っているので、

  • 事業設計であったりもコードを書いたり設計をしたりするときの視点を持ってみる
  • 事業で直面した技術的な課題に対しての困難さであったりの「あのあたり感」は持ち続ける
  • 素直に周りの人に教えをこいながら技術やトレンドをキャッチアップをしていく (これはエンジニアに限らずだけれども)

といったことは自分の人生の中で仕事をしている間は姿勢として持ちづけたいと思っている。

Google Colaboratory (Colab) でProphetを利用する

突発的に投下されるtipsエントリー。

何らかの時系列データが手元にあるときに先々の予測を行う際に使えるツールとして、Facebookが開発した時系列予測のオープンソースソフトウェア(OSS)ライブラリProphetがあります。

以前書いたエントリーの「Prophetを触ってみる」においてはpyenvとpipを利用して手元のMacなどの環境に直接入れるやり方だったのですが、今回はGoogle Colaboratoryを利用するやり方になります。

続きを読む

CIをGitHub Actionsに移行した

Slack眺めるくんこと https://github.com/hideack/slack-cli-stream で書いているささやかなテストをCircle CIで動かしていたのだけれども、社内や自分が携わっている事業部でGitHub Actionsが活用されているのを横目で見ていたので、どんな形で動くのかくらいわかりたいなと思っていたので少し試してみた。

導入はシンプルにできてリポジトリにあるActionsのタブ (今回だと現在のリポジトリの状況に応じてある程度Workflowがレコメンドされるのでそこから "Set up this worklfow" を選択するとGitHub Actions設定用のYAMLの編集になるのでそれをコミットするだけで完了した。

リポジトリページのタブにあるActionsを選択するとこの様な形でレコメンドされる

実際にGitHub Actionsを通して今回のリポジトリに設けてあるmochaでテストを走らせることはできたのだけれども、手元やCircle CIで通っていた一部のテストが落ちてしまった。はて、これは原因何だろうかと見ていく上で、そもそも落ちているテストを確認すると文字色を変えるためのキャラクターコードが想定どおり出力されているかを確認しているものであった。

ターミナルのセッティングとかそのあたりに依存するのだろうかと思い、いくつかこのあたりのキーワードを元に色々と調べていると以下のコミュニティーの議論に到着した。mochaを実行する際に--colors というオプションを与えることで解決できた。

無事、テストがパスする様になったことを確認してmasterにマージしてGitHub Actionsデビュー第一歩を踏み出した。

mac-peripheral-batteryというnpmを登録した

先日書いたMacに接続したMagic Keyboardの電池残量をコマンドラインで得るというエントリの内容をシンプルなnpmにして公開した。ioregのコマンドをラップしてBatteryPercentという要素を持ち得る周辺機器(主としてはMac製品)のそのコマンドで得られる結果をJSONに置き換えているだけのものだけれども。

npm install -g mac-peripheral-battery

でインストールした上で実行すれば先日紹介した様なJSONが得られる。

実行結果

得られるJSON例

こういった形で得られるのでバッテリ残量の割合が求めたければjqコマンドと組み合わせて

☁ mac-peripheral-battery | jq .[0].BatteryPercent | awk '{printf "Magic Keyboardバッテリー残量 %d%%", $1 }'

Magic Keyboardバッテリー残量 70%

こんな形になるので、あとはSlack通知するなりMacのステータスに表示させるなりすれば「よさそう」なところまで持っていける。