大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

【無職に転生 ~ 就職するまで毎日ブログ出す_23】【Ruby】Arrayの演算

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

配列にまつわる演算に関してうろ覚えな部分が多かったのでアウトプットします。Arrayクラスは足し算や引き算などをすることができ、組み合わせによって異なる挙動を出します。最後にはちょっとした問題も用意しているので是非解いてみてください!

加算

足し算の場合、お互いの要素を結合させた配列になります。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a + b
=> [1, 2, 3, 4, 5, 4, 5, 6, 7, 8]

これと似たような挙動としてconcatメソッドがあります。しかし、concatを使用した場合レシーバーである配列は結合された配列の値になります。つまり、破壊的メソッドとなります。

a.concat(b)
=> [1, 2, 3, 4, 5, 4, 5, 6, 7, 8]
a
=> [1, 2, 3, 4, 5, 4, 5, 6, 7, 8]

下記の記述でconcatと同じように破壊的な処理を行うこともできます。

a += b

減算

引き算の場合、共通する要素を配列から取り除いた配列を返却します。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a - b
=> [1, 2, 3]
b - a
=> [6, 7, 8]

全く同じ要素であれば配列の順番を無視して共通の要素が取り除かれます。また、要素の組み合わせが全て一致している場合、空の配列を返します。

c = [4,5,2,3,1]
=> [4, 5, 2, 3, 1]
a - c
=> []

乗算

掛け算の場合、配列同士の掛け算をすることはできません。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a * b
# (no implicit conversion of Array into Integer)

しかし、Arrayに対して数字を掛け算することで、中の要素をその数字の数分だけ複製します。

a * 2
=> [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
a * 5
=> [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5]

配列の中の要素の型は関係ないため、数字でもすべてnil大丈夫です。

d = %w(1 2 3 4 5)
=> ["1", "2", "3", "4", "5"]
d * 2
=> ["1", "2", "3", "4", "5", "1", "2", "3", "4", "5"]
e = [nil,nil,nil]
=> [nil, nil, nil]
e * 3
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil]

除算

配列は割り算をすることができません。undefined methodからArrayクラスには/をそもそも使うことができないようになっています。

a / b
# (undefined method `/' for [1, 2, 3, 4, 5]:Array)
a / 2
# (undefined method `/' for [1, 2, 3, 4, 5]:Array)

和集合

和集合は|で表すことができます。お互いの要素の中で重複していない要素を組み合わせた配列を出力します。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a | b
=> [1, 2, 3, 4, 5, 6, 7, 8]

配列を加算した後に重複している要素を取り除くuniqメソッドで同一の処理を行うことができます。

(a + b).uniq
=> [1, 2, 3, 4, 5, 6, 7, 8]

破壊的な処理は下記メソッドで行えます。

a |= b
=> [1, 2, 3, 4, 5, 6, 7, 8]

積集合

積集合は&で表すことができます。お互いの重複している要素を組み合わせ配列を出力します。

a = [1,2,3,4,5]
b = [4,5,6,7,8]
a & b
=> [4, 5]

問題

上記の基本を踏まえた上でちょっと問題をいくつか用意したので解いてみてください。

第一問

a=[1,2,3]
b=[1,2,3]
c=[1,2,3]

a + b + c

第二問

a = [1,2,3,4,5]
b = [4,5,6,7,8]

b * 2 + a

第三問

a=[1,2,3]
b=[1,2,3]
c=[1,2,3]

a + b | c

第四問

a=[1,2,3]
b=[4,5,6]
c=[7,8,9]

a+b+c+(a.concat(b +  c)) | a

回答

第一問

[1, 2, 3, 1, 2, 3, 1, 2, 3]

解説は不要かなと思います。

第二問

[4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5]

掛け算は先に実行されるのでb * 2から先に実行され、その後aが加算されます。。

第三問

[1,2,3]

これはちょっとした捻くれ問題でした。和集合は実は+より後に実行されます。よって最初に加算が実行されます。

[1,2,3,1,2,3] | c

その後お互いの要素で重複していない要素を出力します。

第四問

 [1, 2, 3, 4, 5, 6, 7, 8, 9]

これは最後にある | aに着目すれば大丈夫ですね。a+b+c+(a.concat(b + c))の中の要素は必ず1,b,cの要素が全てあり、a との和集合ですので全ての重複していない要素が取り出されます。

【無職に転生 ~ 就職するまで毎日ブログ出す_22】【Ruby】リテラルなどの不思議な書き方集

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はRubyKaigiやAtcorderなどで出される問題から引用してRubyの不思議な書き方を理解する記事です。プログラミングのコードの書き方は本当に様々で、Rubyに至っても約1年間勉強していますがいまだに不慣れな書き方がたくさんあります。ですがそこは地道に覚えていくしかありません。今回はリテラルなどを覚えていきたいと思います。

? リテラルと否定演算子三項演算子

それではまず最初に以下の文を見てみます。

irb> !????!:!?!

この問題はRubyKaigi 2019で出された問題のようです。!や?がたくさん並んでいて意味がわからないですよね。ですがこの問題はRubyの基礎知識だけで解くことができます。どう出力されるかわかりますか。答えはfalseが出力されます。

irb> !????!:!?!
=> false

この問題を解く上でのポイントは3つあります。

?リテラル

まず?リテラルですが、これはこの? が記載されているとその直後に書かれた1文字は文字列として出力されるというものです。

?あ
=> ""

文字の「あ」はコード上ではいつもクオーテーションで囲まなければいけませんが、?を直前につけることで文字列に変換することができます。これは自分は知らなかったです。

否定演算子

これはRailsでもよく使います。直後に書かれているオブジェクトの真偽値を入れ替えるものです。例えば、先ほどの文字列の「あ」はnilでもないので真偽値としてはtrueですが、否定演算子を直前に付けることでfalseと出力できます。

!?あ
=> false

Railsでは!!と否定演算子を2個付けることで、オブジェクトの真偽値を無理やりboolean方に変換することが多いですね。

!!?あ
=> true

三項演算子

if文の代わりとして使われることが多い構文です。if分はコードの行数を大きく増やします。elseが含まれるだけで5行も増えます。

hoge = nil
if hoge.nil?
    puts "a"
else
    puts "b"
end

上記のようにシンプルなifとelseの文は多くの箇所で使えると思います。しかし、少し冗長な気もしますよね。

そこで三項演算子の出番です。上記の文を以下のように置き換えることができます。

hoge = nil
puts hoge.nil? ? "a" : "b"

if文を経ったの1行で書けるようになりました。このようにシンプルなif else文は三項演算子に置き換える方がコードが簡潔になります。


以上3点を踏まえた上で問題のコードを解説します。

!????!:!?!

まず、?リテラルでどの文字が文字列として変換されているか確認します。まず1番に判別できるのは末端にある?!です。これは文字列「"!"」として出力されていますね。

!????!:!(?!)

次に?が4つ並んでいる部分ですがこれはどれが文字列に変換されるのかパッとみたところわかりづらいです。ここで三項演算子のことを思い出します。コードの中にがあるので、三項演算子が使われていることがわかるかなと思います。よって?4つのうちどれか一つは三項演算子として使われます。その条件を考えると文字列は以下のように変換されます。

!(??)?(?!):!(?!)

あとは否定演算子で文字列を真偽値に変換します。

false?"!":false

三項演算子falseの部分(:以降)が出力されるので、結果falseが出力されます。

こうして分解するとかなり簡単に理解できたかなと思います。ちなみにこの問題の難易度は1番簡単だったらしいです。。。まだまだ修行が足りないです。💦


%記法

%を使うことで文字列や配列を書くことができます。種類はかなり多いです。

  • %, %Q

ダブルクオーテーションと囲む場合と同じ意味になります。ダブルクオーテーションで囲んでいるので式展開ができます。

