【Ruby】今日のプログラミング学習時間を入力すると、学習進捗を教えてくれるプログラム

プログラミングの勉強を初めてもうすぐ60日になる。
プログラミングを習得するには最低でも600時間勉強しなければいけないらしい。

フルタイムで働いている私は、毎日学習時間の確保との戦いだ。

- トータル何時間勉強したのだろう？
- 今月の目標勉強時間に何時間足りないんだろう？

毎日気になってしかたないので、
「自分の今日のプログラミング学習時間を入力すると、学習進捗を教えてくれるプログラム」をRubyで作った。

## 完成形

```ruby:programingtime.rb

def time
  sum = 0
  while sum >= 0 
    puts "学習時間を入力してください"
    line = "---------------------"
    time = gets.to_f
    sum += time
  
    puts <<~EOS
      今月#{sum}時間勉強したよ！
      #{line}
      残り時間は#{100 - sum}です
      #{line}
      今月の学習時間の#{(sum / 100) * 100 }%を勉強しました
      #{line}
    EOS
  end
end

time
```
わたしの毎月の学習時間目標が100時間なので、
足りない時間を `100 - sum`
学習進捗を `(sum / 100) * 100` 
で出している。

ターミナルでの表示はこんな感じ。

```terminal
学習時間を入力してください
2
今月2.0時間勉強したよ！
---------------------
残り時間は98.0です
---------------------
今月の学習時間の2.0%を勉強しました
---------------------
学習時間を入力してください
3
今月5.0時間勉強したよ！
---------------------
残り時間は95.0です
---------------------
今月の学習時間の5.0%を勉強しました
---------------------
```


Rubyエンジニアにとっては簡単なプログラムだと思うが、
完成形に到るまで初心者にとっては紆余曲折あったため
その過程も書いておこうと思う。

## 完成形に到るまで

### to_fメソッドとto_iメソッド
学習時間は数字だから、gets メソッドとto_i メソッドでいけるっしょー

```ruby:programingtime.rb

    puts "学習時間を入力してください"
    time = gets.to_i
   
    puts "残り時間は#{100 - time}です"
    puts "今月の学習時間の#{(time / 100) * 100 }%を勉強しました" 
```
実行！

```terminal
学習時間を入力してください
2
残り時間は98です
今月の学習時間の0%を勉強しました
```
あれ、2時間って入力したのに0%になってる。なんでだろ…
to_i だと整数に変換されるから、（time/100）の部分が0.2なのに0になるのでは…？
ということは少数点を残してくれる to_f 使うべきなのか。
to_iメソッドをto_fメソッドへ変更。


```ruby:programingtime.rb

    puts "学習時間を入力してください"
    time = gets.to_f
   
    puts "残り時間は#{100 - time}です"
    puts "今月の学習時間の#{(time / 100) * 100 }%を勉強しました" 
```
実行！

```terminal
学習時間を入力してください
2
残り時間は98.0です
今月の学習時間の2.0%を勉強しました
```
今回はちゃんと2%に表示された！
けどこれだと今日の学習時間の進捗だけしか表示がされない。
困った。数字を足していきたいなぁ。

### 数字を足すためにsumと繰り返しのためにreturnをつかう
数字を足していくならsumだし、
また戻ってくるならreturnかな…？
とりあえずやってみよう。

```ruby:programingtime.rb
def time
  puts "学習時間を入力してください"
  time = gets.to_f
  sum = 0
  sum += sum + time

  puts "今月#{sum}時間勉強したよ！"
  puts "残り時間は#{100 - sum}です"
  puts "今月の学習時間の#{(sum / 100) * 100 }%を勉強しました"
  
  return time
end
```
実行！

```terminal
エラー
```
プログラムが動かない…

あ、time関数をよびだしてないからか。
定義しただけで呼び出していないというミス。

```ruby:programingtime.rb
def time
  puts "学習時間を入力してください"
  time = gets.to_f
  sum = 0
  sum += sum + time

  puts "今月#{sum}時間勉強したよ！"
  puts "残り時間は#{100 - sum}です"
  puts "今月の学習時間の#{(sum / 100) * 100 }%を勉強しました"
  
  return time
end

time
```
これでいける！実行！

```terminal
今月2.0時間勉強したよ！
残り時間は98.0です
今月の学習時間の2.0%を勉強しました
```
さっきと変わらない。
繰り返しってreturnじゃなかったっけ。
while文とかfor文だったきもするな。そろそろググろ（もっとはやくググれ）

### while文で繰り返す

```ruby:programingtime.rb
def time
  sum = 0
  while sum >= 0
    puts "学習時間を入力してください"
    time = gets.to_f
    sum += sum + time

    puts "今月#{sum}時間勉強したよ！"
    puts "残り時間は#{100 - sum}です"
    puts "今月の学習時間の#{(sum / 100) * 100 }%を勉強しました"
  end
end

time
```
while文で実行！

```terminal
学習時間を入力してください
3
今月3.0時間勉強したよ！
残り時間は97.0です
今月の学習時間の3.0%を勉強しました
学習時間を入力してください
4
今月10.0時間勉強したよ！
残り時間は90.0です
今月の学習時間の10.0%を勉強しました
```
3+4で7時間になるはずなのに、10時間になっている。
sumの式あってたっけ。ググる。

