flint>flint blog
ページ: « 0 1 2 3 4 5 6 7 8 9 10 11 12 13 »

HTMLテーブルのデータ部スクロール

部分スクロール

HTMLでテーブルを記述するには <table>要素 (タグ) を使用します。 その際、「行」を表す <tr>要素 を<table> 要素の直下に配置しても構わないのですが、セマンティクス、すなわち

それが「見出し行」と「データ行」のいずれであるのかをブラウザに明示する

という観点から、<table> 要素の下に「見出し」セクションを表す <thead>要素 および <tbody>要素 を配置し、<tr> 要素はそれらの中に記述するのが好ましいとされています。 現状では <thead>, <tbody> 要素を使用してもしなくても、レンダリングにおける差異はないのですが、MDNのページにある以下の記述:

表が (ウィンドウのような) 画面に表示される場合で、表全体を表示するのに十分な大きさがないとき、ユーザーエージェントは <thead>, <tbody>, <tfoot>, <caption> ブロックを親である表から独立してユーザーがスクロールさせることができるようにするかもしれません。

を読んで「それは素晴らしい!」と感動して以来、テーブルを書く際は可能な限り <tbody> を記述するようにしているのですが、それから十余年経ってもテーブルデータ部の独立スクロールがWeb標準として実装されるという話は寡聞にして一切聞こえてきません。 面倒くさいのを我慢して律儀に <tbody> タグを記述し続けた俺の10年を返せ。 ......などと言っても詮無き事。 せっかく <tbody> タグを記述したのだから、スクロール機能も自分で実装すればいいじゃない。

というわけで、今回は CSSJavaScript を駆使してテーブルデータ部の独立スクロールに挑戦しようと思います。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

テーブル設計アンチパターン

6月下旬から連日40℃近い酷暑に見舞われ、最高気温が35℃を下回ると「今日はちょっと涼しいね」などという会話が交わされている甲府盆地よりお届け致します。 皆様におかれましては熱中症対策などを十分に講じ、体調に気を付けてお過ごし頂ください。

これまたいつものことですが、現在の仕事は既存システムの改修がメイン。 先月までは Internet Explorer のサポート終了に備え、モダンブラウザで動作しない JavaScript の書き直しや、VBScript による機能のサーバ側への移設といった作業に忙殺されておりました。 ブラウザの移行に伴って発生する動作不良への対応なので、問題が発生するのは基本的にクライアント側なのですが、その原因や対処法を探る際にはサーバ側の動作を含め、対象システムのすべての挙動を調査・把握する必要があります。

そうした分析業務を妨げる要因のひとつに「低品質なプログラム」の存在であることは以前の記事で述べた通り:

それでも、よく管理されているプロジェクト、よくメンテナンスされているシステムではプログラムの質も比較的優良であり、その改修・拡張といった作業は開発元企業に属する人員によって行われている場合が多いようです。 一方、私のような「外注」に改修依頼が出されるようなプログラムというのは、開発元の「正規部隊」が手を付けられない、あるいは手を付けたくないほどに低品質なものであるというのが相場。

今回の記事では、これと双璧を成す「低品質なデータベース設計」について、事例ごとに問題点とその背景について解説してみたいと思います。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

野菜の肉巻き・生姜ソース

一人で暮らしている私は外食をする機会も多かったのですが、新型コロナウイルスが流行し始めて以降は、その頻度は顕著に低下しました。 外食をする場合でも、

  • 混む店には行かない
  • 混む時間帯には行かない
  • 店の前まで来ても混雑していたら入らない

など、感染リスクを抑えるよう心掛けてはいますが、自分の後からマスクを外した状態で大声で話す迷惑きわまりない団体が入店してきた場合などは、有効な対処をすることは困難。 目の前の料理を掻き込むように平らげて、可能な限り速やかに店を出るしかありません。

そんなわけで、必然的に食事は自宅でということが多くなるわけですが、コンビニエンスストアやスーパマーケットで購入する総菜に対して自分の好みにぴったり一致する材料, 切り方, 味付け, ...等々を期待するのは詮無きこと。 飽きずに自宅での食事を続けるには、自炊技術を向上させる必要があります。

そこで今回は、自分が作る料理のレパートリーの中で「定番」の位置を占める一品「野菜の肉巻き・生姜ソース」を紹介します。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

The 10th Anniversary

日本中で新型コロナウイルス感染症が拡大する中、新幹線空港もないド田舎陸の孤島ぶりが幸いして奇跡的な清浄さを保っていた山梨県の、ゴールデンウィーク明け頃からの感染者数急増に恐れ慄いている昨今、皆様は如何お過ごしでしょうか。 タイトルにもある通り、独立して今年で10年。 8年目, 9年目は面倒くさい特段書くこともなかったためアニバーサリー記事の執筆をサボってしまいましたが、さすがに10年の節目には何か書いておかないと、読む人がいるかどうかはともかく自分の意識が緩み切ってしまいそうなので、アップロード予定日の2週間前からポツポツと認 (したた) めている次第です。

