え、ウソ!?プログラミング簡単すぎ!

  • 08 December 2021
Post image

 前回の記事で紹介したプログラミングの思考プロセスを使って、実際に何かを組んでいく様をお見せする。この思考のプロセスは基本的に汎用性があるので、真似してくれたら間違いなく上達する。前回も書いたがこの記事は、なかなか上達しないと悩んでいる初心者をターゲットにしているのでご注意を。
 今回の想定のエンジニアレベルは以下だ。徹底的にこのレベルの思考で進めてみる。

  • HTMLをある程度知っている
  • ブラウザではJavaScriptでプログラムできる

 そして前回の記事で紹介した思考プロセスにそって進めてみる。
思考プロセス

1. 目的(実装すべきもの)

 今回は簡単な「WEBサイトの投票システム」を実装することを想定する。ただサーバー側を用意するのはコストかかるので、今回はブラウザ側のみ。要件は以下とする。

  • 3つの対象に対する投票ができる
  • みんなの投票数が表示される
  • 投票するとボタンが非活性になる
  • サーバーに投票データを送信  

    想定の完成系

     ※バックエンドは用意しないのでデータ送信先APIと投票数取得APIは既に存在している前提とする。


2. タスクに分解して列挙

 今回は簡単なシステムだけど、この工程をしっかり考える。そして慣れないうちはぜったいにタスクをしっかり書き出すんだ。頭の中だけで考えてゴリゴリプログラミングをはじめるのはカッコ良いけど、初心者は日本語でしっかり書き出すことがコツだ。恥ずかしがんなや。
タスク一覧


3. 手段をググってコピペ

 さ、タスクを分解してみたのでこれらのタスクに対する手段をググっていく。

① 3つの投票先とボタンを配置

 まずはUIの作成からはじめる。3つの投票先名称とボタンをHTMLで書いてみよう。これに関しては調べることはないね。

<div class="contents">
  <div>
    <h5>ドラえもん</h5>
    <button>投票</button>
  </div>
  <div>
    <h5>アンパンマン</h5>
    <button>投票</button>
  </div>
  <div>
    <h5>カカロット</h5>
    <button>投票</button>
  </div>
</div>

 見た目を少し整える。3つのブロックを横並びにしてボタンの見た目を少し変更。

「div 横並び css」でググる

一番上に出てきた記事に書かれていたstyleをそのままコピーした。

.contents {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
}
.contents > div {
  width: calc(100% / 3);
  text-align: center;
}
.contents button {
  color: #fff;
  background-color: #eb6100;
  border-radius: 100vh;
  border: none;
  padding: 5px 15px;
}
.contents button:active {
  opacity: 0.5;
}


② 投票数が表示される

 投票数は自体の取得や表示は後で実装するので、まずはUIのみをHTMLで表示。一旦は「0」を表示しておく。

<div class="contents">
  <div>
    <h5>ドラえもん</h5>
    <p>投票数:<span class="count">0</span></p>
    <button>投票</button>
  </div>
  <div>
    <h5>アンパンマン</h5>
    <p>投票数:<span class="count">0</span></p>
    <button>投票</button>
  </div>
  <div>
    <h5>カカロット</h5>
    <p>投票数:<span class="count">0</span></p>
    <button>投票</button>
  </div>
</div>
.count {
  color: green;
  font-weight: bold;
}


③ ボタンを非活性に変更可能

 ボタンが押せない状態の見た目を先に作成しておこう。この時点でその意味がわからなくてもやはりGoogle先生は答えをくれる。

「html button 押せない状態」でググる

 すぐにbuttonタグに"disabled"というのを付けるとボタンを非活性にできるとの情報が出てくる。
 ふむふむ。では"disabled"を付けてみる。すると確かにボタンは押せない状態になるけど、見た目が押せないっぽくない。ではまた、

「html button disabled 見た目」でググる

で検索すると、CSSの書き方がすぐに出てくる。

.contents button:disabled {
  background: #ddd;
}


④ ボタン押下でサーバにデータを送信

 ようやく次は動きの部分なのでJavascriptの出番。「ボタン押下でサーバにデータ送信」はよりシンプルに2つに分解して考えてみる。「ボタン押下で」と「サーバにデータ送信」の2つで考える。

