Posts for: #2024/08

今週は開発者として実装に集中していた

久しぶりに実装に集中した金曜日

既存の web api のある機能を再設計する。既存機能のエンドポイントの見直しも含むのでテストコードなども移行しないといけない。ひとまずエンドポイントの移行と機能分割はできた。最低限の進捗。まだこれから仕様変更や拡張を追加していく。似て非なる機能を分割しているので名前の付け方をわかりやすくしないといけない。用途と名前空間をうまく組み合わせてわかりやすくしたいが、こういう作業は深夜よりも朝の方がうまくいく気がするのでまた明日にする。朝起きれるかなぁ。

オプトラン中間決算

先週の金曜日にオプトランの株価が1500-1600円台まで落ちれば 割安で狙い目ではないかと書いた。実際に月曜日に歴史的な暴落があって寄りと引けで購入していて、それぞれ 1,490 と 1,466 だった。過去5年の最安値が 1,420 なので割安だろうと考えた。昨日、中間決算があって 2024年12月期 第2四半期 決算説明資料 をみていた。通期での業績は変更していないものの、直近の四半期の業績はよくなかった。前四半期がかなりよかったため、半期の累計としてみたら通期目標に対する進捗はよいと言える。しかし、直近の四半期の業績はよくないから、この空気は売り込まれるやつだと昨日の夜の時点では予想していた。経営陣もそれを見越してなのか 7.72% の自社株買い を発表している。月曜日に割安と考えた見立ては失敗だったかなと諦めつつ、今朝の時点では、大きく売り込まれたらまた買い増ししようとも考えていた。結果的に今日の株価は 1,640 で始まって 1,697 で終わった。自社株買いのおかげ?私のこれまでのオプトランの観察眼では、大きく売り込まれるはずだったのが、なにもなく過ぎ去った。また定期的に少しずつ買い集めていって2024年12月期の決算が終わったときに覚えていたらふりかえってみたい。

寝不足でバテた

久しぶりに実装に集中した翌々日

火・水と連日で遅くまでコードを書いていてバテた。晩ごはんをオフィスで食べて帰って20時頃からそのまま寝てた。区切りがよかったのもあって今日は休むことにした。疲れが溜まっていたからすぐ眠れた。2時頃に一度起きたものの、わりとぐっすり眠れた。深夜までコードを書いていたから単純に寝不足だったように思う。私がボトルネックに成りうる大きな課題の1つを解消した。よいペース。今週中にもう1つの大きな課題を fix したい。

一開発者としてコードを書く日々

久しぶりに実装に集中した翌日

昨日に引き続き、日中コードを書いて、晩ごはんを食べた後にまたコードを書き始めて、翌1時半ぐらいまで書いていた。昼間はどうしても他メンバーの進捗をみたり、質問を受けたりするから割り込みで作業を中断されがち。夜は割り込みが入らないことがわかっているからコードを書くことに集中さえできれば区切りのよいところまで一気に書ける。いままで夜に運動していた時間をしばらくはコードを書くことに割く。いま私がボトルネックになりそうな課題を抱えているのでそこを早めに解消しておきたい。

一開発者としてコードを書く

久しぶりに実装に集中

8時半から20時半までコードを書いて、気分転換に買いものへ行ってきて、22時から仕様変更した内容に関するドキュメントを書いて24時までお仕事をしていた。プロジェクトマネージャーを移行 して開発者に戻ったことにより、心理的にコードを書くことに集中しやすくなった。1年半ほど開発者から離れていたことの、勘どころのようなものも徐々に取り戻していく。運動と一緒でコードを集中して書いていると嫌なことを忘れられてよい。コードを書くことも私にとっては瞑想に近いものになっている。

サーバーの拡張とフックポイント

今日は東京株式市場の歴史的な急落もあっていろいろ経済ニュースを読んでいた。

echo の Custom Binding

echo で開発していて気に入っているところの1つに、サーバーサイドの、ここをカスタマイズしたいという箇所にちゃんと拡張するためのフックが用意されているというのがある。例えば、リクエストデータとサーバー内部で使う構造体を紐付ける bind 処理もデフォルトの仕組みを拡張する Custom Binding が提供されている。

Echo 構造体の値に Binder というフィールドがあり、カスタマイズしたい処理を実装した Binder インターフェースの値をセットする。

e := echo.New()
e.Binder = binder.New()

