isyumi_netブログ

isyumi_netがプログラミングのこととかを書くブログ

なぜ『ネットで政治が良くなる』は幻想だったのか。そして解決策案。

 

昔、政治と民意についてこんな話を聞いたことがある。日本医師会の会員数と妊婦さんの数はだいたい同じらしい*1日本医師会は国政に絶大な影響力を持っているのに、妊婦さんの意見は通り辛い。それは何故か考えてみましょう。という話。

 

さて、10年前にはこれからネットで日本が良くなっていくという希望があった。
Twitterなどでみんなが自分の意見を自由に発信できるようになったからだ。

しかし、それは幻想だった。
人々が好きなことを発信できるようになったからといって、急に世の中がガラッと良くなることはなかった。

いくつか、ネットで政治を良くしようみたいな活動をされている人を見掛けるのだが、あまり応援する気にはならない。
『ネットで自由に意見を言えるようになったところで、それだけでは足りない』ということに気づいていなさそうだからだ。

 

僕は三つの課題があると思う。

  1. 正しいことを言うのは難しい
  2. 仲間を集めるのは難しい
  3. 意見が違う人と話し合うのは難しい
正しいことを言うのは難しい

何かを変えたければ自分の困りごとを『証拠に照らして』『緻密な論理展開で』言葉しなければいけない。それは高等技術だ。殆どの人はそんなことできない。ということは、その気になればどんな意見であっても「お前は間違ってる」で片付けることができてしまう。それはよくないと思う。

よくTwitterで社会に対する不満を見かける。
本人は勇気を出して声を挙げたのだ。意見には誠意を持って耳を傾けるべきだと思う。
にもかかわらず、引用欄を見ると事実誤認や論理の飛躍を指摘して冷やかしている人がたくさんいる。ちょっと冷たいなと思う。

とはいえ、僕は発言者が弁論の素人だからといって事実誤認や論理の飛躍が含まれる主張を無条件に受容するべきだとは思わない。
みんなの事は出来る限り正確な情報と論理的思考に基づいて決めるべきだ。

僕はこの『ちゃんと意見を言うのは難しい』『ちゃんとしてない意見を受け付けるべきではない』『でもみんなの意見を聞きくべきだ』という相反する問題について考えている。

仲間を集めるのは難しい

さっきの医師会と妊婦さんの件はこれらしい。一度医者になった人はずっと医者だが、妊婦さんは1年で妊婦さんではなくなってしまうから、組織力に差が出てしまうという話らしい。

Twitterでも、同じ問題意識を持っている人同士でもっと積極的に連帯していこうという話にはなりづらい。
なったとして、すぐに変なカルトが出来るだけだと思う。

僕も経験がある。
とある『良くないことをしている政治家』をTwitterで批判したことがあった。
すぐに、同じようにその政治家を否定している人たちと対話が始まった。
最初のうちは同じ意見を持っている人同士で話が合うと思った。
ところがそうはいかなかった。
僕はその政治家がしたAという行為は良くないと思ったが、Bという行為は別に問題ないと思った。
その人たちにそう伝えた。
そうしたらその人たちがキレだして、複数人から『なんであんな政治家を擁護するんだ』とか『お金を貰ってるのだろ』とか言われて不愉快な思いをした。
もうこの人たちには関わらないでおこうと思ったし、政治についてTwitterに書くこと自体が不利益だと悟った。

自分の意見を世の中に伝えていくには、どうしたって同じ意見を持つもの同士で寄り添う必要がある。
断っておくが、少人数の意見だから黙殺していいとか、大人数の意見だから採用するべきだとかは思っていない。
しかし、現実問題として同じ意見を持つもの同士でまとまらないと政治力にはならない。と同時に、同じ意見を持つ人同士でまとまるのは面倒事が多い。

よって、ある程度責任ある立場の人がハブになってくれたほうがいいと思う。
少なくとも近しい意見を持っているからと言って一般市民同士が無理対話しなくてもいいようにするべきだ。

意見が違う人と話し合うのは難しい

もし僕が正し意見を持つ側だったとしても、口喧嘩の相手が西村博之さんなら絶対に自分が言い負かされる自身がある。

意見の中身ではなく口の達者さで勝敗が決まってしまうなら最初から話し合う意味がない。

