OmniAICreator/Qiita-1.07M huggingface dataset:
[はじめてのiOSアプリ]xcodeで地図アプリを作成（その２）

# はじめに

iOSアプリを作ってみたいけど
何から始めて良いのかわからない

とりあえず、
「やってみました」記事を参考に
地図アプリを真似てみようと思う

という記事の２回目です。

今回は、地図を表示します。

# 地図を表示
1. MapKit.framework を追加
   - [MyGpsMap]-[Build Phase]-[Link Binary With Libraries]を選択し、[+]をクリック<br>
<img width="1316" alt="LinkBinLib.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/a4905208-2092-34a3-bcf3-c84eb4841778.png">
   - 検索窓に [map] と入力し絞り込み[MapKit.framework]を[Add] で追加<br>
<img width="398" alt="AddMapkit.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/7d150702-c470-5644-0bdb-b99a7ea2cf3b.png">
   - 【なぜ？】
     - Apple が提供してくれる地図を簡単に使うことができるフレームワーク(ライブラリ)
     - 苦労は買ってでもする人じゃない限り使うべき
1. Mapkit を画面に配置
   - 画面左側のファイルツリーから[Main storyboard]を選択<br>
<img width="1316" alt="MainStoryboard.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/0a3512b6-75d1-d8a9-22cc-0c95b2ece4b5.png">
     - 【なぜ？】
         - あとで[Main storyboard]にGUIの地図部品を配置したいから、まずは選択しておく
         - [Main storyboard]を編集することで表示内容を決定できる
   - メニューから[View]-[Show Library]を選択、表示されるウインドウで [map] と入力し [Map Kit View]を絞り込む<br>
<img width="727" alt="ShowLib-mapkit.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/38d2f84f-ac14-f5b1-11aa-fd4870c83be3.png">
     - 【なぜ？】
         - [Map Kit View]は地図を表示するためのGUI部品
         - 今回は、機能と名称が一致しているので絞り込みが楽々！
   - 絞り込み表示された[Map Kit View]を、Xcode右画面に表示される iPhone 画面上に、ドラッグ&ドロップする<br>
<img width="1316" alt="MapKitOnStoryboard.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/b9b4c056-1f0b-7322-9414-ec3f3d2c7df8.png">
     - 【なぜ？】
         - [Map Kit View]を[Main storyboard]に配置することで地図が表示できる
  - [Map Kit View]を画面いっぱいに配置
     - 【なぜ？】
         - 地図は画面いっぱいに表示された方が見やすいから<br>
<img width="1316" alt="MapKitOnStoryboard-max.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/b2a7c1e0-81db-cabe-4e03-88cf3731449c.png">
1. テスト実行
   - Xcode 左上の矢印アイコンをクリック<br>
![StartSimulator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/9fde1421-8248-f223-877a-513b285a63f5.png)


   - iPhone Simulatorが起動し、日本全体が表示された<br>
<img width="535" alt="MapJapan.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521802/16d012fc-78e3-bc38-2615-c057144ee159.png">


# 今回の到達点
- シミュレーターを使って地図を表示できた

# 連載
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その１：プロジェクト作成）](https://qiita.com/shinobee/items/1f6d26451336bf736484)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その２：地図表示）](https://qiita.com/items/50e1acee3024c3e26fb9)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その３：位置情報取得）](https://qiita.com/items/b8d287d2e34af20aab64)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その４：位置情報と連携した地図表示）](https://qiita.com/items/a91c49ebf5301d936120)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その５：アプリアイコン設定）](https://qiita.com/items/24804294ab86635ee5d3)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その６：拡大・縮小ボタン追加）](https://qiita.com/items/12c54c4e253bc48cad4d)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その７：地図を拡大・縮小）](https://qiita.com/items/4406c4fdf2fbdcc40533)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その８：地名表示）](https://qiita.com/items/3363779d0ea11ca6073c)
1. [[はじめてのiOSアプリ]xcodeで地図アプリを作成（その９：ソースコード管理）](https://qiita.com/items/d0e63020b0dce4c70542)

<!-- eof -->
自動でBootシーンに切り替える仕組みを作ると人生が楽になる 【Unity】


ゲームを作る時に、初期化用のシーンを経由してから指定したシーンに移行し動作させることってあると思うのですが
そういう設計にすると制作中テストする度に初期化用のシーンに戻る必要が出てきて少し大変ですよね

この問題はUnityのEditor拡張を利用することで解決できます。

実装は簡単。再生時にシーンを切り替える命令を登録するだけ
-----

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using UnityEditor;
    using UnityEngine.SceneManagement;
    
    [InitializeOnLoad]
    public static class PlayModeEditor
    {
        static string m_bootSceneName ="Boot";// ←移動したいシーンの名前を記入する
    
        static PlayModeEditor()
        {
            EditorApplication.playModeStateChanged += ChangeBootScene;
        }
        
        static void ChangeBootScene(PlayModeStateChange state)
        {
            // 実行状態になったら
            if (state == PlayModeStateChange.EnteredPlayMode)
            {
                // 別シーンで起動していた場合切り替える
                Scene scene = SceneManager.GetActiveScene();
                if (!scene.Equals(m_bootSceneName))
                {
                    SceneManager.LoadScene(m_bootSceneName);
                }
            }
        }    
    }


### 実行時の結果
![playmode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/3a3dc6f4-7239-6f95-068f-aed01f3c79c4.gif)


この機能を利用すれば他でも応用できそうです。
matplotlibでscatterの点をクリックすると色を変えたい

#初めに
scatterでプロットしたところまでは良かったのですが、その後データの更新しようとすると難しかったので共有しておきます。
#コード
```scatter.py
import matplotlib.pyplot as plt
import itertools #デカルト積
import numpy as np

if __name__ == '__main__':
    x_max = 10
    y_max = 10

    fig = plt.figure(figsize=(5,5))
    ax = fig.add_subplot(111)

    ax.set_xlim(-x_max*0.05,(x_max-1)*1.05)
    ax.set_ylim(-y_max*0.05,(y_max-1)*1.05)

    x_data = [i for i in range(x_max)]
    y_data = [i for i in range(y_max)]
    tmp_data = list(itertools.product(x_data,y_data))
    t_x = [i[0] for i in tmp_data]
    t_y = [i[1] for i in tmp_data]
    data = [t_x,t_y]
    
    colors = [(0,0,0,1) for i in range(x_max*y_max)]
    art = ax.scatter(data[0],data[1],c=colors)
    
    def onclick(event):
        x = round(event.xdata,0)
        y = round(event.ydata,0)
        tmp = int(x*(y_max) + y)
        if colors[tmp] == (0,0,0,1):
            colors[tmp] = (0.5,0.5,0.5,1)
        elif colors[tmp] == (0.5,0.5,0.5,1):
            colors[tmp] = (0,0,0,1)
        art.set_facecolor(colors)
        plt.draw()


    plt.connect('button_press_event', onclick)

    plt.show()
```
Ruby on railsの基本箇所についての復習①（フォルダを作る）

#はじめに
Ruby on rails（以降rails)を使って、簡単なアプリを作るまでの手順を、なるべく細分化して書いていこうと思います。
#実行
railsアプリを作成するのに必ずしなければいけないのは***アプリのフォルダを作ることです***。
これはターミナル上でrailsコマンドを入力できます。

今回は、`sample`という名前のアプリを作っていきます（名前はなんでもいいです）。
最初にアプリを作る場所（ディレクトリ）を決めます。どこでもいいのですが、今回はデスクトップ上に作成しようと思います。
まずはターミナルでデスクトップに移動します。

```terminal
cd desktop
```

移動したら次はアプリのフォルダを作ります。
アプリのフォルダは、移動したディレクトリで`rails _railsバージョン_ new アプリ名 -d mysql`というrailsコマンドを実行すれば良いです。
railsのバージョンは、ターミナル上で`rails -v`と入力すればわかります。筆者の場合はこの記事を書いている時点で`Rails 5.2.3`となっています。アプリ名は`sample`ですので、

```terminal
rails _5.2.3_ new sample -d mysql
```

と入力すれば狙い通りのフォルダを作れます。

基礎中の基礎の部分ですが、この一連の流れは***何かを参考にしながらでもいいので***間違いなくできるようになってください。
picoCTF 2019 Irish-Name-Repo 1 - Points: 300

#問題

https://2019game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/9a3041dc-409c-be13-04e3-83c87a2149dc.png)

#解いてみた

サイトにアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/0604e327-ca2f-ad75-7c98-ceee3fc1cbc8.png)

ログインする問題なのでログイン画面を探します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/5dfcdc92-d262-7e4f-4573-e542af77ea57.png)

何も入力せずにログインボタンを押してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/4703223d-0328-c4f7-e784-21d5ad7fa98f.png)