「ボタン押下で」

 では例に倣って、

「js ボタンクリック」でググレカス

 一番上に出てきたページのサンプルをそのまま使ってみるわ。

<button onclick="buttonClick()">投票</button>
<script>
function buttonClick(){
    alert('Click');
}
</script>

 投票ボタンをクリックするとアラートが出てくる。ということは、buttonClick関数の中に何か書けば 「ボタン押下で」何かの処理を実行できるってことか

サーバにデータを送信

「js サーバ データ送信」でググる

 一番上の記事では、XMLHttpRequestというのを使えば通信できるって書いている。そのままサンプルコートを貼り付けて修正してみる。記事を読んでみると、送信先のURLと送信するデータの変更方法が書かれている。

function buttonClick(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=1');
}

 ここで一旦投票ボタン押してみるか。。Chromeのインスペクターを起動して 「Network」を見てみると確かにデータを通信していることが確認できる。しかもPayloadを見ると 「id: 1」を送信しているではないか。(送信先が自ドメインの存在しないURLなので405エラーが出ているが)


 ということはこの「id: 1」と固定でコーディングされている部分を投票ターゲットごとのidに変更すれば、正しく実装できそうだな。初心者だと以下のようにするかもね。つまり、functionの名前を変えて3つコピーする。全然良くないコードだけど一旦はこれでもいい

function buttonClick1(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=1');
}
function buttonClick2(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=2');
}
function buttonClick3(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=3');
}

 これでid=1,2,3をそれぞれのボタンをおしたらサーバーに送信するJSのコードが完成だ。(こんな書き方は保守性が低いから後で修正する。)


⑤ 自投票分をカウントアップ

 さてここからは投票数のカウントアップに実装になる。現状はカウント部分は固定の「0」が表示されているよね?これをボタン押したらプラス1にしたい。「1」にするんじゃなくてあくまでプラス1な。今回の実装のなかで実はこれが一番難しいといっていい。HTMLのJSによるDOMの操作が必要でそれには知識も必要だからだ。
 ただ、ここでは完全な初心者でもできるってことを見せたいので、

「html 表示変更 js」でググる

一番上に出てきた以下のページ。

https://javascript.programmer-reference.com/js-dom-inntertext/

 このページで紹介されているjsの、innerTextを使ったら数字を変更できそう。一旦ほぼこのページのままコピペして以下のようにしてみる。

<div>
    <h5>ドラえもん</h5>
    <p>投票数:<span id="target1" class="count">0</span></p>
    <button>投票</button>
</div>
function buttonClick1(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=1');

  document.getElementById("target1").innerText = "変更しました";
}


 ボタン押したら「0」が「変更しました」に変わりましたね。では、元に表示されている数字(0)を取得して、プラス1して、同じ方法で書き換えれば完成だよね。じゃあ今度は、

「html 表示取得 js」でググる

 で検索して出てきたページを見てみる。

https://kita-note.com/js-edit-text

 このページざっと読むと、textContentっていうプロパティでhtmlの表示されている中身を取得できるっぽい。じゃあ以下のようにして、プラス1するとどうかな?

function buttonClick1(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=1');

  var cnt = document.getElementById("target1").textContent;
  document.getElementById("target1").innerText = cnt + 1;
}


 これは失敗でした。表示が「1」になることを想定したのに、「01」となってしまっている。当然プログラマーはこの理由を知っているはずだけど、例にならって

「js 足し算 うまくいかない」でググる

一番上に出てきた記事。

https://pinkmonky.net/detail/?id=61

 つまり変数には型というものがあり、textContentで取得した値は"文字列"であり、JavaScriptの"+"は文字列結合の動作もするから「01」になっちゃってたってこと。このページの方法で修正してみる。

function buttonClick1(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=1');

  var cnt = document.getElementById("target1").textContent;
  document.getElementById("target1").innerText = parseInt(cnt) + 1;
}


 これでボタンを押すたびにカウントアップするようになりました。あとは、ドラえもん以外の2つにも同じ処理をコピペして完成。


⑥ 再度送信できないように

 これはボタンクリック処理の最後で、ボタン要素に対して、上記の「③ ボタンを非活性に変更可能」で実装したdisabledを付与するだけ。では早速。

「js ボタン disabled」でググる

一番上に出てきた記事の通りやってみる。

