OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntuでalt+wasdにカーソルキーのショートカットを割り当てる

# Ubuntuでalt+wasdにカーソルキーのショートカットを割り当てる
## はじめに
PCでFPSやTPSをやったことがある人なら、wasdキーで移動というのは当たり前なことだと思います。
私もフォートナイトをやっていたのでwasdキーでキャラクターを操作していました。

wasdキーでカーソル移動できたら、ホームポジションを崩さずカーソル移動できて便利なのではと思いやってみました。

## 環境
OS: Ubuntu20.04

## 設定方法
`xmodmap`というユーティリティーを利用して設定していきます。
キーボードにはkeycodeが割り当てられており、それを上書きすることでキーを押したときの挙動を変更することができます。

まずはキーコードを調べます。`xev`というコマンドで直前に押したキーのkeycodeを確認することができます。

```shell
$ xev

# aキーを押すと以下のように出力される
KeyRelease event, serial 37, synthetic NO, window 0x7a00001,
    root 0x6c5, subw 0x0, time 215752625, (106,542), root:(2124,656),
    state 0x0, keycode 38 (keysym 0x61, a), same_screen YES,
    XLookupString gives 1 bytes: (61) "a"
    XFilterEvent returns: False

```
`a`に`38`というkeycodeが割あたっていることがわかりました。
次に現在aキーに割り合っている入力を確認します。

```shell
$ xmodmap -pke | grep 38
keycode  38 = a A a A
keycode 138 = SunProps NoSymbol SunProps
keycode 238 = XF86KbdBrightnessUp NoSymbol XF86KbdBrightnessUp
```

`keycode38`に`a A a A`が割当っていることがわかります。
これは左から
1. `keycode38`のみを入力した場合に入力される値
2. `shift + keycode38`を入力した場合に入力される値
3. `mode_switch + keycode38`を入力した場合に入力される値
4. `shift + mode_switch + keycode38`を入力した場合に入力される値
という意味です。


ではあとはこれを上書いていきます。
まず、`mode_switch`を右Altキーに当てはめます。
先程同様、`xev`で右Altキーのkeycodeを確認します。
右Altキーのkeycodeは`108`です。

以下のコマンドで上書くことができます。

```shell
$ xmodmap -e 'keycode 108 = Mode_switch'
```

続いて`mode_switch+keycode38`と`shift+mode_switch+keycode38`に`Left`を割り当てます。

```shell
$ xmodmap -e 'keycode 38 = a A Left Left'
```

コマンド実行後に右alt+aを押すとカーソルが左に移動した思います。
以下同様にwsdにも適用します。


最終的に以下のコマンドを実行します。

```sh
$ xmodmap -e 'keycode 108 = Mode_switch'
$ xmodmap -e 'keycode 38 = a A Left Left'
$ xmodmap -e 'keycode 25 = w W Up Up'
$ xmodmap -e 'keycode 39 = s S Down Down'
$ xmodmap -e 'keycode 40 = d D Right Right'
```

カーソル移動がAlt+wasdでも可能になったと思います。
他にもいろんなキーを割り当てるともっと便利になるかも知れません。
Microsoft Graphでメールを自動送信するスクリプトを作る

メールボックスにテスト用のメールをぶち込みたくて、とりあえずメール送信を自動化するスクリプトを作成した。

※ 2020/07/31 スクリプトを一部修正しました。


手順は、大まかに以下の通り。

1. Microsoft 365の用意
2. Microsoft 365のAzure Active Directoryにアプリケーション登録
3. スクリプトの作成

最終的に出来上がったコードは以下。

```powershell
$header = @{"Content-type"="application/x-www-form-urlencoded"}
$body = @{client_id='<input-your-clientID>';scope='https://graph.microsoft.com/.default';client_secret='<input-your-secret';grant_type='client_credentials'}
$url = "https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/token"

$response = Invoke-WebRequest -Headers $header -Method Post -Body $body $url

$json = ConvertFrom-Json $response.Content
$token = "Bearer " + $json.access_token

$header2 = @{"Content-type"="application/json";"Authorization"="$token" }
$body2 = '{"message": { "subject": "Meet for lunch?", "body": {"contentType": "Text", "content": "The new cafeteria is open."},"toRecipients": [{"emailAddress": {"address": "<input-receiver-mailAddress"}}],"ccRecipients": []},"saveToSentItems": "false"}}'
$url2 = "https://graph.microsoft.com/v1.0/users/{input-sender-mailAddress}/sendMail"

$response2 = Invoke-WebRequest -Headers $header2 -Method Post -Body $body2 $url2
$response2.StatusCode

```
※ 動かなかったらごめんなさい
アプリケーションIDなどは、以下の2章にあるリンク先のページを読めば、何を指定すればいいかわかるはずです。
(Azure Active DirecrtoryのアプリのアプリケーションID、テナントID、クライアントシークレットなんだけどね)

$response2.StatusCodeが202なら成功。
ちなみに、MFAが有効なユーザーを送信者に指定しても、メール送信できた。

以下、大まかに作成に至るまでの流れ。

#1. Microsodt 365の準備
今回は開発者用の無償サブスクリプションを使用しました。テストユーザーも自動で作ってくれるし、らくちん。

#2. Microsoft 365のAzure Active Directoryにアプリケーション登録
スクリプトからメール送信するためには、リクエストにトークンを付与する必要がある。
以下のページに従って準備する。
https://docs.microsoft.com/ja-jp/graph/auth-v2-service?view=graph-rest-1.0

ただし、以下の点だけページとは異なる。
(1) トークンの応答を受け取るためのサービスのリダイレクト URLは、特に指定しなくていい。
(2) **Microsoft Graphのアクセス許可で、Mail.Sendを許可。**

#3. スクリプトの作成
以下のページに従って作成。
https://docs.microsoft.com/ja-jp/graph/api/user-sendmail?view=graph-rest-1.0&tabs=http

#4. 最後に
あとはまあ、この処理をテキトーにループさせてやればいいんじゃなかろうか？
ただ、Graph APIは10分間に10000回のコールだとか、メール受信は1時間に3600回までだとかいろいろ制限があるし、
そもそも短時間に大量のリクエストを出すと危険だし迷惑なので、ループで回すときは
(1) 無限ループにならないようにする
(2) 送信と送信の間にインターバルを数秒とる
などして、攻撃と誤認されないような工夫をしましょう････

あと、プロキシ環境下では試してないけど、たぶん使えなさそう。

以上！
リポジトリ内で自作した GitHub Actions を直接実行する

# 使うタイミング

- 公開アクションのテストを行いたいとき
- プライベートリポジトリでアクションを自作して実行したいとき

# やり方

## 実行したいアクションの準備

GitHub Action を実行するために、設定ファイルと実行ファイル(Javascript or Docker)を用意する。

### action.yml

Javascript アクション設定ファイルの例

```yml
name: "sample"
runs:
  using: "node12"
  main: "dist/index.js"
```

## アクション実行用の設定を書く

### 注意点

- 自作アクションの実行前に `actions/checkout@v2` を実行しておく
- `uses` で **action.yml** のディレクトリを指定することで実行できる

### .github/workflows/sample.yml

```yml
name: Sample
on:
  push

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
    - name: Checkout
      uses: actions/checkout@v2
    - name: Sample
      uses: ./
```

# ひとこと

できないと思って、**Publish**, **試す**, **バグ発見**, **HotFix**, **Publish**... と無限に無駄なことやってた…
Flutter学習2日目前編 -公式を読む 2. エディターの設定編-

**※自分の学習記録のメモとしてこの記事を書いています。**