login.phpに遷移して、「Login failed.」と表示されました。
ソースを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/d446deb0-107a-84c1-b06b-01fa0dcf1289.png)

特に変なところはありませんでした。
SQLインジェクションをやってみます。
まずはベタな

```
' or 1 == 1 --
```

を入れてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/6474c537-762d-5d88-78b1-3fdeaa85c674.png)

おおできました。
NVENC Pascal vs Turing

#NVENC Pascal vs Turing
Pascal GPU を入手したので、ffmpeg のベンチを測る

# GPU
| | Quadro K2000| Quadro P400 | GTX 1660|
|:---:|:---:|:---:|:---:|
|Arch| Kepler | Pascal | Turing|
|Core Name| GK107 | GP107 | TU116| 
| CUDA Core | 384| 256 | 1408| 
| MEM | 2GB GDDR5 |2GB GDDR5 |6GB GDDR5|
|TDP | 51W| 30W | 120W|


# 使用機材
| HOST HARD | |
|:---:|:---:|
|CPU| Xeon E5-2670 v2 | 
|M/B| SABERTOOTH X79 |
|MEM| DDR3 mix 48GB |
|System SSD| WDS120G2G0A (SATA)|
|Data SSD| WDS500G2B0B (USB3) |

| SOFTS | |
|:---:|:---:|
|OS| ubuntu 18.04 | 
|ffmpeg | 3.4.6|
|driver| 440.26|

# 使用動画
| TEST DATA 1 | |
|:---:|:---:|
|Duration | 3m 51s |
| W x H | 3840 x 2160| 
| Fps | 30 |
| bitrate| 14M|

| TEST DATA 2 | |
|:---:|:---:|
|Duration | 2m 19s |
| W x H | 1920 x 1080| 
| Fps | 59.78 |
| bitrate| 22M|

# 使用コマンド
CPU

```
time ffmpeg -i hoge.webm -b:v 25M -c:v h264 -vf scale=1920:-1 cpu.mp4
```
GPU

```
time ffmpeg -i hoge.webm -b:v 25M -c:v h264_nvenc -vf scale=1920:-1 gpu.mp4
```

#結果
| Result 1 | Xeon E5 |K2000| P400 | GTX1660|
|:---:|:---:|:---:|:---:|:---:|
|time(s) | 155 |96| 99|98
|speed| 1.5x |2.41x| 2.35x | 2.37x

| Result 2 | Xeon E5 | K2000| P400 | GTX1660|
|:---:|:---:|:---:|:---:|:---:|
|time(s) | 170 |103| 64| 64
|speed| 0.818x |1.34x| 2.18x | 2.17x|

なんか、どこかボトルネックになってそう・・・
（心当たりがありすぎる）
git 同じ名前のタグとファイルが存在する場合

first-tag という名前のタグがあるとします。

```bash:git
$ git tag
first-tag
```

また、first-tag という名前のファイルも存在しており編集中です。
まだコミットはされていません。

```bash:git
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   first-tag

no changes added to commit (use "git add" and/or "git commit -a")
```

この状態のとき、first-tag ファイルをチェックアウトする（編集を取り消し）にはどうすればよいでしょうか。
もし、単純にファイル名を指定してチェックアウトしてみると。

```bash:git
$ git checkout first-tag
error: Your local changes to the following files would be overwritten by checkout:
	first-tag
Please commit your changes or stash them before you switch branches.
Aborting
```
このようにタグをチェックアウトしようとする動作になり、怒られてしまいます。

こういったケースでは、-- (bare double dash) を使って、チェックアウトしたいのはファイルであることを明示してあげる必要があります。

```bash:git
$ git checkout -- first-tag
$ git status
On branch master
nothing to commit, working tree clean

# もちろんタグは残っています
$ git tag
first-tag
検索能力を身につけよう！！

#はじめに

この記事は、2019/11/1からプログラミング学習を始めた学生がプロのプログラマーになるまでのアウトプットする為の書き込みの場である。

#エンジニアに検索能力が必要な理由

日々開発をする上で様々な技術や未知のエラーに遭遇した時に解決する為に必要なスキル

#キーワード検索
- 複数キーワードで検索する
- 期間指定で新しい記事を探す
- 英語で検索する
- Googleの検索テクニックを利用する

##複数キーワードで検索する
- 複数の単語を活用して検索することにより関連性のの高い検索結果が表示される

- 単語の意味を調べたい時は、語尾に「とは？」をつけることによりより効率的に検査する事ができる

- 何に関係があるのか単語だけではなく状況を含めることにより正確な検索結果を得る事ができる

##期間指定で新しい記事を探す

- グーグルの検索ツールには期間指定する事ができる機能があります。それを活用することにより最新の情報を仕入れる事ができる

##英語で検索する

- 日本語で検索した際に求めていた情報を得られなかった場合、英語で検索すると求めていた情報がヒットする事がある

##Googleの検索テクニックを利用する

- 省きたい単語の前に「ー」をつけ検索することにより正確な情報をヒットさせる事ができる

- フレーズ検索をする事により検索ワードに完全に一致したワードしかヒットしなくなる

##終わりに

もっとこうした方が良いよなどご指摘頂けると幸いです
Linux　viについて

Linuxコマンドでやや難しい内容を書きます。

# vi
サーバ上で設定ファイル等を編集したい場合のエディタ
基本標準インストールされています。

他にも種類があり

* vim ・・・viの発展形
* emacs・・・viとは異なる思想で作られている。

viの基本的な使い方は

1.「通常モード」でファイルを開く
2.「インサートモード」でファイルを編集する
3.「通常モード」へ移行し、「:wq」で保存して終了する

## viを開く

```bash
$ vi [ファイル名]

例:sampleファイルを開く

$ vi sample
```

## 通常モードコマンド

| コマンド | 説明 |
|:-:|:-:|
| :w | 作成・編集したファイルを保存します。 |
| :q | viコマンドを終了します。 |
| :q! | 編集した内容を保存しないでviコマンドを強制終了します。 |
| :wq | 編集した内容を保存してviコマンドを強制終了します。 |

## インサートモード　(「i」  (開始), 「ESC」(終了) )
文字を入力したい場合は、インサートモードにする必要が有ります。

「i」  :インサートモードの開始
「ESC」: インサートモードの終了

## 検索(/)
文字列を検索するには、通常モードで「/」（スラッシュ）を入力し
その後に検索したい文字列を入力し、「Enter」キーで実行することが出来ます。

## アンドゥ(u)
カットやペースト・置換・挿入モードに入ってから挿入モードを抜けるまでの一連の文字入力など
ファイル中の文字に影響を与えた動作を1つ取り消すことができるコマンドです。
【Go】日時を文字列に変換する時によく使うフォーマット指定

# はじめに

しょっちゅう「あれ？Golangで日付を文字列に変換する時のフォーマットってどんなんだっけ？」となって毎回調べているので、個人的によく使うやつを自分用のメモとして残しておきます。

フォーマットの詳しい指定方法については以下の記事がわかりやすくまとまっています。
本記事では細かい解説はしません。

- [Golangでの日付のフォーマット指定の方法について \- Qiita](https://qiita.com/unbabel/items/c8782420391c108e3cac)

# よく使うフォーマット

年月日時分秒の指定方法さえ覚えておけば大体なんとかなると思います。

|日時形式|フォーマット|
:-:|:-:
|yyyy-mm-dd|2006-01-02|
|yyyy-m-d|2006-1-2|
|HH:MM:SS|03:04:05|
|H:M:S|3:4:5|
|yyyy-mm-dd HH:MM:SS|2006-01-02 03:04:05|

# サンプルコード

```go
package main

import (
	"time"
)

