ルール 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に単体で配置すると呼ばれるという備忘録でした。
XcodeのRuntime Warningを表示する方法
はじめに pointfreeのswift-issue-reportingというライブラリを眺めていたらXcodeの紫色の警告を出す方法を知ったので記録も兼ねて記事にしました。(参考) Xcodeの紫色の警告は、Runtime Warningというもので、ビルドが成功してアプリが起動した後の実行時に警告が出るというものです。UIの状態をメインスレッドの外で更新した際に出るのはよく見かけると思います。 このRuntime Warningの表示方法は明確にドキュメント化されていないようですが、pointfreeのUnobtrusive Runtime Warnings for Librariesという記事を読んで、表示方法が分かったのでその方法を記事を元に記録します。 なお、記事にもあるようにこの方法はAppleが明示的に示した方法ではないので、AppStoreに提出するアプリでは使用しないようにした方が良いです。 何が嬉しいのか 開発者がRuntimeWarningを出す目的は、ランタイムでアプリの不具合に気付けるようにすることです。他の手法として、ブレークポイントや assertなどがあります。 ユースケースとして、ライブラリ開発者が正しくない使い方での利用が発生したことを利用側に伝えることを考えます。その手法として、ブレークポイントや assertの2つを考えます。 しかし、ブレークポイントはライブラリ提供側ではなく利用側で設定する必要があるというデメリットがあります。また、assertは実際にアプリの不具合に気づけるものの、アプリケーションもクラッシュしてしまうため、開発の妨げになるケースが考えられます。 RuntimeWarningを使うとライブラリ提供側でアプリの不具合を利用側に伝えることができ、アプリケーションもクラッシュしないため、上記のデメリットを解決しつつ、ライブラリの正しくない使い方に即座に気づくことが可能です。 RuntimeWarningの表示方法 結論 os_logを使い、subsystemにcom.apple.runtime-issuesを指定する dsoにはSwiftUIのフレームワークのベースアドレスを指定する 下記のようなクラスを作れば再利用して使えますが、もっと簡単にswift-issue-reportingのreportIssue関数を使うことで実現できます。 actor RuntimeWarning { var info = Dl_info() init() { dladdr( dlsym( dlopen( nil, RTLD_LAZY ), """ $sxSg7SwiftUI8CommandsA2bCRzlAbCP4body4BodyQzvgTW """ ), &info ) } func log(message: StaticString) { os_log( .fault, dso: info.dli_fbase, log: OSLog( subsystem: "com.apple.runtime-issues", category: "ReportRuntimeWarningSample" ), message ) } } 詳細 RuntimeWarningの表示方法は、os_logを使うことで実現できます。subsystemにcom.apple.runtime-issuesを指定することが一つのポイントです。 それに加えて、dso(dynamic shared object)というパラメータを指定することで、RuntimeWarningを表示することができます。 os_log( ....
[SwiftUI] AsyncImage that can perform downsampling
Prologue This article is originated from AsyncImage that can perform downsampling. AsyncImage is a SwiftUI component to show Image fetched from internet resource. It is available since iOS15 like the following. AsyncImage(url: url) { phase in switch phase { case .empty: ProgressView().progressViewStyle(.circular) case .failure: Text("Error") case .success(let image): image .resizable() .frame(width: 56, height: 56) @unknown default: fatalError() } } Such a simple way is beneficial to build a UI layout with ease....