### sum式を正しくする

`sum += sum + time` としてたので無駄にsumされていた。

```ruby:programingtime.rb
def time
  sum = 0
  while sum >= 0
    puts "学習時間を入力してください"
    time = gets.to_f
    sum += time

    puts "今月#{sum}時間勉強したよ！"
    puts "残り時間は#{100 - sum}です"
    puts "今月の学習時間の#{(sum / 100) * 100 }%を勉強しました"
  end
end

time
```
これでただしくsumされるでしょう！実行

```console
学習時間を入力してください
2
今月2.0時間勉強したよ！
残り時間は98.0です
今月の学習時間の2.0%を勉強しました
学習時間を入力してください
3
今月5.0時間勉強したよ！
残り時間は95.0です
今月の学習時間の5.0%を勉強しました
```
完成！！
これで毎日の数字が足されていくプログラムができた！
式もあってるし、完璧！


## もっと見やすくしてみる

### 改行とlineを追加してみる
もっとターミナル上でみやすく表示させたい！
改行とline追加してみよ。

```ruby:programingtime.rb
def time
  sum = 0
  while sum >= 0
    puts "学習時間を入力してください"
    line = "---------------------"
    time = gets.to_f
    sum += time

    puts "今月#{sum}時間勉強したよ！\n#{line}"
    puts "残り時間は#{100 - sum}です\n#{line}"
    puts "今月の学習時間の#{(sum / 100) * 100 }%を勉強しました\n#{line}"
  end
end

time
```
実行

```terminal
学習時間を入力してください
2
今月2.0時間勉強したよ！
---------------------
残り時間は98.0です
---------------------
今月の学習時間の2.0%を勉強しました
---------------------
学習時間を入力してください
3
今月5.0時間勉強したよ！
---------------------
残り時間は95.0です
---------------------
今月の学習時間の5.0%を勉強しました
---------------------
```
いいかんじ。
満足してると同期エンジニアから、「改行したいならもっと書きやすいヒアドキュメントあるよ」と。

### ヒアドキュメントを使ってみる
ぐぐってみると、
[Ruby のヒアドキュメントすごい - Qiita](https://qiita.com/Linda_pp/items/32fddbbe117cf03fef0f)
なるほど。まとまった文章を書くのにはたしかにヒアドキュメントすごそう。

```ruby:programingtime.rb
def time
  sum = 0
  while sum >= 0 
    puts "学習時間を入力してください"
    line = "---------------------"
    time = gets.to_f
    sum += time
  
    puts <<-EOS
      今月#{sum}時間勉強したよ！
      #{line}
      残り時間は#{100 - sum}です
      #{line}
      今月の学習時間の#{(sum / 100) * 100 }%を勉強しました
      #{line}
    EOS
  end
end

time
```
なるほどこれはコードが綺麗だ。
さすが綺麗なコードを書くで有名な同期エンジニア。

```terminal
学習時間を入力してください
2
      今月2.0時間勉強したよ！
      ---------------------
      残り時間は98.0です
      ---------------------
      今月の学習時間の2.0%を勉強しました
      ---------------------
学習時間を入力してください
3
      今月5.0時間勉強したよ！
      ---------------------
      残り時間は95.0です
      ---------------------
      今月の学習時間の5.0%を勉強しました
```
ターミナルでもしっかり表示されてるが
ちょっとインデントが右寄りになるのが気になるらしい（私は特に気にならない）

ヒアドキュメントはコードのインデントもそのまま反映するらしい。
そのインデントを解除するには `puts <<-EOS` を　`puts <<~EOS` に変えるだけでいいらしい。なんと簡単。

```ruby:programingtime.rb
def time
  sum = 0
  while sum >= 0 
    puts "学習時間を入力してください"
    line = "---------------------"
    time = gets.to_f
    sum += time
  
    puts <<~EOS
      今月#{sum}時間勉強したよ！
      #{line}
      残り時間は#{100 - sum}です
      #{line}
      今月の学習時間の#{(sum / 100) * 100 }%を勉強しました
      #{line}
    EOS
  end
end

time
```
さてさて、ターミナルはどうなる。

```terminal
学習時間を入力してください
2
今月2.0時間勉強したよ！
---------------------
残り時間は98.0です
---------------------
今月の学習時間の2.0%を勉強しました
---------------------
学習時間を入力してください
3
今月5.0時間勉強したよ！
---------------------
残り時間は95.0です
---------------------
今月の学習時間の5.0%を勉強しました
---------------------
```
おぉ！インデントも左寄せですっきり！
これで完成！

## これからの課題
これで「自分の今日のプログラミング学習時間を入力すると、学習進捗を教えてくれるプログラム」をRubyで作るのは実行できた。

ただこれだと一生ターミナルを閉じれない。
データベースにデータを保存する必要があるし、
その後はブラウザからでも入力できるようにビューファイルも作成しないと…
あれそのためにはサーバーを立てないと。

こんなに簡単なプログラムでもいろいろやるべきことがあるんだと実感できた。
少しずつやっていこう。今回はここまで。