肝心の仕事の方はどうかと言えば、この4月からとある大手企業のオフィスに入り、そちらの業務システムの改修に携わらせて頂いております。 使用する言語も VB.NET および、レガシーシステムを構成するVBScriptとこれまでに縁のなかったもので、BASIC を扱うのは PC-98 時代以来となる私は昔を懐かしみつつも、仕事の傍ら勉強に励んでおりました。 そうそう、For ループは Next で閉じるんだったねぇ......。 まぁ、私ほどのプログラマともなれば、使い始めて2ヵ月経った頃には完全に理解できてしまっていたわけですが。

【エンジニア用語解説】
「完全に理解した」
製品を利用をするためのチュートリアルを完了できたという意味。
「なにもわからない」
製品が本質的に抱える問題に直面するほど熟知が進んだという意味。
「チョットデキル」
同じ製品を自分でも1から作れるという意味。または開発者本人。
>> 続きを読む
成田
このエントリーをはてなブックマークに追加

ゲームを通じて英語に触れる

Skyrim on Quarantine

新型コロナウイルス感染症の蔓延への対応として日本で最初の緊急事態宣言が発令されてから一年余り。 この間、程度の変化はあれど、基本的には三密の発生を避けるべく、公的・私的を問わず人が寄り集まることは禁忌とされてきました。 これにより、友人らと遊び歩くことができなくなった人々のストレスはすさまじいものがあります。 我々のような大人については「社会人として理性と責任が求められる立場なのだから我慢してみせろよと」と思うところですが、友人らと共に学び、語り、競い合うことで社会性を身につけていく年代の子供たちは大変に気の毒であり、また、社会制度の変更を含めた継続的な公的ケアが必要になるだろうと考えています。

その一方で、私個人の生活の変化について言うならば、未だ限定的ではあるものの、在宅勤務の導入が進み、人と会うために家から出ていく機会が減った現在の状況は非常に快適であるというのが正直なところです。 趣味といえばプログラミング, 数学, 物理学, 読書料理と、どれも一人でできるものばかりという引きこもり気質の影響も大きいでしょう。 それら孤独に楽しむ趣味の中でも、とりわけゲームに費やす時間は大きく増加。 ゲームのコンテンツそのものを楽しんでいることはもちろんですが、その副次的な作用として、独立して以来めっきりと使用頻度が減っていた英語の読み書きをする機会が増えるという意外な効果が現れました。

というわけで今回は、本エントリを通じてこれらのゲームに興味を持ってプレイを始め、それによって外出制限下でも楽しく時間をつぶすことできる人が増えることを願って、このコロナ禍の期間であるかないかに関わらず私がゲームの中で出会い感銘を受けた英語表現について紹介していきます。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

二地点間の距離の計算

近年のスマートフォン普及の勢いは目覚ましく、日本においてはほとんどすべての人がこれを持ち歩く社会となりました。 そのため、私が開発・改修を手掛けるシステムの中にも、端末が備えるGPSモジュールによって取得された利用者の位置情報を利用するものが多々出てくるようになっています。 位置情報の利用方法は様々ですが、その中で最も大きな割合を占めるのが、システムに登録された施設 (店舗やATM等) と利用者の間の距離を計算して近いものを提案するというもの。 単純な直線距離ではなく、道路や線路などに沿った実際の移動距離を求める場合もありますが、その場合も連続する線分 (折れ線) で近似された経路の長さを計算することになるので、結局は二点間の直線距離の計算に行き着きます。

2地点の座標 (λA, φA), (λB, φB) (λ は緯度、φ は経度) からこれらの間の距離を求める計算はそれほど難しいものではありません。 まず、地球を、原点 o を中心とする半径1の球体 と仮定します。 北極を (0, 0, 1)、ヌル島を (1, 0, 0) とすれば、A, B の座標はそれぞれ、

xA = cos λA cos φA
yA = cos λA sin φA
zA = sin λA
xB = cos λB cos φB
yB = cos λB sin φB
zB = sin λB

となります。 これらの位置ベクトル OA (xA, yA, zA) と OB (xB, yB, zB) が成す角の余弦cos χ は内積として

cos χ = OA ⋅ OB = xA xB + yA yB + zA zB

と計算されるので、χ そのものの値は逆余弦 cos-1 を用いて、

χ = cos-1( xA xB + yA yB + zA zB )

と求めることができます。