ちゃんと弁論について訓練を受けた人同士が論を戦わせたり、時には譲歩し合ったりして話を決めるべきだと思う。

 

以上が、僕の問題意識だ。

この先の民主主義はどうあるべきか

僕はこんなシステムだったらいいと思う。

まず、自分の意見を代弁してくれそうな人を見つけ訴え出る。ここは拙い言葉でもいい。
依頼を受けた人は、論理武装して国会で弁舌をふるう。
その人に思いを託した人がどのくらいの人数いるのかがちゃんと可視化される。

こういうシステムだったらいいと思うし、それを支援するITシステムがあったらいいと思う。

*1:いま確かめてみたら数字が合わなかったのでちょっとニュアンスが違ったかもしれない

好きな技術書ランキング

好きな技術書ランキングを発表するのが流行ってるらしいので便乗します。

もともとは初心者の時に役に立った技術書とかいうトピックだった気がしますが、この際どうでもいいや。

ジョー・セルコ『プログラマのためのSQL

この本に書いてあるのはSQLの事ですが、しかしプログラミング全般に役立ちます。
僕がこの本で学んだのは、プログラムは処理ではなくて宣言だという事です。

まず、どのプログラム言語にもその言語を司っている設計思想があります。
だから、それに合わせたコードを書くべきです。
そして、言語にはセマンティクスが用意されています。
ただ漫然と動くコードを書くのではダメなのです。
その言語のセマンティクスを理解し、それを使って自分の意図をコードで表現することもプログラミングの大事な側面です。

ということをこの本が教えてくれました。

GoFオブジェクト指向における再利用のためのデザインパターン

一般的にデザパタ本と呼ばれている本です。

大体の言語にはinterfaceという機能がります。
これほど使い道がよくわからん機能もなかなかない気がします。

extendsはわかりやすいです。処理を共通化できるから。
それに比べてinterface単体では処理を共通化できず、一体お前は何がしたいのだと思います。

しかし、実際にはextendsを多用するとすぐにコードが汚れてしまいます。
反面intarfaceを(上手に)使ったコードの共通化はあまりコードが汚れないです(上手にやれば)。

初心者の方はぜひこのデザパタ本を写経するといいでしょう。

この本に書いてある内容は古く、現代では通用しないという事で多くの人の意見が一致しているようです。
僕もそう思います。
この本の内容は役に立ちません。

しかし、interfaceを何に使うのかを理解するうえで一番いい本だと思います。
どうしたらコードを汚さずに処理を共通化できるのか、ノックだと思ってやってみるといいと思います。

戸根勤『ネットワークはなぜつながるのか』

ネットワークスペシャリストが自信をもってお勧めできる、
最もわかりやすくネットワークの初歩を教えてくれる本です。
ソフトウェア開発をしていて、ネットワークについてほとんど知らないわけにはいかないと思います。
とはいえWeb系の開発者であればネットワークにめちゃくちゃ詳しい必要もないと思います。

その点この本は粒度が最適だと思います。
この本を読んで興味がわいたらもっと専門的な勉強をしてもいいし、
この本の内容だけでも実際に必要なことはばっちり身に付きます。

トム・デマルコ『デッドライン』

お仕事では、組織運営に対する洞察も重要です。

トム・デマルコさんは「ソフトウェア開発で起こる問題は大体人の問題だ」っていうんですね。

みんな自分たちはハイテクなことをしてるって思いあがってる。
でも本当にハイテクなことしてるのは最先端の発明・発見をしているごく一部の人だ。
それ以外のソフトウェア産業の人はみんな突き詰めれば人間関係ビジネスだ。

だそうです。
で、いかに人間の組織を使ってソフトウェアを作るかという事についてこの本が教えてくれます。

坂田アキラ『坂田アキラの 数列が面白いほどわかる本』

世間のイメージに反して、
プログラミングと数学って実はあんまり関係がないですよね。
Web系のプログラマーが数学を使う機会なんて普通はほぼないと思います。
数学力がない人でも全然問題なくやっていけるわけです。
ところが、数列だけはプログラミングとかかわりが深いので簡単にかじっておくといいかと思います。