[前回の記事](https://qiita.com/umiremix/items/940f38e03be4b71dc33d)に引き続き、公式ドキュメントをまたやっていきます！
今回は[Set up an editor](https://flutter.dev/docs/get-started/editor?tab=androidstudio)ページです。

>add an editor plugin for Android Studio, IntelliJ, VS Code, or Emacs.

（翻訳：Android Studio、IntelliJ、VS Code、またはEmacs用のエディタープラグインを追加します）
と公式に書いてあるのですが、私の場合はおそらく実際に触ることになるであろう、Android StudioとVS Codeの設定をしていきます🏃‍♀️

## Android Studioをインストールする

既にインストール済みだったのでスキップ。

### FlutterとDartプラグインをインストールする

この辺もしかしたら公式の情報古いかも…？なのでアレンジした内容になります。

1. Android Studioを起動します
2. ツールバーの「Android Studio」＞「Preference」を選択

<img width="249" alt="スクリーンショット 2020-07-30 15.53.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/ccfd6225-4526-dcb7-99e1-2c8a85947def.png">
3. Pluginsを選択
<img width="1109" alt="スクリーンショット 2020-07-30 15.56.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/89868a94-f9af-1ac2-71ac-473aad6de59b.png">
4. Flutterプラグインをインストール
<img width="1109" alt="スクリーンショット 2020-07-30 15.57.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/ceb181df-a9da-7a06-8063-8d3c5709eb57.png">
5. Dartプラグインをインストール（私の場合は既にインストールされていました）
<img width="1109" alt="スクリーンショット 2020-07-30 15.58.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/09818a00-b715-7cb9-a33b-94c7a467cb8e.png">
6. インストールが完了したら再起動してプラグインをONにします

## [VS Code](https://code.visualstudio.com/)のインストール

既にインストール済みだったのでこちらもスキップ。

### FlutterとDartプラグインをインストールする

1. VS Codeを起動
2. ツールバーから「View」＞「Command Palette」を選択

<img width="274" alt="スクリーンショット 2020-07-30 17.42.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/6d5fcc1b-fd20-b96c-122d-6f83363dea6c.png">
3. 「install」と入力して「Extensions: Install Extensions」 を選択
![スクリーンショット 2020-07-30 19.19.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/42f41cba-09b1-a16b-1db4-d4002dde5466.png)
4. 検索に「flutter」と入力し、Flutterをインストールします（このとき同時にDartもインストールされるそうです）

### flutter doctorで設定を検証する

1. 再びツールバーから「View」＞「Command Palette」を選択
2. 「doctor」と入力して「Flutter：Run Flutter Doctor」を選択
![スクリーンショット 2020-07-30 19.43.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/21241627-d59a-e9f4-1281-f3c324051ee1.png)
3. 本来ならば下記のようにOUTPUTタブに結果が表示されるんですが、ここでDartから「flutterSDKのパスが通ってない」とお叱りのエラーを受けました👻
公式のパスの通し方だとどうやら不完全のようでした…。（※前の記事の内容は修正済み）パスを修正して改めて実行して無事OUTPUTに表示ができました。
![スクリーンショット 2020-07-30 23.55.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62182/afb57ca2-0c21-7a3d-0133-d55fda644a82.png)

# 感想
ちょっとずつ公式ドキュメントで間違ってたり足りない情報が出てきて、Qiitaにメモしておいてよかった〜と思えるようになりました😂

後編では[ホットリロード](https://flutter.dev/docs/get-started/test-drive?tab=vscode)をやっていきます🔥🔥🔥
ブートローダーのインストールに失敗したときにディスクを消し飛ばす前に確認すること

# はじめに
最近Manjaroをインストールしようとしたのですが、

```
Boost.Python error in job "bootloader".
Command 'grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=Manjaro --force' returned non-zero exit status 1.
Installing for x86_64-efi platform. Could not prepare Boot variable: No space left on device
```

というエラーが出て失敗しました。
"No space left"から/boot/efiのためのパーティションが小さすぎるのかと考えディスクを全消去しやり直しても改善せず、更にはkubuntuのインストールも試して同様にブートローダーのインストールで失敗しました。
一応kubuntuのインストールは成功したので今回の問題の対処法を共有します。

# 最初に確認すべきこと
※マニュアルにも書いてあることです
特に自分でパーティションを設定する場合の注意事項ですが、/boot/efiのためのパーティションはファイルシステムを**FAT32**に設定する必要があります。マウントポイントも**/boot/efi**を選択し、**bootフラグ**を付与することも必要です。
パーティショニングを自動で行う場合などは自動的に上記の設定になると思うのでおそらくあまり気にする必要はありません。

# それでも冒頭のエラーメッセージが出る場合
[参考　ArchWiki Unified Extensible Firmware Interface](https://wiki.archlinux.jp/index.php/Unified_Extensible_Firmware_Interface)

まずはターミナルを起動し

```bash
ls /sys/firmware/efi/efivars/dump-*
```
でdumpで始まるファイルの有無を調べます。自分の場合はこれが大量に存在し容量を圧迫していました。
"No space left"と言われていたのはこれのことだったようです。ディスクを全消去したところでこのフォルダの中身までは綺麗になりません。
(sudo) rmで削除することができるのでdumpで始まるファイルを削除します。
この後kubuntuのインストールを試したところ無事に完了しました。
（Manjaroは後日試します）

# おわりに
自分が件のエラーメッセージを検索にかけたところ、ヒットしたのは主にパーティションのファイルシステムやフラグ付与の話でした。
dumpファイルの存在にもっと早く気づいていればわざわざ全削除までしなくても良かったなあと思っているので同様の症状に悩む方の参考になれば幸いです。
[rails]Controllerにアクションを追加する方法

# Controllerにアクションを追加するには
controllerを作成したあとは、アクションを記述する必要があります。
アクションとはコントローラに定義されている処理内容です。ユーザーが実際に呼び出して使います。

アクションはcontrollerファイルに対して、こんな感じで記述します。

topページを表示したい場合
def~の後は表示したいviewページの名前になります。

```
class HomesController < ApplicationController
  def top

  end
end
```

defはdefine(定義する)を意味します。
docker buildがどんなコマンドなのかメモ

## 一文で説明すると
docker fileがあるディレクトリに対して
docker buildすることでdocker imageが作り出される。



#### ※補足
- docker build
docker fileがあるディレクトリに対してdocker buildすると、ディレクトリごとdocker deamon（ドッカーデーモン）に渡されて、docker deamonからdocker imageが作り出される。

- docker fileとは
docker imageを作るための設計図が書かれているファイル。

- docker imageとは
コンテナを作るための道具。
docker run <コンテナID>　コマンドを実行することでコンテナが作られる。
Angularで特定のルートにデータを持たせる

## はじめに
Angularでは、Routeという個々のルートを定義するオブジェクトがあり、そこにユーザーが追加定義できるdataというプロパティがあります。これを使って、ActivatedRouteを介してコンポーネントに何らかのデータを渡すことができます。

## 環境
Angular 9.1.7

## 1.特定のパスにデータを持たせる
ルーティングを設定するモジュールでRouteオブジェクトにdataというプロパティを持たせます。

```ts:app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'notes',
    // dataを追加
    data: {
      showFooter: false,
    },
    loadChildren: () =>
      import('./notes/notes.module').then((m) => m.NotesModule),
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }
```
## 2.ActivatedRouteを使ってコンポーネントにデータを渡す
RouterのイベントをforEachで回し、ActivatedRouteのプロパティのfirstChildにあるdata、つまり現在表示されているコンポーネントのRouteオブジェクトのdataプロパティを読み取ります。

```ts:app.component.ts
export class AppComponent {
  showFooter: boolean;

  constructor(
    private router: Router, 
    private activatedRoute: ActivatedRoute
    ) {
    this.router.events.forEach(event => {
      // routerイベントのNavigationEndの時に
      if ((event instanceof NavigationEnd)) {
        // アクティブなrouteをsnapshotで静的な状態として取得、routeの一階層下firstChildを指定
        this.showFooter =
          // false以外ならtrueにする 
          this.route.snapshot.firstChild.data.showFooter !== false;
      }
    });
  }
}
```

以上でコンポーネントにRouteのdataを渡すことができました。
## 使用例：ヘッダーやフッターを非表示にしたい時
- 最上層のAppModuleでヘッダーやフッターを読み込んでおり、特定のモジュールで非表示にしたい場合、data内のプロパティを使うことで切り替え、非表示にすることができます。

```html:app.component.html
<app-footer *ngIf="showFooter"></app-footer>
```

## 参考記事
- [Angular 日本語ドキュメンテーション - Route](https://angular.jp/api/router/Route#data)
- [Angular 日本語ドキュメンテーション - ActivatedRoute](https://angular.jp/api/router/ActivatedRoute#firstChild)
- [Angular2/5　ページタイトルをパスに対応したものに動的に変更する](https://qiita.com/mt_middle/items/ca8d24779bb9f5ca462e)
MacでHomebrewを使えばEclipseがなくてもすぐTomcatを使える

#Tomcatの環境設定で困りませんか？
MacでTomcatの環境設定をする際、Tomcatのtar.gzまたはzipファイルを公式サイトからダウンロードしてjava_homeやcatalina_homeのパスを色々設定したりと色々めんどくさくて、嫌になりませんか？

私は一度嫌になって、Eclipseに頼りました。でもEclipseも不具合があったら、また問題を見つけるの大変そうだなと思いました。

そこで、今回一番シンプルなTomcat導入方法を見かけたので紹介します。

#ソース

Installing Apache Tomcat on MacOS Mojave using Homebrew(2019/8/29)
https://medium.com/@fahimhossain_16989/installing-apache-tomcat-on-macos-mojave-using-homebrew-28ce039b4b2e

#設定方法

「Installing and Running Apache Tomcat on Mac OS using Homebrew」の見出しから参照してください。(cask云々と書いてある箇所は割愛して進めました。)

###Step1：Tomcatをインストール

Tomcatのインストールのために以下のコマンドをターミナルで実行します。

<pre>brew update
brew install tomcat</pre>



###Step2：Tomcatを開始する<br><br>


Homebrewのコマンドを使って、自動的に開始(停止)する場合は以下のコマンド






<pre>brew services start tomcat
brew services stop tomcat
</pre>

マニュアルでTomcatを開始(停止)する場合は以下のコマンド

<pre>catalina run
catalina stop</pre>


以上で、Tomcatを開始することができます。

<pre>
Last login: Thu Jul 30 22:52:31 on ttys001
AkihironoMacBook-puro% catalina run
Using CATALINA_BASE:   /usr/local/Cellar/tomcat/9.0.37/libexec
Using CATALINA_HOME:   /usr/local/Cellar/tomcat/9.0.37/libexec
Using CATALINA_TMPDIR: /usr/local/Cellar/tomcat/9.0.37/libexec/temp
Using JRE_HOME:        /usr/local/opt/openjdk
Using CLASSPATH:       /usr/local/Cellar/tomcat/9.0.37/libexec/bin/bootstrap.jar:/usr/local/Cellar/tomcat/9.0.37/libexec/bin/tomcat-juli.jar
NOTE: Picked up JDK_JAVA_OPTIONS:  --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED
.
.
.
.
31-Jul-2020 00:08:31.077 情報 [main] org.apache.catalina.startup.HostConfig.deployDirectory ディレクトリ [/usr/local/Cellar/tomcat/9.0.37/libexec/webapps/host-manager] の Web アプリケーションの配備は [18] ms で完了しました。
31-Jul-2020 00:08:31.080 情報 [main] org.apache.coyote.AbstractProtocol.start プロトコルハンドラー ["http-nio-8080"] を開始しました。
31-Jul-2020 00:08:31.090 情報 [main] org.apache.catalina.startup.Catalina.start 
サーバーの起動 [829]ms
</pre>
Excelリンク集、Tips集(適宜更新中)

社会人エンジニアになってからExcel使う事が激増し、Tipsが溜まっているのでここで少しずつ放出していきます。

## 改行

* [Excelにテキストで貼り付けるときにセル内改行させる方法 - Qiita](https://qiita.com/iwason/items/8b0294bd1cf3497b33a2)

## 検索

* [「*」と「?」を検索する | 日経クロステック（xTECH）](https://xtech.nikkei.com/it/pc/article/NPC/20060213/229088/)

## 小技

* [EXCELファイルサイズが大きい！重い！容量を軽く小さくする方法はある？](https://excelkamiwaza.com/excel_file_size.html)
* 指定行にジャンプするショートカット：`Ctrl` + `G`

## VB

### VBE

#### VBEの起動
- リボンから起動
  - オプションから「開発」リボンを追加
  - リボンの「開発」→「Visual Basic」

- ショートカット
  - Alt + F11

#### 標準モジュールの追加
- メニューの「挿入」→「標準モジュール」(ショートカット：Alt + I + M)

もしくは

- プロジェクト内を右クリックで「挿入」→「標準モジュール」

### VBA

#### VBAでのメモリの解放

nothingを使うことで解放
(オブジェクト変数に参照情報が代入されていない状態)

```vba:
hoge = nothing           'オブジェクト以外の場合
set hogeobject = nothing 'オブジェクトの場合
```
テーブルのタグについて

###テーブルのタグについて
テーブルタグがは料金表や事業の内容などを読者に見せたい時に使うと非常に見やすく、制作の時も便利なタグである。

##tableタグ
tableタグは、中がtableタグであると定義する時に使う。この中にテーブルを書いていく。

##theadタグ
テーブルの上部を記述する時に、使うタグ。

##tbodyタグ
テーブルを書く時に使うタグ。

##tfootタグ
テーブルの下部に記述する時に使うタグ。いつの情報かを記述したりする。

##trタグ
テーブルを書く時にthやtdを囲うタグである。

##thタグ
テーブルの見出しなどに使う。

##tdタグ
テーブルの内容を記述する時に使う。

##details
ユーザーが情報を得たい時に使う。

##summay
detaiilsタグの中に使用して、追加の情報などを見てもらう時に使用する。

##scope属性
タグではないが、rowとcolがありそれぞれ縦列と横列で結びついているということを示す。
GitHubにコミットしても草が生えない時の対処法

先日いつも使っているMacBookを修理に出したため、違うデスクトップのiMacでプログラミング学習をしていました。
その際、いつも通りGitHubにコミットしてみると、なぜか草が生えない…
よく考えるとPCを変えたので、ローカルリポジトリのメールアドレスとGitHubのアカウントの紐づけをしていない！ ということに気付きました。
ということで、この際なのでQiitaに紐づけの方法を書くことにしました。

# 紐づいているか確認する
まず、ローカルリポジトリのメールアドレスとGitHubアカウントが紐づいてるか確認します。
コミットしたディレクトリに移動し、以下のコマンドを実行します。

```
$ git config user.email
```
実行後、ご自身がGitHubに登録しているメールアドレスが表示されない場合は紐付けができていません。

# 紐づける
どこのディレクトリでも良いので以下の2つのコマンドを実行してください

```
$ git config --global user.name "GitHubに登録しているユーザー名"
```
ダブルクォーテーションありです。
<br>

```
$ git config --global user.email GitHubに登録しているメールアドレス
```
ダブルクォーテーションなしです。

これで、紐づけ完了です。
コミットしたディレクトリに移動し、もう一度以下のコマンドを実行すると、GitHubに登録しているメールアドレスが表示されるはずです。

```
$ git config user.email
あなたのメールアドレスが表示される
```
これでGitHubにコミットすれば草が生えます。

また、新しく作成したディレクトリなどにも、この紐づけは適用されるので、次回以降はこの作業はいりません。

# 参考記事
https://yshrfmru.hatenablog.com/entry/2018/11/28/213315
仮想サーバーのメリットとデメリット

#仮想サーバーのメリット

- 物理的なサーバーの台数を減らすことで、設置スペースを削減できる。

- サーバー機のリソースを最大限に活用することができる。

- 新しいサーバーを簡単に導入できる。

#仮想サーバーのデメリット

- 1台の物理サーバーにあまりに多くのサーバー機能を持たせると、パフォーマンスが低下してしまう可能性がある。

- オーバーヘッド(本来の処理に加えて、余分にかかる負荷のこと)が起きる可能性がある。


####※仮想化により集約するサーバー機能を適切に選択したり、仮想化後の利用イメージを明確にしたりするなどして、全体のパフォーマンスが落ちない運用を考える必要がある。
HTTPステータスコードとユニークな404ページいろいろ

こんにちは！
今回はHTTPステータスコードと404エラーについて、お伝えしていきたいと思います。
後半はおまけで404ページをピックアップしていきたいと思います。

## HTTPステータスコードとは
ウェブサイトを閲覧するウェブブラウザから送られるリクエストに対し、ウェブサーバーから返信されるレスポンス内容を表す３桁の数字のこと。

|HTTPステータスコード  |意味  |具体的な説明  |
|---|---|---|
|100番台  |継続  |リクエストに対し、処理が継続されていることを指す  |
|200番台  |リクエスト完了  |リクエストを正しく受理したことを表す  |
|300番台  |リダイレクト（移行）  |リダイレクトや移行など、リクエストを達成するために、追加の処理が必要と返信している状態  |
|400番台  |リクエスト失敗  |リクエストが正しく処理できていない状態　  |
|500番台  |サーバーエラー  |サーバーに問題があり、エラーとなる状態  |

## 404エラーとは
上記の400番台のエラーの一つです。
ブラウザからのリクエストに対して、指定したURLは今現在存在しないページであることを意味します。
404ページとは、サーバーから404エラーが返された場合に表示するページのことです。
おそらく一度は目にしたことがある人が多いのではないのでしょうか。


#### 世の中にはオシャレな404ページがたくさん
「404 デザイン」「404 design」などで検索すれば、たくさん出てきますが、せっかくなのでいくつかピックアップします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/30b76a2f-3482-1e96-e799-2fd7479b28bc.png)
(参考：広島県HP）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/d8e99dd9-0050-581f-38e8-6c45ad8fcd36.png)
(参考：Marvel)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/85f9f6c8-c371-1b8e-eae3-c5210587cf1e.png)
(参考：LEGO)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659719/289a7201-e1ec-d06d-ad59-6168dd2aea9c.png)
(参考：Spotify)

いろいろ見ていると、謝罪文を入れた真面目な404ページから、ちょっとふざけているサイト、激しいアニメーションページなど、どれもサイトの味が出ていて面白いです。

皆さんも興味があれば、いろいろ調べてみてください。

## 参考URL
https://digital-marketing.jp/seo/http-status-code/
大変参考になりました。ありがとうございます。
git-todosはいいぞ

みんなー！進行中のプロジェクトのTODOを管理するのに苦労してるー？
シンプルかつ合理的なツールを見つけたので紹介するよー！

これ -> [git-todos](https://github.com/z0al/git-todos)
last commitが3 years agoでスター数54なのでもう誰もメンテしてない感あるけど、そのシンプルさゆえか問題なく使えました。

他にも見つかったものとして、ソース中の`TODO` `FIXME`的な文字列を検索してリスト化してくれるやつ[(git-todo)](https://www.npmjs.com/package/git-todo)もあったけど、僕の場合は以下の理由でTODOはソースとは別に管理したかったのでgit-todosの方を選びました。

- TODOコメントを書く習慣がない
- TODOコメントを書く時に、ツールを通したときにどう見えるのかを気にしたくない
- TODOコメントをどのファイルのどの位置に置くのが適切かを考えたくない
- TODOの消化とcommitを明示的に結びつけたい

個人とか小人数の小規模プロジェクトだとgit-todosの方が良い気がしたけど、ある程度大規模だともしかしたらgit-todoの方がぴったりハマるのかもしれない。
**(名前ややこしいな)**

以下git-todosの使い方紹介。

## TODOの追加
`git todos add`を叩くと対話的にTODOが作成される。
ここで設定するTitleとDescriptionはそのまま、TODOを消化する時のコミットコメントのデフォルト値として使える。

```sh
$ git todos add
? Title (Required) create readme
? Description with very first greetings
✔ A Todo has been added
✔ You rock! 🚀
```

## TODOの管理
`.todos.yml`というファイルが生成され、そこにTODOのリストが記入される。
手動で変更しても良い。

```yml
todos:
- title: create readme
  description: with very first greetings
  marked: false
  id: 0
todos:
- title: add .gitignore
  description: to keep secrets secret
  marked: false
  id: 0

```

CLIからは`git todos list`で表示できる。（なぜかアルファベット順になる。）

```sh
$ git todos list

1) add .gitignore
2) create readme
```

`git todos show`で個別のtodoを表示できる

```sh
$ git todos show
? Select an item (Use arrow keys) create readme

create readme

with very first greetings
```

## TODOの消化
`git todos finish`を叩くと対話的にTODOを消化できる。
同時に、TODO追加時の`title`と`description`からメッセージを生成しつつ`git commit`もしてくれる。
つまり そのTODOに関係する内容のファイルを`git add`したあとに、`git commit`の代わりに`git todos finish`を叩くといい感じということ。
必要があればGitHubのIssueの解決もしてくれるっぽい。

```
$ git todos finish
? Select an item (Use arrow keys) create readme
? Type of change that you're committing (Required) first import
? Denote the scope of this change readme
? Short description create readme
? Longer description of the change 
? List any issues closed by this change 
✔ Your work has been commited
✔ A Todo has been removed
✔ I see what you did there! 🙏
```

ちなみにその後の`git log`はこんな感じ

```sh
commit a2ae4aee207a3b82bbaa83e218204e054dbe46d6 (HEAD -> master)
Author: nariakiiwatani <nariakiiwatani@annolab.com>
Date:   Thu Jul 30 23:19:49 2020 +0900

    first import(readme): create readme
```
herokuでNode.jsを立ち上げるまでの手順

色々と理解できていないことは多いですが、とりあえずherokuで立ち上げられたので手順を記載。
エラーでまくったしいろんなサイト見すぎてもはや何を参考にしたのかわからなくなってます。


# 前提
① Node.js、herokuはインストール済み
② パッケージマネージャーはyarnを仕様
下記の記事を見てyarnにしました
https://qiita.com/qulylean/items/afa2acff6ed963c88798


# yarnのインストール
上記の記事を参考にyarnをインストールします。

# yarnでhttpモジュールのインストール

コマンドプロンプトを立ち上げて今回作成したいフォルダまでディレクトリの移動をします。

```
フォルダの移動
$ cd フォルダ名

前に戻る
$ cd ..

フォルダの作成
$ mkdir フォルダ名

フォルダを作成して移動
$ mkdir フォルダ名 && cd フォルダ名

ファイルの作成
$ type nul > ファイル名
```

ディレクトリの移動が完了したら下記のコマンドを実行します。

```
$ yarn add http
```

すると必要なフォルダが用意されて下記の状態になります。

```:フォルダ
フォルダ
 ├ node_modules
 ├ package.json
 └ yarn.lock
```

# yarnでexpressモジュールのインストール

次のコマンドを実行してexpressのインストールを行います。

```:expressのインストール
$ yarn add express
```

実行完了すると下記の表示がでるので、package.jsonに記載するためにバージョンだけ覚えておいてください。

```
yarn add v1.22.4
[1/5] Validating package.json...
[2/5] Resolving packages...
[3/5] Fetching packages...
[4/5] Linking dependencies...
[5/5] Building fresh packages...
success Saved 1 new dependency.
info Direct dependencies
└─ express@4.17.1
info All dependencies
└─ express@4.17.1
Done in 3.23s.
```

# package.jsonの変更

初期状態だと下記のようになっていると思います。

```:pakage.jsonデフォルト
{
  "dependencies": {
    "http": "^0.0.1-security"
  }
}
```

それを次のように変更します。

```:pakage.json変更後
{
  "name": "hello_world",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "jade": "*"
  },
  "engines": {
    "node": "12.18.1"
  }
}
```

現在使用しているnodeのバージョンは下記のコマンドで確認が可能です。

```:nodeのバージョン確認
$ node --version
```

# JavaScriptファイルの作成

ファイル名は先程、pakage.jsonで指定したapp.jsにして下記を書きます。

```javascript:app.js
const express = require('express');
const app = express();

const port = process.env.PORT || 5000;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(port, () => {
  console.log('listen: ' + port);
});
```

ここまでできたらまずローカルで動くかを確かめてみましょう。

コマンドプロンプトで下記を実行してください。

```
$ node app.js
```

`listen: 5000` と表示されたらブラウザで下記を開いてください。

```
localhost:5000
```

無事「Hello World!」が表示されていたらOKです。
閉じる場合コマンドプロンプト上でCtrl + C を押すと終了できます。

# Procfileの作成

コマンドプロンプトで下記を実行

```:Procifleの作成
type nul > Procifle
```

作成したら開いて下記を入力

```
web: node app.js
```

最終的には下記のフォルダ構造になります。

```:フォルダ
フォルダ
 ├ node_modules
 ├ package.json
 ├ yarn.lock
 ├ app.js
 └ Procfile
```

# herokuにデプロイ

デプロイするのに書きの順番で実行していきます。

```bash:herokuへのデプロイ
$ git init
$ git add .
$ git commit -m 'init'
$ heroku login
$ heroku create
もしくは
$ heroku create ファイル名
$ git heroku push master
```

次回から更新する際は一度にまとめても記載が可能です

```bash:heroku
$ git add . && git commit -m 'init' && git heroku push master
```

完了したらherokuを開きます

```:herokuを開く
$ heroku open
```

もしくはデプロイ時に出てきた
https://{アプリ名}.herokuapp.com/

をブラウザで開いても大丈夫です。
Hello World!が表示されていたら完了です。


# herokuへのデプロイ時にエラーがでたら

下記のエラーが出た場合はyarnのバージョンが古いためのエラーです。

```
error Your lockfile needs to be updated, but yarn was run with `--frozen-lockfile`.
```

コマンドプロンプトで下記を実行してyarnをアップデートして再度実行してみてください。

```
$ yarn install
```
cargo-makeをrust以外で利用するときの便利tips

[cargo-make](https://github.com/sagiegurari/cargo-make)はrust製のタスクランナーです。
makeより書きやすい(主観)形式のため非常に便利に複雑なタスクを作成できます。

基本cargoに組み合わせて使う想定ですが、バイナリ単体で配布されているため以下のように直接バイナリをインストールすればcargoがなくても利用できます。

```bash
 curl -L -O https://github.com/sagiegurari/cargo-make/releases/download/0.31.0/cargo-make-v0.31.0-x86_64-unknown-linux-musl.zip \
  && unzip cargo-make-v0.31.0-x86_64-unknown-linux-musl.zip \
  && cp cargo-make-v0.31.0-x86_64-unknown-linux-musl/cargo-make /usr/local/bin/cargo-make
```

インストールの依存関係が無いため標準のタスクランナーとしてもおすすめです。
このようにrust意外で利用するときの便利なtipsをまとめました。


## makersで利用可能にする
cargoでインストールすると`makers`コマンドで実行できますが、バイナリで入れた場合は`cargo-make make` と引数`make`を必ず指定しなければなりません。
これは面倒なので以下のように`makers`で`cargo-make make`を呼び出すようにすると便利です。
シェルのエイリアスでも良いですが、この方法だとDockerコンテナ内でもかんたんに使えるのでおすすめです。

```bash
echo '#!/bin/bash\ncargo-make make "$@"' > /usr/local/bin/makers && \
chmod +x /usr/local/bin/makers
```

## デフォルトで用意されているタスクをすべて無効化する
`cargo-make`はcargo用なのでrustプロジェクトでよく使うタスクがデフォルトで大量に用意されています。
ですがrust以外で使うときは必要ないのでまとめて消したくなります。
このような場合、以下の設定をMakefile.tomlに書くことで既存のタスクをすべて無効化でき、
自分で追加したものだけにできます。

```toml
[config]
skip_core_tasks = true
```

## 引数をdocker-composeを起動して実行する
以下のようなタスクを用意すると、 `makers docker_run makers build` のようにdockerコンテナ内で引数のコマンドを実行できます。
手元に開発環境を入れたくない場合やコードジェネレーターなどdockerコンテナ内で実行したいが頻繁に実行するようなタスクを便利にできます。

```toml
[tasks.docker_run]
 category = "develop"
 description = "docker-composeでコマンドを実行します (e.g. makers docker_run makers build)"
 command = "docker-compose"
 args = ["exec", "app", "${@}"]
```
"categorical_crossentropy"と"sparse_categorical_crossentropy"の違い

# 結論
- 使用するラベルが違います。違いはそれだけです。"categorical_crossentropy"にはonehot(どこか１つが１で他は全て０)のラベルを使用します。"sparse_categorical_crossentropy"のラベルには整数を使用します。


# one-hotと整数表現の違い
## 例)10分類の場合

|one-hot表現|整数表現|
|:--------------------------------:|:---:|
|  [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.] | [9] |
|  [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.] | [2] |
|  [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.] | [1] |
|  [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.] | [5] |


# 整数ラベルをone-hotラベルに変換
データセットでは整数ラベルのものが多い印象ですが，損失関数の多くは整数ラベルではなく，one-hotラベルを与えてあげないと動きません．そういう場合は変換する必要があります．(というか，むしろ"sparse_categorical_crossentropy"のように整数ラベルのまま学習できる損失関数が少数派だと感じます．)

以下にコードを記します．

```python
import numpy as np

n_labels = len(np.unique(train_labels))
train_labels_onehot = np.eye(n_labels)[train_labels]

n_labels = len(np.unique(test_labels))
test_labels_onehot = np.eye(n_labels)[test_labels]
```
【Auth0】メールアドレスの確認が済んでいないユーザーのログインを拒否する

# はじめに
Auth0はサインアップ時にログインIDとして登録されたメールアドレスに確認のメールを送ります。
ユーザーが確認メールに記載されているリンクにアクセスすることでメールアドレスのステータスが確認済みとなります。

本記事ではAuth0にRulesを使ってメールアドレスが未確認の場合はログインを拒否することでアプリケーションの利用開始前にユーザーにメールアドレスの確認を強制する方法を紹介します。

# Rulesの設定

管理画面のRulesのページにアクセスし`CREATE RULE`を押して新しいRuleを作成します。

![スクリーンショット 2020-06-18 18.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653972/72b6a625-b633-dba5-fec9-94b09c5dcec9.png)

標準で多数のRuleテンプレートが用意されています。
メールアドレスの確認を強制するRule（`Force email verification`）も標準で用意されているのでこれをそのまま利用します。

![スクリーンショット 2020-06-18 18.40.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653972/e09fc44c-d000-b012-0e99-7f452d93aefd.png)

選択すると以下のコードが展開されるのでこれを保存します。

```javascript:
function emailVerified(user, context, callback) {
  if (!user.email_verified) {
    return callback(new UnauthorizedError('Please verify your email before logging in.'));
  } else {
    return callback(null, user, context);
  }
}
```

このRuleが有効な状態でメールアドレスが未確認状態のユーザーがログインすると`UnauthorizedError`が発生します。
アプリケーション側には以下のようなURLでコールバックされます。

```:コールバック例
https://example.com/callback?error=unauthorized&error_description=Please%20verify%20your%20email%20before%20logging%20in.&state=3ZO2lgVJkICccAxQVvmz9P9o34ccbmeW
```

`error`と`error_description`パラメーターでエラーを判断することができます。

# エラー発生時のアプリケーション側の対応
メールアドレス未確認によってコールバックされたときにアプリケーション側でエラー処理が必要になります。
エラーの内容を読み取ってユーザーに新規登録時に送信したメールの確認を促します。

# エラーメッセージの工夫
コールバックされたときの`error`パラメーターの値だと`unauthorized`としか読みとれません。
他にもエラーを出力する可能性のあるRulesを設定していると`error`パラメーターでは事象を正確に捉えられない恐れがあるので
`error_description`にエラーコードなどを埋め込むことで事象の切り分けをできるようにすることをお勧めします。

```javascript:例
return callback(new UnauthorizedError('[00043] - Please verify your email before logging in.'));
```

参考
https://auth0.com/docs/best-practices/error-handling

# おわりに
ログイン前にメールアドレスの確認を強制したい場合はぜひこのRulesを使ってみてください。
コードのテンプレートが用意されているのでとても簡単に導入できます。
【Laravel】ルートパラメーターを簡単にまとめ

# Laravelのルートパラメータは「必須」と「任意」を覚える

## 必須パラメータ

Laravelのルート定義をする際に、ルートパラメータの設定をする場合があります。
例えば、URLからユーザーIDや記事IDを取り出したい場合、取り出したいURLの部分を{}括弧で囲むことで、その囲まれた部分のパラメーターをコントローラーへ送ることができます。
とまあ、文章で書いてもよくわからないので例文を下記に記述します。

```php
Route::get('user/{id}', function ($id) {
    return 'User '.$id;
});
```
上記の例では、URIが「user/○○」だとした場合にマッチングするルート定義になっています。ルートパラメーターの定義は{id}として記述されていますね。
この場合、{id}にあたる部分である「○○」が$idに格納されます。
なので、上記例の場合、最終的には「User ○○」が出力されます。

ちなみに、上記の例は「必須パラメータ」と呼ばれ、もし{id}の部分がURIに含まれないケースでは、このルート定義にあてはまりません。

## 任意パラメータ
パラメータを指定しても、しなくてもOK！というような、任意でパラメータを入力したいということもあります。
その場合は、パラメータ名の最後に?マークを付けると任意指定可能なパラーメータになります。便利！
こちらも例を見てみましょう。

```php
Route::get('user/{name?}', function ($name = null) {
    return $name;
});

Route::get('article/{name?}', function ($name = 'study') {
    return $name;
});
```
こんな感じで、{name?}のところはURIであってもなくても良いという感じです。
例えば、「user/masahiro」というURIでアクセスした際は「masahiro」と出力されますし、
「article」だけでアクセスした場合は、デフォルト値が適応されて「study」が出力されます。

## パラメータの数は自由に書ける
```php
Route::get('posts/{post}/comments/{comment}', function ($postId, $commentId) {
    // 
});
```
上記のように、必要に応じて{}を使用することでパラーメータの定義可能です。
{post}は\$postIdに対応していて、{comment}は\$commentIdに対応していますね。

参考文献
https://readouble.com/laravel/7.x/ja/routing.html
【Express】ミドルウェアとは何か

##ミドルウェアとは何か
ミドルウェアとは：サーバーの動作をカスタマイズするもの。
ルーターハンドラが作動する前に何かを行うもの。

<h6>・ミドルウェアがない時</h6>

```
新しいリクエスト
↓
通常のルーターハンドラが作動
```
<h6>・ミドルウェアがある時</h6>

```
新しいリクエスト
↓
ミドルウェアが作動！
↓
通常のルーターハンドラが作動
```

##ミドルウェアの設定

```javascript

app.use()
```
を用いて設定する

##ミドルウェアの動作例
・リクエストしているHTTPメソッドと、リクエストを送っているパスをターミナルに表示させる

```javascript
app.use((req, res, next) => {
     console.log(req.method, req.path)　
     next() //ミドルウェア機能の終了を明示的に表示
})
```

<h6>・ミドルウェアを使ってアクセスを制限する</h6>
GETリクエストを送るとアクセスを拒否され、それ以外だと通常のルーターハンドラが起動

```javascript
app.use((req, res, next) => {
  if(req.method === 'GET'){
    res.status(400).send('GETリクエストは使用できません')
  }else{
    next() //ミドルウェア機能の終了を明示的に表示
  }
})
```
Gitで新規リポジトリを作成するあれこれ

# 概要
使い始めの頃と比較して少しずつ慣れてはきたが、毎回リモートリポジトリの作成とpushまでで手が止まるので自分なりのメモ。
~~毎度ググるの面倒くさいですからね。~~

## リモートリポジトリもローカルリポジトリも空の場合

①リモートリポジトリの作成

**GitHub>New Repositories**

- 新規でリモートリポジトリを作成。
- 作成したリポジトリからURL取得。

詳しくはこれ参照。
https://qiita.com/mst_141/items/23828bef5cf6fc68f50d

②ローカルリポジトリの作成

```
$ git init
```

③インデックスに追加

```
$ git add <ファイル/フォルダ>
```

③ローカルリポジトリに登録
（個人的にターミナルからコメントできる方が早くて好き。）

```
$ git commit -m "<メッセージ>"
```

④リモートリポジトリにpush
次回以降「git push」だけで済むように「-u」オプション付き。

```
$ git remote add origin <URL>
$ git push -u origin master
```

## リモートリポジトリを新たにローカルまで持ってくる場合

リモートリポジトリからURL取得してclone

```
$ git clone <リポジトリURL>
```

# まとめ
ブランチ切り替えやリベースなんかも使う機会が多発する頃に再度アウトプット予定。
言語も楽しいけどチーム開発ツールで知見増やすのも楽しい。
バリデーションエラーの表記を日本語表記に変更する方法

学習を進めてる中``Name can't be blank``等のバリデーションエラーを日本語に変更する方法を学んだのでまとめようと思います。

まず日本語の設定にするためのgemをインストールします。

```ruby:Gemfile
gem 'rails-i18n'
```
これだけではまだ変更は完了していません。
config/application.rbに以下の一文を追記します。これにより、サーバ再起動後にエラーメッセージが日本語化されます。

```ruby
config.i18n.default_locale = :ja
```

これにより、サーバ再起動後にエラーメッセージがこのように表示されるはずです。

```
Nameを入力してください。
```
カラムの日本語化自体もできるみたいですが今後実装する際に追記したいと思います。

ちなみに。。。。。

###i18nとは

[Wikipedia](http://qiita.com)によると・・・

>情報処理における国際化と地域化（こくさいか と ちいきか）は、ソフトウェアを開発した環境とは異なる環境、特に外国や異文化に適合させる手段である。

>国際化（アメリカ英語: internationalization イギリス英語: internationalisation、i18n) は、ソフトウェアに技術的な変更を加えることなく多様な言語や地域に適合できるようにする、ソフトウェア設計の工程である。

ソフトウェアの技術的変更なしで様々な言語に対応できるということでしょうか。。
なぜ日本人エンジニアは英語を勉強しないのか

#Why Japanese people?
日本人は英語ができる人が少ない。私自身もそこまでできるわけではない。
しかしエンジニアは英語ができると本当にいいことが多いしとてつもなく強い。

みなさんはこんなコードを書いたことがあるだろうか

```php
#php風
$フルーツ = 'リンゴ';
もし($フルーツ == 'リンゴ' なら){
  出力 'これはリンゴです。';
}
ちがうなら{
  出力 'これはリンゴではありません';
}
```
違和感が半端ない・・・(でもちょっとわかりやすいかも)

もしかしたら気づいていない人もいるかもしれないので改めて言いたい。
**プログラミング言語は英語なのだ。**

何故英語が全くできないのにそれを応用したプログラミング言語にまず飛びついてしまうのだろうか。

#初心者がまず習うこと
エンジニアになった時のことを思い返してみてほしい。
変数というものにどうやら値が格納できるみたいだ。
そして変数は後から何が格納されているかわかるように**意味のある名前**にする必要があるらしい。

しかし現実はどうだろう。
適当に日本語を考えてgoogle翻訳にブチ込んで意味も分からず使っていないだろうか。

**「なんか翻訳したら知らん単語出てきたけど、たぶんそういう意味だからそのまま使おう、最近のgoogle翻訳は賢いからなｗ」**
などと言っていないだろうか。

google翻訳はたしかに優秀だが、結果だけ見ると**意味のわからない言葉を変数に使っている。**初心者が勉強する一番基本的にルールを守れていないのだ。

#横文字、ちゃんとわかってる？
エンジニアの世界では横文字が非常に多い。
HTTPやAPIといった、英語単語の頭文字をまとめた略称も非常に多く存在する。
初心者はまずこういった単語を覚えるのに躓くだろう。

一番のアドバイスは**何の略なのかを併せて覚えること。**
HTTPならHyper Text Transfer Protocolとしっかり覚えることだ。
雑な直訳だが、ハイパーテキストを転送するためのプロトコルなのだ。「http」という文字列、英4文字を覚えようとするから**「htt・・・なんだっけ？」**や**「httpってどういう意味だっけ？」**とわからなくなったりする。

**英語でしっかり覚えれば意味までセットで覚えられるのだ。**

#英語も言語
優秀で意識の高いエンジニアは勉強を欠かさない。
新しい言語やフレームワークが出たら試してみたり、常にアンテナを張って新しい情報をキャッチしようとする。

しかしそういった情報はすべからく英語で書かれている。
せっかく新しい情報をキャッチアップしようとしているのに**日本語記事やまとめが出ている時点でもうそれは新しい情報ではないのである。**

また英語も同じ言語である。
新しいプログラミング言語を勉強する気力があるなら、英語を勉強するという選択肢は決して無駄な寄り道ではないはずだ。

#英語ができない苦労から目を背けない
これは自身にも言い聞かせていることだが、英語から逃げてはいけない。
むしろ向き合うことでいいことが本当にたくさんある。

上記にあげた例は勿論だが、特に私の場合はAWSのドキュメントや学習教材等、英語がわかるから豊富で良質なものに触れることができる。
ITPやGDPRをはじめとする世界の個人情報への見方や各ブラウザプラットフォーマーの政策にいち早くキャッチアップできる。海外の人たちとの会議の場にアサインしてもらう。周りの人から一目置かれる。などなど、たくさんいいことがある。
エンジニアになって間もない時、「プログラム書いてる俺かっけぇ・・・」と誰しもが思ったはずだ。**英語でしゃべっているあなたも、きっとそれ以上にかっこいい。**

業務時間で英語に触れて勉強するのは難しいかもしれない。
それでも特にエンジニアは英語ができない危機感を持つべきだし、英語へ向き合っていくべきなのだ。

英語で記事を読んだりするのはものすごくストレスがかかる。
しかしその苦労の先に見えてくる世界に是非とも触れてほしい。

**世界にはばたくエンジニアになるために！！**
Goでドメインの名前解決を強制的に行う（curl –resolveに相当することを行う）方法

## やりたいこと
Goでドメインの名前解決を強制的に行う。

ドメインの名前解決を外部DNSを通して行うのではなくて自分でIPアドレスを指定して解決したい場合は、通常はローカルマシンのhostsファイルに以下のように記述すればよい。

```
203.0.113.0    google.com  # google.comを 203.0.113.0 に解決させる例
```

hostsファイルを使用する以外だと、`curl`コマンドに`--resolve`オプションというのがあり、以下のように指定することでコマンド実行時に直接名前解決を行わせることが可能だ。

```
curl https://google.com --resolve "google.com:443:203.0.113.0"
```

今回はこのcurlの場合と同様に、hostsファイルを使わずにリクエスト実行時に強制的にドメインにIPアドレスを与えるということをGoでやりたかった。

そもそも可能なのか、可能だとしたらどういう方法でできるのか分からず色々と検索していたら、まさに同じことをやろうとしてた人の[stack overflowの質問ページ](https://stackoverflow.com/questions/40624248/golang-force-http-request-to-specific-ip-similar-to-curl-resolve)を見つけて無事解決した。

## 方法
上記のリンク先に投稿されている回答の通りなのだが、http接続時に使用する`http.Transport.DialContext`をカスタマイズすることで実現できた。

```
func main() {
    dialer := &net.Dialer{
        Timeout:   30 * time.Second, // このへんのタイムアウト設定はこれがデフォルト値
        KeepAlive: 30 * time.Second,
        DualStack: true,
    }
    http.DefaultTransport.(*http.Transport).DialContext = func(ctx context.Context, network, addr string) (net.Conn, error) {
        if addr == "google.com:443" { // 接続先が google.com:443 の場合に、203.0.113.0:443 に解決する。ドメインだけでなく、「:443」とport番号の指定が必要な事に注意。
            addr = "203.0.113.0:443"
        }
        return dialer.DialContext(ctx, network, addr)
    }
    resp, err := http.Get("https://google.com")
    log.Println(resp.Header, err)
}
```

##
【Python初心者】if __name__ == '__main__'を手を動かして理解する。


何をするか
----
`if \_\_name\_\_  == '\_\_main\_\_ ':`とすることで、
出力がどう変わるかを4steps+2stepsで体験しました。

今回は、初心者がよく使う「spyder」などツールで間接的に.pyを実行する際の挙動を示しています。

ターミナルで「$ python XXX.py」と直接実行する場合は、本記事下部の＜参考記事＞から詳細をご覧ください。


いざ実践
---



#\_\_name\_\_ 

###1. まず、`print('Hello!')`する関数をかき、「hello.py」として保存する。


```python:例1_hello.pyを定義する
#hello.py
def function():
    print('Hello!')
```

###2\. 次の新規.pyで「hello.py」をimportしてみる

```python:例2_hello.pyをimport
import hello
hello.function()

#出力内容
#--------------------
# Hello!
#--------------------
```
↓
functionが実行されたことがわかる。

###3\. hello.pyを編集して、 \_\_name\_\_ も一緒に出力してみる

```python:例3_nameを追加
#hello.py
def function():
    print('Hello!')
    print(' __name__とすると、なんと表示されるのか..!? -->' ,  __name__)
```

###4\.もう一度importを実行してみると...

```python:例4_hello.pyを実行してみる
import hello
hello.function()

#出力内容
#--------------------
#Hello!
#__name__とすると、なんと表示されるのか..!? --> hello
#--------------------
```
↓
\_\_name\_\_の部分には、「hello.py」の「hello」が表示された！

##結論（ \_\_name\_\_ とは ）

 \_\_name\_\_ にはimportされたモジュール`'hello.py'`のモジュール名`'hello'`が入っていることが分かった。

#\_\_main\_\_

###次に、hello.pyを編集して、 \_\_main\_\_ を追加してみる。

```python:例1_mainの中に「佐藤」を仕込む。
#hello.py
def function(name):
    print('Hello!',name)
    print('ちなみに__name__の中身は-->',__name__)

if __name__ == '__main__':
    print('mainの中の関数が実行されるのか..?',function('Sato'))
```

###hello.pyを実行してみる。
```python:例2_「田中」を表示する
import hello
hello.function('Tanaka')
#出力内容
#--------------------
#Hello! Tanaka
#ちなみに__name__の中身は--> hello
#--------------------
```
↓
\_\_name\_\_はモジュール`'hello.py'`のモジュール名`'hello'`のままだった。
そのため、function()内にもかかわらず、`if __name__ == '__main__':`の中身(仕込んだ「佐藤」)が実行されなかった。


##結論（ \_\_main\_\_ とは ）

 `if __name__ == '__main__':`にすることで、\_\_main\_\_以下が実行されないことが分かった。



#まとめ
importされた時に、実行させない部分を `if __name__ == '__main__':`以下に書く。
※　$ python hello.py など直接呼び出すときは実行されます。



参考
[【python】if __name__ == '__main__':とは？](https://qiita.com/yuta-38/items/5107914933fc6d5babb8)
npmコマンドを使えるようにするまでのまとめ【mac】

macの初期状態ではnpmコマンドを使うことができないので、それを使える状態になるまでを記事にまとめました。
macでnpmコマンドを使えるようにするには、Homebrewのインストール,Nodebrewのインストール,Node.jsのインストールが必要なので、それを順番にインストールしていきます。

#### このページの最後に順番にやっていった場合の各場面での画面のスライドを埋めこんでいますので、解説が分からない場合は、そちらで確認しながらやってみてください！

## Homebrewのインストール
パッケージ管理システムのひとつのHomebrewをインストールします。
(パッケージをmacに最適にインストールしてくれるようにするツールです)

<img width="1440" alt="npmインストール1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/0f8f9460-7fba-fde3-8974-3ebe1471f0b0.png">

[Homebrew公式](https://brew.sh/index_ja) にアクセスし、インストールの部分のコードをコピーし、ターミナルを起動してペーストしてEnterで実行します。(インストールは少し時間がかかります。)
一応、インストールのコードを下記に記載します。

```terminal:ターミナル
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

## Nodebrewのインストール
Node.jsのバージョンを管理するためのツールのNodebrewをインストールします。

brewコマンド(Homebrewのコマンド)を使い、nodebrewをインストールします。

```terminal:ターミナル
brew install nodebrew
```

## Node.jsのインストール
[Node.js公式](https://nodejs.org/ja/) にアクセスし、推奨版の部分をクリックし、Node.jsの推奨版をインストールします。(最新版でもOKです)
<img width="1440" alt="npmインストール9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/473780/47e999a6-421b-cdf5-e35e-80cf99031022.png">

このNode.jsをインストールすることで、npmコマンドが使えるようになっています。

## まとめ
今回の解説を手順通り進めると下記のスライドのような画面の移り変わりになっていきます。
分からなくなった場合は是非確認してみてください。(必ずできます)

<p class="codepen" data-height="540" data-theme-id="dark" data-default-tab="result" data-user="engineerhikaru" data-slug-hash="QWyXxBx" style="height: 540px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="npm_install_howto">
  <span>See the Pen <a href="https://codepen.io/engineerhikaru/pen/QWyXxBx">
  npm_install_howto</a> by engineerhikaru (<a href="https://codepen.io/engineerhikaru">@engineerhikaru</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

この記事が良いと思った方は、LGTMをしていただければ嬉しいです！
フォローも是非お願い致します(^^)
Node.jsとJavascriptの違い、関係について

# はじめに
はじめてNode.jsを学んだ方や使用した方はこう思いませんでした？

**「なんで同じJavaScriptなのに名前が違うの？サーバーサイドで動くJavaScript？使ってるけどいまいちよくわからない…」**

そんな疑問を持った方たちのために簡単に解説していきます。

# 言語・処理系について
そもそもプログラミング言語とは、コンピュータに情報や命令を伝えるための**「文字・記号の集まり及びそのルール」**です。そして、プログラミング言語によって書かれた文字列を処理系によって処理することで、コンピュータに情報を伝達することができます。

日本人は日本語を理解することができますよね？逆に、日本語を知らない外国人は日本語を理解することができません。これは、日本人が頭の中に日本語の処理系を持っているから言語を理解できるのです！

このように言語は、その言語の意味やルールを処理・理解してくれる処理系がないと全く機能しなくなってしまいます。

# プログラミング言語における処理系とは？
日本語や英語などを理解するための処理系はそれぞれの人間の頭脳でした。じゃあ、プログラミング言語における処理系は何でしょう？
それは、プログラミングをする環境を構築する際にインストールしたやつです！

|言語 |処理系|
|---|---|
|Python  |CPython |
|C  |GCC  |
|PHP|PHP|
など

基本的にプログラミング言語と処理系はセットなのです。

では、フロントでJavaScriptを動かしている方は、何もインストールしてないのに動くじゃん！と思うかもしれないですが、これはブラウザに処理系が搭載されているためです。

# じゃあNode.jsって？
そうです、

**Node.jsとはJavaScriptの処理系です！**

プログラミング言語と処理系の関係について理解できれば、名前が違う！といった疑問も解消できるはずです。

JavaScriptはブラウザで動くフロントサイドの言語と昔は言われていましたが、このNode.jsという処理系によってPythonやPHPといったサーバーサイドの言語と同じようなことができるのです！

# おわりに
自分でも曖昧な部分があったので、記事として書き起こすことで整理してみました。
自分の成長のためにも、間違った部分やご指摘があればどんどんコメントお願いします！
【初心者でもわかる】HTMLとCSSだけで上部固定ヘッダーを作る方法（position: fixed;）

# どうも7noteです。よく見かける上部に固定されているヘッダーをHTMLとCSSだけで作る方法を解説。
どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/header/
GridLayoutのRecyclerViewで一覧機能を作る

# 【Kotlin】GridLayoutのRecyclerViewで一覧機能を作りたい方向け
GridLayoutのRecyclerViewの鋳型（ボイラープレート）です。

一覧画面の実装等でお使いいただけます。
2020/7/29時点でローカルで検証し正常に動作することを確認済みです。(Android Studio 4.0)

ソースコードはこちらからダウンロードいただけます。
https://github.com/kzytech/recyclerViewGridLayoutBoilerplate

## recyclerView デモ
![Diagram](https://res.cloudinary.com/dyrbzxv2c/image/upload/v1596019144/gridgif.gif)

## recyclerView フロー図
![Diagram](https://res.cloudinary.com/dyrbzxv2c/image/upload/v1595654759/Untitled_Diagram.png)
サーモグラフィーでの温度検知

提案
サーモグラフィーを使って体温を測るという対策を学校でもやってみたいと思い、システムを提案しました。
開発環境
Raspberry Pi、
提案手法
この提案の手法は以下の通りです。

これと似たものを学校でもやっていきたいと考えております。
①　サーモグラフィーカメラを設置し、コロナ患者を特定。
②　コロナ患者が分かったらその人に学校から出るように指示。
[JavaScript] 「Hello World」する方法

# 概要
Progate で演習した際には、実行環境があらかじめ用意されていた。
本記事では、ローカルで JavaScript を実行するための環境を構築の仕方を記載する。

# 成果物
Google Chrome のコンソール画面に「Hello World」という文字列を表示する。
![スクリーンショット 2020-07-30 22.41.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663833/fd0c4375-5387-a2c2-8b49-508189a415a4.png)

# 前提知識
- [Unix コマンドの基礎知識](https://qiita.com/ub0t0/items/67b5d7096b5f6ffa068d)
- [Progate](https://prog-8.com/languages/es6) の JavaScript 講座 I

# 使用するソフト
Visual Studio Code : js のスクリプト記述のために利用
ターミナル : macOS High Sierra ver 10.13.6 に標準搭載されている実行環境
Google Chrome （Google Chrome 右クリック → [検証] で [Console] 画面を表示）

# 全体像
JavaScript は HTML から呼び出して実行する
![スクリーンショット 2020-07-30 23.02.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663833/b72432f7-1487-6477-aa11-b3d3f1a786e2.png)

# 手順
### 作業ディレクトリ・ファイルの作成
ターミナルで、任意のフォルダー（ここでは「jssample」とする）を作成し、`index.html` を作成

```:ターミナル
mkdir jssample
cd jssample
touch index.html
```

### HTMLの編集
Visual Studio Code で `index.html` を開く
`html`と入力すると `html:5` が予測変換で出てくるので選択すると以下の記述が自動的に入力される

```.html:index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
```

`<body>`の中に`<p>Hello World</p>`を入力し、上書き保存
   
 
```.html:index.html
<body>
    <script type="text/javascript" src="main.js"></script>
    <p>Hello World</p>
</body>
```

### 記述したHTMLの確認
ブラウザで`index.html`を表示するために、以下のコマンドをターミナルに入力する

```.html:ターミナル
open index.html
```
ブラウザで「Hello World」が表示される。

### HTML に Javascript ファイルを読み込み、コンソール画面に表示する
流れは以下の通り

1. ターミナルで `main.js`を作成し、「console.log("Hello World");」と入力
2. `index.html`で`main.js`を呼び出す`<script>`タグを記述
3. コンソール画面の確認



```:ターミナル
touch main.js
```
`main.js`の作成

```.js:main.js
console.log("Hello world!!!");
```
コンソールに文字列を出力するコードを書く

ここで、コンソール画面を確認すると、何も表示されない。
JavaScript を実行するためには、HTML から`main.js`を呼び出すためのコードを追加する必要がある

以下のように`<script>`タグを追加する

```.html:index.html
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script type="text/javascript" src="./main.js"></script>
    <title>Document</title>
</head>
```
`<script>` タグの使い方

```.html:index.html
<script type="text/javascript" src="./ファイル名.js"></script>
```



Google Chrome の Console 画面で表示されていることを確認
![スクリーンショット 2020-07-30 22.41.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663833/fd0c4375-5387-a2c2-8b49-508189a415a4.png)


# 参考ページ
[HTML, Javascript の違いについて](https://kumaweb-d.com/web/how-to-html-css-php-javascript/)
TwitterAPIをServerlessを使ってLambda + Nodejsで動作させてみた

# 概要
TwitterApiを使ってあれこれしたいと思ったので動かすまでの手順をまとめてみた
Nodejsで作成した理由はなんとなくフロントエンドと同じjavascriptでやれたら楽かなーと思ったぐらいです。

# 基本セットアップ
ServerlessやNodejsなどのインストールは以前私が書いた記事ですが、こちらが参考になるかと思います。
https://qiita.com/tama0571046/items/cfe262b002f6434b915e

TwitterAPIを使用するまでの流れは記事がたくさんありますので、調べるとすぐに出てくるかと思います。

私が参考にしたサイト
https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/


# Serverless
### ServerlessをAWSの連携
まずはAWSにログインして[IAM]の[ユーザー]からアクセスキーとシークレットキーを取得してきてserverlessに教えます

```zsh
sls config credentials --provider aws --key XXXXXXXXXXXX --secret XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

### プロジェクト作成
Serverlessを使ってプロジェクトを作成します。

```zsh
serverless create --template aws-nodejs --name twitter_server --path twitter_server
cd twitter_server
```


### node_moduleを追加
entry pointだけ変更してあとはそのままEnterでOK

```zsh
yarn init
> question name (twitter_server): 
> question version (1.0.0): 
> question description: 
> question entry point (index.js): handler.js
> question repository url: 
> question author: 
> question license (MIT): 
> question private: 
```

### twitterモジュールを追加

```zsh
yarn add twitter
```

### event.jsonの追加
handler.jsのevent引数で取得できます

```zsh
vim event.json
```

```vim:event.json
{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}
```

### handler.jsの修正
Twitter APIのリファレンスを参照して取得したいデータに合わせてコーディングしてください。
https://developer.twitter.com/ja/docs/ads/general/api-reference

なんとなくこんな感じかな。というのを下記に記述します。
もっといいやり方あったら教えて下さい。

```js:handler.js
'use strict';

var Twitter = require('twitter');

// 初期化
var tweet_client = new Twitter({
  consumer_key: '***',
  consumer_secret: '***',
  access_token_key: '***',
  access_token_secret: '***'
});

module.exports.hello = event => {
  if (event.action == 'test') {
    finish(test());
  }
};

function finish (body) {
  if (body) {
    console.log(body);
    return {
      statusCode: 200,
      body: body
    };
  }

  console.log('No Action');
  return {
    statusCode: 500,
    body: 'NoAction'
  };
};

function test () {
  tweet_client.get('statuses/home_timeline', {})
    .then((tweets) => {
      console.log(tweets);
      return tweets;
    })
    .catch((error) => {
      console.log(error);
      return error;
    })
};
```
function名をhelloから変えたい場合はserverless.ymlも合わせて修正してください
serverless.ymlを修正することでデプロイ先のリージョンなどを変更することもできます

# Lambda
### デプロイ

```zsh
serverless deploy -v
```

### デプロイしたfunctionの実行

```zsh
serverless invoke --function hello -p event.json --log
```

### 不必要になったら消すようのコマンド

```zsh
serverless remove -v
```

以上です。

# 所感
Node.jsで複雑なTwitterAPI取得のソースコードは向いてないのかなと思いました。
TwitterAPIで取得するところが非同期処理になるため、await/async地獄になってしまいました。
例えば、APIを使ってリストの一覧を取得してきて、そのデータを使用してリストのメンバーを取得するみたいな処理を書こうとするだけで結構めんどくさかったです。
だったらPythonで書けばよくね！？と思ったので、次はPythonで試してみます。
また、そちらも記事にしていこうと思います。
Repository is not clean. Please commit or stash any changes before updating

Angularのバージョンを8から9にしようとすると、こんなエラーメッセージが。<br>
```
Repository is not clean. Please commit or stash any changes before updating
```
結論下記のように--allow-dirtyを加えたng updateコマンドで解決できました。<br>

```
ng update @angular/cli@9 @angular/core@9 --allow-dirty --force
```
CDKは別途下記コマンドでupdateします。<br>
```
npm install @angular/cdk@9 --save
```

<strong>2022/6/14加筆
--forceを追加
</strong>
RSpecの単体テストにて"translation missing: ja.activerecord.○○"というエラーが出たときの対処法

Deviseを日本語化したときのエラー。エラー画面はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/484801/6a887d1b-3688-0d46-a527-5d7299cbb4bb.png)

#### ◆原因
どうやらdeviseのエラーメッセージを日本語化したことによって`本来Deviseで用意されているエラー文(英語)`と`テスト実行時のエラー文(devise.ja.yml)`に相違が出てしまい、エラーになってしまってるぽい。

#### ◆解決策
巷に落ちている`devise.ja.yml`の内容もそれぞれ引用元によって異なるため、このエラーが出た際には**devise.ja.ymlに記述を追加する**必要がある。

実際に記述を追加していく。
今回の場合エラー分が
`expected [translation missing: ja.activerecord.errors.models.user.attributes.name.blank] to include "can't be blank"`
なので

```ruby:config/locals/devise.ja.yml
ja:
  activerecord:
    errors:
      models:
        user:
          attributes:
            name:
              blank: "が入力されていません"
```
と追記してあげる。

これで無事にテストが通るように！

## 参考にした記事
・[Devise日本語化後の「translation missing」に対処する](https://poinorou.hatenablog.com/entry/2019/09/16/090336)

・[translationmissing:ja.activerecord.errors.models.hoge.attributes.base.restrict_dependent_destroy.many の対処方法](https://qiita.com/moperon/items/da8cd6e674dba2552c42)

・[Createの際のエラーUser translation missing: ja.activerecord.errors.models.company.attributes.user.required](https://teratail.com/questions/199168)

・[deviseを日本語化する](https://qiita.com/you8/items/921e0dd1210eb0d158df  )
[Rspec]Fabricateの基本的な使い方まとめ

なんとなく使えてしまうFabricateですが、ふとしたきっかけでちゃんと理解したいなと思ったのでまとめました。

## Fabricateとは
オブジェクト生成ライブラリです。
テストで使用するためのオブジェクトを簡単に作成できます。

## 使い方
非常にシンプルで、モデルの属性に無難なデフォルト値を設定します。
サンプルで`person`というオブジェクトを定義しました。

```ruby
Fabricator(:person) do
  name "Niki"
  age 23
end
```


### 生成メソッド
生成メソッドは3種類あります。よく使うのは`Fabricate.build`と`Fabricate`。

```ruby
Fabriate(:person)
# newしてsaveしたものを返す
Fabricate.build(:person)
# newだけしてsaveはしない
Fabricate.attributes_for(:person)
# 属性のHashを返す
```

一見`Fabricate.build`は必要なくない？となりますが、これは間違いです。
`.build`を使うとインスタンスを保存しないので、specの処理時間の軽減につながります。

なので、`.build`を使えない場合のみインスタンスを生成し、基本的には`.build`を使うようにしています。

## 属性の値を明示する
定義したオブジェクトの属性の値を変えたい場合は以下の様にします。

```ruby
person = Fabricate(:person, name: "Peru")
person.name = "Peru"
```

また、関連しているデータを紐づけることも簡単にできます。
例えば、`book`モデルが`belong_to`で`person`モデルに紐づいている場合は以下の様にして`Fabricate`で表現できます。

```ruby
Fabricator(:book) do
  name "キングダム"
  price 1000
end

book = Fabricate.build(:book, person: Fabricate.build(:person))
```

これらは基本的な内容ですが、ちゃんと理解するとテストのコーディングスピードも上がると思います。他にも色々便利なメソッドがありますので暇があれば調べてみて下さい。
何かいいメソッドや書き方があれば、是非コメントください！