ルール AIの書いた文章ではなく自分で書くこと AIから教えてもらったことをそのまま鵜呑みにしないで、必ず他の情報(一次情報かどうかは問わない)も調べた上で記述すること 可能な限り、経験として得た知識について記載すること。事後的に経験として得たものでも可とする Goの型について 最近Goを本格的に勉強し始めた。これまでGoで何かアプリケーションを開発した経験はあるが、基礎から勉強をし直すということでA Tour of Goを取り組んだ。その中で、Goのinterfaceについて面白かったのでまとめることにした。 interface Goではinterfaceは公称型ではなく構造的部分型として扱われる。一方、structは公称型として扱われる。 また、interfaceは明示的に準拠せずとも、型のシグネチャが一致していれば自動的に準拠される。 動的型付け言語におけるダックタイピングのようなことがGoのInterfaceではコンパイル時に保証することができる。 package main import "fmt" type Movable interface { move(spped int) } type Vehicle struct { } func (*Vehicle) move(speed int) { fmt.Println("Vehicle moves at", speed, "km.") } type Trolley struct{} func (*Trolley) move(speed int) { fmt.Println("Trolley moves at", speed, "km.") } func main() { var movable Movable = &Vehicle{} // *Vehicleはmove(speed:)を実装しているので自動的にMovableに準拠する movable.move(30) movable = &Trolley{} // *TrolleyもVehicleと同様に自動的にMovableに準拠する movable....
TIL@2025-10-20
ルール AIの書いた文章ではなく自分で書くこと AIから教えてもらったことをそのまま鵜呑みにしないで、必ず他の情報(一次情報かどうかは問わない)も調べた上で記述すること 可能な限り、経験として得た知識について記載すること。事後的に経験として得たものでも可とする 独自ドメインのDNSを設定した 一昨日か昨日くらいに独自ドメインのDNSを設定した [前提] DNSはCloudflare DNSを利用している ドメインはGoogle Workspaceのメールアドレスのドメインとしても利用していてMXレコードも存在する 今回、ポートフォリオのサイト上記の独自ドメインで管理したい 気になったこと DNSレコードにCNAMEを設定しようとしたら、以下のようなInfoButtonが出てきた 日本語にすると「ゾーンapexには通常CNAMEは使えないので、CNAME Flatteningを使います」という旨のメッセージ 無知なのでゾーンapexもCNAME flatteningも知らなかったので調べた。 ゾーンapex サブドメインのないドメインのことapexドメインやネイキッドドメインとも言われるらしい。 fummicc1.netはゾーンapexだけど、www.fummicc1.net はゾーンapexではない。 CNAME Flattening 通常ゾーンapexに対してCNAMEを設定できないので、CloudflareではCNAME Flatteningという仕組みを用いてCNAMEを登録できるようにしているらしい。詳細はまた次回(今日は時間が全然取れなかった) 参考 https://developers.cloudflare.com/dns/cname-flattening/ https://dev.classmethod.jp/articles/tsnote-dns-record-apex-domain/
TIL@2025-10-15
ルール AIの書いた文章ではなく自分で書くこと AIから教えてもらったことをそのまま鵜呑みにしないで、必ず他の情報(一次情報かどうかは問わない)も調べた上で記述すること 可能な限り、経験として得た知識について記載すること。事後的に経験として得たものでも可とする duコマンドで隠しファイルのサイズが表示されない問題 duコマンドを利用するとdisk usageがk確認できますが、*を末尾につけると隠しファイルが表示されないという問題があった。 du ~/* -hs aオプションを使うと隠しファイルも全て見てくれる。 du ~/ -ha ただ、duコマンドはディレクトリに関して再帰的に処理をするので一つ下のディレクトリの合計サイズを見たい場合は--max-depth (-d)オプションをつけてあげる必要がある。 du ~/ -ah -d 1
TIL@2025-10-14
ルール AIの書いた文章ではなく自分で書くこと AIから教えてもらったことをそのまま鵜呑みにしないで、必ず他の情報(一次情報かどうかは問わない)も調べた上で記述すること 可能な限り、経験として得た知識について記載すること。事後的に経験として得たものでも可とする LLMのtemperatureを0にしたらエラーが出た話 LLMを使ってテキスト生成をする際、評価をする際に同じ入力に対して実行の度に結果が違うと困るのでtemperatureを0.0にして実行したい。 HuggingFaceを利用してgenerate関数にtemperatureを0に設定したら下記のエラーが出た。 ValueError: `temperature` (=0.0) has to be a strictly positive float 原因は引数の設定にあった。generateメソッドでは、do_sampleというbool型の引数を取れるが、これをTrueにした場合temperatureは0より大きい値を指定する必要がある。もし決定的にしたいのであれば、temperatureを0にするのではなくdo_sample=Falseにする必要があることのこと。 参考 https://huggingface.co/Open-Orca/oo-phi-1_5/discussions/2 https://huggingface.co/docs/transformers/ja/generation_strategies https://zenn.dev/hellorusk/articles/1c0bef15057b1d
TIL@2025-10-13
ルール AIの書いた文章ではなく自分で書くこと AIから教えてもらったことをそのまま鵜呑みにしないで、必ず他の情報(一次情報かどうかは問わない)も調べた上で記述すること 可能な限り、経験として得た知識について記載すること。事後的に経験として得たものでも可とする bashでスクリプトは実行しないけど文法のチェックをする方法 Claudeと会話をしていると動作確認のフェーズで以下のようなシェルの実行を提案されることがある。 bash -n ./foo.sh foo.shを実行するのだなと思って、この処理は私の方で実行しますと回答したが、後になって調べてみるとnオプションはスクリプトを実行しないで文法に問題がないかをチェックするオプションとのこと。 但し、あくまで文法チェックなので変数名が正しいかどうかなどはチェックできないとのこと。
TIL@2025-10-12
git commit --fixupで任意のコミットの内容に変更を加える これまで、すでにコミットをした後に気づいた細かい不具合修正やlinterの適用やtypoの修正はgit commit --amendを利用して直前のコミットに混ぜることでコミットログを綺麗にするようにしていた。しかし、もし混ぜ込みたいコミットが直前ではない場合だと--amendは利用できないので新しくrefactor: fix typoやrefactor: apply formatterのようなコミットを作成していた。 今回、新しくgit commit --fixup <revision>というオプションを知った。これを使うと指定したコミットに対してfixup(修正)をするコミットを作成でき、git rebase --autosquash <revision>^と組み合わせることで特定のコミットに任意の変更を後から混ぜることができる。※ git rebaseをするためコミットハッシュは変わる エディタを開かずにinteractive rebaseを行う git rebase --autosquashを行うにはgitのバージョンが2.44以降である必要がある。もしそれ以前のgitバージョンを利用している場合は--autosquashは-iオプションをつける必要がある。その場合、エディタが開いてしまうが、GIT_SEQUENCE_EDITOR=:やGIT_SEQUENCE_EDITOR=trueを指定しておけばエディタが開かずにinteractive rebaseが可能となる。 参考 https://blog.nishimu.land/entry/2024/08/18/213902 https://github.blog/open-source/git/highlights-from-git-2-44/
TIL@2025-10-11
cURLでBasic認証のページにアクセスする方法 cURLでBasic認証のページにアクセスする場合、https://<username>:<password>@<サイト名>という形式になると思いますが、直接URLにbasic認証を記述せずに-uオプションを使うことで認証とURLを分けることができます。 curl -s -u "<username>:<password>" "https://<サイト名>" -hでヘッダーに指定する場合はbase64エンコードをした値を記載しますが、-uオプションの場合は直の値をそのまま記載できるという違いがあります。
SwiftのObjectIdentifierを勉強する
はじめに この記事はSwiftのObjectIdentifierについての記事です ObjectIdentifierとは ObjectIdentifierとはクラスまたはメタタイプの一意のidを表す型です。 structやenum, 関数、タプルに対してはObjectIdentifierを生成できなく、classやactorに対してObjectIdentifierを生成できます。 // --- Structに対してはObjectIdentifierを生成できない --- struct S {} let s = S() let num: Int = 0 ObjectIdentifier(s) // Error: Argument type 'S' expected to be an instance of a class or class-constrained type ObjectIdentifier(num) // Error: Argument type 'Int' expected to be an instance of a class or class-constrained type // --- Classに対してはObjectIdentifierを生成できる --- class B { var value: Int init(value: Int) { self.value = value } } actor A {} let b = B(value: 0) let a = A() ObjectIdentifier(b) ObjectIdentifier(a) structに対してObjectIdentifierを生成しようとするとエラーになる ObjectIdentifierによる比較は参照が同じという意味になるので===と同じ意味になる認識です。...
GeoHashを可視化できるアプリを作ってみた
はじめに こんにちは、Swift Advent Calendar 2024の19日目を担当しますfummicc1です。 この記事では、ジオハッシュ(GeoHash)を可視化できるアプリについての話を書きました。 Swift Advent CalendarなのでSwiftに関連する話も書いたつもりですが、Swift以外の話も含まれているのであらかじめご了承いただけると嬉しいです。 この記事に書いてあること ジオハッシュについて ジオハッシュを可視化するアプリを作った話 ジオハッシュを確認できるアプリを作った際のSwiftに関連する話 ジオハッシュとは ジオハッシュは地図上の特定の区域を表現した文字列のことやそのアルゴリズムのことを指します。世界地図に対して「経度を2分割→緯度を2分割」という処理を繰り返すことで生成されるビット列をハッシュ化することで文字列を生成します。 ジオハッシュの例: 区域ごとに一意の文字列が割り当てられる ジオハッシュの生成では、境界を区切って0,1を割り当てる作業を緯度・経度ごとに行います。経度だけに絞ってみると下記のように分割されていきます。 経度を1bitで分割 経度を2bitで分割 経度を3bitで分割 どこまで分割を行うかでビット列の長さが変わり、長ければ長いほど狭い区域を表現するジオハッシュ文字列となります。 ジオハッシュのビット列は、経度と緯度それぞれについてのビット列を交互に並べたものです。 例えば、経度のビット列が「11100」で,緯度のビット列が「10001」の場合、ジオハッシュは「1110100001」となります。 ビット列は5bitごとに32種類の英数字にマッピングされます。数字10個 + アルファベット22個からa,i,l,oを除いたものの合計32種類から構成されます。 ジオハッシュ生成の流れ このジオハッシュから、地点の緯度・経度の区域を特定することができます。 例えば、日本はおおよそ1桁のジオハッシュでは「w」もしくは「x」で表現されます。ジオハッシュの桁が長ければ長いほど、その文字列が示す区域が狭くなるので1桁のジオハッシュだと結構な領域を示しています。詳しい制度についてはこちらに記述がありました。 日本はおおよそwかxに属する 西日本付近でxからwに変わる ジオハッシュの特性を応用することで、「ある地点の近くにある場所」の探索を文字列の比較で実現ができることができます。(ただし、多少の精度の誤差があることに注意が必要です。) ジオハッシュをSwiftで実装したい 勉強も兼ねてGeoHashSwiftというリポジトリに実装しました。ですが、既にGeoHashというSwiftで実装されたライブラリがあったのでそちらも参考に実装をしました。 ジオハッシュを可視化するアプリが欲しかった ジオハッシュのライブラリを作った後に実装が正しいことを確認する必要があったのですが、文字列を見ても正しいジオハッシュかどうかが直感的に分からなかったので入力した緯度経度から生成されるジオハッシュを簡単に確認できるアプリを作りました。 検索機能もつけてみました。(手元で動かすととても重いです) ビット列の長さをスライダーで変えられることができて、マップの中心のジオハッシュと周囲の区域のジオハッシュが表示されるアプリとなっています。 周囲のジオハッシュは幅優先探索で5ステップ先の周囲までを取得しています。全てのジオハッシュを取得すると2 ** ビット列の長さのジオハッシュを取得することになるので、計算が重くなったので断念しました。 5ステップ先のジオハッシュを取得するだけでも、Map上で動作確認をすると処理が重いと感じたので改善に取り組んだことをメモします。 Viewに記述された処理をメインスレッド外で実行する SwiftUIのViewはMainActorであるため、Viewに直接計算メソッドを書いている場合、処理がメインスレッド上で実行されてしまいます。今回はGlobalActorを定義してメソッドをactorで隔離させることでメインスレッドで処理が走らないようにしました。 @globalActor struct ComputationActor { actor ActorType {} static let shared = ActorType() } struct ContentData: Identifiable { var bound: [CLLocationCoordinate2D] = [] var geohash: GeoHash var id: GeoHash { geohash } } struct ContentView: View { // ....
SwiftUIのEmptyViewのonAppearは呼ばれることがある
SwiftUIのEmptyViewはレイアウトに影響しないことで知られています。 EmptyViewはViewが存在しないことを意味するのでonAppearメソッドも呼ばれないと想定されます。 ただ、RootViewにEmptyViewのみを配置した場合はonAppearメソッドは呼ばれるので注意が必要です。 @main struct SampleApp: App { var body: some Scene { WindowGroup { ContentView() // ContentViewだけを表示するとonAppearは呼ばれる // ContentView2() // ContentView2だけを表示するとonAppearは呼ばれない } } } struct ContentView: View { var body: some View { EmptyView() .onAppear { print("onAppear is called") } } } struct ContentView2: View { var body: some View { EmptyView() EmptyView() .onAppear { print("onAppear is not called") } } } ContentViewではView HierarchyにEmptyViewがあって、ContentView2ではView HierarchyにEmptyViewがないのでonAppearは呼ばれないみたいです。 ContentView ContentView2 onAppear is called onAppear is not called おわりに 簡潔な記事ですが、EmptyViewのonAppearはRootViewに単体で配置すると呼ばれるという備忘録でした。