ジョン・マコーミック『 世界でもっとも強力な9のアルゴリズム

今までの本の中で、一番知識によっている本です。
この本を読みながら何か練習したりしなくてもいい本です。
圧縮や暗号化についてざっくり知っておくと便利だと思います。

そもそも、この「好きな技術書ランキング」みたいなのが今ネットで流行ってるのって、
この業界には「なぜかみんな知ってるけど、それをどこで教わってるのかわからない」みたいな知識が膨大にあるからだと思います。

という意図を鑑みるとこの本が一番お勧めかもしれません。
「なぜかみんな知ってるけど、教わる機会がない話」集としてはよくできてると思います。

泉水翔吾、 佐藤歩『超速! Webページ速度改善ガイド 』

Web系の開発者ならば、平場でPageSpeed Insights90点くらいは出せるようになってほしいと思います。

この本を読むとページ速度を上げるうえでどこが大事かがわかります。
それがわかっていると、開発の早い段階から速度を上げやすい設計にできます。

それとは別に、ページ速度はわかりやすい点数が出る点がいいと思います。
プログラミングというものはどうしてもゴールがあいまいになりがちです。
その点、この本を参考に特定のページの速度を上げる経験を繰り返すことによって
プログラミングスキルが全体的に向上するものではないかと思います。

ただ、ちょっと内容が古いところもあります。
最新情報は別途追った方がいいと思います。
変化が速い領域なのです。

徳丸 浩『体系的に学ぶ 安全なWebアプリケーションの作り方』

いわゆる徳丸本です。

あまり「読むべき本」などと強い言葉は使いたくないですが、
これは唯一「読むべき本」だと思います。

XSSSQLインジェクションCSRFなどについてわかりやすく書かれています。

リーアンダー ケイニ―『ジョナサン・アイブ 偉大な製品を生み出すアップルの天才デザイナ』

デザインの本も挙げたいなと思いました。

『誰のためのデザイン』『インターフェースデザインの心理学』などの名著と迷いましたが、
最終的にこの本を選びました。

具体的な技術はいろんなところで身に着けるとして、
そもそもIT系の人がちゃんとデザインに興味を持つことが大事だと思いました。

デザイン次第で商品の評価がこれほど変わるのかという事と、
いいデザインにするという事を工程に完全に組み込まなければいけないという事の両方を学べます。

『工程の最後にデザイナーさんに仕上げをお願い』ではないのです。
『いいデザインのものを作るという事がゴールで、プログラミングはそのお手伝い』と考えなければいけないのです。

プログラミング中級者の伸び悩み

流石にもう僕はプログラミング初心者ではないと思う。多分中級者くらいだ。
これまで初心者向けの教材や切磋琢磨の場にたくさんお世話になってきた。ありがとう。

さて、それ以降の人って何をしたら伸びるんだろうね。

Twitterやブログを見ていると、自分より優秀そうな人はたくさん見つかる。
でも、自分とその人の間にどういう差があってどうすれば近づけるのか分からない。
僕はそんなことを5年位悩んでる。

まず、初心者を脱するとどうなるか。

初心者の頃は、とりあえずプログラミングが好きなら勝手に伸びる。
作りたいものを作りたいように作ってるだけでどんどん成長していく。
会社に入らないと身につかないスキルがあるという意見もある。コードを整理整頓する技術などだ。しかし、僕は幸いなことに生まれつき脳のワーキングメモリが極めて乏しかったため、ちょっとでもコードが散らかると頭が爆発するので、その手の技能も趣味開発で身につけることができた。
この段階であれば、自分の足りない知識が何かを自分で検知できる。開発をしていて困ることはたくさんあるからだ。
本屋さんに行けば自分に必要な本が必ず10冊くらい見つかる。
ところが、そのうちただコードを書いているだけでは全然成長しなくなってくる。
だいたいのものは一通り作れるようになってるからだ。
既に持っている知識と適宜のググりで困ることはほとんど無い。
もちろん本当は知らないことがいっぱいあるんだと思う。でも、苦手なことを無意識に回避する方法を覚えてしまっている。だから、自力で自分の苦手分野に気づくことができなくなってくる。