func main() {
	t := time.Date(2019, time.February, 9, 8, 7, 4, 0, time.UTC)
	// => 2019-02-09 08:07:04 +0000 UTC

	/*
	 * 日付
	 */

	// yyyy-mm-dd
	t.Format("2006-01-02") // => "2019-02-09"

	// yyyy-m-d
	t.Format("2006-1-2") // => "2019-2-9"

	/*
	 * 時間
	 */

	// HH:MM:SS
	t.Format("03:04:05") // => "08:07:04"

	// H:M:S
	t.Format("3:4:5") // => "8:7:4"

	/*
	 * 日付 + 時間
	 */

	// yyyy-mm-dd HH:MM:SS
	t.Format("2006-01-02 03:04:05") // => "2019-02-09 08:07:04"
}
```

# おわりに

改めてちゃんと調べてみて気づきましたが、月日時分秒の順番で12345になってるんですね。
そう考えると簡単に覚えられるな。。。まとめた意味なかったかも。。。

# 参考

- [Golangでの日付のフォーマット指定の方法について \- Qiita](https://qiita.com/unbabel/items/c8782420391c108e3cac)
nvmのnodeのバージョンごとにyarnをインストールする方法

これまで、brewでインストールしたyarnを使っていたのだが、nvmでインストールした各Node.jsのバージョンごとにyarnのバージョンを変更したくなった。
調べてみると、npmでyarnをインストールすることで実現可能なことがわかった。

ちなみにyarnの公式に[yarnをnpm経由でインストールするのはお勧めできない](https://yarnpkg.com/ja/docs/install#alternatives-stable)との記述があるのだが、開発で必要になったのでメモを残しておく。

> 注意: npm から Yarn をインストールすることは一般的にはお勧めしません。 Node ベースのパッケージマネージャで Yarn をインストールする場合は、パッケージは署名されておらず、整合性のチェックはベーシックな SHA1 ハッシュのみで行われており、システム全体にまたがるアプリケーションをインストールする場合にはセキュリティリスクとなります。
これらの理由から、使用中の OS に最も適した方法で Yarn をインストールすることを強くお勧めします。

## 実行環境
macOS 10.14.6
nvm 0.35.1
npm 6.12.1

## 手順

nvmでNode.jsをインストールして、yarnをインストールする。

```
$ nvm install 12.13.1
$ nvm use 12.13.1
$ npm install -g yarn
```

上記を実行するとバージョン12.13.1用のディレクトリにyarnがインストールされる。
yarnをインストールする時に、バージョンは指定しなかったので、現時点で最新の1.19.2がインストールされた。

下記コマンドで確認。

```
$ which yarn
/Users/hoge/.nvm/versions/node/v12.13.1/bin/yarn
$ yarn -v
1.19.2
```

次に、nvmで新たにバージョン13.2.0のNode.jsをインストールして、同じくyarnをインストールする。
yarnのインストールの際、`npm install hoge@*.*.*`のように@の後ろにバージョンを指定することで特定のバージョンをインストールすることができる。

```
$ nvm install 13.2.0
$ nvm use 13.2.0
$ npm install -g yarn@1.18.0
```

先ほどインストールしたyarnはそのまま残り、バージョン13.2.0用のディレクトリに新たにyarnがインストールされる。

```
which yarn
/Users/takuma/.nvm/versions/node/v13.2.0/bin/yarn
```

また、バージョンを確認すると、先ほど指定した1.18.0がインストールされている。

```
$ yarn -v
1.18.0
```

ちなみにbrewのyarnはアンインストールせずに、そのまま残しておいて大丈夫!

- 参考
  - https://stackoverflow.com/questions/52174381/yarn-not-installing-in-nvm-version-node-version
C言語を勉強する初めの一歩をまとめてみた#42tokyo

#はじめに
42tokyoという学校の入試に挑むにあたり、C言語の勉強をしておこうかなと思いました
どんな感じで勉強したらよいか考えてみたので簡単にまとめます

#開発環境
開発環境は手軽なものがよいです
クラウド上で開発環境が用意できるAWSのCloud9というものが良いと思います
↓こちらの記事を参考にしたらとても簡単にできました！
https://dx.nissho-ele.co.jp/blog/aws-beginner-cloud9_20190419.html

#教材（無料）
基礎を抑えるという意味では無料のもので十分かと思います
下記の２つがよさげです
（自分はまだほぼやってませんが、、）

###ドットインストール
https://dotinstall.com/lessons/basic_c
「C言語入門」というレッスンが22動画無料で見れます
ドットインストールは色々他のレッスンもよかったのでオススメできます

###苦しんで覚えるC言語
http://9cguide.appspot.com/index.html
なんか良いみたいです
42tokyoのグループ(非公式)とかでおすすめされてます

#おわりに
ピシンがんばんりましょう！
記事について何かあればtwitterの方にご連絡ください！m(__)m
アプリ・サーバー・DBの関係

#サーバとは
サーバとはサービスや機能を提供するもの、または主に性能面において整備されたコンピュータのこと。
#DB(データベース）とは
大量のデータがコンピューター上で整理され、みんなが扱えるようにしたもの。
#アプリとサーバとDBの関係
アプリが起動するとサーバに命令を送り、サーバがデータベースにデータを要求しデータベースがサーバにデータを送り、サーバがアプリにデータを返す。
React Hooksの魅力

ようこそ、[React Hooks Advent Calendar 2019](https://qiita.com/advent-calendar/2019/react-hooks)へ！まずは1日目ということで、React Hooksの魅力について語ってみます。

## React Hooksの魅力

### 関数コンポーネントでも広がる機能性

もともとReactのコンポーネントはクラスコンポーネントしかなく、そして`render`だけで済むものが関数コンポーネントで書けるようになりました。ただ、関数コンポーネントを拡張していって、`state`などが必要になると、改めてクラスコンポーネントに書き換える必要が出てしまいました[^1]。

React Hooksでは、関数コンポーネントのまま、`state`や更新時のフックを実現できるようになります。

[^1]: React 16.12時点でも、`componentDidCatch`や`getSnapshotBeforeUpdate`といった一部のコールバックは関数コンポーネントで再現できません。


### カスタムフックによるモジュール化

クラスコンポーネントでは、クラス内部に`componentDidMount`や`componentDidUnmount`といったコールバックは1つしか作れなかったので、前準備と後始末を分けて書くしかない、ということがありました。

React Hooksでは、コールバック類をいくつでも書けます。さらに、複数のHooksをまとめて呼び出すカスタムフックを作ることで、準備と後片付けをまとめて再利用することも可能としています。

### 粒度の細かな制御

クラスコンポーネントには、全体をメモ化して、`props`や`state`が変化しない限り再描画を抑える機能があります。また、`componentDidUpdate`は更新のたびに実行されます。

React Hooksの場合、`useMemo`を使えば「特定の変数群が変わらない限り」という条件でメモ化ができますし、`useEffect`でも同様に「特定の変数群の変化」をきっかけとしてコールバックを実行できます。
Windows系OSに対するデジタル・フォレンジック、データ復旧手段についての考え

今日も大学学業頑張っている5555です。

今日暇つぶしの時、少しPowershellについての参考文献を読みました：
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/get-childitem?view=powershell-6

この記事も一気にwindowsオプションファイルをリストする方法を紹介しました：
https://blog.ipswitch.com/how-to-accurately-enumerate-windows-user-profiles-with-powershell

すると、```PS> Get-ChildItem 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList'```実行していたが、少し気になるのは```Name```の一番下、長い数字列のところです。

![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526362/865c7eea-6937-9510-fcdd-da9a13540efb.png)

更に調べると、**一つ長い数字列(SID)は唯一のWindowsアカウント名を対応しています。**

例えば、
図の**la**というアカウントは**S-1-5-21-207235803-1283372969- 343841458**に対応します。
では、もし**la**というアカウントを削除し、同じ名前で新たな**la**というアカウントを作ったら、この長い数字列（SID）は変わりますか？
答えは当然です。

いわゆる、**この長い数字列（SID）はアカウントの指紋です。**

レジストリでの様子はこんな感じです：
![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526362/f4757c6a-9663-d9fb-0192-ee4ce58cd841.png)

**ProfileListh**は**la**というアカウント名が示しています：
![图片.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526362/d4495ff3-145d-ea56-ec9a-4265afd5bfed.png)

Windowsでファイルを削除した後、**実はハードディスクにまだ存在しています**。しかし削除されたファイルの元の所属はアカウント名に対応するではなく、この唯一の長い数字列です。**例えば、SIDは12345、Titaniaというアカウントはfsociety.dat削除したら、ごみ箱内にfsociety.datの元の所属はSID12345だけ示しています。**（重複アカウント名の場合を考え、唯一の長い数字列を使ったらより容易でしょう）

これは**デジタルフォレンジックまだデータ復旧**に使える手段かなわたくしは考えています。（**one SID=one account**）

##プログラミング実装について：##
１、まず長い数字列（SID）とアカウント名をマッピングする変数を作ります。
２、ごみ箱の位置を判断しなければならない：
  　 -  winxpの場合は：**Recycler**
  　 -  win7以降の場合は：**$Recycle.Bin**
３、ごみ箱内の長い数字列（SID）全てアウトプット、対応しているアカウント名もアウトプット、全てのファイルもリストします。

原理はこういう感じですが、値段凄く高いデータ復旧ソフトウェアもこういう手段使っているかな。正直、削除されたファイルのブロックに再び新たなファイルを書き込んだら復旧できないでしょうか。後日PYTHONを使い、この原理を再現したいと思います。
SSLとTLSの違いについて

