コンテンツ自動生成プログラム

GWに趣味で、パターン画像を再帰的に描画するプログラムをC#とOpenCVで実装しました。
フラクタル図形描画プログラムのようなものです。
遠出している最中に処理を考え、その日の内に処理の流れだけ実装し、別日に本実装をしたのですが、
すんなり動くものが実装できて良かったです。
素直に書いたら5重ループになったので、計算量削減には若干手間がかかりました。
人力でも作成可能な画像ではあるのですが、
気が遠くなるような時間がかかるところをPC性能や再帰回数次第ですが数分で描画できます。
自分の代わりに何かコンテンツを自動生成してくれるプログラムは、万能感を感じることができるので好きです。

最近はお絵描きAIがどちらかと言えば悪い意味で話題になっていて、
データを学習しない自動生成プログラムまで叩かれるのではないかと少し不安になりますね。
データを学習するしないに関わらず、法的・倫理的に他者の権利を侵害しない範囲で、
自動生成技術が進歩して行くと良いなと思います。

ユーザビリティの考慮

自分はまだ仕様の整理やプログラムの設計・実装に精一杯で、
ユーザの使用環境を考慮したソフトの使いやすさに気が回らないことが多いです。

例えば最近の失敗だと、お客様からの要望仕様通りではあるのですが、
作業者にキーボードのない小型タッチパネルPCにて
書類ファイル(Wordなど)の入力・登録を強いるような機能仕様としてしまっていました。

ユーザの使用環境を正しく想定できていれば、そのような作業内容は現実的でないため、
後から別のPCにて入力・登録できるようにするといった改善仕様を考えられたのだと思います。

中々難しいですが、ユーザビリティを考慮したソフトを作るようにしたいです。

設計の重要性

最近ソフトウェアのある1機能の開発を行ったのですが、想定よりも工数が多くかかってしまいました。
工数がオーバーした原因を考えると、
全体の設計がぼんやりとした甘い状態からコードを書き始めてしまったために、
実装時の迷いや構造の見直しによる手戻りが生じたりしてしまったからではないかと思われます。

プログラムもそれ以外のものでも、
何かを作る際に全体が曖昧なまま個々の詳細から作り込むと、
最終的にそれらを整合性を保ちながら結合させるのは難しく、
結果として辻褄を合わせるはめになり、時間がかかったり構造が歪になってしまう気がしています。

そうならないためにも、全体を曖昧に設計した後、
まずは徐々に全体設計の詳細を詰めて行き(抽象度を下げて行き)、
中盤以降に詳細を作り込み始める(プログラムだとコードを書き始める)のが良いのだと思います。

今回の場合だと、設計は処理の流れと曖昧なクラス設計のみだったのですが、
社内メンバーからの助言を盛り込むと、
データの流れも考えた上で、クラス設計の最低限上位の部分まではしっかり設計してから、
コードを書き始めるべきだったのかと思います。

手を動かさないと何も進めていないように感じたり思われたりするかもしれませんが、
その時間をかけることで結果的に工数を削減できるのではないかと思われるので、
時間に上限は設けた上でしっかり設計を行うようにしたいです。

Python->C#書き直し業務所感

ここ最近は他社のソフトを作り直す案件に携わっています。
自分の担当はPyhonで書かれた部分をC#で書き直す作業です。
書き直すコードはざっくり言うと画像に写っている人間を検出するコードで、
以下のような処理を行っています。
1. 推論エンジンに入力画像を投げる
2. 推論出力結果から検出された物体の情報を切り出す
3. 切り出した物体情報を元の入力画像上の値に変換する
物体の情報をどのようにデータ構造に格納しているかなどがわかって、書き直していて面白いです。

書き直していて思った所感は他に以下の2点です。

1. Pythonの方が多次元配列を扱いやすい
 Pythonには数値計算ライブラリのnumpyがある関係で多次元配列が扱いやすいです。
 機械学習を行う際の主流になるのも納得です。
 C#で書き直しているコードでは1次元配列で保持し、
 多次元配列のインデックスを1次元配列のものに変換してアクセスするようにしたのですが、
 インデックスの計算などにミスしてしまい、修正に少し手間取ってしまいました。
 …とここまで書いて、ふと調べてみましたがC#でもnumpyのライブラリがあるようでした。
 書き直したコードのパフォーマンスなどに問題あれば、使用を検討しようと思います。

2. コードのコピペをする際は中身を極力解読すべき
 既存Pythonのコードを調査していたところ、コアの部分がネットからコピペされていました。
 ライセンスなどないコードだったのでそれ自体は問題ないかとは思いますが、
 よく解読せずにコピペしたために生じたのではないかと思われる実装ミスがありました。
 (コピペ内で行われている処理をコピペ外で重複して行っており、
  設定次第では正常に動作しなくなっていました)
 マジックナンバーなど解読できないこともあるかと思いますが、
 不精せずに可能な限り解読を試みてコメントを付与して、
 保守しやすい状態にする必要があると感じました。

以上です。

2022年お世話になりました

早いもので2022年ももう少しで終わりですね。

弊社は本日、午前は通常業務、午後からは大掃除を行いまして、本年の業務終了と相成りました。
明日から4日まで冬季休暇で5日から通常業務となります。

皆様本年はお世話になりました。
来年も何卒よろしくお願いいたします。
それではよいお年をお迎えください。

最近やったこと・やっていること

1. EXCELマクロをVBAで実装する案件を行いました。
VBAは一度読んだことがある程度だったので文法を調べつつだったのですが、
C#では手軽にコードレスに行えるところでも手間がかかるなどして、
想定以上に工数がかかってしまいました。
ですが必要な機能をひとまず実装してみて、コードを少しづつ洗練して行く過程は楽しかったので、
良い経験にはなったかなと思っています。