2点ABを結ぶ単位球面上の最短距離すなわち測地線の長さは、全周 2π に対する角度 χ の比 χ/2π でなので、これを地球の半径 R 倍だけ拡大してやれば、実際の二点間の距離 δ が得られます。

δ = 2πRχ/(2π) = Rχ

以上のプロセスを JavaScript で書き下したならば、以下のようになるでしょうか:

//地球半径 (単位: m)
const EARTH_RADIUS = 6378100;

//2点 (srcLat, srcLong), (dstLat, dstLong) 間の距離を計算
function calcDistance(srcLat, srcLong, dstLat, dstLong){

    var srcX = Math.cos(srcLat)*Math.cos(srcLong);
    var srcY = Math.cos(srcLat)*Math.sin(srcLong);
    var srcZ = Math.sin(srcLat);

    var dstX = Math.cos(dstLat)*Math.cos(dstLong);
    var dstY = Math.cos(dstLat)*Math.sin(dstLong);
    var dstZ = Math.sin(dstLat);

    return EARTH_RADIUS*Math.acos(srcX*dstX + srcY*dstY + srcZ*dstZ);
}

ただし、関数 calcDistance の引数 srcLat, srcLong, dstLat, dstLong の単位は一般的に用いられるではなく、ラジアンであることに注意してください。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

文理の境界

明けましておめでとうございます。 この年末年始は、新型コロナウイルス感染拡大の影響を勘案して宮城県への帰省を控え、甲府市で過ごしております。 それにより、こちらへ移り住んでから9年目にして初めて元日の富士山を拝むことができました。

さて、その新型コロナウイルスは昨年の初めより世界中で猛威を振るっており、1年以上が経過した今もなお終息の気配すら見えてきていないというのは皆様ご存知の通り。 その原因もまた様々なところに求められてはいますが、その中でもとりわけ大きな要因のひとつが「多くの人々が "移動", "密集", "対面での会話" を充分に抑制しなかった」ことにあるのは間違いのないところでしょう。 個人的には政府および自治体のこれまでの取り組みおよび示されている今後の展望は無為無策の誹りを免れ得ないものだと考えていますが、その一方、他の先進国の状況についての報道を見る限り「日本はまだマシな部類である」というのも事実ではあるようで、この世界的な災害の背後には特定の国の事情に因らない、より普遍的なメカニズムがあるように感じられています。

生命, 健康, 財産が脅かされているにも関わらず、人々が自らの相互接触の抑制に消極的である理由について、心理学的な観点からは「正常性バイアス」や「認知的不協和」といった要因が指摘されています:

正常性バイアス (Normalcy bias) とは、認知バイアスの一種。 社会心理学、災害心理学などで使用されている心理学用語で、自分にとって都合の悪い情報を無視したり、過小評価したりしてしまう人の特性のこと。

自然災害や火事、事故、事件などといった自分にとって何らかの被害が予想される状況下にあっても、それを正常な日常生活の延長上の出来事として捉えてしまい、都合の悪い情報を無視したり、「自分は大丈夫」「今回は大丈夫」「まだ大丈夫」などと過小評価するなどして、逃げ遅れの原因となる。

認知的不協和 (cognitive dissonance) とは、人が自身の認知とは別の矛盾する認知を抱えた状態、またそのときに覚える不快感を表す社会心理学用語。 アメリカの心理学者レオン・フェスティンガーによって提唱された。 人はこれを解消するために、矛盾する認知の定義を変更したり、過小評価したり、自身の態度や行動を変更すると考えられている。

いずれも妥当な分析でありますが、人々の言動を観察するうちに、これに加えてまた別の種類の認知の歪みが感染症対策への消極性の一因になっているのではないか、と考えるようになりました。 客観的な裏付けがあるわけでもなく、強く断言・主張できる類の理論ではないのですが、自分の業種とも関連した話題でもあるため、本エントリで述べてみることにした次第です。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

CSVにありがちなこと

アプリケーションにおいてな持続的データを扱う場合はデータベース (ほとんどの場合RDB) を使用するのが一般的ですが、その多くは他のアプリケーションとのデータ交換を行うためのインターフェイスとしてCSV: Comma-separated Values (カンマ区切り) と呼ばれるフォーマットでのエクスポート/インポートをサポートしています。

このCSVという形式は (一見すると) 非常に単純で、「カンマ区切り」の呼称が示す通り、各行に個々のレコードに属するフィールドをカンマで区切って並べただけ。 例えば次に示すデータ:

表題 著者 価格
みずほ銀行システム統合、苦闘の19年史 日経コンピュータ 1800
大聖堂・製鉄・水車 ジョゼフ・ギース/フランシス・ギース 1210
彼女は一人で歩くのか? 森博嗣 660