function buttonClick1(){
  var send_data = new XMLHttpRequest();
  send_data.open('POST', 'https://i-407.com/');
  send_data.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
  send_data.send('id=1');

  var cnt = document.getElementById("target1").textContent;
  document.getElementById("target1").innerText = parseInt(cnt) + 1;
  document.getElementById("button1").disabled = true;
}

 ボタンを押すとボタンが非活性になって、再度押せなくなるよね。投票ってことは当然押したボタン以外のすべてのボタンも非活性にしないといけない。今はとりあえずすべてのボタンをdisabledにする。

  document.getElementById("button1").disabled = true;
  document.getElementById("button2").disabled = true;
  document.getElementById("button3").disabled = true;

⑦ 初期表示は現在の投票数を表示

 最後は初期表示のカウント数の表示。当然上記と同じくinnerTextで値を入れてやればいいだけ。初期表示はサーバーから取得する前提。(サーバ実装はされている前提)
 サーバーからのデータ取得は「サーバにデータを送信」で出てきたページに書いていた通り。問題はページの初期化時にjsでサーバーからデータを取得するにはどうすればいいかってこと。

「画面表示時 js」でググる

 これも一番上に出てきたページよると、window.onloadっていうのでできるみたい(棒)。コピペコピペ。

window.onload = function(){
  var data_url = new XMLHttpRequest();
  data_url.open('GET', 'https://i-407.com/'); //このURLは実際のAPIURLにする必要がある
  data_url.send();
  
  data_url.onreadystatechange = function() {
    // 今回はAPI実装はないので、ここは仮のランダム値を入れる
    document.getElementById("target1").innerText = Math.floor(Math.random() * 11);
    document.getElementById("target2").innerText = Math.floor(Math.random() * 11);
    document.getElementById("target3").innerText = Math.floor(Math.random() * 11);
  }
}

 これで完成!

ググって一番上に出てきた記事のコピペしかしてませんけど!?

 完成形の投票システムは以下のページにあるので、完成ソースはこのページで見て。

完成系

 あのーまじで、ほぼ素人の知識力による検索ワードで一番上に出てきた記事をコピペしただけでWEBシステムを完成させたんだけど。「こんな簡単な実装を長々と書いてドやってんじゃねー」っていう声が聞こえてきそうなんだけど、当記事が伝えたいのは実装方法なんかではない。ただただ、Googleで検索してコピペすることがプログラミングの基本であり、コードを書くのは誰でもできる簡単なお仕事ってこと。

 では今回何が一番難しくて、誰でもできない作業だったかというと、やはり「タスクに分解して列挙」だ。これでちょっとはプログラミングに対する考えは変わってくれるかな。コードをカタカタやることなんかより、その前にしっかり考えて列挙することの方が重要だし、これに頭を使うわけだ。つまりなかなか上達しない人、初心者はこの「タスクに分解して列挙」を磨けばすぐに中級者以上になれるってこと。最短距離で中級者以上になれるんだよ?
 “オブジェクト指向”?、“interface”?、あのそういうの後でいいんで。こういう知識からばっかり勉強しても、「タスクに分解して列挙」ができないんだったら何もできないんだよ。

 次回は「4. 手段やタスクに問題がなかったか振り返る」で上記のウンコードをリファクタする。今回のようなとりあえず動けばいいよって感じでやると問題は起こりがち。しかし、とりあえず自分で完成させることって一つの成功体験だし何より楽しくね?

You May Also Like

プログラミング下手な人、変わりたいならまず

プログラミング下手な人、変わりたいならまず

 近年のプログラミングって一体何をしているのか。どのようなプロセスを経ているのか。多くのできるエンジニア・プログラマーは教えたくないのか、教え方がわからないのか、はっきりと説明してくれない。だから初心者エンジニアはなかなか上達できずに悩んでしまうのだ。これからの数回の記事を読んでも …

いいから黙ってVSCodeとVimバインド

いいから黙ってVSCodeとVimバインド

 さてついにプログラミングを始めるわけだが、あなたはまずエディタを用意する必要がある。要はプログラムコードを書き込むツールだ。エディタと呼ばれるものとIDEと呼ばれるものがあるが、とりあえずはエディタの方を用意しよう。  この記事によると2021年 …