Binder はリクエスト構造体の値と echo.Context の値を受け取る Bind() メソッドを実装する。基本的には echo.DefaultBinder を適用した後にカスタマイズしたい bind 処理を実装すればよいと思う。

type Binder struct{}

func (b *Binder) Bind(i any, c echo.Context) error {
	defaultBinder := new(echo.DefaultBinder)
	if err := defaultBinder.Bind(i, c); err != nil {
		return err
	}
	switch req := i.(type) {
	case *myRequest:
		if err := req.BindSomething(c); err != nil {
			return err
		}
	}
	return nil
}

func New() *Binder {
	return &Binder{}
}

bind 処理をどう実装するかはいろいろやり方があると思うが、echo.Context の値を渡せるので request 構造体にその実装を隠蔽するというのもいいんじゃないかと思う。

type myRequest struct {
}

func (r *myRequest) UnmarshalJSON(data []byte) error {
	type Alias myRequest 
	if err := json.Unmarshal(data, (*Alias)(r)); err != nil {
		return fmt.Errorf("failed to unmarshal ids request: %s", data)
	}
    // implement custom validation
	return nil
}

func (r *myRequest) BindSomething(c echo.Context) error {
    // implement custom binding
    return nil
}

日経平均株価の歴史的な急落

金曜日から2日連続 で株価指数が 5% 超も下落するのは世界的にも珍しいらしい。

金曜日に史上2番目の下落幅という見出しでメディアでは煽られていて、下落幅と下落率は違うからそんな不安に感じなくてよいと楽観していたら、今日は史上2番目の下落率 (-12.40%) となった。さらにストップ安になっている銘柄が相次いでいるから実体はもっと悪いと考えられるとのこと。一方でリーマンショックのような、金融機関が破綻しているような状況でもなく、実体経済が傷んでないのに売りが売りを呼ぶ急落になっているので今後どうなるのかはよく分からない。明日も下がるのか、反発するのか、誰にもわからない (素人はしばらく何もしない方がよい) 。注目していた任天堂の株価も -16.53% と日経平均株価以上に急落している。これだけ落ちると、信用取引の追証が2営業日以内となるため、任天堂は明後日「投げ売り」されてもう少し下がる可能性もあるかもしれない。いずれにしても、私は今週いっぱいぐらいかけて空売りの返済をしていく。買うときも売るときも一度に行うのではなく、タイミングや数量を分割してならしていく。

株価の急落について私の記憶にあるのは、2016年の米大統領選挙でトランプ氏が初当選したとき、2020年にコロナが流行り始めたときを思い出した。たまたまだけど、4年に1回は急落がやってきている。2016年も2020年もとくになにもせず私は見守っていただけだった。しかし、今回は事前にポートフォリオを見直したり、空売りでリスクヘッジしていたりと急落の場面にも対応できた。以前よりは経済の背景を学んで資産運用の行動に反映できるようになってきた。これは経営においてもよいことだと思う。

モルックというマイナーなスポーツ

今日は運動というほど動いていないけど、モルックへ出掛けて日向で十分に汗をかいた感じ。

モルック談義

line のオープンチャット で仲良くなった方から磯上公園で モルック をやるのでよかったらどうぞとお誘いをいただいた。日曜日のお昼で暑そうだから少し躊躇したものの、モルックというスポーツ自体を知らなかったので関心があって参加してきた。結果的にはこの予定がなかったらだらだらしていたなと思うと外へ出るきっかけを作ってくれたのでよかったかもしれない。参加者は私を含めて5人。うち2人はバドミントンに来られた方で知っていて、もう2人は初めて会う方だった。地元の知り合いを増やしていくことは長い目でみてよいことかもしれない。12時半に集まって16時前に解散した。モルックをやっていたのは正味1時間程度かな?どちらかといえば雑談していた時間の方が多かったと思う。ちょっとだらだら雑談し過ぎた感はあった。以前のオフ会 に参加したときも思ったが、お互いによく知らない人たちの集まりをするときは終わりの時間を最初に決めておくというのは大事だと思う。雑談時間を設けることはよいが、いつになったら終わるのか (帰れるのか) わからない空気感はよくない。今回も雑談時間に1人だけずっと喋り続ける人がいる。よく知らない人たちの中でファシリテーションして、みんなが話せるように調整すると喜ばれるかもしれない。