これをCSVで表現すると、メモ帳 (Notepad) でも開くことのできる以下のようなテキストデータとなります:

表題,著者,価格
みずほ銀行システム統合、苦闘の19年史,日経コンピュータ,1800
大聖堂・製鉄・水車,ジョゼフ・ギース/フランシス・ギース,1210
彼女は一人で歩くのか?,森博嗣,660

コンピュータあるいはプログラミングに詳しくない人であっても、一瞥してその内容を見て取ることができるでしょう。

この「単純さ」こそ、CSVが多くのアプリケーションのエクスポータ/インポータとして採用されている最大の理由であるわけですが、それはあくまでも表面的なもの。 このフォーマットを正しく扱うプログラムを作るとなると、なかなかに複雑な処理が要求されることとなり、一筋縄ではいきません。 実際、市販され広く普及している「CSVをサポートしている」ソフトウェアの中にさえ、厳密にはこれを正しく扱えておらず、そのためにデータ交換に際してトラブルを生じるものが数多く存在します。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

Catast (ウェブ復刻版) 公開

Catast

学生時代 (2003年) に作った Windows 用パズルアクションゲーム "Catast" を、何を思ったか、16年が経過した今頃になってウェブアプリとして作り直してみました。

実はこのゲームのウェブ版を作るという構想はかなり前からあったのですが、その実現を阻むいくつかの要素がありました。 それらを影響の大きさに従って並べてみると、次のようになるでしょうか:

  1. 当時のウェブブラウザの貧弱あるいは互換性のない JavaScript およびCSSの実装 (特に Internet Explorer)
  2. 当時のスマートフォンの性能 (画面サイズ, タッチパネルの反応精度) の低さ
  3. 私氏自身の JavaScript のコーディング技術の低さ

しかし、それから月日は流れ、殆どすべての人が (端末ベンダ謹製の得体の知れない「ブラウザ」ではなく) Chrome や Firefox がインストールされたスマートフォンを持つようになり、また世間的に「もう Internet Explorer はサポートしなくていいよね」という雰囲気 (コンセンサス) が形成されてきたこともあって、上記 1, 2 として挙げた外部的な要因はほぼ取り除かれたように思われます。 また、3 に挙げた私自身の JavaScript の腕前も、本業の方で JavaScript が絡む案件をこなしているうちにそこそこのレベルには達したと自負するに至り、ではここいらでちょっとチャレンジしてみようか、というわけで今回の Catast 復刻に着手した次第。

そこで今回は、この開発作業において苦労した点などについて話をしてみたいと思います。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加

低品質コードの成長過程

インデントの深さや変数・関数の命名規則に関する信条の違いで殴り合いの喧嘩ができる我々プログラマにとって、他人の書いたコードを読んだり、それに手を入れたりすることは大変にストレスフルな作業。 しかしながら今日では、ビジネスとして作成されるプログラムがたった一人の人間によって書かれることは極稀なことであり、職業プログラマは誰もが多かれ少なかれ、そのストレスに耐えながら仕事をしています。

それでも、よく管理されているプロジェクト、よくメンテナンスされているシステムではプログラムの質も比較的優良であり、その改修・拡張といった作業は開発元企業に属する人員によって行われている場合が多いようです。 一方、私のような「外注」に改修依頼が出されるようなプログラムというのは、開発元の「正規部隊」が手を付けられない、あるいは手を付けたくないほどに低品質なものであるというのが相場。 さすがに本記事のタイトルに入れることは思いとどまりましたが、そのようなコードは「糞コード (くそこーど)」と呼ばれ、ある種この業界の名物となっているとかいないとか。

「なんだこの糞コードは! (怒)」「書いた奴出てこい!(怒)」
こんな声を聞いたり、叫んだりしたことはありませんか?
ウンコードについて学ぶことによってウンコードを撲滅しましょう!

私自身、既に本が書けそうなほどに糞コードを相手にしてきましたが、その中のひとつに、それ自体は非常に小さくシンプルなものでありながら、糞コードが生産されるプロセスを理解するのに大変有用な事例がありました。

if ($record->type != TYPE_A && $record->type != TYPE_B && $record->type != TYPE_C){
    //一般的な処理
}
else if ($record->type != TYPE_B && $record->type != TYPE_C){
    //タイプAに対する処理
}
else if ($record->type != TYPE_C){
    //タイプBに対する処理
}
else {
    //タイプCに対する処理
}

今回はこのコードを教本として、糞コードが出来上がるまでの過程を、読者の皆様と共に考察していきたいと思います。

>> 続きを読む
成田
このエントリーをはてなブックマークに追加
ページ: « 0 1 2 3 4 5 6 7 8 9 10 11 12 13 »