SSL/TLSとはについて調べて、
どちらも、インターネット上でデータを暗号化して送受信するプロトコルであり、重要なデータを暗号化して、サーバとPC間での通信を安全に行なうために必要だとわかった。
※ [HTTP/HTTPSについて学んだことまとめ](https://qiita.com/katu_/items/97938eda9caf64d98fbc)でまとめました。

しかし、SSLとTLSの違いについて学習しきれていなかったのでまとめます。

## SSLとは
- Secure Sockets Layerの略称
- 1990年代中頃、当時主要であったブラウザ「Netscape Navigator」を制作したNetscape社によって開発された
- 1994年11月、SSL 2.0がリリース、のちに重大な脆弱性が発見された
- 1995年11月、SSL 3.0がリリース、のちに脆弱性が発見され2015年6月、使用が禁止された
- 仕組みとしてはもう使われていないが、情報を安全にやりとりするという意味での言葉として残ってる

## TLSとは
- Transport Layer Securityの略称
- 1999年1月、TLS 1.0がリリース、実質SSLからTLSへ移行された
- 2006年4月、TLS 1.1がリリース、セキュリティの強化が行われた
- 2008年8月、TLS 1.2がリリース、脆弱性のある古い仕組みが排除され、最新の暗号化に対応するなどの改良が行われた

## TLSとSSLの違いまとめ
- SSLはTLSの前身となる仕組みである
- TLSはSSLの次世代規格である
- TLSはSSLの脆弱性を解決するために開発された
- TLSが登場したときに、既にSSLという名称が広く使われていたことから、TLSのことも含めてSSLと呼ばれたり、SSL/TLSような併記で使われたりする

### 参照
- [TLSとSSLの違いについて](https://jp.globalsign.com/ssl-pki-info/ssl_practices/ssltls_brittle.html)
- [SSLとTLSの違いとは](https://ssl.sakura.ad.jp/column/ssl_tls/)
- [HTTPS と SSL と TLS](https://blog.qbist.co.jp/?p=1441)
【Rails】flashの使い方

flashを利用して、アクション実行後に簡単なメッセージを表示させることができます。
ログイン周りの処理において特に重宝されます。
（Sessionはモデルを持たない→ActiveRecordがエラーメッセージを吐かないから）

##使い方
`flash[:<キー>] = <メッセージ>`で登録し、`flash.each do |message_type, message|...`で出力します。

##`flash`と`flash.now`
flashの仲間に`flash.now`があり、
`flash`→次のアクションまでデータを保持する→`redirect_to`と一緒に使う
`flash.now`→次のアクションに移行した時点でデータが消える→`render`と一緒に使う
という使い分けが必要です。

##TODOアプリにflashを実装する
簡単なTODOアプリにflashを実装していきます。
・[Ruby on Railsで簡単なアプリを作成](https://qiita.com/d0ne1s/items/5e63dde992f20f25b8bb)
・[RailsアプリをHerokuにデプロイする手順](https://qiita.com/d0ne1s/items/59b5d9ed69e822c5b39c)
・[【Rails】バリデーションを実装する](https://qiita.com/d0ne1s/items/822f66d16d65ae28162b)
・[【Rails】ログイン機能を実装する](https://qiita.com/d0ne1s/items/7c4d2be3f53e34a9dec7)

###`application.html.erb`にflash表示領域を確保する
```erb:/app/views/layouts/application.html.erb
<!DOCTYPE html>
.
.
  <body>
    <% flash.each do |message_type, message| %>
      <%= message %>
    <% end %>
.
.
```
###tasksコントローラーを修正する
`redirect_to`の前に`flash`を、`render`の前に`flash.now`をそれぞれ追加します。

```/app/controllers/tasks_controller.rb
class TasksController < ApplicationController
  before_action :logged_in_user, only:[:create, :edit, :update, :destroy]
  def index
    @tasks = Task.all
  end

  def new
    @task = Task.new
  end

  def create
    @task = Task.new(task_params)
    if @task.save
      flash[:success] = "タスクを追加しました。"
      redirect_to tasks_url
    else
      flash.now[:danger] = "登録に失敗しました。"
      render 'tasks/new'
    end
  end

  def edit
    @task = Task.find(params[:id])
  end

  def update
    @task = Task.find(params[:id])
    if @task.update(task_params)
      flash[:success] = "タスクを修正しました。"
      redirect_to tasks_url
    else
      flash.now[:danger] = "更新に失敗しました。"
      render 'tasks/edit'
    end
  end

  def destroy
    @task = Task.find(params[:id])
    @task.destroy
    flash[:success] = "タスクを削除しました。"
    redirect_to tasks_url
  end

  private
    def task_params
      params.require(:task).permit(:title)
    end
end
```

###sessionsコントローラーを修正する
tasksコントローラー同様、`redirect_to`の前に`flash`を、`render`の前に`flash.now`を追加します。

```/app/controllers/tasks_controller.rb
class SessionsController < ApplicationController
  def new
  end
  
  def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:password])
      log_in user
      flash[:success] = "ログインしました。"
      redirect_to root_url
    else
      flash.now[:danger] = "ログインに失敗しました。"
      render 'new'
    end
  end

  def destroy
    log_out if logged_in?
    flash[:success] = "ログアウトしました。"
    redirect_to root_url
  end
end

```
AWSのロードバランサーをCLBからALBへの移行する

# 概要
・AWSのロードバランサーをCLBからALBに移行する

# CLB/ALBとは・・・
・こちらに詳しく記載されていました。
https://www.wafcharm.com/blog/difference-between-alb-and-elb/
・こういうところの言語化は人任せな私をお許しください。
・とにかくこれから使う方には不要な知識になりますが、とにかくALBの方が断然良いので移行しないと！

# 手順
1. ALBの作成
2. AutoScalingGroupへ作成したALBのターゲットグループを紐付け
3. DNS登録（CLBのDNS名からALBのDNS名に変更）
4. AutoScalingGroupからCLBを外す

# 実施
### １.ALBの作成
・AWSコンソールでロードバランサーの一覧画面を表示し、
・移行対象のロードバランサーで種類がclassicになっているものを選択
・詳細表示枠の移行タブを選択
・「ALB移行ウィザードを起動」ボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/bd116e82-885e-586e-57c0-a7119a49564f.png)

・いきなりALB作成画面の最終確認画面が表示されますのでここでは「作成」ボタンを押さない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/3e761bc5-8b29-9230-b3d3-c64e9049c0f5.png)

・「1. ロードバランサーの設定」タブを選択
・ロードバランサー名がCLBと同じ名前になってしまっているのでALB用の名前に変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/857d09c5-0835-618f-cedb-b870b7de76f9.png)

・「4. ルーティングの設定」タブを選択
・ALBのターゲットグループを作成することになりますのでこちらもCLBと同じ名前になってしまっているのでALB用のターゲットグループ名に変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/96519a33-bc79-1c7b-df76-b0aed354f3df.png)

・確認タブから「作成」ボタンを押下
 ※ 他の設定は移行対象のCLBの情報を引き継いでいるので特に変更は不要（何か変更したい場合は対応する）

### AutoScalingGroupへ作成したALBのターゲットグループを紐付け
・対象のAutoScalingGroupを選択し編集
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/028b9eb4-ae55-2ad3-72b6-44b0a82cb654.png)

・編集画面で「ターゲットグループ」項目に作成したALBのターゲットグループを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/bd56b812-0367-99d7-de2e-f67445e382a5.png)

### DNS登録（CLBからALBに変更）
・DNSでCLBのDNS名を指定していたレコードを選択
・エイリアス先をCLBからALBに変更し、「レコードセットの保存」を押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/b01d2210-995a-9fbf-b186-c930c0d8cfcc.png)

### AutoScalingGroupからCLBを外す
・2.でALBのターゲットグループを紐付けた画面で「Classic ロードバランサー」項目に入っているCLBを削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377903/224aeafb-ce45-5297-d415-2008031d044c.png)

# 確認
・実際にドメインにアクセスしてALBの方にリクエストがきていることを確認し、CLBにリクエストがきていないことを確認する
・CLBを削除してもOK

# 所感
ステージング環境で試しても結局本番環境でも同じことをするので、リスクはありますが、やらないとレガシーになり、
あとでえらい目見そうなのでやって良かった公文式的な。
1ミリでも誰かのためになれば幸いでございます。
ROS_Turtlebot３_step1（デフォルト位置変更）

#ROS_Turtlebot３_step1　

勉強の備忘録です。
turtlebot3の位置は、デフォルトでは原点です。

```amcl.launch
  <arg name="initial_pose_x" default="0.0"/>
  <arg name="initial_pose_y" default="0.0"/>
  <arg name="initial_pose_a" default="0.0"/>
```

![Screenshot from 2019-11-25 20-24-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351913/797fac98-adc0-3b6a-912e-0556b4af7797.png)
なので![Screenshot from 2019-11-25 20-27-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351913/0c980eff-d631-8989-2047-0fdc6210a11b.png)これをいちいち使わないといけません。
そこでめんどくさいので、設定方法はないものかと探索！

turtlebot3_navigation/launch amcl.launchをこのようにすると解決しました。
でも少し不具合があるような気もしている。。。また中身たどってみていこう。