また、初心者のうちは新しい言語を覚えたりフレームワークを使ってみたりする度に成長していく。新しい世界観に出会えるからだ。
でも、徐々に新しい技術を身につける時の負荷が落ちてくる。

初心者を脱した僕が何をしたのか。
まず、本屋さんでいわゆる名著の類を読み始めた。プログラミング原論とか型システム入門とか。
頑張って読んだけど難しすぎて全然アレだった。
多分僕はまだこの次元には達してないようだ。

次に、資格を取り始めた。TOEICと数学検定とAtCoderIPA
ここ数年間は毎月100時間くらい勉強している。
AtCoderと数検は一応それなりに難関と言えるところまで到達した。

他にも、mozaic bootcampに参加させてもらった。
これは大変良かった。
ただ、365日誰かにこうやって教えてもらうわけにも行かなそうである。

何より、会社での仕事を一生懸命やってきた。

そんな僕は、なぜ伸び悩んでいると思うのか。
実は先日いわゆる転職活動というものをした。
その結果、あんまり自分の評価が高くないということを思い知った。
初心者を卒業してから何年間もずっと精進して生きてきた。だから当然それなりの評価があるものだろうと思っていた。ショックだった。

確かに、コーディングテストや知識を問う系のテストは上手く行った。
『○○なアプリを作りたいからどんなインフラにするか考えて』系も大丈夫だった。
でも、その次のステップでほぼ落ちた。

伸び悩みながらも頑張ってやってきたつもりだったが、実は全然伸びていなかったんだろうなと。
自分が技術力だと思っていたものとみんなが技術力だと思っているものは全然違うんだろうなと。
しかも、今僕は何が理由で落ちたのかよくわからないでいる。
これは困った。

今後僕はどうするか。
とにかく自分よりもっとレベルの高い人に色々教えてもらえるようにならないといけない。

二つ目標を決めた。自分よりレベルの高い人がたくさんいる会社で働くこと。もう一つはもっとコミュニティに関わる。

自分よりレベルの高い人がたくさんいる会社で働くというは、かなり難しい目標だ。だって、普通に考えて受からないからね。
これは煽りじゃないんだけど、その会社で一番技術力低い技術者って、どうやって会社に入ったんだろうね。
それってある意味一番難易度が高いハードルを突破した人ってことじゃん。
だれかレベルが高い会社の受かり方教えてください。

もう一つはコミュニティに関わるということ。
そうすれば色んな人が自分にいろんなことを教えてくれるようになると思う。
具体的にはこれをやろうと思っている。QiitaのQ&Aやteratailで質問に答える。みんなの技術ブログにちょっとコメントする(自分も試してみましたとか)。趣味でアプリを作ってる人がいたらちょっと使ってコメントをいう。
なぜそう思ったかというと、昨日中田敦彦Youtube大学でオンラインサロンについて見たからだ。
オンラインサロンには興味がないが、オンラインサロンの活用術でこんなことを言っていた。『一番興味を持たれるのは一番みんなに興味を持ってる人。一番発信力があるのは一番人の話を聞いている人。一番手助けされるのは一番手助けしてる人』
これは確かにと思った。だから、僕はこのIT界隈にもっと貢献しようと思う。

『あのアーティストの代表曲は』の技術詳解

 

こういうWebアプリを作った。
https://famous-song.app/

本人は企画として面白いと思っている。
せっかくなので、どういう技術で作られているかについて解説する。

概要

まず、認証とRPCは全てFirebaseを使っている。
サーバーサイドはFirebase HostingとCloud Functions。
フロントエンドはTypeScript/React/Redux/typescript-fsaあたりを使った。
投票ページはSPAで、それ以外の結果表示ページはSSRしている。

意図

SSR

最近はSSR不要論も多い気がする。
ただ、フロントエンドでSPAと合流するようなSSRならともかく、ペライチのHTMLを生成するだけならSSRしたほうがロードが速いし実装も楽だと思う(そこに反対する人はいないと思う)。
SSRにはReactのtsxを使った。
tsxを使うと、引数にTypeScriptの型をそのまま使えるので簡単である。