モルックを初めてやってみた所感。モルックのルール を一読して2-3回ゲームをやればすぐ覚えられる。投げる木の棒 (モルック) と倒す木の棒 (スキットル) と得点ボードがあればできる。DIY で自作してもよいかもしれない。特定のピンを狙って木の棒を投げるのが意外と難しかったのと、得点の積み上げに戦略性や投げる順番も関わってくるのでゲーム要素としてもおもしろかった。狙ってピンに当てるコントロールが大事なのはそうだけど、初心者でも十分に楽しめる要素はある。場所は 10m 四方程のスペースがあればよい。体力はいらないから老若男女でも楽しめる。運動にはあまりならない。1ゲームを5人でやって15分程度で終わるのでキャンプやバーベキューの隙間時間などにやるのもよさそうに思えた。なにかの機会でまた試してみるかもしれない。

mongodb も一応は外部結合できる

今日は出張中にたまっていた日記をまとめて書いていた。昨日筋トレしたから運動はおやすみ。

mongodb における外部結合

出張中のふりかえりやプロジェクトマネジメントの合間に mongodb の $lookup (aggregation) 機能を調査していた。一言で言えば、rdbms で言うところの外部結合 (join) を mongodb で実現する機能と言える。しかし、aggregation の機能として実装されていることから rdbms の外部結合とはパフォーマンスの側面で大きく違うのでは?と推測する。mongodb のような kvs では基本的に外部結合のようなことは行わず、結合済みのコレクションを定義するやり方がプラクティスとされる。一方で整合性を保証するには外部結合は有効なデザインパターンの1つなので使いたい場面があってもおかしくない。実際に mongodb に $lookup が実装されているのだから、そのニーズは大きいのだと思われる。

ちょうどいまやっている開発でその要件があったので mongo-go-driver の次のチュートリアルをみながら実装してみた。

例えば、次のような2つのコレクションがある。

type Group struct {
	ID          string      `bson:"_id"`
	Name        string      `bson:"name"`
	UpdatedAt   time.Time   `bson:"updatedAt"`
}

type MyData struct {
	ID           string    `bson:"_id"`
	GroupID      string    `bson:"groupID"`
	RegisteredAt time.Time `bson:"registeredAt"`
}

MyData の GroupID フィールドが Group コレクションの ID を保持して外部参照している。MyData コレクションに対する aggregate に渡すパラメーターとして pipeline を渡す。

myPipeline = mongo.Pipeline{
	{{
		Key: "$lookup", Value: bson.D{
			{Key: "from", Value: "group"},
			{Key: "localField", Value: "groupID"},
			{Key: "foreignField", Value: "_id"},
			{Key: "as", Value: "foreignGroup"},
		},
	}},
	{{
		Key: "$unwind", Value: bson.D{
			{Key: "path", Value: "$foreignGroup"},
			{Key: "preserveNullAndEmptyArrays", Value: false},
		},
	}},
}

$lookup の操作の後に $unwind で配列を flatten する処理がセットになる。result set にマッピングするためには flatten が必要になるのだと推測する。aggregate() を呼び出すと cursor が返ってきて、その cursor に外部結合される値の配列を渡すことで result set を取得できる。デバッグはややこしいし、コード上もちょっとわかりにくいけど、これは mongodb のお作法だと割り切ってユーティリティ化してしまえばよいものだと思う。

type joinedMyData struct {
	ID           string    `bson:"_id"`
	Group        Group     `bson:"foreignGroup"`
	RegisteredAt time.Time `bson:"registeredAt"`
}
...

cursor, err := collection.Aggregate(ctx, myPipeline)
if err != nil {
	return nil, err
}
var joined []joinedMember
if err = cursor.All(ctx, &joined); err != nil {
	return nil, err
}

また時間があるときにある程度のデータ量でどのぐらいの負荷に対してパフォーマンスが出るのかを測ってみたい。

ストレッチ

昨日1週間ぶりに筋トレをしたせいか、今朝から筋肉痛になっていてカラダが痛い。その影響もあって今日の開脚幅は開始前146cmで、ストレッチ後152cmとカラダが硬かった。足も腰も肩周りも全身にわたって軽い筋肉痛だった。それだけよい感じの負荷をかけて筋トレができていたと言えるのかもしれない。あちこち筋肉痛はあったものの、ストレッチを受けていての辛さのようなものは感じなかった。ちょうどよい感じにほぐされているような印象を受けた。もしかしたらトレーナーさんが気を遣っていつもよりは弱めにストレッチしてくれたのかもしれない。トレーナーさんが立候補していた店長選挙は落選してしまったらしい。もし店長になったらよそのお店へ転勤になって担当者が変わってしまうのかなとも思っていた。トレーナーさんは私が通っているお店の副店長を務める方向で調整しているらしい。待遇をあげていくにはキャリアアップをしていかないといけないといった背景もあるようにみえる。

