HP Pavilion 15-eh3000 : タッチ対応で32GBメモリに増設可能な格安PCのメモリ交換記

以前使っていた DELL Inspiron の 2-in-1 の PC のバッテリーが、2時間程度しか持たず実用的ではなくなってきたので、買い換えたい。

予算もあまりないので安く済ませたいのだが、どうしてもタッチ対応は外せないし、PCを更新するなら RAM は 32GB にしたい。

しかし選択肢は意外となく、最終的に HP Pavilion 15-eh3000 を購入し、メモリを 32GB に増設(換装)する方法に行き着いたので、そのメモ。

購入 PC の条件

条件を決めないことには PC を選べないので、とりあえず以下の条件で探すことにした。

  • ノート PC
  • タッチ対応
  • メモリ (RAM) は 32GB
  • 予算は 8~9万 程度
  • CPU は Core i5 / Ryzen 5 程度ならなんでも
  • 内蔵グラフィックで OK
  • DELL 以外

本当は筆圧対応ペン入力対応な 2-in-1 の方がよかったのだが、価格やメモリサイズ的に条件を合わせるのが難しいのがわかっていたので、泣く泣く妥協している。

タッチパネルやペン入力載せるようなモデルは、実装スペースの関係かオンボードメモリのものばかりで、BTO のカスタマイズで 32GB の選択肢すら存在しないものが大半である。

価格.com では、メモリの空きスロットや、メモリ交換の可否で絞り込むことができない。
価格.com のキーワードに「メモリスロット」と入れ、 PCビューで詳細表示すれば、絞り込めはせずともSO-DIMMスロットがあるモデルが多少探しやすくはなるが、そんなに選択肢がない(価格.comに載っていないだけかもだが)ことがわかる。

この方法で、SODIMM スロットが2つ存在するモデルを検索し、自分で 32GB メモリに換装する方針で絞り込んでいった。

Lenovo あたりだと、1枚オンボードで 1枚 SODIMM スロットという変態構成の端末がある。
しかし1枚だけメモリを増量させても、デュアルチャンネルにならないことや、相性問題が起きやすいリスクがあるので避けている。

DELL を除外しているのは、以前私用で使っていた Inspiron も、会社で使っていた Latitude も、どちらもスリープ処理が下手くそで非常に困ったからだ。
ちゃんとスリープされず、電源につないでいれば24時間ファンをぶん回してうるさいし、バッテリー状態にしておくと勝手に5%まで残量減らしてるし、どれもどうも調子が悪かった。
毎日そんな不要な充放電が繰り返された結果、あっという間にバッテリーが劣化してしまったのが、若干トラウマになっている。

結局、 HP Pavilion 15-eh3000 の Ryzen 5 7530U + 16GB RAM モデルに...

続きを読む

Raspberry Pi 5 に Ubuntu 24.04 LTS を入れて SSH するまで

ついに日本でも、 Raspberry Pi 5 の技適対応モデルが発売された。

Raspberry Pi にインストールする OS と言えば、まずは Raspberry Pi OS (旧 Raspbian) だが、同じ Debian ベースの Ubuntu も Raspberry Pi 向けの公式イメージを出している。

但し、 Raspberry Pi 5 に対応しているのは、 Ubuntu 23.10 (コードネーム: mantic) 以降のみとなる。

現在リリース済みの 23.10 は「非LTS」バージョンとなり、サポートが 9ヶ月 (2024年6月まで) と短い。
常用するなら、サポートが 5年 (ESM なら 10年) と長い LTS バージョンが望ましいが、残念ながら 22.04 LTS Raspberry Pi 5 に非対応だ。

LTS バージョンの次回リリースは 24.04 LTS (コードネーム: noble / 2024年4月リリース予定) で、現在絶賛開発中だ。

そんな開発中の 24.04 LTS も、デイリースナップショットが手に入る。
そいつを使ってディスプレイやキーボードが無い状態で、インストールから SSH 接続までやってみよう。

Raspberry Pi 5 をターゲットに書いているが、 Raspberry Pi 3, 4, Raspberry Pi Zero 2 W でも同じ手順でできるはずだ。

なお、この記事は 24.04 LTS がリリースされたら、それに併せて内容に書き換えていくつもり。

TL;DR