SSRのCache-Controlにはこれを指定した。
public, max-age=10, stale-while-revalidate=1000
キャッシュが古くてもとりあえずCDNのキャッシュを返し、その間にCDNからCloud Functionsにアクセスしてキャッシュを入れ替える。
こうした理由はコレだ

  • Cloud Functionsはそこそこ重い
  • リアルタイム性が超重要というわけではない
  • ユーザーも、おかしいなと思えばリロードするくらいのリテラシはあると思う

コマンド化

フロントエンドからRealtime Databaseの公開データを直接書き換えるのではなく、
フロントエンドからサーバーサイドにコマンドを送って、サーバーがそのコマンドを元に公開データを書き換える仕組みにした。
こうした理由は、この方がバリデーションやアクセス制御の点で楽だからだ。

この方式には1個欠点がある。
フロントエンドでサーバーの処理待ちがしづらいことだ。
RESTであれば、POSTを投げてからサーバーで処理が終るまでグルグルを出しておくということが簡単にできる。
しかし、Firebaseでコレをやってしまうとグルグルを消すタイミングがわからないという問題だ。
そこで、サーバーで処理が終わったこともRealtime Database経由でフロントエンドに通知することに指定ある。
その部分を抽象化してあるので、フロントエンドはasync/awaitで簡単に処理の待ち合わせができるようになっている。

フロントエンドでの正規化

それなりに大きいフロントエンドであれば、フロントエンドでも状態を正規化して持つべきだ。
正規化というのはRDB用語かもしれないが、要するに

  • 値段は三桁ごとのコンマを入れずに数値で持つ
  • Dateはタイムゾーンを統一しておく
  • 省略可能なものに関しては必ず省略する
  • RDBと同じように関係で表せるものは関係で表す

というよううなことだ。
タイムゾーンに関しては、YYYY-MM-DDの文字列で持つというのも結構優秀だ。
省略可能なものというのは、例えば誕生日・現在時刻・年齢や直角三角形の3辺など、二つが確定すれば残り一個も確定するようなものに関してはその1個を省略して持つほうが扱いやすい。
関係で表すとは、例えば、商品一覧とユーザー一覧と購買一覧があるなら、無理にオブジェクトで親子関係を作らずに配列を三つ持つということだ。

重要な点は、そのデータがどのように使われるかをあえて意識せず、データとしての完全性を最優先した型で持つことだ。
一見、そのデータがどのように使われるかに応じて型を決めたほうが後の処理を楽に作れる気がする。小さなアリケーションならこういう考え方もあると思う。
しかし、そういう考え方だと早晩コードが散らかってカオスになる。データの使い回しがしづらくなる。
やはり、データは極力完全な形で持つべきだ。

タブレイアウト

僕は、タブレイアウトって素晴らしいと思っている。
昔rebuild.fmでもそういうことを言っている人がいた。
2ch専ブラのJaneStyleやTabtterなど、人気のツールはだいたいタブレイアウトだ。
だから僕もタブレイアウトにした。
Webというものはクモの巣状にリンクが広がっていくモデルなので、ネイティブアプリと違って階層構造で画面遷移を表現しづらい。
それならば全てはタブであるという一般化をしたほうが認知しやすい。

アイキャッチの自動生成

Twitterなどにリンクを投稿する時のOGPのことだ。
実装の詳細はここに書いた。
https://qiita.com/isyumi_net/items/ee94a5e2d963958eb515
頑張ってレイアウトを計算すれば画像処理の延長で生成自動化は可能だが、
今使っている技術の延長で画像を生成できるということで、puppeteerを使った画像生成をした。特にBootstrapを使えるのでデザインが統一できて良い。

あのアーティストの代表曲は

 

序文

あのアーティストの代表曲は何だと思うかについてのアンケートサイトを作った。

https://famous-song.app/

きっかけ

たまたまいろんなアーティストのCD売り上げランキングを調べていた。
このランキングは、僕の主観におけるそのアーティストの代表曲と一致していない場合があり面白いと思った。

例えば、B’zで一番売れた歌は『愛のままにわがままに 僕は君だけを傷つけない』だが、B’zといえば『ultra soul』な気がする。

という話を会社でしてみた。
そこから、あのアーティストの代表曲といえば何だという話になった。
これが大変盛り上がった。

なので、アンケートサイトを作ってみた。

集計方法