```amcl.launch
  <arg name="initial_pose_x" default="-2.0"/>
  <arg name="initial_pose_y" default="-0.5"/>
  <arg name="initial_pose_a" default="0.0"/>
```

こちらのように問題解決しましたー！
![Screenshot from 2019-11-25 20-06-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351913/5208b681-0325-1ecb-75d2-cae106120434.png)

■謝辞
@MoriKen さんのお力添えもあり感謝です！

■turtlebot3はこちらから
http://emanual.robotis.com/docs/en/platform/turtlebot3/overview/
http://wiki.ros.org/turtlebot3
初心者によるプログラミング学習ログ 168日目

#100日チャレンジの168日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

168日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>168日目<br><br>webサイトコーディング課題<a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a> <a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1198694604536631296?ref_src=twsrc%5Etfw">November 24, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
よく見るHTTPステータスコードを解説しましょう！

元の記事：[https://jp.scrapestorm.com/tutorial/meaning-of-frequently-seen-http-status-codes/](https://jp.scrapestorm.com/tutorial/meaning-of-frequently-seen-http-status-codes/)

人々は今データ分析にかなり重視しています。スクレイピングがますます頻繁になると、IPがWebサイトに禁止されたのはさぞよく遭遇するでしょう。自分もScrapeStormのチュートリアルを作成する時、Webサイトをスクレイピング中によくHTTPステータスコードが見つかります。通常、意味も知らず、直接閉じますか、IPを切り替えます。今回は好奇心を持って、HTTPステータスコードを調べて、紹介します。
###1xx Informational 情報
リクエストは受け取られました。処理は継続されます。但し、HTTP/1.0規約に1xx番号の定義がありませんから、特定の条件以外に1xx番号を送信しません。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/102.png)
###2xx Success 成功
リクエストは受け取られ、理解され、受理されました。よく見るのは200番号と201番号です。
**200 OK**
OK。リクエストは成功し、レスポンスとともに要求に応じた情報が返されます。
ウェブブラウザでページが正しく表示された場合は、ほとんどがこのステータスコードを返しています。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/200.jpg)
**201 Created**
作成。リクエストは完了し、新たに作成されたリソースのURIが返されます。
###3xx Redirection リダイレクション
リクエストを完了させるために、追加的な処理が必要。
**301 Moved Parmanently**
このアドレスは違うアドレスに移動しました。Location:ヘッダに移動先のURLが示されています。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/301.jpg)
**302 Found**
発見した。リクエストしたリソースが一時的に移動されているときに返される。Location:ヘッダに移動先のURLが示されています。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/302.jpg)
###4xx Client Error クライアントエラー
クライアント（ユーザー）側のリクエストに対して、エラーがあった場合を通知します。
**401 Unauthorized**
認証が必要である。ID或はパスワードが誤る場合、返されるステータスコードであります。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/401.jpg)
**403 Forbidden**
禁止されている。リソースにアクセスが受け取りました、だが拒否します。通常、「あなたにはアクセス権がありません」と表示します。スクレイパーとしての我々はこの403番号が最も会いたくないでしょう。一旦403番号の場合、IPが禁止された可能があります。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/403.jpg)
**404 Not Found**
目的のページが存在しない。ライアントがサーバに接続できたものの、クライアントの要求に該当するもの (ウェブページ等) をサーバが見つけられなかったことを示すものです。また、要求に応えられない理由をごまかすためにも使われます。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/404.png)
###5xx Server Error サーバエラー
サーバがリクエストの処理に失敗した。
**503 Service Unavailable**
サービスが一時的に過負荷やメンテナンスで使用不可能である。この状態は一時的なものであり、しばらくすると再開します。
![alt](https://jp.scrapestorm.com/wp-content/uploads/2019/11/503.png)
"You have multiple authentication backends configured ..." への対処法（Django）

# この記事について
日本語で書かれている対処法がなかったので、書き残しておきます。

# 問題の発生

Djangoで作成していたアプリケーションにて、Userを作成してそのユーザーでログインした場合に以下のエラーが発生。

```
You have multiple authentication backends configured 
and therefore must provide the `backend` argument or 
set the `backend` attribute on the user.
```

# 原因

複数のAUTHENTICATION_BACKENDSを使用していたにも関わらず、ログインさせる処理でbackendの指定をしなかったため。

```Python:views.py
# ユーザー登録画面

# ログイン処理
login(self.request, user) # ここでエラー

```

※ソーシャルログイン機能を実装するために```django-allauth```を使用していました。

```Python:settings.py

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.ModelBackend', # ID/pass
    'allauth.account.auth_backends.AuthenticationBackend', # ソーシャル
)
```

# 対処法

backendを指定した。

```Python:views.py
# ユーザー登録画面

# ログイン処理
login(self.request, user, backend='django.contrib.auth.backends.ModelBackend')

```

# 結果
解決しました。
backendを指定する必要があったんですね。
spark-shell でテキスト読み込み

##### 読み込み用のテキストを用意

```bash:directories.txt
Documents
metastore_db
derby.log
Downloads
dev
anaconda3
Music
Pictures
Public
Templates
Videos
Desktop
```

##### 読み込み用のRDD生成

```bash:spark-shell
scala> val dirRDD = sc.textFile("directories.txt")
dirRDD: org.apache.spark.rdd.RDD[String] = directories.txt MapPartitionsRDD[7] at textFile at <console>:24
```

##### 空でないか確認

```bash:spark-shell
scala> dirRDD.isEmpty
res6: Boolean = false
```

##### リストのサイズをカウント

```bash:spark-shell
scala> dirRDD.count
res7: Long = 12
```

##### リストの中身を表示

```bash:spark-shell
scala> dirRDD.collect
res8: Array[String] = Array(Documents, metastore_db, derby.log, Downloads, dev, anaconda3, Music, Pictures, Public, Templates, Videos, Desktop)
```
MacOS Catalinaでroot直下にディレクトリをシンボリックリンク

## 下記を設定後に再起動

```bash
~ » sudo mkdir -p /System/Volumes/Data/sample
~ » sudo chown -R $USER:admin /System/Volumes/Data/sample
~ » echo -e 'sample\tSystem/Volumes/Data/sample' | sudo tee -a /etc/synthetic.conf
```

## 区切りはタブの必要がある

```bash
~ » cat /etc/synthetic.conf
sample  System/Volumes/Data/sample
```
【Kotlin】Collectionの要素を安全に取り出す

この記事は[MicroAd Advent Calendar 2019](https://qiita.com/advent-calendar/2019/microad)の1日目の記事です。

# 状況
「`List`や`Set`と言った`Collection`から要素を1つ取り出す」場合、`get`メソッドや`first`関数を使いたくなります。

```kotlin
val list: List<String> = listOf("a", "b", "c")

val first: String? = list.first { it == "d" }
val secondElement: String? = list.get(1) // 実際は[]を用いることができるが、説明のためgetを用いる
```

しかし、これらの処理は、該当する要素が見つからなかった（e.g. `empty`だった、検索条件に引っかからなかった、要素以上のインデックスだった、等）場合、それぞれ`NoSuchElementException`と`IndexOutOfBoundsException`を投げます。
つまり、「見つからなかったら`null`にする（or した上で`null`だった時の処理を入れる）」的な処理に使うことはできません。

サンプルコードの通り、これらの取得結果を`nullable`型に代入しても警告やエラーにならないため、深いバグになりやすい点でも注意が必要です。

# 対処
（条件分岐や例外処理をしない形での）`Collection`の要素を安全な取り出しは、`null`やデフォルト値を返す関数を用いることで実現できます。
ここでは具体的に以下の3種類を紹介します。

- `~OrElse`系
- `~OrNull`系
- `find`系

「`~`系」としてまとめていますが、これらは関数によって有ったりなかったりします。
その具体的な有無に関しては[ソースコード](https://github.com/JetBrains/kotlin/blob/master/libraries/stdlib/common/src/generated/_Collections.kt)をご覧下さい。

## `~OrElse`系関数を用いる
見つからなければデフォルト値を返すのが`~OrElse`系関数です。
`getOrElse`や`elementAtOrElse`系が有ります。

この`~OrNull`系関数は、以下のように、デフォルトの値生成に`Int -> デフォルト値`のラムダを取ります。

```kotlin
val index // 取得対象インデックス想定

list.getOrElse(index) { i -> // iにはindexが入ってくる
    // デフォルト値の生成処理
}
```

## `~OrNull`系関数を用いる
見つからなければ`null`を返すのが`~OrNull`系関数です。
`firstOrNull`や`getOrNull`などが有ります。

## `find`系関数を用いる
`~OrNull`系関数と同じく、見つからなければ`null`を返すのが`find`系関数です。
`find`と`findLast`関数が有ります。

内容的にはそれぞれ`firstOrNull`と`lastOrNull`を呼び出しています。

# 終わりに
この記事では条件分岐や例外処理をしない形で`Collection`の要素を安全に取り出す方法についてまとめました。

この記事を書いたきっかけは、チームの人間が何人も「`Java`の`Stream API`の`findFirst`メソッドと`first`関数の挙動が違う」という罠を踏んだことです。
しかも前述の通り`nullable`型に代入しても警告やエラーにならないため、ヒヤッとする所に取り残してしまうことも有りました。

`get`系はともかく、何か検索して取ってくるような処理では「見つからなければ`null`またはデフォルト値」を返すだけでいい気がするんですが、何でそうなっていないんでしょうか……。

ともあれ、この記事が`Collection`の要素を安全に取り出すことに役立てば幸いです。
Rails/アンチパターン:  一見すると存在しないアクション





何の変哲も無い（？）コントローラー。これはエクスポート処理関連の各種コントローラーの親クラス

```ruby:controllers/export_controller.rb

class ExportController < ApplicationController

  def some_method
    やりたい処理
  end
end
```


そして、何もないHogeController。よく見るとExportControllerを継承している。これを見落とすとやばい

```ruby:controllers/hoge_controller.rb
class HogeController < ExportController

end
```

最後にrouting。HogeControllerのsome_methodアクションにroutingしている

```ruby:routes.rb
get '/hoge', to: 'hoge#some_method'
```


# 何が問題か
* アクション＝そのcontrollerに定義するという設計スタイルの慣れていると、ExportControllerを継承しているのを見落としガチで、その場合 「some_methodアクションなど定義されていない。routing自体が意味のないものになっている」という判断をしてしまいがち

# どうあるべきか

```ruby:controllers/export_controller.rb

class ExportController < ApplicationController

  def common_some_method
    やりたい処理
  end
end
```



```ruby:controllers/hoge_controller.rb
class HogeController < ExportController

  def some_method
    common_some_method
  end
end
```


--- 
#### あるいはConcernを使う


```ruby:controllers/concerns/export_concern.rb

module ExportConsern
  extend ActiveSupport::Concern

  module ClassMethods
    def common_some_method
      やりたい処理
    end
  end
end
```



```ruby:controllers/hoge_controller.rb
class HogeController < ApplicationController
  include ExportConcern

  def some_method
    common_some_method
  end
end
```


など。何れにしても重要なのはHogeControllerには明示的にアクションを定義し、親クラスのメソッドが暗黙的にアクションとして呼ばれることがないようにするべき



# まとめとか補足とか
* 実際には気付ける方法は幾つかあるので、そこまで問題かというまあまあなところ
* とにかく親クラスのメソッドをアクションとして使用するのは良くない
* と思っていますが、実際どうなんでしょう



# 宣伝のようなもの
都内でRailsエンジニアでアンチパターンや失敗談を共有する会をやりたいと考えています。
conpassとかで見かけたらよろしくです。
CentOS7で一般ユーザがsudoを使えるようにする

## 環境

* CentOS Linux release 7.6.1810 (Core)


## 前提

`sudo`しようとしてパスワードを入力すると、`(ユーザ名) is not in the sudoers file.  This incident will be reported.`となる。

ここでは、`sudo`できないユーザを`normaluser`とする。

```
[normaluser@localhost ~]$ whoami
normaluser

[normaluser@localhost ~]$ sudo su -
[sudo] password for normaluser:
normaluser is not in the sudoers file.  This incident will be reported.
```



## 手順

### 1.  rootでログインする

`root`の権限を与える操作なので、`root`でログインする必要がある。

以下のコマンドを入力し、`root`のパスワードを入力する。

```
[normaluser@localhost ~]$ su -
Password:
```

ログインに成功すると、コマンドの頭の文字が`$`から`#`に変わる。

```
[root@localhost ~]#
```

`su`が使えない場合は、ログイン画面に戻って`root`でログインする。



### 2. wheelグループを全コマンド実行可能なグループにする

`vi`コマンドで`/etc/sudoers`を開く。デフォルトでは100行目付近に、`wheel`グループのコマンド実行権限についての設定がある。

viエディタをコマンドモードで開いている間に`:set nu`と打つと、行番号が表示される。

```
[root@localhost ~]# vi /etc/sudoers

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

## Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL
```

パスワードを要求するならそのまま。
要求しないなら以下のように変更する。

(コメントアウトする場所を変更する。)

```
## Allows people in group wheel to run all commands
# %wheel  ALL=(ALL)       ALL

## Same thing without a password
%wheel        ALL=(ALL)       NOPASSWD: ALL
```



### 3. ユーザをwheelグループに追加する

以下のコマンドを実行する。

```
[root@localhost ~]# usermod -aG wheel normaluser
```

変更できたか確認する。

```
[root@localhost ~]# id normaluser
uid=1001(normaluser) gid=1001(normaluser) groups=1001(normaluser),10(wheel)
```

`wheel`グループに入っていることが確認できればOK。



### 4. sudoできるか確認する

一般ユーザに戻り、`groups`コマンドを使って`wheel`に所属できているか確認する。

※`exit` で`root`から戻った場合は、再ログインする。

```
[normaluser@localhost ~]$ groups
normaluser wheel

[normaluser@localhost ~]$ sudo su -
[sudo] password for normaluser:
Last login: Mon Nov 25 01:01:20 PST 2019 on pts/0
[root@localhost ~]#
```
`normaluser`のパスワードを入力すると、`root`にログインできる。

以上で、`sudo`を実行できることが確認できた。



## 参考

 [CentOSでuserをsudo可能にする]( https://qiita.com/Esfahan/items/a159753d156d23baf180 )
CentOS6の内容ですが、ほぼ同様の手順です。
preg_matchが2を返す

# https://bugs.php.net/bug.php?id=78853


[preg_match](https://www.php.net/manual/ja/function.preg-match.php)は、パターンにマッチした場合は1を、マッチしなければ0を、エラーが発生したらfalseを返します。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/9894f7a5-617f-5e43-0d63-3b07558193c0.png)

ということでこんな正規表現を試してみましょう。

```php
var_dump(preg_match('/^|\d{1,2}$/', "7"));
```

[結果](https://3v4l.org/m49BV)

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/2d4b0286-aa7e-b8f0-4402-3ae777028a98.png)

なんだこれ？

2が返ってきました。
仕様が変わったけどドキュメントが更新されてなくて古いのかと思えば[英語版](https://www.php.net/manual/en/function.preg-match.php)にもしっかり"1か0かfalseを返す"と書いてあって、ドキュメントが古いわけでもなさそうです。

PHP7.3から発生するようになったみたいなので、ちょっくら原因でも探ってみるかとソースを覗いてみたのですが、
[7.3.0](https://github.com/php/php-src/blob/php-7.3.0/ext/pcre/php_pcre.c#L988)
[7.2.24](https://github.com/php/php-src/blob/php-7.2.24/ext/pcre/php_pcre.c#L742)

諦めました。


ちなみにPHP7.0でコンパイルオプション`pcre.jit`というものが追加され、[正規表現にJITを使う](https://qiita.com/ryosukes/items/3f526ff0dd3fc4f9c3b5)ようになっています。
このJIT用メモリというのが意外と小さく、たとえば以下の正規表現は`pcre.jit`の状態によって返り値が変わってきます。

```php
var_dump(preg_match('/^(A{1,2}B)+$/',str_repeat('AB',8192)));
```

`pcre.jit=0`であれば返り値は正しく1となります。
しかし、デフォルトの`pcre.jit=1`であれば返り値はfalseとなり、[preg_last_error](https://www.php.net/manual/ja/function.preg-last-error.php)にはJIT用メモリが足りないよという[PREG_JIT_STACKLIMIT_ERROR](https://www.php.net/manual/ja/pcre.constants.php)が返ってきます。


でも`pcre.jit=0`にしても、最初の正規表現では2が返ってきました。
preg_last_errorを確認してもエラーは起こっていないので、`pcre.jit`は特に関係ないようです。


さてこのバグですが、先日[修正されました](http://git.php.net/?p=php-src.git;a=commit;h=e1da72bdf18aa3d413c5324bccfd8dc521c217e3)。
[7.4にもマージされた](https://github.com/php/php-src/commit/cfb643ca2b1e03d0211b5bf089560c1dd3a41359)ので、2019/11/28リリース予定のPHP7.4.0正式版ではなおっていると思います。

なお、中身は[ifをひとつ突っ込んだだけ](https://github.com/php/php-src/commit/e1da72bdf18aa3d413c5324bccfd8dc521c217e3)で、どうしてこんなので直るのかさっぱりわかりません。
Eloquent、Queryあたりでよく詰まったところ



###　モデル名::query()とは？
モデルを生成している。Event::query()なら、Eventモデルに書かれた内容を元に、モデルをコピーしているようなイメージ。


```php

    $query = Event::query();　//←モデルEventのコピーを作ってる状態

    return $query->displayed()->notEnd()->orderByForEvent()->get(); //このgetでDBから中身取得
```


### EloquentとQueryって？
DBとモデルを対応づける機能が定義されている。
このサイトがわかりやすい！
https://nextat.co.jp/staff/archives/131



###　$requestとは？
Railsでいうところのparams。ユーザーから受け取った情報が入ってる。




###　変数等に何の値が入ってるか見たい時

```php

    var_dump(中身を見たい変数名等);
    exit;
```

binding.pryの代わりに活用。


### よく苦しめられるエラー

```php

Call to undefined method Illuminate\Database\Eloquent\Builder::all();
```
もしくは

```php

Method Illuminate\Database\Eloquent\Collection::（なんらかの変数名） does not exist.
```


$query = Event::query();はモデルを作成しているが、
$query = Event::query();->all();や
$query = Event::query();->get();とすることで、
モデルの中身の配列を取得してしまうため、モデルに使うメソッドを使用するとエラーとなる。


### リレーション先のテーブルにデータが入っているものだけ取得したい
https://www.yukiiworks.com/archives/256
上記を参考に。

```php

        $query = モデル名::with('リレーション先のテーブル名');

        $query->whereHas(
            'リレーション先のテーブル名',
            function ($content) { 　　　　　　　//引数は任意の単語で
                $contents->whereExists(
                    function ($contents) {
                    }
                );
            }
        );

```
これで取得できました。
「Elasticsearch実践ガイド」を読んだ個人的メモ

Elasticsearchで開発する機会があるので、基礎的なことから学習するため、
[Elasticsearch実践ガイド](https://www.amazon.co.jp/dp/4295003913)
を買いました。読んだ個人的な感想をメモします。

## 今回読んだ目的
以前、[EC2にElasticsearch、Fluentd、Kibanaを入れる方法](https://qiita.com/murapon/items/23c409f995f4cf1cb534
)で、アクセスログをElasticsearchに入れてkibanaで分析するのをしたのだけど、今回は、

- CSVファイルを読み込み、そこに記載されたデータをElasticsearchに登録
- API経由でElasticsearch内のデータをいろいろな方法で検索

をする必要があり、１からの学習する為、読んだ。
Elasticsearch自体は、[Amazon Elasticsearch Service](https://aws.amazon.com/jp/elasticsearch-service/)を使うので、環境周りの設定は後回しで、使い方を主に学習。

## 概要とメモ
### 「第1章 Elasticsearchとは」から「第2章 Elasticsearchの基礎 2-3 REST APIによる操作」
全文検索の仕組みからElasticsearchの基本的な事柄が記載。
ネットの記事だと、簡単な説明のあと、インストール作業、使ってみよう的なのが多いので、書籍の方がまとまった情報が得やすい。
データを入れて検索する処理などが、MySQLなどのDBと似ているので、 インデックスと聞くと検索を早くするのに使うものを想像しがちなんですが、ElasticsearchではDBのテーブル的なものを意味するものでだった・・。
Elasticsearchは独特？の用語が使われているので、用語は正しく理解することをおすすめ。
#### 一部抜粋
- ドキュメント：DBのレコードに該当
- フィールド：ドキュメント内の項目名、値のセット
- インデックス：DBのテーブルのようなもの
- ノード：Elasticsearchが動作するサーバー
- クラスタ：ノードのグループ

「2-3 REST APIによる操作」は、実際に使いながら方がわかりやすいのでざっと読むだけ。

### 「第2章 2-4 Elasticsearchの導入方法」
いろいろな構築方法が書いてあるが、
今回は本を買う前に、[初めてのElasticsearch with Docker](https://qiita.com/kiyokiyo_kzsby/items/344fb2e9aead158a5545)を見て、docker環境を作ってたので、その環境を利用。バージョンは7.1（AWSでサポートしている最新バージョンが7.1なので）。
書籍では、6.2でしたが、基本操作を見るだけだったので、バージョンの違いによる影響は感じません。

### 「第３章 ドキュメント/インデックス/クエリの基本操作」
一般的なDBのようにテーブルを定義しなくてもデータを入れてくれますがドキュメントタイプを定義することでテーブル定義のように扱うことも可能。ただ一度定義するのを変更することができないので、要注意（フィールドの追加はできても変更はできない）。
curlで実行、確認ができるので、デバッグがしやすいし、連携するプログラムも書きやすい。

ここには載ってなかったが、
あいまい検索は、
[Elasticsearchのfuzzy queryを使って、あいまい検索を試してみる](https://qiita.com/EastResident/items/5ebdd5d301838fd1be24)
日付の差分を条件にしたい時は、
[Elasticsearch でフィールド同士の差分で検索したい](https://inokara.hateblo.jp/entry/2018/07/31/094040)
ランダムにソートしたい時は、
[よく使うElasticSearchのクエリ（データ取得）](https://qiita.com/nakazii-co-jp/items/997a980f34bce5440628)
の各ページを参考にできそう。

### 「第4章 Analyzer/Aggregation/スクリプティングによる高度なデータ分析」
#####Analyzer
形態素解析だけでなく、フィルターをかけて文字列の変換をしてくれる。
以前、DBで検索処理した時は、ひらがなをカタカナに、全角英数字を半角英数字に変換してデータを入れて、検索対象の文字列も同様に変換することで、できるだけ文字のゆらぎを抑えて、広範囲に検索できるようにしてたら、それらを全部やってくれる。
できることが多くので逆に迷いそうではある・・。
#####Aggregation
集計ができる機能。SQLで **GROUP BY** して **COUNT** するイメージ。
SQL文より記述量が多く、慣れるまで面倒そう・・。

### 「第5章 システム運用とクラスタの管理」
今回、AWSを利用するのでここはざっと読んで終わり。
（AWSがどこまでやってくれるは、別途調査が必要かなと。）
いろいろと注意点があるので、オンプレでやる時は考慮する点が多そう。

### 「第6章 Elasctic Stack インテグレーション」
Kibana、Logstash、Beats、X-Packについて書かれてるけど、使う予定がないので流し読み。

## 感想
初心者にもわかりやすい。特に第1章〜第3章まではわかりやすくこれを読めば、ある程度の操作ができるようになると思う。
逆に第5,6章は導入する環境やサービスによって実施内容が異なるので、必要になったときに後から読み返したい。
AWS認定 デベロッパー アソシエイト（DVA-C01）の受験記録

**2019/11/22に試験に合格しました。**

https://qiita.com/murapon/items/ae5778ae221a62ed9d21

と

https://qiita.com/murapon/items/15d511d18d6575a620eb

に続けて、今年3つ目の試験です。
こちらも、SAAに合格できたらあまり学習しなくても合格できるという話を聞きますが、人によりますので、注意してください。

## 学習内容

### 1. 試験ガイドの確認
https://aws.amazon.com/jp/certification/certification-prep/

「開発者 – アソシエイト」の欄にある、「AWSホワイトペーパーおよびよくある質問」の、
ホワイトペーパーやよくある質問、対象サービスのBlackbeltを全て読みます。
読んでも全然頭に入らないので、1,2回ざっと読んで終了。
問題集へ・・・。

### 2.WHIZLABSで学習

https://www.whizlabs.com/aws-developer-associate/practice-tests/

デベロッパー試験の向けには黒本がないので、WHIZLABSのみで学習しました。
Udemyと迷ったのですが、問題の数が多いこちらにしました。
買ってから気付いたのですが、問題数が多い（700問以上）のは、旧試験の問題も含まれている為で、
新試験用は、65×5回分で、Udemyと大きな違いがありませんでした・・。

前回と同様、複数回繰り返して9割以上正解できるようになりました。

## 試験振り返り
832/1000で合格しました。
今回は、「これ〇〇ゼミでやったやつだ」的に、自信を持って答えられる問題が3割、残りは消去法と、勘で解きました・・。
結果として、今まで一番良い点数が取れたのですが、前回までの試験よりも自信を持って答えられる問題が少なく不合格かもしれないと一瞬思いました。
問題集による学習で、全問暗記したとしても、試験範囲を全てカバーできたわけではないので、
最低限、試験対象となるサービスのblackbeltやホワイトペーパーに目を通し、Lambdaにサーバーレス の実装は体験しておいた方がよかったと思いました。
ヌレボージョーボー

```python
import random
wine = ["ボ", "ジョ", "レ", "ヌ", "ボ"]
random.shuffle(wine) #これのせいで無駄に時間がかかった。
print("".join([wine[i] if i < len(wine)-3 else wine[i] +"ー" for i in range(len(wine))]))
```

誰かもっと短くしてください。

#元ネタ
[ヌジョレーボーボー](https://qiita.com/mattn/items/ae764601862b0073071e)
[UE4]Targetに複数の要素を一撃で投入する


ブループリントのExcuteノードには一つだけでなく<font color="Blue">複数のTarget</font>を<font color="Red">**一撃で**</font>投入することが可能です！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464248/28fa0110-7436-7af2-7d74-149b7ff55429.png)

例の上の方のように、複数の要素から複数のワイヤーを伸ばしてつなげるのも問題ありませんし、
下のようにTArrayで帰ってきているものをそのまま投入することも可能です！


<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="und" dir="ltr"><a href="https://t.co/DzMvZp1VLU">pic.twitter.com/DzMvZp1VLU</a></p>&mdash; Takashi.Suzuki (@wankotank) <a href="https://twitter.com/wankotank/status/1198910479181070336?ref_src=twsrc%5Etfw">November 25, 2019</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Laravelでマイグレ。$table->integer()の罠

「わ〜！なんでやねんなんでやね〜ん」と私グレてます。

```php5:laravel6でmigrationカスタマイズ
            $table->integer('gender', 1);           // 性別：-1 ♂, 0, 1 ♀
```
ってやってました。そうしたらこう怒られるんです！

```bash
   Illuminate\Database\QueryException  : SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table definition; there can be only one auto column and it must be defined as a key (SQL: create table `pre_registers` (`id` bigint unsigned not null auto_increment primary key, `first_name` varchar(100) not null, ...
```
って。わけわからん。

もうどうしようもなくなって事務所を飛び出して、夜の街をぶらついたんです。でもやっぱり「戻ってググろう」って思い直して…

要するに結論は第２引数指定したら`autoincriment`されるんだって。


## 参考記事
[integerのサイズの指定方法に注意](https://qiita.com/msht0511/items/49ca034426ad7c036e23#%E7%B5%90%E8%AB%96)
scss mixin使い方

scssでのmixinの使い方について

##mixinとは
ｃｓｓのいくつかのコードを１つにまとめて簡単に呼び出す事ができるようにする機能
これによって同じ内容の記述を何回も書く必要がなくなる

##mixin定義方法

```scss
@mixin コード名 {
  width:100px;
  height:100px;
}

//mixinを呼び出す
.example{
@include コード名;
}
```
NPMとpackage.jsonについて調べたこと（その周辺の用語も）

勉強したことの備忘録としてメモしているので間違っているところがあればぜひご指摘ください！

## npmには２種類ある
1.   オンライン上のパッケージレジストリ
1.   Node.jsに付属している、パッケージを操作するためのCLI(コマンドラインインターフェース）


- Node.jsのプロジェクトにはnpmのパッケージ１こに対応する。
➡︎プロジェクト一つ開発するということはパッケージを一つ作り上げる

- npmに取ってパッケージは、package.jsonというファイルの親ディレクトリに含まれるファイル群。

## npmとは
Node Package Managerの略で、JavaScriptライブラリのパッケージマネージャー。Node.js用のパッケージ管理ツール。npmプロジェクトの情報管理しているのが、package.json。

## パッケージマネージャーとは
コンピューターに何のソフトウェアがインストールされたかを記録し、新しいソフトウェアのインストール・新しいバージョンへのソフトウェアの更新・以前インストールしたソフトウェアの削除を容易に行えるようにするプログラム。
[元サイト](https://www.debian.org/doc/manuals/aptitude/pr01s02.ja.html)

## パッケージとは
ファイル群を一つにし、インストールや削除をまとめてできるようにしたもの。多くの場合、パッケージはある特定のプログラムにすぎない。

## package.jsonとは？
- 空のpackage.jsonを作ったり、npm init　コマンドで作成できる

### package.jsonに書かれている内容
1. script
2. dependencies
3. devDependencies

1.はnpm initで作成した直後のpackage.jsonに含まれているが、他はライブラリをインストールした時に追加される項目

#### scriptについて
これはコマンドショートカットで記述できる。
役割は、実行するコマンドの内容を指定した値でセットすること。

ex)scriptプロパティの中で、"start":"node index.js"と記述すると、node index.jsというコマンドをnpm start もしくはnpm run startで実行できる。


#### dependenciesとdevDependenciesについて

- どちらも依存ライブラリを管理する。
- dependenciesは「***サービスを動かす上で必要なライブラリ***」を管理している
- devDependenciesは「***開発効率をあげるツールや、保守運用に役立つツール***」など、直接サービスを動かす上では必要ではないが、あると便利なツールを管理する。


[参考サイト](https://tsuyopon.xyz/2019/02/08/how-to-create-a-package-json/#packagejson)
【2019年11月】バージョンの"CR"ってなんだ？RC=Release Candidateと違うの？

# 1.0.0.CR2 って、どういうバージョン？

最近取り上げている Quarkus ですが現在のバージョン番号は `1.0.0.CR2` となってます。いや…"CR" ってなんすか？ということなのですが…

同様の疑問がこちらに上がってました。

- [What does CR mean in version numbers?](https://softwareengineering.stackexchange.com/questions/125308/what-does-cr-mean-in-version-numbers)

> "Hibernate" の "CR" てバージョンは何よ？

ということですが

> It's actually Candidate Release.
> CR=candidate for release

`Candidate Release`だし、 `candidate for release` なんだよね！という腑に落ちない感じになっております。

…いや、だから、それってどうなん？？と思っておりますと、ご丁寧に jboss のプロジェクトにおけるバージョン管理というかバージョンの比較方法についてのリンクが張ってありました。

- [JBoss Project Version Convention](https://developer.jboss.org/wiki/JBossProjectVersioning)

これによると、数字の `x.y.z` のそれぞれの大小でバージョンの新旧がきまるのは当然ですが、文字列部分も **compareTo** を定めてありますね！

```
this.charAt(k)-anotherString.charAt(k)
```

まずは文字の先頭から文字コードの大小比較と…

```
this.length()-anotherString.length()
```

短い方が新しいバージョンとなる、というルールのようです。

ということでまとめると、

```
major.minor.micro.Alpha[n]
major.minor.micro.Beta[n]
major.minor.micro.CR[n]
major.minor.micro.Final
```

この順番ね！ということだそうです。

`RC` じゃ `Final` の後にきちゃうから、という **Comparable な都合**で `candidate for release` という荒技を編み出した模様です。。。
curlで取得したウェブのソースコードに色を付けたい

iPadでコーディングをしているとブラウザからソースを確認できないため不便です。
ソースを見る専用のアプリもあるようだけど、アプリを入れずにどうにかならないかと模索しました。

対象はiPadからリモートでLinuxに入って作業するような人です。
※iPadのプログラミング環境構築の話はこちら
https://qiita.com/shuuuta/items/7a3f3801e0209f9ad5ac

# コマンドの流れ

curlで取得してsource-highlightで色つけてlessで見ます。

# source-highlightをインストール

source-highlightが必要なのでまずはインストール。aptなら以下で。

```
$ sudo apt install source-highlight
```

# 使ってみる

コマンドはこんな感じ。

```bash
curl -s https://qiita.com|source-highlight --failsafe -f esc --line-number -s html|less -R
```

オプションはこんな感じになっています。

- source-highlight
    - -f esc: エスケープシーケンスを使って色を表現。
    - -s html: ハイライトの種類をhtmlに指定。
- less -R: カラーエスケープシーケンスを読み込む。

# 関数にしておくときっと便利

~/.bashrcにこんな感じで書いておくと都度長々書かなくてすみますね。

```bash:.bashrc
function websource {
  curl -s $1|source-highlight --failsafe -f esc --line-number -s html|less -R
}
```

```bash
websource https://www.yahoo.co.jp
```

<img width="1194" alt="D2D41134-A51C-4731-9E31-CB078E14D286.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479523/cb489d0b-9f42-121e-fd1c-33739b0e5d70.jpeg">

ちゃんと色分けされて取得できました。

# ソース表示と開発者ツールをお願いします

ブラウザのソース表示とウェブインスペクタがiPad OSで実装されたらいいなぁと思っていましたが、残念ながらきませんでしたね。
実装される気配もないですが、この2つさえ使えればあとはフロントエンド制作もなんとかなりそうなんだけどなぁ。
appleさんよろしくお願いします。

# [追記] batコマンドを使う方法

コメントでbatというコマンドを教えていただきました、ありがとうございます。
https://github.com/sharkdp/bat/blob/master/doc/README-ja.md

githubから落としてインストールしたら

```bash
curl -s https://qiita.com|bat
```
でハイライトされたコードが見られます。
<img width="1194" alt="7F3A967A-3826-44F1-A021-82A97FB11675.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479523/aa6fb2aa-54de-0cd6-0227-070072ff5bc9.jpeg">
デフォルトのカラーはこっちの方が好みだなぁ。