準備するもの

  • Raspberry Pi 5
    • Raspberry Pi 3, 4 でも同じ手順でいけるはず
  • 4GB 以上の micorSD カード
    • IOPS が高い、「アプリケーションパフォーマンスクラス」が A2 のものが良いだろう。値段や速度を考えると、実用上は 64GB 以上になるだろうか。
    • 私は、ARCANITE 64GB microSDXCカード 【A2】、UHS-I U3、V30、4K、C10 値段の割にパフォーマンスが良かったため、これを使った。
    • 後述するが、最終的には NVMe SSD にした方が断然良い
  • microSD を書き込める PC (Win, Linux, mac)
  • インターネットに繋がる Wi-Fi または イーサネットケーブル

以下もあると便利だが、今回の手順では無くても問題ない。

  • micro-HDMI で繋がるディスプレイ 又は 変換コネクタ
  • RasPi に繋げる USB キーボード

イメージファイルの取得

続きを読む

JavaScript で TOTP を計算する

TOTP: Time-Based One-Time Password Algorithm とは、二要素認証でよく見る Google Authenticator 等で QRコード を読み込ませたりして、一定時間毎に替わる 6桁 くらいの数字を入力するアレだ。

RFC 6238 に詳しい仕様が書かれている。
コイツを TOTP をブラウザ上で生成したい。

幸い近年の Web API には、バイナリ操作やクリプトまわりの機能が出揃っているので、わりかし簡単に実装できそうだ。
…とまぁ、そんな愚生が思いつくような話など既に、偉大なる先人たちによる多くのサンプルが残されている。

せっかく自分で実装するなら、最新の ES 仕様や Web API を活用して簡潔に、それでいて汎用的な仕様で書いてみよう。

実装

続きを読む

D&DしたQRコード画像をブラウザ上でデコードする

ブラウザ上にドラッグ&ドロップ (D&D) されたQRコードの画像を、読み込んでデコードするUIを作りたい。

Pure JavaScript で動作する、QR コードデコーダー(パーサー) cozmo/jsQR が有名なので、これを使ってみよう。

jsQR は、 png や jpg といった画像コンテナの解凍機能も、 HTML や DOM, Web 周りに特化した機能も一切無いため、読み込ませた画像は何らかの方法で Uint8ClampedArray な RAW 画像に変換して渡す必要がある。

ちょっと遠回りにはなるが、

  1. D&D されたファイルの File API を読み取る
  2. FileReader API を使って、ファイルを DataURI として読み込ませ、 img タグに表示させる
  3. OffscreenCanvasOffscreenCanvasRenderingContext2D を経由して ImageData を作成する
  4. jsQR に処理を投げる

といった処理になるだろうか。

早速実装してみよう。

実装

続きを読む

ブラウザのタイトルや URL をコピーするブックマークレット【スマホ&阿部寛対応】

ブラウザで表示しているページのタイトルと URL を一括でコピーしたり、 markdown などのマークアップ言語でフォーマットされたものを、クリップボードにコピーしたくなることは無いだろうか?

意外にも、主要なブラウザには表示ページのタイトル名すら簡単にコピーする方法がない。

いくつかのブラウザ拡張機能(アドオン)には、上述の機能を提供しているものがいくつもある。
しかし、これだけのために拡張機能を入れるのもなんだかなと。
場合によっては、ポリシー等様々な理由で拡張機能を入れることを制限されている場合もあるだろうし。

そこで、表示中ページのタイトルと URL を任意の種類にフォーマットしてクリップボードへコピーしてくれるブックマークレットを作ってみた。

ブックマークレットとした事により、拡張機能の使えないスマートフォンの Chrome や Safari といった、とても不便なブラウザでも利用できる。

使い方

ブラウザのタイトルや URL をコピーするブックマークレット

続きを読む

VSCode + MinGW-w64 via MSYS2 で WIN32API の Unicode ビルド

VSCode + MinGW-w64 via MSYS2 で WIN32API の Unicode ビルド
本記事は C++ Advent Calendar 2023 の6日目の記事だ。

5日目は @uyamae 氏の C++ をclang で解析するときに情報をvcxproj から取得する方法 だった。


Windows 上でサクッと C++ ビルド環境を用意したい

さて、Win32API のコードをビルドしたいけど Visual Studio を入れるまでもない場合、 MinGW の GCC C++ コンパイラ (g++) と Visual Studio Code (VSCode) の組み合わせでも割と快適にビルドできる。

しかし、 VSCode のドキュメントの手順 そのままでは マルチバイト・Unicode周りでハマったので、非ASCII 圏で問題ないように設定する方法を紹介する。