とりあえず、CD売上ランキング上位30人を事前に入力しておいた。
その他のアーティストも入力できるようにしてある。
Twitterに放流してみたものの、あまり広まらなかったのでシュフティで50円くらい払ってアンケートに答えてもらった。

結果

B’zはもちろん『ultra soul』だった。
意外だったのはEvery Little Thingの代表曲にfragileを選んだ人が一番多かった。ここは絶対『Time goes by 』だと思ってたのに。
他にも色々おもしろい結果が出たから見てほしい。
https://famous-song.app/

思ったこと

まず、ちょっと古い。そもそもアーティストのCD売上ランキングというものを取ると、2000年前後のアーティストが大半を占める。
今の10代~20代前半の人にはピンとこないのではないか。
ここには二つの理由があると思う。
一つはCDという媒体の問題。
もう一つはポップカルチャーが細分化してしまったという問題。おそらく、未だにCDという媒体が続いていたとしても、アーティストのCD売上ランキングはほとんど変わらなかったと思う。

プログラミング初心者が一歩成長するために身に着けたいものを発見した。

結論

型が言えるようになろう。

概要

必要な知識はちゃんとあるはず。それでも、プログラミングが遅い。バグが多い。
そういう人を何人か見た。

その人たちに型が言えないという共通点があると思った。

まず、型が言えないとはどういう状態か説明し、解決策を提案する。

自己紹介

多分本当に速い人。

業務のプログラミングは速い。
AtCoderで容問を速解きするだけなら相当上位。

本題

型が言えないとはどういう状態か

例えば、極単純な電卓アプリの型を考えてほしい。
二つの数値に四則演算をして計算結果を画面に表示するとする。
この際、値域や未入力の状態やゼロ除算の対応やカーソル位置などは全部置いておこう。
この電卓の型を言うならこんな感じだろう。

{
  input1: number,
  input2: number,
  method: "+" | "-" | "*" | "/",
  output: number,
}

一応、オペランドだとかそいういう用語が存在するがそういうのも置いておこう。
とりあえずこれで十分なはずだ。

当たり前だと思った人はこちら側の人間だ。おめでとう。
どうも、大多数のプログラマーはこれができないらしい。
かなり適当な統計だが、どうも職業プログラマーの半分強の人はそうっぽい。

では、その人たちはどうしているか?
実装を書きながら必要に応じて型定義を書くしか無いのだ。

こういう人がプログラムを書くとどうなるか。

全体の流れを型で見通すということができないので、そこかしこにparseIntが氾濫する。
手戻りが多すぎて時間がかかる。
本来Aという処理とBという処理をどうつなげるか考えて型を書くから静的型付き言語は間違えにくいのに、Aという処理を書くことに集中している時に型を書き換えるから間違いが増える。
そこをどういう値が通過するかは言えるが、どういう値が通過することはないかを言えないので、極力狭い定義をしようとしない。

型が言える人とはどんな感じか。

自分の場合であれば、作るアプリにどういう機能があるかわかっていたら、こういうものはだいたい事前に全部列挙できる。

  • RDBの定義
  • RESTのエンドポイント
  • いろんなオブジェクトの型
  • 各クラスにどんなメソッドがあるか
  • URL設計
  • 何をDIしないといけないか

先に列挙しておいて型と型をつなぐように実装を書いている。
だからあんまり間違えないし、ほぼ何も考えなくても正しいコードになっている。

僕だけの特殊技能ということでもないようだ。できる人はみんなほぼ無意識にできるっぽい。

どうすればいいか

練習するしか無いんじゃないかと思う。
gitの練習サイトのようなものがあるから、似たような練習アプリを作ってあげたらいいんじゃないかな。

僕はプログラミングがとても速いのだ

 

概要

僕がいかにプログラミングが速いかについてAtCoderの成績を元に説明する。
どちらかといえば、AtCoderのことをよく知らない人向けに書いた。ところどころ厳密ではない書き方をしたが、わからない人を混乱させないための言い回しなので、詳しい方はご勘弁願いたい。
正直言って、自分でこんな記事を書くのはダサくて恥ずかしい。
でも、自分で言わないと誰もわかってくれないから書く。
なんでわかってもらう必要があるかと言うとオチンギンガ……

経緯