nums = %(789)
=> "789"
%(123 456 #{nums})
=> "123 456 789"

# 上と同じ記述
nums = "789"
=> "789"
"123 456 #{nums}"
=> "123 456 789"
  • %q

シングルクオーテーションと囲む場合と同じ意味になります。こちらはダブルクオーテーションではないので大丈夫です。

a = "sample"
=> "sample"
%q(a)
=> "a"

# 上と同じ記述
'a'
=> "a"
  • %s

シンボルを書く:と同じような書き方になります。

%s(SYMBOL)
=> :SYMBOL

# 上と同じ記述
:SYMBOL
=> :SYMBOL
  • %W

配列を書くための%記法になります。各要素は()の中で空白で区切ることができます。中の文字列はダブルクオーテーションで囲まれているので式展開ができます。

c = "hoge"
=> "hoge"
%W(a b #{c})
=> ["a", "b", "hoge"]
  • %w

こちらも配列を書くための%記法になります。しかし、各要素はシングルクオーテーションで囲まれているので式展開はできません。

c = "hoge"
=> "hoge"
%w(a b #{c})
=> ["a", "b", "\#{c}"]
  • %I

シンボルの配列を書くための%記法です。大文字なので式展開できます。

c = "hoge"
=> "hoge"
%I(a b #{c})
=> [:a, :b, :hoge]
  • %i

シンボルの配列を書くための%記法です。式展開できません。

c = "hoge"
=> "hoge"
%i(a b #{c})
=> [:a, :b, :"\#{c}"]

||=演算子

こちらは通称「nilガード」と言われている演算子です。もし変数の値が初期化されていないのであれば値を格納します。既に初期化されているならば新しい値は格納されずに値はそのままです。

foo ||= 'hoge'
=> 'hoge'
foo ||= 'fuga'
=> 'hoge'

&.演算子

こちらは通称「ぼっち演算子」と言われています。Rubyのメソッドは返却値がnilになっていることが多く、それによってnilクラスに定義されていないメソッドが実行されてしまいUndefined Method Errorになってしまうことがよくあるかと思います。

a = nil
a.upcase
# (undefined method `upcase' for nil:NilClass)

その時にぼっち演算子を使うと例外を回避できます。返り値は必ずnilとなります。

a = nil
a&.upcase
=> nil

参考記事

難読Rubyコードクイズ問題と解説 in RubyKaigi 2019 - エムスリーテックブログ

Rubyで%記法(パーセント記法)を使う - Qiita

Ruby初心者を脱した人が悩みがちな、ちょっと特殊な記法・演算子・イディオム - Qiita

【無職に転生 ~ 就職するまで毎日ブログ出す_21】【CSS】Materialize × JavaScript

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はMaterializeとJSを組み合わせて様々な機能を実装してみたいと思います。前回Materializeについて書いたのですが、そのときは見た目を整える程度でただスタイリングしただけです。

【無職に転生 ~ 就職するまで毎日ブログ出す_16】【CSS】Materialize - 大ちゃんの駆け出し技術ブログ

Materializeが他のCSSフレームワークより優れている点として、公式でJSとの組み合わせ型でモーダル表示やサイドバーなどを表示する機能が紹介されているところです。この強みを紹介するべく今日はいくつかMaterializeとJSを組み合わせた機能を紹介します。

例により下記htmlファイルをコピペしてCDNでMaterializeを有効化します。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>マテリアルデザイン</title>
       <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
    />
  </head>
  <body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
  </body>
</html>

JSファイルの作成

今回はJSを使うのでHTMLファイルに適当なJSファイルを読み込ませましょう。

<body>
・
・
<script type="text/javascript" src="js/sample.js"></script>
・
・
</body>

作成したファイルは空のままでOKです。

Collapsibles

Collapsible

Collapsibles are accordion elements that expand when clicked on. They allow you to hide content that is not immediately relevant to the user. Collapsiblesは、クリックすると拡大するアコーディオン要素です。これにより、ユーザーにすぐには関係のないコンテンツを隠すことができます。

下記gifのようにクリックすると中の隠された要素が出現するような機能ですね。

https://i.gyazo.com/4d9a18b266c32e7f7b48e55918ecca3b.gif

それでは実装してみます。ほとんどサイトに書いてあるコードと内容は同じですが、せめて文章は変えています。下記のようにbodyタグの中に要素を配置します。

<ul class="collapsible">
  <li>
    <div class="collapsible-header">
      <i class="material-icons">filter_drama</i>天気予報
    </div>
    <div class="collapsible-body">
      <span
        >きょうは、日本海から近づく低気圧や、上空に流れ込む寒気の影響で、広い範囲で大気の状態が不安定になるでしょう。午前中は日の差す所もありますが、午後は雲に覆われて、雨の所が増えてきそうです。カミナリを伴う所もあるでしょう。急に強まる雨や、落雷、突風に注意が必要です。ひょうの降るおそれもあります。最高気温は、引き続き全国的に平年並みか低いでしょう。
      </span>
    </div>
  </li>
</ul>

ulタグにはcollapsibleクラスを、collapsible-headerクラスには表示されている要素、collapsible-bodyには表示されていない要素を設定します。現状はJSを設定していないため、スタイリングのみ適用されています。

https://i.gyazo.com/253055ecf2bab4f7a519610d29633a75.gif

それでは作成したJSファイルに下記内容を記載します。

// js/sample.js
document.addEventListener('DOMContentLoaded', function() {
  var elems = document.querySelectorAll('.collapsible');
  var instances = M.Collapsible.init(elems);
});

これによってクリックすると要素が出現するようになりました。

https://i.gyazo.com/34cb5375bf4b89602e18ae4888c95e97.gif

下記の分で指定した要素にCollapsibleの機能を初期化しています。

var instances = M.Collapsible.init(elems);

この初期化の際により細かい設定(optioins)を施すことができます。例えば、要素が表示されるアニメーションをより遅くしたい場合、inDurationで開くときの速さ、outDurationで閉じるときの速さを設定することができます。デフォルトだとそれぞれ300で設定されているので、1000(1秒)かかるように設定します。

// js/sample.js
document.addEventListener("DOMContentLoaded", function () {
  var elems = document.querySelector(".collapsible");
  var instance = M.Collapsible.init(elems, {
    inDuration: 1000,
    outDuration: 1000,
  });
});

開閉時間が上のgifに比べて遅くなりました。

https://i.gyazo.com/bcaf350e69fcfede9bfbf2a4b8371263.gif

このようにMaterializeはJSファイルで細かく設定することで少しリッチなモーションを実現することができます。


Media

こちらは画像のアップ表示を簡単に実装できるものです。下記ファイルを作成しましょう。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>マテリアルデザイン</title>
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
    />
  </head>
  <body>
    <img class="materialboxed" width="650" src="images/sample.png" />

    <script type="text/javascript" src="js/sample.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
  </body>
</html>

images/sample.pngについては各自好きな画像を設定してください。あとはJSで初期化します。

// js/sample.js
document.addEventListener("DOMContentLoaded", function () {
  var elems = document.querySelectorAll(".materialboxed");
  var instances = M.Materialbox.init(elems);
});

画面を見てどう実装できたのか見てみます。

https://i.gyazo.com/23c2ca7c86061b6a2c3e9fa7e0d2d38f.gif

このような実装もMaterializeでは非常に簡単に行うことができました。

Modal

モーダルを表示させる方法です。下記ファイルをコピペします。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>マテリアルデザイン</title>
    <link
      href="https://fonts.googleapis.com/icon?family=Material+Icons"
      rel="stylesheet"
    />
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
    />
  </head>
  <body>
    <!-- Modal Trigger -->
    <a class="waves-effect waves-light btn modal-trigger" href="#modal1"
      >モーダル表示</a
    >

    <!-- Modal Structure -->
    <div id="modal1" class="modal">
      <div class="modal-content">
        <h4>衆院選 きょう公示 連立政権継続か 政権交代実現か 最大の焦点</h4>
        <p>
          第49回衆議院選挙が19日公示され、12日間の選挙戦がスタートします。
          今回の選挙は、与党が過半数の議席を確保して、連立政権を継続するのか、野党が勢力を伸ばして、政権交代を実現するのかが、最大の焦点となります。
        </p>
      </div>
      <div class="modal-footer">
        <a class="modal-close waves-effect waves-green btn-flat">閉じる</a>
      </div>
    </div>

    <script type="text/javascript" src="js/sample.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
  </body>
</html>

表示要素はニュースにしてみました。Modal Structureの要素はモーダルを呼び出すためのボタンなどを設定します。Modal Structureはモーダルで表示する部分です。modalのクラスを設定することで画面上では非表示にし、ボタンが押された時に表示することができるようにします。

JSで初期化します。

document.addEventListener("DOMContentLoaded", function () {
  var elems = document.querySelectorAll(".modal");
  var instances = M.Modal.init(elems);
});

これにより簡単にモーダル表示機能が実装ができました。

https://i.gyazo.com/e467770ac69dbda46273e2eea00814e5.gif

optionsにopacity(不透明度)を設定することでモーダル背景の黒部分の不透明度を調整できます。

document.addEventListener("DOMContentLoaded", function () {
  var elems = document.querySelectorAll(".modal");
  var instances = M.Modal.init(elems, { opacity: 0.2 });
});

上の画像に比べてかなり薄くなりました。

https://i.gyazo.com/f87541bdfee3e9f0f1ca9ac8b573bd9f.gif

終わりに

実際に使ってみて思ったのは本記事でも紹介したようにJSと組み合わせた実装方法が非常に多く公式で紹介されている点です。他のCSSフレームワークよりJSとの組み合わせ方がたくさん載っているので、様々な実装を簡易的に行うことができます。今後もこのフレームワークを使ってチーム開発を進めていきたいと思います。

【無職に転生 ~ 就職するまで毎日ブログ出す_20】【書籍】超習慣術

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はメンタリスト DaiGoさんの書籍から『短期間で“よい習慣"が身につき、人生が思い通りになる! 超習慣術』を紹介したいと思います。

https://i.gyazo.com/a7ee5f6ed112396459249494c028d9b1.jpg

自分はブログなど何かを習慣化するときのこちらの本で紹介されている方法を参考にしたため、習慣化がかなり得意になったと思っています。誰でもすぐに始めることができる内容となっているので、そこまで難しく考える必要はなく気軽に読んでいただければと思います。

習慣化に取り組まない言い訳

「習慣化」という言葉を聞いて皆さんは何を思い浮かべますか?多分ためになることを頑張って継続している姿を思い浮かべるの中と思います。例えば、毎朝のランニング、ジムに通って筋トレ、自炊、毎日の勉強などなどです。こういった習慣化に取り組むことに対して、取り組む人もいれば取り組まない人もいます。取り組まない人の考え方として、習慣化に取り組むことは比較的ハードルが高く、頑張ることを継続することに対していろいろな言い訳から取り組まないことを選択しています。主な言い訳としては以下のようなものが挙げられます。

  • 習慣づくりは辛い
  • 自分の行動は自分の意思でコントロールしているので習慣化は意味がない
  • 習慣化を作るには強い意志力が必要である

しかし、著者であるDaiGOさんはこれらの言い訳は全て勘違いと断言しています。

https://i.gyazo.com/44bfa272221cd6cfdfc2771fbbbb3871.png

人生が楽になる

習慣づくりは辛いと考える人が多いですが、実は習慣づくりによって決定疲れがなくなり人生が楽になります。現代では私たちの生活はいろいろな選択肢で溢れています。決まった仕事であれば話は別ですが、朝起きたらスマホをいじる、ご飯を食べる、ランニングするなど、私たちのたくさんの選択肢の中から行動を選ぶ必要があります。

このたくさんの選択肢がある状態は人類の歴史上では最近始まったことです。それまでは人類のほとんどの人は選択肢がなく、決まった仕事を決まった時間までやり、決まった時間にご飯を食べ、決まった時間に寝るという生活を何千年もおくってきました。そのため、選択肢などはほとんどなく決められた人生を歩むのみで毎日は一定していました。

しかし、1980年以降の発展により私たちはスマホという何でもできるデバイスを手にし、比較的自由な生活を送ることができるようになりました。自由 × 膨大な選択肢という状態が当たり前になっていますが、これは100年前まではあり得なかったことです。それにより私たちは常に行動を選択しています。そして、選択肢が非常に多い影響で行動を選択する回数は非常に多く、人類歴史上1番脳が選択することに苦しんでいる状態です。

https://i.gyazo.com/3de421168538a41facc716abfc2660c7.jpg

しかし、習慣化をしていれば行動する時に悩むことがないため、選択する行動回数を制限することができます。習慣化することで行動に悩むことがなくなることで、より脳への負担が減り楽に生活できるようになります。

行動はほとんどコントロールされていない

「自分の行動は自分の意思でコントロールしているので習慣化は意味がない」ということに対しても反論を唱えています。実は人間の意識的な行動と無意識行動の割合は明確に発見されています。なんと実に95%もの行動が無意識の行動であるというのです。つまり、20行動して初めて1回の行動に私たちの意識があるということです。私たちの行動は常に私たちが選んでいると思っていますが実はそうではありません。無意識的な反射や選択で行動を自然に選んでいることがたくさんあるのです。

朗報として、無意識の行動は習慣化された行動も含まれています。よって、習慣化されているので私たちはそれをしようとする意識がなくても、無意識に行動をすることができます。つまり、たくさんの行動を習慣化すればするほど、95%という非常に大きな行動の割合に習慣化したい行動を移すことができるのです。

https://i.gyazo.com/59d2b3a52c51362617322317bbfeaf56.png

意志力は強化される

「習慣化を作るには強い意志力が必要である」と思われる方も非常に多いです。意志力とは何かに取り組もうとする時に使うエネルギーです。そんな意志力ですが、強い意志力は確かに習慣化する上で必要かもしれません。しかし、習慣化を成功させていくことでこの意志力は鍛えることができるといいます。そして、どんな些細な行動であってもこの意志力は鍛えていけるというのです。例えば、寝る前にいっぱいの水を飲み寝るということを習慣化づけるだけでも意志力は鍛えられます。なぜなら、脳が習慣化の成功体験を得るからです。脳は習慣化の成功体験を得れば得るほど、より意志力が強くなるようになると言われています。些細なことでもいいので何かを習慣化していくことで、今は踏み出せない習慣化したい取り組みも将来的には行動に移せるようになります。

https://i.gyazo.com/c89812c7f26c02783204152faee125e3.jpg

具体的な習慣術を紹介

本の中ではたくさんの習慣術が紹介されていますが、その中でもかなり簡単に始めれて効果の高い習慣術を三つほどご紹介します。

if then プランニング

まずは最も効果が高いとされているif then プランニングです。これはどんな状況なら(if)何をするのか(then)を決めておく(プランニング)というものです。例えば、休日の朝が暇なら(if)、ジムに行く(then)ということを自分の中のルールとして決めておきます。

たったこれだけで効果があるのかと思うかもしれませんが、これが非常に効果的であることが科学的に立証されています。効果量というある事柄の効果を量的に計測したものがあります。効果量が0.3以上ならそれを試す価値があるとされ、0.5以上なら効果が期待できるというものです。そして、if then プランニングの効果量は0.65~0.99の間とされており、非常に高い効果量となっています。

https://i.gyazo.com/1c3c31d202468e5ba173de05ad619dec.png

ご褒美と結びつけることでif then プランニングは非常に効果が高まります。例えば、1時間ゲームがしたいなら1時間読書をするという具合です。ifの中に何かやりたいことを設定することで、よりthenの行動が起きやすくなります。最初何かご褒美がないと始められないという人はまずはここから始めてみてもいいかもしれません。

https://i.gyazo.com/57a52a32a2240c491440b3439a35ad47.png

20秒ルール

20秒ルールとは習慣化したい行動にかかる手間を20秒減らすというものです。例えば、通勤中に本が読みたいのであればリュックの取り出しやすい位置に本をしまっておく、朝ジムに行きたいのであればスポーツウェアを着て寝るというものです。本を取り出しにくいところにしまっておいたり、朝着替える手間を減らしたりすることで、スムーズに行動に移すことができるようになるため効果が期待されています。この手間は減らした分だけ効果が高いとされているので、本当にスムーズに行動したければ手間は減らせるだけ減らしましょう。

https://i.gyazo.com/eda9a2120162afd5676d10b31d064139.png

これは応用ですが、逆に悪い習慣には手間がかかるようにしてみるといいです。例えば、自分がよくやっていることとして何か勉強をする時必ずロフトにスマホを置いて取りに行く手間を増やしています。これが意外と面倒で勉強を始めたら夜までスマホを使うことがなくなりました。このように行動に対する手間を意識することでいい習慣を習慣化しやすくなり、悪習慣を断ち切りやすくなります。

https://i.gyazo.com/bab99eba1b75db14a2bd02c47b3fb2b3.png

マジックナンバー4

これは「1週間のうちに4回以上行う行動は習慣化されやすい」という科学的なデータを取り入れた方法です。習慣化は何時間やったなど時間の送料を重要事する人が多いですが、実はそれよりも行動の頻度の方が重要です。例えば、60分の筋トレを週に2回するのではなく30分の筋トレを週に4回行った方がより習慣化しやすいとされています。

さらに習慣化成功の目安は8週間とされています。8週間目以降は習慣化されている行動へのハードルは非常に低くなりその行動はずっと続きます。なので、週4回のペースで8習慣続けることを目標にするといいでしょう。

https://i.gyazo.com/d7a847044606342125156c54ee571b89.png

最も効果的な方法

3つの習慣化のための方法を説明してきましたが、1番効果的な方法があります。それは同じ目標に向かって誰かと一緒に頑張ることです。本の中ではジム通いの習慣化をする実験が説明されていました。グループ①はジムに行くとお金がもらえ、グループ②は同じグループの人たちと競走し合い、グループ③の人たちはジムで仲間を作って取り組みました。すると習慣化できたのはグループ③であったそうです。このことから習慣化は同じ目標を持つ誰かと一緒に頑張ることで達成しやすくなることがわかりました。そのため、上述した方法はあくまで手軽な手段とし、まずはあなたと同じ目標を持つ人と繋がりその人と一緒に頑張ることが習慣化を成功させる最短ルートになると思います。

https://i.gyazo.com/d3a1736a6b2ed16ef12821c9aeb9fa4c.png

【無職に転生 ~ 就職するまで毎日ブログ出す_19】【Rails】たまに使えるクエリメソッド

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はRailsのActive Recordにおいて頻繁には使用しないけどケースによっては使うことがあるメソッドを紹介したいと思います。RailsガイドのActive Recorddのメソッドには本当にたくさんのメソッドがありますが、よく使うメソッドはせいぜい10個程度でしょうか。しかし、他のも様々な便利なメソッドがあるので、使い方を理解しておきましょう。

Active Record クエリインターフェイス - Railsガイド

group

取得メソッドにGROUP BY句を追加したい場合に使います。つまり項目が同じであるレコードをまとめます。

例えば下記のように難易度のクラスが定義されていたとします。enumで難易度が3段階で定義されています。

class Difficulty < ApplicationRecord
  belongs_to :user
  belongs_to :hoge
  enum level: {easy: 0, middle: 1, hard: 2}
end
Difficulty.levels
=> {"easy"=>0, "middle"=>1, "hard"=>2}

この時、難易度ごとにグループに分けて取得したい場合、groupメソッドで引数にグループ化する項目を指定することでGROUP BY句を使うことができます。

Difficulty.group(:level)
  Difficulty Load (1.3ms)  SELECT `difficulties`.* FROM `difficulties` GROUP BY `difficulties`.`level`
(Object doesn't support #inspect)
=>

しかし返り値は返ってきていないことがわかります。これはGROUP BYはSQLでは集計関数と併用することが必須条件であるためです。そのため、集計関数を使うことで取得できます。例えば集計関数COUNTを呼び出すcountを使用すれば以下のように出力することができます。

Difficulty.group(:level).count
   (0.5ms)  SELECT COUNT(*) AS count_all, `difficulties`.`level` AS difficulties_level FROM `difficulties` GROUP BY `difficulties`.`level`
=> {"easy"=>60, "middle"=>58, "hard"=>66}

GROUPごとにキーが難易度、バリューがその難易度の投票数を格納したハッシュが返却されます。


よく使われる方法として集計した中から最大のバリューのキーを取得したい場合があります。上記でいうと難易度が"hard"を取得したいと思います。その場合、下記のようにHashクラスのインスタンスメソッドであるmaxを使うことで配列として出力することができます。

Difficulty.group(:level).count.max { |x, y| x[1] <=> y[1] }
   (1.2ms)  SELECT COUNT(*) AS count_all, `difficulties`.`level` AS difficulties_level FROM `difficulties` GROUP BY `difficulties`.`level`
=> ["hard", 66]

注意点としてgroupを使う場合はActiveRecordの便利なメソッドを使うことができなくなります。これは、groupの返却値はハッシュオブジェクトであるためです。

=> {"easy"=>60, "middle"=>58, "hard"=>66}

Active Recordは基本的にレシーバーがDBと連携したモデルの値がある方がチェーンメソッドをつなげていくことができるため便利ですが、groupの場合はクエリメソッドのチェーンが途切れてしまうので注意しましょう。

having

GROUP BY句で取得した結果に対してさらに制約を加えるHAVING句を使うことができるメソッドです。groupメソッドにチェーンすることで使用することができます。

Difficulty.group(:level).having("count(*) > ?", 59).count
   (1.0ms)  SELECT COUNT(*) AS count_all, `difficulties`.`level` AS difficulties_level FROM `difficulties` GROUP BY `difficulties`.`level` HAVING (count(*) > 59)
=> {"easy"=>60, "hard"=>66}

order

ORDER BY句を使うことができるメソッドです。こちらの利用頻度はgroupに比べればたくさんあるかなと思います。よくある使われ方としてはscopeと組み合わせて使われる方法です。

class Post < ApplicationRecord
    scope :recent, -> { order(:created_at).first(5) }
  # Ex:- scope :active, -> {where(:active => true)}
end

Post.recent # => 最近作成された投稿を取得

逆に古いものを取得するにはorderの第二引数に降順を表すシンボル:descを指定します。

class Post < ApplicationRecord
    scope :recent, -> { order(:created_at).first(5) }
  scope :old, -> { order(:created_at, :desc).first(5) }
  # Ex:- scope :active, -> {where(:active => true)}
end

Post.old # => 最初あたりに作成された投稿を取得

複数のフィールドを指定して並べることもできます。

Post.**order**(updated: :asc, created_at: :desc)

limit

上から順にいくつ取得するかを指定します。

class Post < ApplicationRecord
    scope :recent, -> { order(:created_at).limit(5) }
  # Ex:- scope :active, -> {where(:active => true)}
end

firstでも同じ方法で取得できました。

offset

limitはひきすうをつかえあfirstと差別させる方法としてoffsetメソッドがあります。これはlimitと併用し、上から何行飛ばしてからlimitでデータを取得するかを指します。例えば、11番目から取得したい場合は10個飛ばすことで取得できます。

User.order(:created_at).limit(5).offset(10)
  User Load (2.9ms)  SELECT `users`.* FROM `users` ORDER BY `users`.`created_at` ASC LIMIT 5 OFFSET 10

pluck

カラムを引数として指定して指定したカラムの値を配列として取得することができるメソッドです。

User.pluck(:name)
   (0.5ms)  SELECT `users`.`name` FROM `users`
[
 "Kaido",
 "Ussop",
 "Bellamy",
 ]

こちらも返り値が配列であるためクエリメソッドをつなげて呼び出すことができなくなります。そのため、whereなどで先に制約を加えておいて特定の配列を返すようにすることができるようになります。

【無職に転生 ~ 就職するまで毎日ブログ出す_18】【Ruby】Range

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はRubyのRangeクラスについて書いていきます。Rangeクラスはあまりピンとこない方も多いかもしれませんが、Rubyを触っていれば時々何気なく使っています。

class Range

範囲オブジェクトのクラス。範囲オブジェクトは文字どおり何らかの意味での範囲を表します。数の範囲はもちろん、日付の範囲や、「"a" から "z" まで」といった文字列の範囲を表すこともできます。

要は書きみたいな記述。

(1..3)
=> 1..3

これが実はクラスだったんですね。今まで配列の省略記法と思っていましたが実は別クラスのインスタンスでした。

(1..3).class
=> Range

Rangeインスタンスの作り方

範囲オブジェクトを作る書き方としては一般的には上述したような書き方を使います。例えば、1 ~ 5の数の範囲オブジェクトを作る場合は以下のように記述します。

(1..5)
=> 1..5

このように数..数を()で囲むことで始端から終端までの範囲オブジェクトを生成できます。上記と同じ書き方として、Rangeのnewメソッドを使用することもできます。一般的なインスタンスの生成方法ですね。第一引数に始端、第二引数に終端を入れることで始端から終端までの範囲オブジェクトを作ることができます。

Range.new(1, 5)
=> 1..5

また、終端を含めないやり方として、...で始端と終端を繋げる方法があります。これにより終端の一つ手前の数を終端とした範囲オブジェクトを作ることができます。

(1...5)
=> 1...5

上記で5が含まれていないことを確認してみます。eachメソッドを使うことができるのでeachで範囲オブジェクトの中の各値を出力してみます。

(1...5).each {|i| p i}
# 出力
1
2
3
4

このように5を含まない1から4までの値が出力されます。上記の方法はRangeクラスでは行うことはできません。

また、アルファベット順で範囲オブジェクトを作ることもできます。使う機会は少ないかなと思いますが、、。

Range.new("a", "e").each {|s| p s}
"a"
"b"
"c"
"d"
"e"
=> "a".."e"

始端と終端をnilにすることもできます。ただ、使い所はあるのかわかりません。それぞれ、「終端を持たない範囲オブジェクト」、「始端を持たない範囲オブジェクト」と称されるそうです。

rubyのバージョンによってはできない場合もありますので注意してください。

Range.new(1, nil) # ruby2.6より
=> 1..
Range.new(nil, 5)  # ruby 2.7より
=> ..5
Range.new(nil, nil) 
=> nil..nil

範囲オブジェクトはイミュータブル

範囲オブジェクトはruby3.0.0以降イミュータブルなオブジェクトです。つまり、破壊的メソッドなどが使えず変更されることがないということです。理由としてはfreezeメソッドが初期化時に実行されるらしいです。

freezeメソッド

オブジェクトを凍結(内容の変更を禁止)します。 凍結されたオブジェクトの変更は例外 FrozenError を発生させます。いったん凍結されたオブジェクトを元に戻す方法はありません。 凍結されるのはオブジェクトであり、変数ではありません。代入などで変数の指すオブジェクトが変化してしまうことは freeze では防げません。 freeze が防ぐのは、 `破壊的な操作' と呼ばれるもの一般です。変数への参照自体を凍結したい場合は、グローバル変数なら Kernel.#trace_var が使えます。

Object#freeze (Ruby 3.0.0 リファレンスマニュアル)

a1 = "foo".freeze
a1 = "bar"
p a1 #=> "bar" # 変数の代入はできる

a2 = "foo".freeze
a2.replace("bar") # can't modify frozen String (FrozenError)

オブジェクトが凍結されているかどうかはfrozen?メソッドで確認できるので範囲オブジェクトに対して実行してみます。

Range.new(1, 5).frozen?
=> true

インスタンスメソッド

Rangeクラスのインスタンスメソッドは以下のようになります。

https://i.gyazo.com/97bcb04482683389d585df7443bc8001.png

他のクラスに比べるとかなり少ないですね。これに加えてEnumerableモジュールがincludeされています。Enumerableモジュールについては以前こちらの記事で紹介しました。

【無職に転生 ~ 就職するまで毎日ブログ出す_13】【Ruby】Enumerable - 大ちゃんの駆け出し技術ブログ

インスタンスメソッドからいくつか使えそうなメソッドを紹介します。

cover?(obj)

引数で指定したオブジェクトがレシーバーの範囲オブジェクトの範囲に含まれているかどうかを真偽値で判定するメソッドです。

(1..5).cover?(5)
=> true
(1...5).cover?(5)
=> false

実はinclude?メソッドがRangeクラスに定義されているのですが、こちらもほぼ同じ挙動を見せます。

(1..5).include?(5)
=> true
(1...5).include?(5)
=> false

明確な違いとしてはcover?の方には引数に範囲オブジェクトを指定することができます。

(1..5).cover?(1..5)
=> true
(1...5).cover?(1..5)
=> false

include?にも範囲オブジェクトを引数に指定知ることはできるのですが、どんな引数でもfalseを返してしまうので全く機能していません。

(1...5).include?(1..4)
=> false
(1...5).include?(1..2)
=> false

max

範囲オブジェクトの終端の値を取得します。

("a".."w").max
=> "w"
("a"..."w").max
=> "v"

また、引数に数値を指定することで、終端から引数の数値の数だけ範囲オブジェクトの値を取得します。返却値は配列となります。

("a"..."w").max(3)
=> ["v", "u", "t"]

min

maxの逆です。範囲オブジェクトの始端の値を取得します。

("a".."w").min
=> "a"

こちらも引数を指定することでその数だけ範囲オブジェクトのしたんから始まる要素を取得します。

("a".."w").min(10)
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]

ちなみに引数が範囲オブジェクトの要素を超えた場合は全要素を配列として返却します。エラーにはなりません。

("a".."w").min(100)
=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w"]
("a".."w").max(100)
=> ["w", "v", "u", "t", "s", "r", "q", "p", "o", "n", "m", "l", "k", "j", "i", "h", "g", "f", "e", "d", "c", "b", "a"]

minmax

始端と終端を配列として取得します。

("a".."w").minmax
=> ["a", "w"]

step

stepメソッドはIntegerクラスで使われることが多い気がします。

2.step(5){|n| p n}
# 出力
2
3
4
5

上記の場合はレシーバーは数値で引数も数値です。そしてブロックを使うことでレシーバーの数から引数の数まで出力します。

Rangeクラスのstepメソッドの場合、始端から引数の数だけ飛ばした数を次々に出力するメソッドです。

(0..100).step(10) {|i| puts i}
# 出力
0
10
20
30
40
50
60
70
80
90
100

to_a

範囲オブジェクトを配列に変えることができます。すごく使い勝手が良さそうです。Arrayクラスだけで1から100までの配列を作ろうとした場合、以下のようにmapメソッドを使うことで作成できます。

array = 100.times.map{|i| i + 1}
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51...

しかし上述したやり方ですと見栄えが少し悪い気がします。そこでRangeクラスとto_aメソッドを組み合わせればかなりシンプルに1から100までの配列を作ることができます。

array = (1..100).to_a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51...

【無職に転生 ~ 就職するまで毎日ブログ出す_17】【書籍】オブジェクト思考設計実践ガイド 2章 - 4章までざっくりと

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日は書籍「オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方」という本を4章までざっくりとまとめました。

2 単一責任を理解する

オブジェクト指向設計実践ガイドを読む No.2【単一責任のクラスを設計する】

変更が簡単なコードを組成

変更が簡単なコードとは以下の性質を持つ

  • 見通しが良い (変更がもたらす影響・変更箇所が明確にわかる)
  • 合理性 (如何なる変更でもかかるコストは変更がもたらす利益の割にあっている)
  • 利用性が高い (新しい環境、予期していなかった環境でも再利用できる)
  • 模範的 (コードに変更を加える人が上記の品質を自然と保つようなコードになっている)

上記の性質を満たすための第一歩

⇒ それぞれのクラスが明確に定義された単一の責任を持つように徹底すること


なぜ単一責任が重要なのか

別のクラスとの依存性がわずかしかないため、単独で変更した時に他のクラスへの影響がほとんどないため

クラス(メソッド)が単一責任かどうか見極める方法

  • あたかもそれに知覚があると仮定し質問する

「Gearクラスさん、あなたの比率を教えてくれませんか?」→ ○

「Gearクラスさん、あなたのタイヤのサイズを教えてくれませんか?」→ ❌

  • 一文でクラスを説明してみる

「Gearクラスはギアの比率を教える責任がある」 → ○

「Gearクラスはギアの比率を教える責任がある。それと、タイヤのサイズを教える責任がある。」→ ❌

⇒「それと」や「または」が含まれていれば、それは単一責任から外れている


3. 依存関係を管理する

  • 複雑な処理があればあるほど、2で学習した単一責任のクラス、メソッドが複雑に絡み合って、依存関係を生み出していく
  • 依存関係があるということはオブジェクトがその関係にあるオブジェクトのことを知っているということ

    Untitled

依存関係を理解する

  • 一方のオブジェクトに変更を加えた時、他方のオブジェクトも変更しなければならない時がある

サンプルコード

class Gear
  attr_reader :chainring, :cog, :rim, :tire
  def initialize(chainring, cog, rim, tire)
    @chainring = chainring
    @cog = cog
    @rim = rim
    @tire = tire
  end

  def gear_inches
    ratio * Wheel.new(rim, tire).diameter
  end

  def ratio
    chainring / cog.to_f
  end
end

class Wheel
  attr_reader :rim, :tire
  def initalize(rim, tire)
    @rim = rim
    @tire = tire
  end

  def diameter
    rim + (tire * 2)
  end
end

Gear.new(52, 11,26, 1.5).gear_inches

オブジェクトが次のものを知っている時、オブジェクトには依存関係がある

  • 他のクラスの名前:GearはWheelという名前のクラスが存在することを予想している
  • self以外の何処かに送ろうとするメッセージの名前:GearはWheelのインスタンスがdiameterに応答することを予想している
  • メッセージが要求する引数:GearはWheel.newにrimとtireが必要なことを知っている
  • それらの引数の順番:GearはWheel.newの最初の引数がrimで、2番目がtireである必要があることを知っている
ratio * Wheel.new(rim, tire).diameter

設計課題:依存関係を管理しそれぞれのクラスが持つ依存を最低限にすること


疎結合なコードを書く

依存オブジェクトの注入

以下の場合にGearクラスを変更しなければならない ・Wheelクラスの名前をWheelyにした時 ・gear_inchesメソッドにディスクやシリンダという別の直径の値を反映させたい時

改善!

class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring, cog, wheel)
    @chainring = chainring
    @cog = cog
    @wheel = wheel
  end

  def gear_inches
    ratio * wheel.diameter
  end

  def ratio
    chainring / cog.to_f
  end
end
・
・

Gear.new(52, 11, Wheel.new(26, 1.5)).gear_inches

・GearはWheelというオブジェクトの名前を知らない (wheelメソッドでアクセウするようにしている) ・他の直径を計測する必要があるオブジェクトにもGearクラスを変えることなしに対応できる

Gearは知っていることが少なくなったおかげで、賢くなった


依存を隔離

外部メッセージを隔離

外部メッセージ = 「self以外に送られるメッセージ」

diameterは外部のクラスを参照する(外部にメッセージが送られる)

  def gear_inches
    ratio * wheel.diameter
  end

def gear_inches
  ratio * diameter
end

def diameter
    wheel.diameter
end

メソッドとして切り出すことで、レシーバーであるwheelの変更に対して柔軟になる


引数の順番への依存を取り除く

  • 引数ある場合、引数を渡す順番に依存してしまうため、その依存をなくし順番からの依存をなくす
class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring, cog, wheel)
    @chainring = chainring
    @cog = cog
    @wheel = wheel
  end

  def gear_inches
    ratio * wheel.diameter
  end

  def ratio
    chainring / cog.to_f
  end
end

Gear.new(52, 11, Wheel.new(26, 1.5)).gear_inches

newメソッドの順番が定義しているinitializeメソッドによって固定されてしまい、送り手(メソッドを呼び出す側)が順番に依存して引数を渡す必要がある ⇒ initializeメソッドの引数の順番が変われば、送り手も変えなければならない

初期化の際に引数にキーワード引数を使う

class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring: "52", cog: "11", wheel: "10")
    @chainring = chainring
    @cog = cog
    @wheel = wheel
  end

  def gear_inches
    ratio * wheel.diameter
  end

  def ratio
    chainring / cog.to_f
  end
end
Gear.new(chainring: 52, cog: 11, wheel: Wheel.new(26, 1.5)).gear_inches
Gear.new(cog: 11, wheel: Wheel.new(26, 1.5), chainring: 52).gear_inches
  • 引数の依存から逃れることができる

参考記事

Rubyのキーワード引数の使い方を現役エンジニアが解説【初心者向け】 | TechAcademyマガジン

Rubyのキーワード引数はシンボルっぽく定義するけど、シンボルそのものではない、という話 - Qiita



依存方向の管理

オブジェクト指向設計実践ガイドを読む No.3【依存関係を管理する】

依存関係には常に方向性がある

依存関係の逆転

これまでの例はGearがWheelまたはdiameterに依存している

Wheelの仕様に変更があればGearはそれに合わせて仕様を変えなければいけない場合がある

これを反対にWheelがGearに依存するようにする (依存関係の逆転)

class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring, cog)
    @chainring = chainring
    @cog = cog
  end

  def gear_inches(diameter)
    ratio * diameter
  end

  def ratio
    chainring / cog.to_f
  end
end

class Wheel
  attr_reader :rim, :tire, :gear
  def initalize(rim, tire, gear)
    @rim = rim
    @tire = tire
        @gear = Gear.new
  end

  def diameter
    rim + (tire * 2)
  end

    def gear_inches
    gear.gear_inches(tire * 2)
  end
end

Wheel.new(26, 1.5, Gear.new(52, 11)).gear_inches

Gearの仕様に変更があればWheelはそれに合わせて仕様を変えなければいけない場合がある

  • メリットがある場合がある(上記の例ではメリットはない)
  • アプリケーションが大きくなるにつれて依存方向の選択が重要になる

依存方向の選択

クラスがあたかも人間であるように考え、クラスにアドバイスをするとするならば、次のようにアドバイスするのではないか

**「自信より変更されないものに依存しなさい」 
(自信よりも変更される可能性が多いクラスに依存すると自身が変わる回数が多くなる)**
  • あるクラスは他のクラスよりも要件が変わりやすい (理解!)
  • 具象クラスは抽象クラスよりも変わるかのせいが高い (理解!)
  • 多くのところから依存されたクラスを変更すると、広範囲に影響が及ぶ (理解!)

変更の起きやすさを理解する

変わりにくいコード

  • プラグインやgemのコード
  • 既存のメソッド、クラス (spliceメソッド、Arrayクラス)

変わりやすいコード

  • 自分が書いたコード

コードの中で変わりやすいコードと変わりにくいコードを順位づけることが、依存関係を決める上で重要な鍵になる なぜなら、変わりやすいコードが依存するのはそれよりも変わりにくいコードであるほうがよいため

具象と抽象を認識する

依存オブジェクトの注入の際に、GearのWheelクラスの具象性(具体的な引数)をwheelに置き換えることで、他のクラスを知っていることをなくして抽象化した

class Gear
  attr_reader :chainring, :cog, :wheel
  def initialize(chainring, cog, wheel)
    @chainring = chainring
    @cog = cog
    @wheel = wheel
  end

  def gear_inches
    ratio * wheel.diameter
  end

  def ratio
    chainring / cog.to_f
  end
end
・
・

Gear.new(52, 11, Wheel.new(26, 1.5)).gear_inches

変更前が具象、変更後は抽象

メリット:変わりにくいオブジェクトになる

⇒ 変わりにくい変わりやすいの性質が上下する

大量に依存されたクラスを避ける

シンプルに多くから依存されたクラスを持てばそれを変更した時依存されているクラスの数だけコードを修正する必要がある

問題となる依存関係を見つける

依存関係を決める上で、重要になる尺度

  • クラスの変わりやすさ
  • 依存されている数

適切に設計されたアプリケーションはDの危険領域にあたるクラスがない

D = 変わりやすく多くのクラスに依存されている

https://i.gyazo.com/b5a9392f8889dd9bb4319287bf683035.png

4.柔軟なインターフェースを作る

オブジェクト指向設計実践ガイドを読む No.4【柔軟なインターフェースをつくる】その 1

オブジェクト指向設計実践ガイドを読む No.4【柔軟なインターフェースをつくる】その 2

https://slidesplayer.net/slide/11190418/60/images/3/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%AE%E6%A6%82%E8%A6%81+%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0+B-%EF%BC%91+C-%EF%BC%91+A-1+C-%EF%BC%92+D-1.jpg

インターフェースを定義する

(レストランの例え話)

お客 ⇒ 具体的な作り方を知らないままメニューを見て頼む (何が作れるのかは知っている)

コック ⇒ 具体的な作り方を独自で知っている

上記の例で言うと、メニューは公開されている情報 (パブリック) public

作り方は公開されていない情報 (プライベート) private

パブリックインターフェースとプライベートインターフェス

パブリックインターフェースのメソッドの特徴

  • クラスの主要な責任を明らかにする (クラスの責任を明確に述べる契約書)
  • 外部から実行されることが想定される
  • 気まぐれに変更されない
  • 他者がそこに依存しても安全
  • テストで完全に文書化される

プライベートインターフェスのメソッドの特徴

  • 実際の詳細に関わる
  • 他のオブジェクトから送られてくることは想定されない
  • どんな理由でも変更されうる
  • 他者がそこに依存するのは危険
  • テストでは言及されないこともある

パブリックインターフェースとプライベートインターフェースの例

シチュエーション: ・ある旅行(Trip)では必ず必要な自転車(bicycle)が整備されている必要がある ・整備士(Mechanic)が自転車を整備する

class Trip
    has_many: bicycles
    def clean_bicycle
        @mechanic = Mechanic.new(name: hoge)
        bicycles.each do |bicycle|
            @mechanic.clean_bicycle(bicycle)
            @mechanic.pump_tires(bicycle)
            @mechanic.lube_chain(bicycle)
            @mechanic.check_brakes(bicycle)
        end
    end
end
class Mechanic
    def clean_bicycle(bicycle)
    end
    def pump_tires(bicycle)
    end
    def lube_chain(bicycle)
    end
    def check_brakes(bicycle)
    end
    private
end

上記では以下の問題点がある

  • TripクラスがMechanicクラスの多くのインターフェースを知っている ⇒ Mechanicクラスを変更するとTripクラスが大きく変更される可能性がある
  • つまり、Tripクラスはメニューだけでなく、作り方も全部知ってしまっている(厨房が筒抜け)

⇒リファクタリング

class Trip
    has_many: bicycles
    def clean_bicycle
        @mechanic = Mechanic.new(name: hoge)
        bicycles.each do |bicycle|
            @mechanic.prepare_bicycle(bicycle)
        end
    end
end
class Mechanic
    def prepare_bicycle(bicycle)
        clean_bicycle(bicycle)
        pump_tires(bicycle)
        lube_chain(bicycle)
        check_brakes(bicycle)
    end
    
    private

    def clean_bicycle(bicycle)
    end
    def pump_tires(bicycle)
    end
    def lube_chain(bicycle)
    end
    def check_brakes(bicycle)
    end
end
  • Tripクラスはパブリックインターフェースを少ししか知らない状態 ⇒ Mechanicクラスに変更が起きてもTripクラスに変更は起きにくい

【無職に転生 ~ 就職するまで毎日ブログ出す_16】【CSS】Materialize

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

チーム開発でMaterialize CSSを使う機会がありましたので基本的なところをアウトプットしたいと思います。TailwindとBootstrapを使ったことがありましたが、Materializeはなかったので比較をしてみたいと思います。

Materialize


Materialize CSS

公式ページではMaterialize CSSは以下のように説明されています。

Created and designed by Google, Material Design is a design language that combines the classic principles of successful design along with innovation and technology. Google's goal is to develop a system of design that allows for a unified user experience across all their products on any platform. Googleが開発・設計したMaterial Designは、デザインを成功させるための古典的な原理と、革新的な技術を組み合わせたデザイン言語です。Googleの目標は、あらゆるプラットフォームのすべての製品で統一されたユーザーエクスペリエンスを実現するデザインシステムを開発することです。

Googleが作成したCSSフレームワークのようです。UXが統一されることを目指して開発されているようですね。

デザイン性としても他のフレームワークと比べて一般的なデザインなので、かなり使い勝手が良さそうに見えます。

CMSなど管理画面のスタイリングに使用されることが多いイメージがあります。 マテリアルデザインは多くの人にとって見慣れたデザインなので、ユーザビリティの向上を目的とする場合におすすめのCSSフレームワークですね。

2021年版!おすすめのCSSフレームワーク総まとめ。特徴や比較も! | Web Design Trends

後々触れていくのですが、このMaterial DesignはVuetifyも参照してるようです。なので、Vuetifyと見た目などがすごい似てくるCSS フレームワークだと思いました。

Vuetify - A Material Design Framework for Vue.js

CDNでインストール

簡単なhtmlファイルを作成して下記コードをコピペすればインストールできます。

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>マテリアルデザイン</title>
    <link
      rel="stylesheet"
      href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css"
    />
  </head>
  <body>
    <a class="btn-small">ボタン</a>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
  </body>
</html>

https://i.gyazo.com/aa606dc663db0f911815d54a478eac15.png

公式にも書いてありますが下記のCDNを記載すれば簡単に導入することができます。

<!-- Compiled and minified CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">

<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>

まずは基本的な色からです。

Materializeの色の種類はパッと見ると非常に多いなと思いました。

https://i.gyazo.com/fc4f9bfc5afe71486075ae75e6c65341.gif

Color

これどこかで見たことがあると思ったら、Vuetifyのカラーと同じ構成でしたね。後述しましたがVuetifyとデザインがほぼ同じです。

マテリアルカラーパレット


ではクラスにred lighten-2を追加します。

<a class="btn-small red lighten-2">ボタン</a>

https://i.gyazo.com/9195b3b860b72731c8ed727e0f7b947a.png

Grid

Gridシステムですがこちらはかなり使い勝手が良さそうに見えました。rowクラスで囲みその中にcolクラスとs数の組み合わせでスペースを指定します。

<div class="row">
  <div class="col s1 card-panel teal lighten-2">1</div>
  <div class="col s1 card-panel teal lighten-2">2</div>
  <div class="col s1 card-panel teal lighten-2">3</div>
  <div class="col s1 card-panel teal lighten-2">4</div>
  <div class="col s1 card-panel teal lighten-2">5</div>
  <div class="col s1 card-panel teal lighten-2">6</div>
  <div class="col s1 card-panel teal lighten-2">7</div>
  <div class="col s1 card-panel teal lighten-2">8</div>
  <div class="col s1 card-panel teal lighten-2">9</div>
  <div class="col s3 card-panel teal lighten-2">10</div>
</div>

https://i.gyazo.com/db0b385cd1febde96a0fb86f38ea2f01.png

デフォルトでGridの横幅は12分割で構成されているのでsの最大値は12です。

https://i.gyazo.com/8d706919e52cc51d166bfb0cbb0e2318.png

Gridの位置を指定したいときはoffset-s数で指定することができます。

<div class="row">
  <div class="col s1 card-panel teal lighten-2">1</div>
  <div class="col s1 card-panel teal lighten-2">2</div>
  <div class="col s6 offset-s6 card-panel red lighten-2">6</div>
</div>

https://i.gyazo.com/19430b701a5df1e05fe1719de1a1df15.png

Text align

テキストの位置の変更は3種類あります。left-align, right-align, center-alignの3つです。

<div>
  <h5 class="left-align card-panel teal lighten-2"></h5>
</div>
<div>
  <h5 class="right-align card-panel teal lighten-2"></h5>
</div>
<div>
  <h5 class="center-align card-panel teal lighten-2">中央</h5>
</div>

https://i.gyazo.com/27db52936348b6d23ee6607806fe8cda.png

Hiding/Showing Content

画面のサイズに合わせて要素を画面から消したり出現させたりすることが調整できます。

  • hide・・・どの画面サイズでも消す
  • hide-on-small-only・・・モバイル画面サイズで消す
  • hide-on-med-onl・・・タブレット画面サイズで消す
  • hide-on-med-and-down・・・タブレット画面より下の画面サイズで消す
  • hide-on-med-and-up・・・タブレット画面より上の画面サイズで消す
  • hide-on-large-only・・・デスクトップの画面サイズで消す
  • show-on-small・・・モバイル画面サイズで出現させる
  • show-on-medium・・・タブレット画面サイズで出現させる
  • show-on-large・・・デスクトップの画面サイズで出現させる
  • show-on-medium-and-up・・・タブレット画面より上の画面サイズで出現させる
  • show-on-medium-and-down・・・タブレット画面より下の画面サイズで出現させる
<div>
  <h5 class="card-panel red lighten-2 hide-on-small-only"></h5>
</div>
<div>
  <h5 class="card-panel teal lighten-2 hide-on-large-only"></h5>
</div>

画面サイズによって消えたり出現したりします。

https://i.gyazo.com/237ff50656716208f5f3ff72fa947bf3.gif

基本的に上述したクラスでレスポンシブデザインを構成します。上記の例では要素のdisplay操作しかできていませんが、下記のようにscssファイルを作ると各スタイルをレスポンシブ対応することができます。

@media #{$small-and-down} {
    // styles for small screens and down
  }
  @media #{$medium-and-up} {
    // styles for medium screens and larger
  }
  @media #{$medium-and-down} {
    // styles for medium screens and down
  }
  @media #{$large-and-up} {
    // styles for large screens and up
  }
  @media #{$extra-large-and-up} {
    // styles for extra large screens and up
  }

Components

単一スタイルだけでなく、Bootstrapのように複数のスタイルから構成されるクラスもあります。

Card

cardクラスを指定することで画面にカードのようなコンポーネントをスタイリングできます。これまたVuetifyっぽいなと思いました。

<div class="row">
  <div class="col s12 m6">
    <div class="card red darken-1">
      <div class="card-content white-text">
        <span class="card-title">materialize css</span>
        <p>
          Googleが開発・設計したMaterial Designは、デザインを成功させるための古典的な原理と、革新的な技術を組み合わせたデザイン言語です。Googleの目標は、あらゆるプラットフォームのすべての製品で統一されたユーザーエクスペリエンスを実現するデザインシステムを開発することです。
        </p>
      </div>
      <div class="card-action">
        <a href="#">リンク</a>
        <a href="#">リンク</a>
      </div>
    </div>
  </div>
</div>

https://i.gyazo.com/e8d6a645bc8ca7097f8f70d3827e7f2f.png

他にもかなり自由にカードをデザインできるので試してみてください。

Cards

Pagination

ページネーションのスタイリングもできます。paginationクラスを指定してその中にリストで要素を並べるだけです。

<ul class="pagination">
  <li class="disabled">
    <a href="#!"><i class="material-icons"></i></a>
  </li>
  <li class="active"><a href="#!">1</a></li>
  <li class="waves-effect"><a href="#!">2</a></li>
  <li class="waves-effect"><a href="#!">3</a></li>
  <li class="waves-effect"><a href="#!">4</a></li>
  <li class="waves-effect"><a href="#!">5</a></li>
  <li class="waves-effect">
    <a href="#!"><i class="material-icons"></i></a>
  </li>
</ul>

https://i.gyazo.com/dcac818e26c04ddfbe49e4bfd31bf414.png

他のCSSフレームワークとの違い(今のところ)

Bootstrapとの違い

Bootstrapよりはかなり細かくスタイリングできるのかなと思います。なのでBootstrap感は出ないかなり整ったUIを形成できると思いました。ただ、すごくGoogle感が出ます笑

Tailwindとの違い

Tailwindほどは細かくスタイリングする必要はないです。ある程度はコンポーネントなどもあるのでクラスがTailwindよりはたくさんのクラスをつけることはなさそう。

終わりに

次回はJSとMaterial Designを組み合わせてみます。JSを組み合わせることでさらに画期的な動きができるようになるみたいです。

【無職に転生 ~ 就職するまで毎日ブログ出す_15】【本】GRIT

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はビジネス本からGritという本を読んだのでそのアウトプットをしようと思います。GRITとは一言で言うと「やり抜く力」と表されます。GRITはエンジニアとしてキャリアを積む上ですごい大切なマインドだと思いました。ですのでこの記事でそのマインドの大切さを広めたいと思います。

https://i.gyazo.com/874023116ac336ebf19b24797129764a.jpg

執筆の経緯

この本を書こうと思った著者の経緯を説明します。この本の経緯はアメリカの最難関陸軍士官学校である「ウェストポイント」の研究から来ています。毎年25000人の志願者からたったの1200人のみが入学することができる、倍率が20倍の学校です。ただでさえ陸軍士官学校へ入学しようと言う人は日頃から相当な努力をされているに違いありません。よってこの学校に入れるのは選ばれた才能を持つエリートのみであるはずです。

https://i.gyazo.com/4bbc20957cdd9a08b0a6675bb5ec2c67.jpg

入学 = 優秀な人?

しかし、この学校の訓練は相当厳しいもので選ばれたエリートであっても相当数が途中で挫折してしまいます。せっかく倍率20倍の学校に通うことができるようになっても、最後までやり遂げ卒業する人と途中で諦める人で大きく分かれてしまうのです。しかし、優秀な人25000人の中から選ばれた2000人は本当に優秀であるはずです。2000人もいるのでそれぞれの才能に多少の優劣はあれども、その才能の差はほとんどないのではないでしょうか?なのにどうして同じ優秀な人であるはずの人たちがやり遂げる人とそうでない人で二極化してしまうのか?この違いを著者は「GRIT」の有無であることと結論づけました。

https://i.gyazo.com/6c1a61147aad14978d467bfaa5f3559a.png

GRITとは?

改めて。GRITとは「やり抜く力」のことです。英語では「The power of passion and perseverance」となり、訳すと「情熱と粘りの強さ」となります。つまり、「やり抜く力」と理解して差し支えないと思います。

ここで上述したようにいかに才能がある人でも挫折してしまうことがあります。それに対して著者はGRITが無いために才能あるものでも挫折してしまうと言います。したがって、才能がいかにあってもGRITがなければ意味がない、つまりGRITがあれば才能がなくても才能あるものに勝てるという結論を著者はしています。

https://i.gyazo.com/5f07975bdafb997ca8b849440ede84ec.png

成果の大きさの公式

「いやいや、凡人は天才に勝てないよ」

こう思う人は一般的な成果の大きさを信じているからだと著者は主張します。一般的な成果の大きさとは、才能と成果は直結しているというものです。才能があるから人は成果を上げているのであり、才能がない人は成果を上げることができないという考えです。しかし、この才能と成果はかなりシンプルに捕らえられている気がします。才能があれば成果が出るというシンプルな世界であるのであれば、もはや才能のない人たちは努力してもそれが実ることがないと捉えられてもおかしくありません。

https://i.gyazo.com/fe2b9c81cc94fdc507ce9f1f03a5d5cb.png

上記の考えを図にしてみました。才能は成果に直結しているという考えです。

しかし、才能と成果にはそれぞれ公式が隠されています。そもそも才能は成果に直結しているのではありません。才能はあってもその才能は果たして成果を実現するだけのものでしょうか。才能という言葉はあまりにも抽象的であり、もっと別のものが成果をあげていると思います。

ここでふさわしい言葉としては「スキル」が成果につながっていると著者は言います。スキルとは才能によって生まれるものです。しかし、才能があるだけではスキルは生まれません。才能があり、その才能をスキルにするまでの努力が必要です。そしてその努力こそGRITです。才能があるとはいえ成果を出すためにはそれ相応の努力の時間が必要であり、それによって高いスキルが生まれます。スキル=才能×GRITなのです。

加えて成果を上げる際にもGRITは大切です。成果を上げるためには恵まれた才能と弛まぬ努力で獲得したスキルを持って、さらに弛まぬ努力で成果をあげようとしなければなりません。同じスキルを持っている人でも成果をあげている人とそうでない人がいます。それは、そのスキルを持ってさらに諦めない努力をしたかどうかです。よって成果=スキル×GRITです。

著者の意見では才能よりGRITが成果を出す上で重要と述べています。才能ももちろん大切です。才能があればあるほど成果を出すためのスキルが生まれやすいです。凡人と才能ある人が同じ時間努力すれば才能ある人が高いスキルを持ちます。しかし、努力しなければ才能がある人でも十分なスキルにはなりません。よって、スキルはただの習得の速さでしかなくGRITがあることの方が重要性は高いです。さらに、スキルも成果もGRITによって生み出されます。よってGRITは成果を上げるまでに2度影響します。その点を踏まえてもGRITは才能よりも重要となります。

https://i.gyazo.com/47949796caf3342cb96460a60f5c920f.png

GRITの伸ばし方

さらに嬉しいことにこのGRITは努力で伸ばすことができます。才能は天性的なものであり、努力しても才能を変えることはできません。しかし、その才能より重要なGRITを伸ばせることは凡人である自分にとっては吉報でしかありません。本の中では多くの方法が紹介されてますが、本記事ではかなり要約して紹介していきます。

GRIT は努力ではない

ここまで紹介してきてなんですが、GRITとはただがむしゃらに努力をしまくることではないということだけ言っておきます。努力をするにしてもそれは考え・思考を持って戦略的に努力をしていくことが求められます。

そして、その努力はスキルの熟練度で負荷を決めていくのがいいとされています。熟練度が初期、中期、後期の段階で努力の戦略は全く大きく異なります。ここを意識しないでただがむしゃらに努力することでは、才能人たちより高い成果を得ることはできません。

https://i.gyazo.com/37abea97351db29184df23371e65a849.png

GRIT初期 (才能×努力のはじまり)

まずは0の地点からスキルを生み出していく段階です。この段階で重要なことは興味あることを好きにする段階です。興味があることに対して途方もない努力をするのではなく、興味があること状態を好きである状態にすることが大事です。誰しもが最初は興味本意で始めます。その興味は後に大きな成果につながるかもしれません。例えば、今やチャンネル登録者数1000万人を超えたヒカキンさんでさえ、最初はほとんどチャンネル登録者数が伸びない、YouTubeでビートボックスを演奏するYouTuberでした。しかし、YouTubeの活動を楽しみYouTubeが好きになりいろいろなYouTube活動をされた結果、チャンネル登録者数1000万人という大きな成功を達成しました。

https://i.gyazo.com/0de1f4edc30baac65033be1e474d9736.jpg

ヒカキンさんがここまで成功したのはYouTube活動を楽しむことにフォーカスされたからだと思います。つまり、動画を何本も週に無理して投稿し続けるのではなく、無理せずに弱ストレスで動画投稿をしていたのです(多少無理はしていたかもしれませんが、、、)。これが強ストレスで毎日投稿をずっと続けていたら大変負荷が強くYouTubeをやめていたかもしれません。最初から好きでないものに対して強ストレスで取り組んだら、簡単に挫折してしまいます。ましてや後々成果につながったかもしれない興味あるものを諦めてしまうということにさえなってしまうのです。よってスキルにしていくことを意識せずそれ自体を楽しむことから始めます。なのでハードルは下げて楽しむことに集中しましょう。

https://i.gyazo.com/e0deb1a73d4493bc7b3e3c20efa16f83.png

GRIT中期 (才能 × 努力のゴール)

中期段階では好きになったものを成果が出せるスキルに仕上げていきます。いつまでも弱ストレスで楽しむことに集中するわけにもいきません。弱ストレスを強ストレスにして成長速度を早めていきます。ここで成長速度を上げるために必要なものとして、「意図的な練習」というものがあります。

https://i.gyazo.com/ec8a3571c729ab0a9eebb2857c8fd72b.png

意図的な練習とは「ストレッチ目標」を立ててそれに向かって努力することです。ストレッチ目標とは弱点克服のための難易度が高い目標のことです。例えば、自分の好きなことが本を読みこのようにブログにアウトプットすることだとしましょう。この時本を読むスピードが遅いとその好きなことは低いスキルのままです。そこで、本を読むときに制限時間を3時間と設定して読み切るというストレッチ目標を立てます。それにより負荷の高い努力ができ、また弱点克服という意味のある努力であるため、スキルを高める上で最適なストレッチ目標と言えるでしょう。このような弱点克服のようにスキルを高めるために変化を意図した練習があるかないかでそのスキルの成長は大きく違ってきます。

https://i.gyazo.com/ce7b727b38c8fef4c560873716616593.png

GRIT後期 (達成の最大化)

いよいよ成果を生み出すためのスキルを獲得しました。これを成果に繋げます。しかし、前述した通り成果を出すためにも粘り強い努力が必要です。そしてその成果はすぐには出ません。継続的に努力していくことが必要です。

ここで重要なことは、スキルを持って誰かの役に立つ方法がないかを探し、見つけたらそれに向かって努力することです。この人に影響を与えることを目標とした努力を自己超越目標と言います。獲得したスキルで成果をあげようと思ってもそれが結果につながるかわかりません。時間を費やしたのに成果が出なければやる気を失い挫折してしまいます。せっかく獲得したスキルが無駄になってしまいます。

なので、誰かのためにスキルを役立てることは継続的な成果につながります。その成果が小さくても成果は生まれるので成功体験を手に入れられます。そして、さらなる成功体験を手に入れるために努力を続けます。自己超越目標を達成し続けることで継続的な努力(GRIT)を可能にするのです。

https://i.gyazo.com/a06dbb69a3acc4ebdb13bed41c19514f.png

終わりに

次回はまたRailsあたりに戻ります。

【無職に転生 ~ 就職するまで毎日ブログ出す_14】【jQuery】使ったことなかったので基礎中の基礎だけ学習しました。

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

jQueryをアウトプットします!「え、今更?w」みたいな反応になるかと思うのですが、いやほんとにjQueryって結構読めないなってなりました。自分はVue.jsは使えるのですが、jQueryは全く使ったことがありません。そして、現在チーム開発のプロジェクトではRailsjQueryが導入されており、自分は途中から参加したので全くコードが読めていません笑。なので少しでも理解しておいた方がいいので、このブログにて基本を上げておきます。

jQueryとは

参考にした記事では以下のように説明しています。

jQueryJavaScriptのためのライブラリです。jQueryを使用することでシンプルにJavaScriptを記述できるようになり、それまで数十行にわたるコードが必要だった処理もわずか数行で実行できるようになりました。

【初心者向け】jQueryとは|メリット・デメリットから記述方法まで解説|IT・ものづくりエンジニアの転職・派遣求人情報なら【パソナテック】

生のJavaScriptの書き方って確かにすごい冗長だなって思っていました。例えばHTMLの文字を変えるだけでもまずは要素を取得し、

const hoge = document.getElementById('hoge');

その後に要素を変更する記述を書きます。

hoge.innerHTML = '置き換えた文字';

たったこれだけでも2行は必要です。しかし、jQueryの場合以下のように書くだけです。

$('#hoge').html('置き換えた文字');

このようにJavaScriptで各コードを短く書くことができるのがjQueryです。

$について

普通ののJavaScriptと異なる点として$(ドルマーク)がめっちゃ多いなって思いました。例えば下記のような感じ。

$(document).ready(function() {
 $("p").css("color", "blue");
});

$("p")とかなんやねん!」と思っていたのですがそこまで難しいものではありませんでした。

$ = jQuery と等しい

jQueryのドルマーク ($)の意味とは?その意外な正体 | PisukeCode - Web開発まとめ

毎度呼び出す度に「jQuery」と書いていては非常に冗長になります。

jQuery(document).ready(function() {
 jQuery("p").css("color", "blue");
});

よってドルマークの1文字で代用できるようにしているんですね。

IDを指定したい場合は「#ID名」で指定します。例えば、IDがhogeである要素を指定する場合は下記のようになります。

$('#hoge')

クラスの場合「.クラス名」で指定します。

$('.fuga')

要素を指定した後はチェーンメソッドで実行したい処理を記載します。

$('#hoge').css("color", "blue");

jQueryで使えるメソッド

メソッド一覧は下記サイトを参考によく使いそうなものをピックアップします。

jQueryの「メソッド一覧」と使い方 - STAND-4U

.css()

上述したように指定した要素にスタイルを直接追加します。

$("#hoge").css("color", "blue");

複数のスタイルを一度に追加したい場合は、{}で囲いスタイルとそのプロペティの間に:を挟むことで実現できます。

$("#hoge").css({"color":"blue", "margin":"2rem"});

.hasClass()

要素に引数のクラスが含まれているかどうかを真偽値で返すメソッドです。if文と一緒に併用されるかなと思います。

if($("#hoge").hasClass('clicked'))

.toggleClass()

指定したCSSクラスが要素に無ければ追加し、あれば削除します。クラスを追加するaddClassや削除するremoveClassもあるのですが、toggleClassはどちらも行えるので便利です。

$("#hoge").toggleClass("fuga");

.append()

各要素に引数で指定したHTML要素を追加します。

$('#hoge').append("<b>Hello</b>");

基本的には何かを作成した時にそれをリダイレクトせずに要素だけを追加したい場合に使われます。例えばコメントを作成した時にリダイレクトなしに作成したコメントを追加する場合などです。

$('#hoge').append(comment) // commentには作成されたHTMLが格納されている

.val()

引数がない場合、要素のvalueを取得できます。valueですのでinputなどのフォームの値を取得します。

const hoge = $("input").val();

引数を指定する場合はフォームの値を変更します。

$("input").val("変更した値");

jQueryは早く開発したい時のみ使用

jQueryのメリットとしては学習コストがかなり低いところにあると思います。他のJSフレームワークであるVue.jsやReactはかなり元のJavaScriptとは記述方法が異なるのでそのぶん慣れるまでの時間がかかります。ですので、例えば初学者の方達が集まるチーム開発や本当にベータ版で早くリリースしたい時には便利です。

しかし、jQueryは使われなくなっていることは間違いありません。なので、モダンな開発現場ではほとんど使われないため、特にWeb系で働く場合はjQueryを全て理解する必要はなく、使う時にググって解決する程度でいいかなと思います。

終わりに

次回はビジネス本をアウトプットしようかなと思います。

参考記事

jQueryのドルマーク ($)の意味とは?その意外な正体 | PisukeCode - Web開発まとめ

【初心者向け】jQueryとは|メリット・デメリットから記述方法まで解説|IT・ものづくりエンジニアの転職・派遣求人情報なら【パソナテック】

jQueryの「メソッド一覧」と使い方 - STAND-4U