先に解決方法だけ示しておくと、

  1. tasks.json の g++ ビルド時の引数を書き加えてやりつつ

                 "command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
                 "args": [
                     "-fdiagnostics-color=always",
    +                "-DUNICODE",
    +                "-D_UNICODE",
    +                "-municode",
    +                "-std=c++23",
                     "-g",
                     "${file}",
                     "-o",
                     "${fileDirname}\\${fileBasenameNoExtension}.exe"
                 ],
  2. C/C++ extension for VS Code の設定から、 以下の IntelliSense 設定も変えればよい

    • 定義:

      _DEBUG
      UNICODE
      _UNICODE
    • C 標準: c23

    • C++ 標準: C++23

VSCode + MSYS2 上の MinGW-w64 の組み合わせでの設定

続きを読む

Power Automate で少ないステップ数でコレクションを操作するコツ

本記事は、 Microsoft Power Automate Advent Calendar 2023 - シリーズ2 の5日目の記事だ。

"シリーズ1" の4日目は、 @inaho3517 氏の 本でPower Automateを勉強してみた だ。
ちょっとAmazonで検索しただけでも、 めっちゃ本が出てる のね…
知らなかった。
シリーズ2はまだまだ空きがあるので、ぜひご参加を。


実行ステップ数を節約したい

さて、 Power Automate を含め Microsoft Power Platform には、プラン毎に最大要求数の制限がある。
例えば、多くの人が使っているだろう Office 365, Microsoft 365 F3/E3/E5 に含まれる Power Automate の場合、 24時間ごとの 6,000 要求数が上限だ。

Power Automate では、実行されたトリガー・アクションひとつひとつが、結果の成否にかかわらずこの「要求数」を消費する。
大きな数のループや、2重ループなどを行うと、意外と簡単に 6,000 要求数に達してしまう。

時々妥当な範囲で上限を超える程度なら、即時実行をブロックされることはない ものの、設計の段階では超えない事に越したことはない。

唐突だが、アルゴリズムなどの計算量の効率を示す指標として、オーダー表記というものがある。

雑に説明すると、N件のデータを処理するのにどれくらいの勢いで計算コストが増えていくかと言ったもので、例えば単純なループ処理なら O(N), 2重ループとかになると O(N2) といった書き方をするのを、一度は目にしたことがあるのではないだろうか?

ということで、ループによってアクション要求数(ステップ数)が増えがちな Power Automate のコレクションの処理を例に、ループ処理を排除し O(1)定数時間で処理する方法を紹介する。

とりあえず Office Script?

続きを読む

ブラウザ操作中の通信の内容をローカルファイルに自動で保存する

本記事は JavaScript Advent Calendar 2023 の4日目の記事だ。

3日目は @feo52 氏の 最初のレンダリング直前に起動するpagerevealイベント #JavaScript だった。
Window インターフェース に最初のレンダリング直前に呼ばれる pagereveal イベントを追加する提案の実装を Chrome で試してみる内容だ。これは確かに便利そうなイベントに感じる。
令和の IE こと Safari の存在のせいでなかなか Web 標準に組み込まれる敷居が高いものの、是非ワーキンググループでの議論が進んでいただきたいモノだ。
ところで、こういうのって CSS のワーキンググループでドラフトに載ったりするのね。詳しい流れはよく知らんけども。


いにしえの自分の回答がわかりにくい

さて、ブラウザが裏で呼んでいる API の内容をファイルに書き出したかったのだけれども、ファイルサイズが大きいからか開発者ツール経由ではうまく保存できなかった。
そこで、ブラウザ操作中の通信の内容をローカルファイルに自動で保存する方法がなにか無いかな~と探していたら、偶然にも以前に自分自身がスタック・オーバーフローで回答した puppeteer を使った方法についての内容がヒットしてしまった。

すっかり忘れていたのだが、今見返すとちょっとこのままだと使いづらそうなので、もうちょい使いやすくまとめてみる。

基本的には以前に書いた以下の記事と同じ考え方で、 Chrome DevTools ProtocolFetch Domain を直叩きして、特定の通信の内容を横取りしてローカルに保存している。

実際のコード

続きを読む

Docker Compose で、ベースイメージが更新された場合のみ再 up する

本記事は Docker/コンテナ仮想環境 Advent Calendar 2023 の3日目の記事だ。