僕はAtCoderで水色である。
正直、水色というのは凡庸な成績だ。
なぜこのような成績になってしまうかと言うと、僕に難問を解く力がないからだ。
逆に、簡単な問題を速く正確に解くのは得意だ。
なので、AtCoderのレートではなく簡単な問題を解く速さと正確さをアピールしたかった。

前提

AtCoderの難易度について

AtCoder界隈では問題の難しさを色で区分する習慣がある。
これは、主観ではなく解答できた人のレーティングを元に算出した客観的な分類だ。
簡単な順に

  1. 灰色
  2. 茶色
  3. 緑色
  4. 水色
  5. 青色
  6. 黄色
  7. 橙色
  8. 赤色

である。
灰色が一番簡単である。
だいたいどのくらいのレベルかと言うと、灰色の中で一番難しいのがこのくらいの問題である。

X,Y,H,Mが与えられる。
時計の長針と短針の長さがそれぞれXcm,Ycmである。
H時M分の時、2つの針の先の距離は何cmか?

決して難問ではないが、そうそう即答できるわけでもないと思う。
AtCoder未経験者が想像する「一番簡単な問題」よりは難しいと思う。
諸説あるが、大体普通のお仕事でWebアプリケーションを開発する仕事の難度は高くて茶色前後だと思う。
ちなみに、僕はこの問題を10分で解いた。参加者の中央値は50分だ。
(それ以前の問題を解くのにかかった時間を引いた)

調査方法

AtCoder Beginner Contestの中で直近26回のコンテストを対象にする。
これは、これまで僕が出場した全てのAtCoder Beginner Contestだ。

問題は緑問題以下を対象とする。
これはざっくり言って、参加者の上位1/3が正解できる難易度の問題だ。

制限時間以内に正答できなかった人は制限時間である6000秒で正答できたとみなす。

集団の偏りについては、AtCoderの参加者は世間一般のプログラマーよりプログラミングが上手なのか下手なのかは色んな意見があるが、ここではだいたい一緒とみなして話をすすめる。
また、そもそも他の参加者は全力を尽くしているのかという問題があるが、そこは考えないようにする。
例えば、AtCoderのルールでは強豪ユーザーはAtCoder Beginner Contestでいい点を取るメリットは全くないが、彼らも一生懸命問題を解いていると想定する。

解答の速度と正確さを評価することにする。

速さ

解答の速さは

  • 自分が正答するのにかかった時間を他の参加者の中央値と比べる
  • 自分が正答するのにかかった時間が参加者の上位何%か調べる

正確さ

AtCoderでは、解答を提出するとその場で正誤がわかる。
誤答をするとスコアが下がるので、一般的に参加者は極力誤答を提出せずに正答を提出しようとする。
なので、正答するのに要した誤答の数が少ないほど正確なプログラミングが出来ると言える。

結果

解答の速度

問題を解いた時間をグラフにした。

f:id:isyumi-net:20200820174842p:plain

左に行くほど簡単な問題である。
茶色の真ん中あたりからオレンジのグラフが全て6000に張り付いている。そもそも半分の人は解けていないのでこういうグラフになっている。
これを見ると、大体中央値の1/3くらいの速度で正答できていることがわかる。

 

次に、これは解答速度が参加者の内上位何%だったかを表したグラフだ。

f:id:isyumi-net:20200820174901p:plain

大体、上位15%であることがわかる。
計算した所

  • 灰色問題までは平均13%
  • 緑色問題までは平均18%

であった。

解答の正確さ

僕が一度も間違えずに提出できたのは
100回中85回 で、成功率は85% であった。
これは48,990人中3,4662位で、上位7%である。
中央値は50%なので、1.7倍正確にプログラミングができると言える。

結論

簡単な問題(とはいえ、一般的な仕事の基準では十分難問)を解くことについて、僕はこのくらいのスキルだと言える。

  1. 僕のプログラミングの速度は、一般的なプログラマーの中で上位15%くらいである
  2. 僕のプログラミングの速度は、一般的なプログラマーの3倍くらいである
  3. 僕のプログラミングの正確さは、一般的なプログラマーの上位6%くらいである
  4. 僕のプログラミングの正確さは、一般的なプログラマーの1.7倍くらいである