2. Pythonの環境構築や調査を行いました。
既存のPythonで書かれた処理をC#で置き換える案件のためです。
Pythonは学生時代に講義で習ったのと研究でグラフ出力するのに使用したことがある程度なのですが、
久しぶりだったのもあり楽しかったです。
得られた知見としては、特段の事情がなければ環境構築はAnaconda上で仮想環境を作成して行うのが良いということです。
今回まずはローカルの環境にpipでライブラリのインストールを行っていたのですが、
その際にcmakeでのビルドが必要だったりして中々上手く行きませんでした。
しかしAnacondaで試してみたらすんなり出来ました。
ライブラリの取得先がpipとは異なるからなのか、パスの設定などまで行ってくれるからなのか、
理由ははっきりわかっていませんが、
依存している他ライブラリのインストールまで含めて良しなにやってくれるようです。
pythonやライブラリのバージョン競合も防げますし、環境の削除も一発ですし、
本番環境でなければAnaconda上で済ませてしまいたいと思いました。

3. 私事ですが毎朝2,3分走っています。
朝は少しでも寝ていたいため毎朝ギリギリの時間に出発しているのですが、
3か月ほど前からは特にそれが顕著で、毎朝バス停まで走るはめになっています。
初めはぜぇぜぇ言いながら走っていたのですが、
最近は走るのが少し楽になってきて一周回って楽しくなってきました。
心なしか体力も向上した気がしており、仕事でも疲れにくくなったように感じています。
運動の重要性をひしひしと実感しております。

以上、近況的な投稿でした。

コロナに感染しました

題の通りで、先月末コロナに感染しました。
快復傾向に至るまで1週間ほどかかり社内メンバーにはご迷惑をおかけしてしまいました。

症状としては喉の痛みが少しあったのと、38-39℃ほどの発熱で、
発熱は連日続いたため大変しんどかったです。
発熱外来では解熱剤を貰えなかったのですが、
家にロキソニンが余っていたのでそれを呑んで耐え凌ぎました。
現在は快復はしたのですが、後遺症なのか痰が喉に絡み続けていて、
咳を出さざるを得ず若干過ごしにくいです。

社内メンバーにも家族にも感染を広げなかったのは不幸中の幸いでした。

開発担当の案件も遅れが出てしまったのですが、
社内メンバーに開発を手伝ってもらい、
本日無事納品することができて一安心しました。
(福岡さん、masugiさん、ありがとうございました。)

皆様お気を付けてお過ごしください。

WindowsFormにおけるコントロールの別ウィンドウ化

弊社で最も規模の大きなプロジェクトはWindowsFormにて開発が行われています。

先日、そのプロジェクトにてコントロールを別ウィンドウ化する処理を
既存の実装を参考にして実装したのですが、
予想以上に手軽に出来て驚きました。

以下のようにするだけでした。

// 別ウィンドウとなるフォームを作成
var window = new Form {
	Owner = this.ParentForm,
	Width = this.Width,
	Height = this.Height
};
// 別ウィンドウ化したい対象コントロールの親コンテナに新規ウィンドウをセット
// (別ウィンドウに移し替える)
targetControl.Parent = window;
// 別ウィンドウクローズ時に親コンテナを元に戻すように
window.FormClosed += (_, _) => {
	targetControl.Parent = this;
};
window.Show();

親コンテナのSetterは参照を移し替えるだけかと思い込んでいたのですが、
配置も移し替えるのですね。
便利に作られていてありがたいです。

栄養ドリンクと夏季休暇

皆さんは休日、どのように過ごされていますでしょうか。

自分は疲労により椅子に座る気力もなくベッドに転がってだらだらとスマホを弄るなど、
無をしてしまうことが多々あります。
流石にもっと精力的かつ有意義に過ごしたいと思い、
先々週から週末に栄養ドリンクのユンケルを1本飲むようにしてみています。
流行りのエナジードリンクでなく栄養ドリンクなのは、
エナドリは学生時代に飲み過ぎたせいか少し苦手になってしまったからです。
まだ2週だけですが、心なしか週末に心身共に元気な状態で過ごせた気がします。
(プラシーボかもしれませんが。。。)

ところで、弊社は明日から15日まで一応夏季休業となっております。
この連休も元気に過ごせるよう、ユンケルを飲んでおこうかなと思っています。
皆様もお体にはお気をつけて、元気にお過ごしください。

タプルを用いた値の交換

2つの値を交換したい時、皆さんはどのようにしていますか?

私は本日、以下のように愚直に行っていました。

var x = 1;
var y = 2;
var tmp = x;
x = y;
y = tmp;

スマートでないな~と思っていたのですが、
コードレビューにて同様の処理をタプルを用いて以下のように記述できるとの指摘を受けました。

var x = 1;
var y = 2;
(x, y) = (y, x);

う~ん、これはスマート!
(シンプルで可読性が高くて良いですね!)

タプルの構築と分解代入の複合により実現されるようです。
少し調べてみたところ、
コンパイル時には以下のような具合に最適化されるようです。

var tmp1 = y;
var tmp2 = x;
x = tmp1;
y = tmp2;

コンパイラも賢いですね!

今後もこのような知見を活かしてコードをシンプルに保てるようにしたい所存です。

(参考)
以下のサイトを参考に一部コードを引用させていただきました。
ありがとうございました。

複合型の分解 – C# によるプログラミング入門 | ++C++; // 未確認飛行 C