2日目は @ko-he-8 氏の /var/lib/docker/が肥大化していたけどdocker system prune --volumesで解決しなかったので調べてみた #Docker だった。
なんかの拍子にコンテナが管理外になってしまっていて docker system prune で削除できないときのお話になっている。
開発用の仮想マシンをリセットせずに使い続けていたりすると、こういう状況に良くなるよね…


Docker Compose だけで雑に本番運用する際に、定期的にリビルドしたい

信頼できるオフィシャルイメージを元に、カスタムイメージをビルドして本番運用する場合、 CI 等でビルドしたイメージをコンテナレジストリに push し、それを本番環境側で pull するのが一般的なベストプラクティスだ。

しかし、クラスタも構築せず VM 1台でいくつかのコンテナを動かすような小規模な運用ほ場合、わざわざ CI やレジストリを準備するのも面倒だ。
このため、運用環境上で Docker Compose を使ってイメージのビルドやコンテナの起動を行ってしまう単純な構成にしたくなる。

そんな時、ベースイメージのセキュリティ更新に追従するために、定期的にイメージをリビルドした上で、必要な場合に限ってコンテナを再 create & up させる方法を考える。

BuildX 既定化による弊害

以前は、 docker-compose pull --no-paralleldocker-compose build --pull の標準出力のいずれかから、 新しいイメージが pull されたことを示す "Downloaded newer image" の文字列があるかどうかを確認し、 docker-compose up すればよかった。

ところが、 docker 23.0.0 にて、 Linux 環境における既定のビルダーが BuildKit というものに切り替わってしまった。
旧来の docker-compose V1 の docker-compose build ないし、 Docker Compose V2 の docker compose build 実行時は docker CLI を通じてビルドされる ため、この仕様変更の影響を受ける。
このため、規定の設定のままだと build の仕組みが変わってしまい、上述のベースイメージのダウンロードを検出できなくなった。

BuildKit は規定では出力をいい感じにまとめてしまうので、そのままだとベースイメージの pull があったかどうか判別できない。

環境変数で DOCKER_BUILDKIT=0 を設定しておけば、旧来の Legacy Builder でビルドをしてくれるが、いつまでサポートされるかわからないので、 BuildKit を使う方法でなんとかしたい。

幸い、 docker build --progress=plain の出力の指定 は、 docker compose build でも働いてくれる。

この出力から ^#[0-9]+\s+resolve\s+ の正規表現がヒットする場所を探してくれば検出できそうだ。

Docker Compose V2 に対する出力オプション

また、既に廃止済みの docker-compose V1 の代替として、 Docker Engine 20.10.13Docker Compose V2 プラグイン がインストールされるようになって以降、現在はこちらの docker compose コマンド使う必要がある。

Compose V2 は、多くの面では docker-compose V1 と互換があり、作成されるコンテナ名のセパレータが一致しない事 (これも --compatibility フラグ で互換性を維持できる)以外はおおむねそのまま利用できる。

ただ、コマンドの UI 出力の内容や、それに纏わるオプションは V1 から大きく変わっているので、そこらへんは調整してやる必要がある。

--ansi never オプションを指定すると、ANSI エスケープコードが無効化され、ターミナルの色がつかなくなったり、パイプ時に余計な文字コードが確実につかなくなる…はずなのだが、指定しても up した時のログぐらいにしか効果が出ないような気はする。
規定値だと auto なので、パイプ処理された場合はそもそも ANSI エスケープコードがつかないはずではあるが、とりあえずオプションの方でも never を強制しといた方が良さそうなので設定しておく。

--progress plain オプションを指定すると、インタラクティブな出力が無くなり、以下のようにパイプで処理しやすいプレーンなテキストが出力されるようになる。
Docker Engine 24.0.3 に同梱されている Docker Compose 2.19.0 移行で compose のグローバルオプションに昇格したオプションであるため、それより低いバージョンだと指定できない点に注意。

$ docker compose --progress plain pull
 alpine-built1 Skipped - No image to be pulled
 alpine-built2 Skipped - No image to be pulled
 alpine-pure2 Skipped - Image is already being pulled by alpine-pure1
 alpine-pure1 Pulling
 070eb51debd9 Pulling fs layer
 070eb51debd9 Downloading [>                                                  ]   28.1kB/2.808MB
 070eb51debd9 Downloading [==================================>                ]  1.911MB/2.808MB
 070eb51debd9 Verifying Checksum
 070eb51debd9 Download complete
 070eb51debd9 Extracting [>                                                  ]  32.77kB/2.808MB
 070eb51debd9 Extracting [==================================================>]  2.808MB/2.808MB
 070eb51debd9 Pull complete
 alpine-pure1 Pulled