自分を騙す言い訳

今日の運動はジム筋トレ,縄跳び(両足跳),散歩,ジョギング,ハンドグリップ,ダンベルをした。統計を 運動の記録筋トレの記録 にまとめる。ジョギングの後に 右股関節の改善体操 をした。どこかのタイミングで今月からは運動を監視するのをやめて別のことへ移行していく。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。今日の議題はこれら。

  • お手伝い先のプロジェクト近況

今週の出張でお手伝い先でのふりかえりや進捗報告の要旨などを共有しつつ、うちの会社の課題管理ビジネスへの取り組みについて雑談したりした。ここ2-3ヶ月は私がバテてしまい、休日もオフィスへ足を運んでいるものの、運動したり日記を書いたり趣味の調べものをしたりと、のんびり過ごしていることが多い。課題管理ビジネスへの集中力が途切れてしまった。はらさんも上半期は自分のプロダクト開発などをやろうと考えていたものの、あまり想定したように進捗せず、下半期は他社のお仕事のお手伝いで忙しくなってくるらしい。はらさんは よりひろいフロントエンド を作ったり、最近は Apple Vision Pro のアプリ開発をされている。私と似たような状況だなと話しを聞いていて次のようなことを話された。

歳をとると自分を騙すのがうまくなる。うまくいっていない言い訳を、もっともらしく、自分で受けいられるように作ってしまう。
危機感をもたなくなる。うまくいっていないことや結果が出ていないことを直視しないといけない

まさに私にも当てはまることでこの2-3ヶ月の自分をみているみたいだ。私自身、今年はほとんど休まず会社のことばかりやってきたから、たまにはだらだらする時期があってもいいのかな程度に自分への言い訳をしていた。はらさんとは隔週で雑談する機会を設けている。こういう話しをするだけでもこの雑談には意味がある。これが自分ひとりだと、自分への言い訳をして、何もしないままどんどん時が過ぎ去っていくだけだったと思う。誰だって自分のネガティブな側面を直視するのはつらいから無意識に目を背けてしまう。信頼できる人たちからそういうことを指摘してもらって自身を省みるきっかけになればと思う。

いそがみの筋トレ

前回の所感 。19時過ぎから出掛けて、トレーニング器機の待ち時間などもあって21時前まで筋トレしてきた。出張中ずっと運動していなかったので行く前はやや面倒に感じていたが、やりきったら達成感があって行ってよかったと思えた。週2-3日のペースで筋トレや運動を継続していくのが心身ともによさそう。慣れてきたモノへのやる気はやり始めてから出てくる。なによりも大事なのはやり始めること。

体育館のトレーニングルーム通いも気付いたら5回目になった。少しずつ成果は出ていて、器機によっては重りをあげたり回数を増やしたりできるようになったのもある。そして終わってから外で縄跳びをして、ハンドグリップをしながら帰ってきた。これも筋トレした後だとややカラダがだるいのもあるけど、跳び始めてしまえば出来てしまう。毎日の運動は時間を取られて他のことが疎かになってしまった現状があるため、今後は週2-3日の筋トレの機会に集中して運動していくよう、日々の生活を変えていく。

日経平均株価の急落

fin-py という金融関係者向けのコミュニティがあり、数年前から参加している。何人か仲のよいメンバーもいるし うちの会社の顧問税理士さん もそのメンバーの1人でもある。老後の心配が出てくるのか、日々の生活が安定すると将来の生活に目を向ける余裕が出てくるのか、人生においてお金の話しは歳をとってから関心が出てくる話題の1つだと思う。