docker compose build, up のステータスの出力は、標準出力ではなくて標準エラーの方に出るので、パイプラインつなぐときは注意。

実際のコード例

compose.yaml が存在するディレクトリを /var/lib/docker-compose-dir とした場合、以下のようにできるだろう。

cd /var/lib/docker-compose-dir && { \
  /usr/bin/docker compose --ansi never --progress=plain pull --no-parallel; \
  /usr/bin/docker compose --ansi never --progress=plain build --pull; \
} 2>&1 | \
grep -E "Downloaded newer image|\s+Pull complete\s*$|^#[0-9]+\s+resolve\s+" && \
/usr/bin/docker compose --ansi never up -d

--

さて、こういうコードは cron 等で定期的に実行させたい。
そういった場合、あとから状況を確認しやすくするために、 docker compose の各出力は journald にも書き込んでおきたい。

条件分岐を行うための grep と、 journald に記録するコマンド (logger 等) の両方にパイプしたい場合、 bash や BusyBox ash 等が持つ プロセス置換 が使えそうだ。
crontab が起動するコマンドは、 sh という名前で POSIX 標準互換モードで動かすディストリビューションが多い (debian (Ubuntu) 系, fedora (RHEL, CentOS) 系) ので、明示的に bash (または ash) を呼び出し、その中でプロセス置換を行う方が安全だろう。

例えば Ubuntu の crontab 内で定期的にイメージのリビルドを行う場合、以下のようにすると良いだろう。

cd /var/lib/docker-compose-dir && { \
  /usr/bin/docker compose --ansi never --progress=plain pull --no-parallel; \
  /usr/bin/docker compose --ansi never --progress=plain build --pull; \
} 2>&1 | \
bash -c "tee >( logger -i -t user/docker-auto-rebuild -p user.info )" | \
grep -E "Downloaded newer image|\s+Pull complete\s*$|^#[0-9]+\s+resolve\s+" && { \
  /usr/bin/docker compose --ansi never up -d 2>&1 | \
  logger -i -t user/docker-auto-recreate -p user.info; \
}

なお、実際には cron 内のコマンドでは改行できないので、改行は削除して記述しよう。

VSCode で C# のブロック {} 前後の改行の設定を変更する 2023

本記事は C# Advent Calendar 2023 の2日目の記事だ。

1日目は @RyotaMurohoshi 氏の 【Allって】LINQ、この場合どうなる?【空配列は?】 #C# - Qiita だった。

以前バズった空配列議論のツイートを例に、 .NET の LINQ の各エッジケースでどう振る舞うかまとめた記事になっている。
なかなかのボリュームで読み応えがある。

慣れていないと迷ったり勘違いしやすい話なので、参考になる。

C# を K&Rスタイル で整形したい

さて、 C# の既定のコードフォーマットでは、名前空間やクラス、メソッドなど、各種ブロックの {} (中括弧・波括弧) の手前に改行が入る。(所謂、オールマンスタイル)

namespace MyNamespace
{
    class Class1
    {
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                ;
            }
            else
            {
                ;
            }
            try
            {
                ;
            }
            catch
            {
                ;
            }
            finally
            {
                ;
            }
        }
    }
}

言語の既定に従うのも悪くは無いとは思う。思うのだが、 Java, JavaScript, Go, Rust 等々、他のメジャーな C言語 スタイルの言語では、 Java のコーディング規約に則って改行を入れないの(K&Rスタイル)が一般的なので、 C# で改行を入れるこのコードスタイルはどうにも気持ちが悪い(主張の強い個人の感想です)

手癖で改行を入れない書き方をしていても、 Shift+Alt+F でドキュメントのフォーマットをすると改行されてしまう。

…と言うことで、 Visual Studio Code (VSCode) を使って C# の開発する際に、各種ブロックの {} (中括弧・波括弧) の手前に改行が入らない形でフォーマットする方法を紹介する。

omnisharp.json は機能しない

vscode でこの設定を変更する場合、古くは omnisharp.json が使われていた。

ところが、 2023年中頃の VSCode の C# 拡張機能の更新 (v2.0.320) で、既定で Roslyn と Razor をベースとした新しい言語サーバーを利用するようになったため、 OmniSharp が使われなくなった。
このため、明示的に OmniSharp を有効 にしない限り、 omnisharp.json に書かれた設定は機能しなくなっている。

.editorconfig を使おう

続きを読む