下落幅は1987年のブラックマンデー以来、史上2番目らしい。一方で下落率でいうと 5.81% で史上30番目になる。2008年のリーマンショックでは下落率が11.41%と、この倍以上であったことからそこまで不安を煽る状況でもないが、メディアは不安を煽った方がニュースバリューになるからこういう見出しになるのは仕方ないらしい。米国の経済事情だったり、為替の円高転換などの要因で日本株が急落している。fin-py で時事のニュースなどをやり取りしていたのもあり、為替の円高転換は Exclusive: BOJ to weigh rate hike next week, detail plan to halve bond buying, sources say の記事が出た7月24日ぐらいから注目していた。私の投資のポートフォリオも徐々に含み益の保有株を売ったりして、円高になって株価が下がってもよいように準備していた。今日の急落にも備えていたから投資資金の50%ほどは含み益の状態で売却できた。今日の取引終了後も為替は円高に進んでいるし、日経平均先物も悪化しているので月曜日もさらに下がりそうにみえる。これでしばらく為替は円高へ進んでいくのかな。その状況を確認しながら追加でポートフォリオを変更してもよいかもしれない。しばらく為替や株価の変動が大きいだろうから落ち着くまで見守ろうと思う。fin-py で日々の経済のニュースなどを見聞きしているうちにその先の展望を推測して対策を講じたり準備したりできるようになってきた。これまでは起こった状況で気付いて含み損になってしまって何もしていなかった。急な変動が起こりそうな気配や背景を知っていると、準備ができていて、ポートフォリオを機動的に変える決断を早くできる。

たまたまこんな日に 任天堂 2025年3⽉期第1四半期 決算発表 があった。もともと2025年3月期の通期の業績は前期よりも悪くなることが以前からわかっていたのになぜか株価は高止まりしていた。今回の為替の急な円高 (任天堂は海外の売上比率の方が大きいため、円高になると為替差益が減る) と、第1四半期の業績も市場予測よりも悪かった?せいか、月曜日は株価が急落するようにみえる。以前から株価が高過ぎるのと、どこかで為替の円高転換もあるだろうと、2月頃から少しずつ空売りしていた。最悪の時期は任天堂の空売金額が-10%ほどの含み損になっていたものの、(想定したよりも過激な円高がやってきて) 今日の時点で3%ほどの含み益になっている。おそらく月曜日から任天堂の株価は急落すると推測される。

以前 オプトラン という会社について書いた。ここも半導体産業、且つ為替で業績に影響を受ける会社になる。ずっと観察してきたし、ボラティリティが高いのでポートフォリオに入れたり出したりする定番の会社になっている。今日の時点では、おそらく思惑?だけで1711円と株価が急落している。過去の最安値が1420円、年初来最安値が1561円になる。1500-1600円台まで株価が落ちれば2-3年後のために投資していくのによいんじゃないかと注目している。

次開発は開発者として専念

今日も出張戻りで運動はおやすみ。帰ってから運動をする余裕もあったけれど、日銀の追加利上げ決定から為替が円高に動いて、日経平均先物が急落しているのをみかけて、帰りの新幹線内から経済系の関連記事を読んだりしていた。景気が悪化すると経営に影響するから、こういった転換点に敏感になった。

5次開発の要件打ち合わせ

前回の所感 。これまでは2時間をとって要件の発散会議をしてきた。今回は残課題の issue が溜まっていて、まずはそれらを fix してから最低限の機能開発をするといった段取りで進めることを出席者に共有した。そのため、要件を発散させるような話しはほとんどしなかった。主には残課題の共有をしながら、11月頃から最初のお客さん導入を想定して、それまでにやらないといけない要件の機能の再確認を行った。ちょうど2時間ぐらいでおさまった。優先順位なども改めて確認する必要もなさそうに考えている。お手伝い先のプロダクト開発において課題管理が普通になってきたので、特別な確認や打ち合わせをしなくてもどの課題をやらないといけないかは明示されるようになった。これはこれで課題管理の方法論の成果でもある。一方でメンバーからはどの issue を担当すればよいか、開発始めの段階は担当者を割り当ててほしいという意見もあったので、私がいくつか残課題をそれぞれのメンバーに割り振っていった。これも開発が進むうちに、自分が関心のある issue を取ったり、やらないといけないものを自分で割り当てるようになっていけば自律的な開発へ向けてさらに進展していく。

これまでは機能開発を3ヶ月、QA を1ヶ月としてきた。今回は機能開発を2ヶ月、テスト/QA 期間を2ヶ月とる。自動テストや QA 工数の削減のための取り組みに時間を割いて、人間が QA 検証する工数を削減していく。私自身やらないといけない残課題がいくつかあるので早め早めに fix していって集中力をもって取り組む必要がある。今回はマネージャー業をメンバーに移行した分、久しぶりに開発に専念してコードを書ければいいなとも思う。どうなるかな。