OmniAICreator/Qiita-1.07M huggingface dataset:
【メモ】いまさら正規表現入門

# はじめに
  
 > 「正規表現ってちょっと難しそうだからまた今度勉強しよう・・・」って先延ばしにしていたら３ヶ月経っていた人向けの記事です。

## 正規表現って？

正規表現とは、

`いくつかの文字列を１つの文字列で表現する方法`

例えば、

```example
090-0000-0000     // 電話番号
111-0000          // 郵便番号
```

こいつらは、

```example
/\d{3}-\d{4}-\d{4}/
/\d{3}-\d{4}/
```

こう表せます。

ちなみに正規表現を英語にすると`Regular Expression`で、しばしば`regex`や　`regexp`と略されるそうです。

どちらが正しいのかは[こちら](https://stackoverflow.com/questions/3058246/which-is-the-correct-shorthand-regex-or-regexp/3058259?stw=2#3058259)で議論されていて、
結果的にどちらでも良いと結論づけられています。

なお、ベストアンサーは`/regexp?/ `です。
`?`は`p`の有無を両方許容すると言う意味です。

## 1. /<正規表現>/

~~正規表現を書くときは`/(スラッシュ)`で囲みます。~~

言語によるみたいです。

## 2. /<正規表現>/g

文末に`g`がある状態すなわち、
/<正規表現>/`g`だと全ての文章からマッチするものを全て見つける。
逆に`g`を付けなければはじめてマッチした時点で処理をストップする。

/<正規表現>/g`?`

## 3. \dの意味

正規表現において`\d`は`半角数字`を表します。
なので、

```
444 <=> /\d\d\d/
20191110 <=> /\d\d\d\d\d\d\d\d/
```

であり、

```
444 <=> /\d{3}/
20191110 <=> /\d{8}/
```

であり、

```
444, 20191110 <=> /\d{3,8}/
```

とも表せます.

## 4. []の意味

`[AB]`の意味は`AもしくはB`と言う意味です。

```
America, Bmerica <=> /[AB]merica/
```

また`[a-z]`は`a || b || c || ... || z`と言う意味になります。`[0-9]`や`[A-Z]`についても同様です。

## 5. 他の様々なメタ文字

| メタ文字 | 意味 |備考 |
|:-:|:--|:-:|
| . | 任意の一文字 |   |
| ? | 直前の文字列の有無の許容, 最短のマッチを返す | "(.*?)" |
| + | 直前の文字が１文字以上 |   |
| () | 括弧内がキャプチャされる, グループ化 | (?: )でキャプチャ回避  |
| * | 直前の文字が0文字以上 |   |
| \w | [a-zA-z0-9_] | \Wは\wの否定 |
| ^ | 直後の文字以外, 行頭 | [^A] |
| $ | 行末 |   |
| \t | タブ |   |
| \s | スペース | 環境によって意味が異なる場合がある, \Sは\sの否定 |
| ｜ | OR | (A｜B) |
| \n | 改行文字 | windows環境だと\r\n |
| \b | 単語の境界 | \Bは\bの否定 |
| (?<=) | =の直後文字列の直後の位置にマッチする |  |
| (?=:) | :の直後の文字列の直前の位置にマッチする |  |
| (?<!) | !の直後の文字列以外の直後の位置にマッチする |  |
| (?!) | !の直後の文字列以外の直前の位置にマッチする |  |
| \1 | キャプチャされた１番目の文字列 |  |

### 参考にした記事

* [初心者歓迎！手と目で覚える正規表現入門・その１「さまざまな形式の電話番号を検索しよう」](https://qiita.com/jnchito/items/893c887fbf19e17d3ff9)
* [サルにもわかる正規表現入門](https://www.mnet.ne.jp/~nakama/)
* [正規表現とは?](https://qiita.com/soarflat/items/2b50c1efe2ea54a762d7)
CKAD受験記

# はじめに

CKAにつづき、Certified Kubernetes Application Developer(CKAD)を受験したのでメモを。
CKA取得済みのため、一からCKAD向けの学習をする人には、あまり参考になりません。

CKA受験から、CKAD受験の感覚は２週間。

CKAの受験記録は[こちら](https://qiita.com/yo24/items/4edbbb9a9816e63ee83d)


# CKAを取得済みで、CKAD受験を迷われている方へ

CKAを取得済みの人が、CKADを取得するメリットは、ほぼないと感じました。

2019/11 CKADの試験範囲はCKAのサブセットのように感じました。

CKAの試験範囲から、クラスタ管理やControl Planのトラブルシューティングを除いたものが、CKADの試験範囲かなといった感じ。
CKADで目新しいのものは、Liveness, Readiness Probeぐらいでした。


# 学習方法

CKA取得後、以下のコンテンツで学習しました。

### Udemy - Kubernetes Certified Application Developer (CKAD) with Tests

CKAの受験時も利用したUdemyコース同じ作者の[コンテンツ](https://www.udemy.com/course/certified-kubernetes-application-developer/)です。
コースは、レクチャー+ハンズオンで構成されますが、ハンズオンのみ実施しました。

CKAD受験後にCKAを受験を予定する人は、同じ作者のCKA用[コンテンツ](https://www.udemy.com/course/certified-kubernetes-administrator-with-practice-tests/)で代用可能なので、こちらを購入してもよいかもしれません。

※定価はお高いので、udemyのセール中に買いましょう。セールは頻繁に開催されています。

### CKAD Exercises

有名なCKAD用の[ハンズオン コンテンツ](https://github.com/dgkanatsios/CKAD-exercises)です。これを１周しました。

なお、ハンズオン用の環境は、付属していないので注意しましょう。
自分は、先に記載したUdemyコースのハンズオン環境を利用しました。

また、本試験はハンズオンより難しいので注意しましょう。

# 試験結果

スコアは、81%(合格ライン:66%)でした。
１問 時間切れで解けず、+ 3問ぐらい間違えてそうでした。

# 試験の感想

CKAと同じく、時間が足りませんでした。
問題ごとに難易度がまちまちなのも、CKAと同じです。

時間を要しそうな問題やエラー等で詰まった問題は飛ばし、最終問題まで回答することが必要です。
その上で、簡単な問題を全て回答するのが合格の近道です。

あと、今回は日本語試験(CKAD-JP)で受験しました(CKAの時は英語)。
試験官が日本語でチャットするのかと思っていましたが、英語でした。
試験は、CKAと同じく言語の切り替えは可能で、英語と日本語の差異は？？？
CORSエラーが出てしまったらヘッダー情報を追加しよう

## 状況・経緯
Node(express)を使用してAPIを作成。そのAPIを別で立てたローカルサーバーでアクセスしたら以下のようなエラーが出た。

```
Access to fetch at 'http://localhost:3000/' from origin 'http://127.0.0.1:8080'
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
```

`http://127.0.0.1:8080`から`localhost:3000`へのアクセスは CORSポリシーによってブロックされていますといわれてしまった・・・


## CORSとは

オリジン間リソース共有（**C**ross-**O**rigin **R**esource **S**haring）のこと。セキュリティ上の理由からブラウザからオリジン間HTTPリクエストを制限している。

>オリジン間リソース共有Cross-Origin Resource Sharing (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジンで動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、**オリジン間 HTTP リクエスト**を実行します。

[オリジン間リソース共有 (CORS)](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)


##  No 'Access-Control-Allow-Origin' header is present on the requested resource. とは

>CORS リクエストへのレスポンスが、リソースが現在のオリジン内で操作しているコンテンツによってアクセスできるかどうかを判断するために使われる、必須の Access-Control-Allow-Origin ヘッダーを欠いています。

ヘッダー情報に`Access-Control-Allow-Origin`がないからダメと怒られているらしい。

## 解決策

解決するには、
`set the request's mode to 'no-cors' to fetch the resource with CORS disabled.`
CORSを無効にして `no-cors`モードをセットしろとのこと。

なので、

ヘッダーに 

```
Access-Control-Allow-Origin: *
```
を追加した。

### 何をしたのか

自分で用意したサーバーへのアクセスを許可した。

今回の場合、`http://127.0.0.1:8080`でアクセスしようとしたらエラーが出たのでこのように書くとアクセスが許可される。

```
Access-Control-Allow-Origin: http://127.0.0.1:8080
```

また、ワイルドカードである`*`を使用することであらゆるアクセスを許可することができる。

### `Access-Control-Allow-Origin: *`を使う際の注意点

公開するAPIには使用しても問題ないが、非公開APIには具体的なドメインやドメイン一覧を設定すること。

詳しくは↓
[Reason: CORS header 'Access-Control-Allow-Origin' missing](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS/Errors/CORSMissingAllowOrigin)

### expressでサーバーを立てた場合

``` server.js
const express = require('express');

const app = express();

const port = process.env.PORT || 3000;
app.set('port', port);

// サーバースタート
app.listen(port, () => console.log(`App started on port ${port}.`));

// ドメイン直下(localhost:3000)にアクセスした時の処理
app.get('/', (req, res, next) => {
  res.set({ 'Access-Control-Allow-Origin': '*' }); // ここでヘッダーにアクセス許可の情報を追加
  
  // 何らかの処理
});

```

このような感じになる。

### この記事を読んでもCORSがいまいちよく理解できないときは
GIFアニメーションを使って詳しく解説しているこちらの記事がおすすめです。
[CORSの仕組みをGIFアニメで分かりやすく解説](https://coliss.com/articles/build-websites/operation/work/cs-visualized-cors.html)

https://coliss.com/articles/build-websites/operation/work/cs-visualized-cors.html

---

**参考**
[オリジン間リソース共有 (CORS)](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)
[CORS のエラー](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS/Errors)
[逆引きメモ：expressの使い方](https://qiita.com/morou/items/06cbe49f64d56d31b793)
ゲームエンジンGodotでROSの点群ビジュアライザを作ってみた

# 概要
ゲームエンジンGodotでROSのノードとして動作する点群ビジュアライザを作ってみました。

作ったもの：https://github.com/ymd-stella/godot_ros_pcviz

![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472745/4eb82c7f-c272-40a4-effe-274ef2f85708.png)

# Godot
https://github.com/godotengine/godot
Godotはオープンソースのゲームエンジンです。
UnityやUnreal Engine 4に比べて知名度が低いですが、軽量で簡単に使えるという大きな利点があります。

# Godotをセットアップ
以下からダウンロードしてunzipしたら実行形式のファイルを入手できます。
https://godotengine.org/download/linux

# godot-cpp
https://github.com/GodotNativeTools/godot-cpp
Godotの標準のスクリプト言語はGDScriptというpython似の言語ですが、GDNativeを使うとC++でプラグインを作成できます。
これを利用してGodot上でROSノードを動かします。
バージョン3.1のbranchを使ってCmakeでビルドしました。

# Godotのノードとシーン
Godotではカメラ、描画対象などをノードとして扱います。
各ノードにはスクリプトをアタッチして振る舞いを変えることができます。
ノードは子ノードを任意の個数持つことができるので、ツリー構造を作ることができます。
このツリー構造をシーンとして保存することができます。
点群ビジュアライザを作るために描画を行う[ImmediateGeometry](https://docs.godotengine.org/en/3.1/classes/class_immediategeometry.html)と視点の設定を行う[Camera](https://docs.godotengine.org/en/3.1/classes/class_camera.html)を含むシーンを作成しました。

# カメラ操作
GodotのGUI上でカメラ初期位置を設定することが可能です。
良さそうなアセットが見つからなかったのでとりあえず実行中のマウス操作は無しにしました。

# カラーマップ
OpenCVを利用してparula(matlabのデフォルトカラーマップ)で色付けしました。
Rvizのrainbowよりも強弱が直感的になって良さそうです。

# ROSノードを動かす
Godotのノードのメソッドをオーバーライドして、PointCloud2のSubscriber生成、ros::spinOnce()の実行、ImmediateGeometryの生成・操作をしています。
（コマンドライン引数は取れないのでダミーデータをros::initに渡しました）

# 最後に
100行程度のC++コードでシンプルな点群ビジュアライザを作ることができました。
後は、rvizと同等のカメラ操作を可能にするスクリプトとtfを処理するプラグインを作れば使えるようになりそうです。
SPMでRun Scriptで実行したいライブラリを導入する

## tl;dr

Xcode11が出て格段に使いやすくなったSwift Package Manager

ライブラリが基本的にDerivedData内にいくことや、別途の環境構築が不要なことからできるならどんどんとSPMに移行していきたい気持ちがあると思います。

その中でも今回はRun Scriptで実行したいライブラリ（コードを綺麗に管理するためのSwiftLintやSwiftFormatなど）をSPM導入するためにした工夫を紹介します。

## 注意

今回の記事はSwiftFormatをもとに説明します。
大前提としてSPMで落としてきたライブラリのファイルの中に実行ファイルが含まれることが必要となります。
SwiftLintは依存パッケージの一部がXcode11の最新バージョンに対応できていなかった上、実行ファイルがSPMで配信されるファイルに含まれていなかったのでこの方法は利用できません。

## どうするか？

これらのツールをCocoaPodsで導入する場合 `$PODS_ROOT` という環境変数がCocoaPodsのビルドフォルダを指していたのでそれを利用することができました。
ですがSPMの場合、このような環境変数が存在していません。なのでそれをどう用意するかが肝となります。

Swift Package Dependenciesから適当に右クリック>Finderで表示とすると、Xcode11におけるSPMであつかうライブラリ群は`DerivedData/<AppName>-xxx/SourcePackages/checkouts`という場所に落とされてきていることがわかります。
ですので目標としてはこれを適当な名前でexportもしくは指定してあげることになります。

ですが場所がDerivedDataの中なので一度クリーンなどしてしまったり、環境が変わるとこのフォルダ名が変わってしまいます。そのためハードコーディングは好ましくありません。

そこで利用するのが`$BUILD_ROOT`です。これは`DerivedData/<AppName>-xxx/Build/Products/`を常に指している環境変数になります。
そしてこれにフルパスから親のディレクトリのフルパスを取り出せる`dirname`というコマンドを使ってあげることで目的の環境変数を作ります。

すなわち最終的なコマンドはこうなります（SwiftFormatの場合）

```sh
export SPM_ROOT=$(dirname $(dirname $BUILD_ROOT))/SourcePackages/checkouts
"${SPM_ROOT}/SwiftFormat/CommandLineTool/swiftformat" . [YourOption]
```

これでSPMで導入したSwiftFormatをRun Script内から呼び出すことが出来ました。

## まとめ

今回はSwiftFormatでの一例を示しましたが、SPMでとってきたライブラリの何かしらを使いたいということは今後出てくると思います。ぜひ参考にして、コンパクトでナウいプロジェクトを目指していきましょう！
【HTML】まずはこれだけ！HTMLを書いてみよう   Lv.1「まずは書いてみうよう」

# 【HTML】まずはこれだけ！HTMLを書いてみよう   Lv.1「まずは書いてみうよう」

今回からHTMLを実際に書いてみましょう！！

　わかりやすく解説します。

## ペルソナ

- プログラミングをこれから勉強しようとしている方
- 初めてプログラミングを書こうと思っている方
- Webページを作ってみたい方

**テキストエディタをまだ導入できていない方は[こちら](https://qiita.com/rrrrr1231/items/83798faca9a95a6e0f50)を参照してください**

## 内容
HTMLがブラウザで表示される体験をしよう！
（今回は言語の詳細は省きます。）

## Key Word


- 「index.html」
- タグ


# 目次

1.HTMLを書いてみよう！
2.まとめ


## Contents

### 1.HTMLを書いてみよう！

前回まででテキストエディタを導入できたと思います。
ではVScodeを使って実際にHTMLを書いてみましょう！

まずはHTMlを書くのに必要なファイルを作っていきます！

①　**VScodeを開き、新しくファイルを作る**

導入したVScodeを開いてください。

開いたら、まずは**commnadキー + n**を押してください。
すると新しくファイルが作成されたと思います。
[![Image from Gyazo](https://i.gyazo.com/921711a8bf1cef2818545c58d434cc4c.gif)](https://gyazo.com/921711a8bf1cef2818545c58d434cc4c)

上部のタブに**Untitled-1**というファイル名が出ていればOKです！
[![Image from Gyazo](https://i.gyazo.com/f8aabbf0758296dfb1f7fc901294c3e4.png)](https://gyazo.com/f8aabbf0758296dfb1f7fc901294c3e4)

続いて、**HTMLを作成するのに適切な拡張子を持ったファイル名**に変更をします！

(拡張子の詳細はここでは省きますが、例えば画像の拡張子にはJPGやpngがあります。「ファイル名.**JPG**」の「JPG」の部分のことでこのファイルは「JPGという形式の画像ファイルですよ」と宣言しているものと思ってください。これがないと、ファイルを開こうと思ってもパソコンが、「このファイルはなんのファイルなの？」と混乱して開けなくなります。）

HTMLファイルの拡張子は基本的に**html**です。
覚えやすいですね。

画面に戻っていただいて、先ほどのファイルを作成した状態で、**commandキー + s**を押してください。
するとドロップダウンでファイルを保存する場所、名前の変更・指定ができるボックスが出てきます。
[![Image from Gyazo](https://i.gyazo.com/902999154c717b0904e6d5e53ad926b5.png)](https://gyazo.com/902999154c717b0904e6d5e53ad926b5)

今回は保存先を「デスクトップ」、ファイル名を「index.html」としましょう！
[![Image from Gyazo](https://i.gyazo.com/3f3d27604b97efc3f3e64433bdfccc89.gif)](https://gyazo.com/3f3d27604b97efc3f3e64433bdfccc89)

ファイル名がこのように変わったでしょうか？
[![Image from Gyazo](https://i.gyazo.com/8d1e11ccd44d86e336687cb65a090e55.png)](https://gyazo.com/8d1e11ccd44d86e336687cb65a090e55)



②**実際に書いてみる！**

今回は言語の書き方の詳細は省きます。
まずは実際に書いてみたことがWeb上に表示されるんだということを体験してみましょう！！

ではエディタ上に

```html:index.html
<h1>Hello World</h1>
```
と書いてみましょう！

[![Image from Gyazo](https://i.gyazo.com/1c18cc14b7ce917abfc6d6a3f4f0ff4d.png)](https://gyazo.com/1c18cc14b7ce917abfc6d6a3f4f0ff4d)
こうですね！

何やら、「Hello World」という文字が

```html:index.html
<h1></h1>
```

という文字に囲まれていますね。

これが**タグ**と言われるもので文字の構造化をする役割を持っています。
構造化について知りたい方は[まずはこれだけ！　HTML](https://qiita.com/rrrrr1231/items/587ebc4608897278fedd)を参考にしてください。

このタグは簡単にいうと見出しを作るタグになります。

ではブラウザ上に表示してみましょう！

③**ブラウザで表示してみる！**
ブラウザで表示する方法は色々ありますが、今回はドラッグして表示させましょう。

[![Image from Gyazo](https://i.gyazo.com/e24825e9b12e35cc0f5aac73c457dafb.gif)](https://gyazo.com/e24825e9b12e35cc0f5aac73c457dafb)

左がエディタ、右にGoogle Chromeを開いています。
エディタの「index.html」といタブをブラウザにドラッグ&ドロップしてみましょう。

うまくブラウザ上にHello Worldと表示されたでしょうか？


### ２.まとめ


今回のポイントは

**HTMLを書いてブラウザに表示させる**でした！

- HTMLというプログラミング言語がPCに認知される
- ブラウザを使用することで人間がみやすい形に変換してくれる

という体験ができたのではないでしょうか？


今回はHTMLの詳細ではなく、実際に書いたコードがブラウザ上で表示されるんだ
という体験をしてもらいました。

次回以降は、HTMLのタグの種類やルールを含めて詳しくお伝えしていきます！
これであなたもプログラマーとして一歩踏み出しましたね！！

一つずつ頑張っていきましょう！！

今回も最後までありがとうございました！！
第一回日本最強プログラマー学生選手権-予選- E - Card Collector(閉路判定付きUnion Find)

# 第一回日本最強プログラマー学生選手権-予選- E - Card Collector(閉路判定付きUnion Find)

やや特殊なUnion Find。閉路を追加、閉路の数を判定できる機能付き。

```python

from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce


sys.setrecursionlimit(2147483647)
INF = 10 ** 13
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007



class UnionFind:
    def __init__(self, n):
        # 負  : 根であることを示す。絶対値はランクを示す
        # 非負: 根でないことを示す。値は親を示す
        self.table = [-1] * n
        self.size = [1] * n
        self.cycle = [0] * n
        self.group_num = n

    def root(self, x):
        if self.table[x] < 0:
            return x
        else:
            self.table[x] = self.root(self.table[x])
            return self.table[x]

    def is_same(self, x, y):
        return self.root(x) == self.root(y)

    def get_size(self, x):
        return self.size[self.root(x)]

    def unite(self, x, y):
        r1 = self.root(x)
        r2 = self.root(y)
        if r1 == r2:
            return
        # ランクの取得
        d1 = self.table[r1]
        d2 = self.table[r2]
        if d1 <= d2:
            self.table[r2] = r1
            self.size[r1] += self.size[r2]
            self.cycle[r1] += self.cycle[r2]
            if d1 == d2:
                self.table[r1] -= 1
        else:
            self.table[r1] = r2
            self.size[r2] += self.size[r1]
            self.cycle[r2] += self.cycle[r1]
        self.group_num -= 1


    def get_cycle(self, x):
        return self.cycle[self.root(x)]

    def add_cycle(self, x):
        self.cycle[self.root(x)] += 1
        return


n, h, w = LI()
uf = UnionFind(h + w)
ans = 0
rca = sorted(LIR(n), key=lambda x:x[2], reverse=True)
for r, c, a in rca:
    r -= 1; c -= 1
    if uf.is_same(r, h + c):
        if uf.get_cycle(r):
            continue
        else:
            uf.add_cycle(r)
            ans += a
    else:
        if uf.get_cycle(uf.root(r)) and uf.get_cycle(uf.root(h + c)):
            continue
        else:
            uf.unite(r, h + c)
            ans += a


print(ans)
```
aws サーバー ディスク容量確認

```
[ec2-user@dev-1a ~]$ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
devtmpfs         1.9G   56K  1.9G    1% /dev
tmpfs            1.9G     0  1.9G    0% /dev/shm
/dev/nvme0n1p1    40G   37G  2.5G   94% /
[ec2-user@dev-1a ~]$ sudo du -k /* | sort -rn | head -20
33235996	/var
20619868	/var/log
18140284	/var/log/mysql
6697948	/var/lib
6335368	/var/lib/mysql
5748652	/var/www
5135228	/var/lib/mysql/nanana
3674508	/var/www/nanana
3234940	/usr
1869268	/usr/share
1835776	/var/www/import
1651724	/var/log/elasticsearch
1243340	/var/www/import/import
1166272	/var/www/import/import/storage
1138572	/var/www/import/import/storage/logs
971540	/usr/share/kibana
943544	/home
943540	/home/ec2-user
797896	/usr/lib
749228	/home/ec2-user/.composer
```
slackのファイルを削除するプログラム

# slackのフリープランは5GBまで

古いファイルを削除したいが、複数選択削除がUIで無いので、プログラムで削除する。

# 環境

PHP

# プログラム

同じこと考えてる人は多い。
丸パクリでおｋでした。
https://qiita.com/9umaske/items/49bc1bd89330fe946ff3

# slack API を使用するために

slackアプリを作成して、
scopeに「files:read」と「files:write:user」を追加
ワークスペースに追加
tokenを取得しましょう。

# 使用するAPI

## files.list

ts_toを指定することで古いファイルを取得できる。
ただし、ソート順はtimestampで昇順になる（古い→新しい）。

## files.delete

files.listで取得したIDを指定して削除する。
**slackアプリを作成した人のアカウント権限がadminでないと他の人のファイルを削除できないので、adminになるかadminの人にアプリを作成して貰う必要があります。**

# 動作時間

10個で数秒です。
githubのContributor機能が便利

以前こちらでgithubのプルリクエストのテンプレート機能をご紹介しましたが、
https://qiita.com/a-nishimura/items/0c43a0a5fe6dc817729d
テンプレートとは別にコントリビュータのためのガイドライン作成機能もあるのでメモです。

チームの新規アサイン時などに、概要やガイドライン、PRのテンプレートとサンプルのメンバーへの周知などに活用すると便利ですね。

## Contributor導入方法

``contributing.mdま``たは``CONTRIBUTING.md``
というファイル名でガイドラインを作ります。
内容はこんな感じ

```
# contributors template test

## title

- hogehoge
- fugafuga

## memo

- memomemo
```

※ファイル拡張子の指定は特にないようだが、マークダウン形式で記載しておくと整形されるので便利かと思います。

このファイルを

- リポジトリのルート直下
- docsフォルダを作成してその配下
- .githubフォルダを作成してその配下

のいずれかにpushします。
するとプルリクエスト作成時にcontributingのリンクが表示されます。

<img width="1052" alt="スクリーンショット 2019-11-11 10.56.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/c3bdd633-d181-1c43-4776-22d937097de9.png">


``Open a pull request``のプルリクエスト作成時にのみリンクが表示されます。
既存のpull requestのview時には表示されません。


参考
https://help.github.com/ja/github/building-a-strong-community/setting-guidelines-for-repository-contributors
Voice Overで特定のオブジェクトにフォーカスさせる

画面やユーザのアクションを受け取った際に、自動で特定のオブジェクトをフォーカスさせて読み上げさせるとアクセシビリティが向上します。

また、逆に意図しないラベルが勝手に読み上げられてしまうとユーザの混乱を招いてしまう可能性があります。
最初にフォーカスするオブジェクトを設定することで、そのような混乱を防ぐことができます。

次のアクションを促すようなUIラベルや、アプリの挙動を示すUIラベルによく使っています。

## UIAccessibility Post Notification を使う
```Swift
UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: hogeLabel)
```

## 参考
[UIAccessibility Post Notification](https://developer.apple.com/documentation/uikit/1615194-uiaccessibilitypostnotification)
【学習ノート】AWS SAA取得に向けて(CloudFront,Rout53)

# CloudFront
静的なWEBページ、動画、画像などのコンテンツをキャッシュし、オリジンサーバの代わりに配信するCDN[^1]サービス
189のエッジロケーション[^2]があり、利用者に近いエッジロケーションからコンテンツを高速に配信できる

URLのパスに応じて異なるオリジンサーバを指定することで、1つのドメインで複数のサービスを提供できるため、ドメインの統一が可能

## バックエンド
- オリジンサーバとして以下のサービスを利用可能
    - ELB
    - EC2
    - S3
        - S3は静的webページのホスティングが可能
    - オンプレミス環境のサーバ
        - 本番はそのままに一時的なアクセス増加への備えが可能

## 配布(ディストリビューション)
配信するコンテンツの内容によって、異なる下記２つのディストリビューション方法がある

- ダウンロードディストリビューション
    - HTTP/HTTPSを利用してHTML、CSS、画像などのデータ配信を行う際に利用する
- ストリーミングディストリビューション
    - RTMP(Real Time Messaging Protocol)を利用して動画のストリーミング配信を行う際に利用する

## キャッシュのルール
拡張子や、URLパスごとにキャッシュ期間を設定することできる
CDNはキャッシュの強制削除等も含めて、適切にキャッシュ意を運用する必要がある
その為、

- 頻繁にアップデートされるコンテンツはキャッシュ時間を短く設定する
- 更新スパンが長いコンテンツはキャッシュ時間を長く設定する
- キャッシュを無効化することでネットワーク経路としてだけ利用する

といった運用が可能になる。

# Route 53
Route53は***ドメイン管理機能***と、***権威DNS機能***を持つ

## ドメイン管理機能
以下のような機能を提供する

- 新規ドメインの取得
- 既存ドメインの更新
- ゾーン情報の設定
 
利用するメリット

- ドメイン利用料がAWS利用料と合算されるので、別途、支払手続きを行う必要がない
- 自動更新機能により、ドメインの更新漏れがない

## 権威DNS機能
ドメイン名とIPアドレスを名前解決する
権威DNSなのでキャッシュサーバは別に用意する必要がある

### Aliasレコード
Route53で特徴的なレコード
Aliasレコードはレコード情報に登録する値としてAWSリソースFQDNを指定可能
CNAMEとの違いとして、AliasはZoneApexにも指定が可能

### トラフィックルーティング
名前解決の問い合わせに対して、どのように応答するかを決める7種類のルーティングポリシーが用意されている

- シンプルルーティング
    - 標準的な1:1のルーティング
- フェイルオーバールーティング
    - 稼働系/待機系の構成
    - 稼働系サーバのヘルスチェックが失敗すると待機系へルーティングする
    - Sorryページをセカンダリレコードとして登録しておくと、自動的にsorryページを表示させることができる
- 位置情報ルーティング
    - ユーザの位置情報にもとづいたルーティング
    - このポリシーを利用すると、日本からのアクセスは日本語のコンテンツが配置されたWebサーバへ接するといった制御が可能
- 地理的近接性ルーティング
    - リソースの場所にもとづいたルーティング
    - 必要に応じてトラフィックを別の場所へ移動する
- レイテンシールーティング
    - サーバが冗長化されている時、最も遅延が少ないサーバへルーティングする
    - また特定サーバだけ高負荷になった場合、リクエストを分散する
- 複数値回答ルーティング
    - 1つのレコードに複数のIPアドレスを登録し、リストからランダムにIPアドレスを返すルーティング
    - ヘルスチェックがNGのサーバには振り分けない
- 加重ルーティング
    - 指定した比率で複数のリソースにルーティングする

#### トラフィックフロー
ルーティングポリシーの組み合わせにより、レコード間の設定が複雑になることがあります。
トラフィックフローはそれらをビジュアル的にわかりやすく、ポリシーを組み合わせるためのツールを使って定義できる。
ちなみに有料(50.00USD ポリシー記録ごと / 月)
一度トラフィックフローで設定して、設定された内容をもとに手動で設定しようとした方がいましたが、トラフィックフローで設定した内容はブラックボックス化されてしまい、トラフィックフロー上でしか見えないようです。
※お金払ってね、ってことですね。

## DNSフェイルオーバー
同じ機能を実行する複数のリソースがある場合、トラフィックを異常なリソースから正常なリソースへルーティングする
route53のヘルスチェックでは以下の正常性とパフォーマンスを監視できる

- ウェブアプリケーション
- ウェブサーバー
- その他のリソース

作成した各ヘルスチェックは、次の方法のいずれかでモニタリングできる

- ウェブサーバーなどの指定するリソースのヘルスチェック
- そのほかのヘルスチェックのステータス
- Amazon CloudWatch アラームのステータス

---

[^1:] Content Delivery Networkの略。　[このサイトのイラストはすごくシンプルで分かりやすかったです](https://www.cdnetworks.co.jp/about/)
[^2:] [2019/11/11時点の確認情報](https://aws.amazon.com/jp/cloudfront/features/)

参考図書:AWS認定資格試験テキスト　AWS認定ソリューションアーキテクト[アソシエイト]
phpenvで5系と7系を使用する場合の注意点

# 現象

phpenvで5.6と7.2を切り替えて確認しようとしたところ、
httpdがstartに失敗するようになりました。

# 原因

phpenvでインストールすると、自動で/etc/httpd/conf/httpd.confに

```
LoadModule php7_module        /usr/lib64/httpd/modules/libphp7.so
LoadModule php5_module        /usr/lib64/httpd/modules/libphp5.so
```
が書かれていました。

**5系と7系を切り替える際はどちらかをコメントアウトする必要があります。**

コメントアウトするとstartでき、phpが変わっているのを確認できました。

/etc/httpd/conf.d/php.confにも書いてあるので、コメントアウトしてください。
GrowiでPlantUMLが使える

## 概要
[plantuml-encodingを使ってPHPでPlantUmlする](https://qiita.com/_mmmm_/items/094cc8ac4a2980751524)
[PlantUMLをスマートに共有したい旅に出た](https://qiita.com/_mmmm_/items/baf17fa6c7ed1fa1438b)

> 最終目的: PlantUMLのコードをテキストとして実データで保持しつつ(git管理しつつ)、図は自動で更新され、かつ閲覧のみならば簡単に行える環境を探す

この目的を達成する良い管理方法を模索してきましたが、GrowiでPlantUMLが使えると知り達成出来そうなのでまとめます。

## 機能
### 使い方
<img width="1194" alt="スクリーンショット 2019-11-11 10.47.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/489139/79ad22d5-5fb4-e509-360b-92e99fa1132a.png">

コードブロックにせず、直接 `@startuml` `@enduml` で囲んで記述するだけでPlantUMLで図が表示されます。

### 良いところ
- 社内で共有が容易
- 編集の差分を確認出来る
- 複数人で編集も可能
- 文字化けしない

## おわり
Growiが使えるのならば、ローカルで環境作る必要もないのではと思うほど便利でした。
ずっとこの機能を知らなかったので悔しいです。
Wordpressの有償テンプレートでGoogleMapsが表示されない

せっかくWordpressの有償テンプレートを買ったのに、全然GoogleMapsが動かなかったので悩んでいました。ChromeのDevツールを見ると、

```
Geocoding Service: This API project is not authorized to use this API.  For more information on authentication and Google Maps JavaScript API services please see: https://developers.google.com/maps/documentation/javascript/get-api-key
_.xd @ js?key=xxxxxxxxxxxxxxxxxxxxxxxxxxx&ver=5.2.4:60
(index):185 gmaps err:REQUEST_DENIED
```

と表示されていました。
GoogleAPIsでGoogleMapsAPIは複数使えるようにしていたので、どうしたものかと思っていたら、"Geocoding"がキーワードになっているとは梅雨知らず。

実はGeocoding APIを有効にしないといけなかったのでした。
API一覧から検索して有効にしてみてください。
後、APIで制限をしていたら、必ずGeocodingAPIを制限内容に加えてください。
MacにDockerでGolang環境を作ってみる  - vol.2 Docker起動？

今回の記事は、以下を参考に作成しました。
で、自分なりに「あれ？」って詰まったところ？を捕捉しつつ記載します。

こちらの記事にお世話になりました。
メインのやった内容はこちらなので、
並行して読んでいただけるとありがたいです。
https://qiita.com/yonaimineakio/items/0990648bbce64de7edfa


# 作業ディレクトリ作成 & ファイル配置
　今までHomeにいたので、任意の場所に移動して、ディレクトリを作ってみました。

```
　　$ mkdir go_doc
　　$ cd go_doc/
```

　ここで移動した「go_doc」ディレクトリに、以下のファイルを作成します。
　（元記事参照）
　　・main.go
　　・Dockerfile

　つまり、階層はこんな感じ。

　　　**任意の階層**
　　　**　　∟ go_doc**
     **　　　　　　　∟ Dockerfile**
     **　　　　　　　∟ main.go**

## Dockerfile って何書いてんの？
 で、この状態から、以下のDockerfileが何を定義しているのか、個人的に絵にしてみる。

```ruby:Dockerfile
     FROM golang:1.9
     mkdir /echo
     COPY main.go /echo
     CMD ["go", "run", "/echo/main.go"]
```

　　 **FROM golang:1.9**
　　　　https://hub.docker.com/_/golang
　　　　①公式の Golang Docker コンテナの、バージョン1.9をベースにするよ。
<img width="836" alt="スクリーンショット 2019-11-11 10.00.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/23adf1f7-16c0-9b16-2814-de3fddd7abd3.png">

　　 **mkdir /echo**
　　　　②DockerのHomeの下に、「echo」っていうディレクトリを作るよ。
<img width="840" alt="スクリーンショット 2019-11-11 10.03.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/2ae2f805-42e0-44c8-ef99-d3b00ce8e0aa.png">

　　 **COPY main.go /echo**
　　　　③Localにある「main.go」ファイルを、
　　　　　②で作った「echo」ディレクトリの下にコピーするよ。
<img width="833" alt="スクリーンショット 2019-11-11 10.08.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/1b758ad6-279c-7bec-24fb-7c3c989e5a36.png">

　　**CMD ["go", "run", "/echo/main.go"]**
　　　　④Docker側でコマンド実行！
<img width="795" alt="スクリーンショット 2019-11-11 10.12.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/525955/1c90ce21-ecca-bcde-d12e-0baeb7c94885.png">

　　結果。
　　　・ Dockerのベース定義
　　　・ 実行ファイルの配置
　　　・ 実行
　　っていう手順を書いてる、ってことなのかなー、と。
　　Dockerfile 自体には他にも定義できることがいっぱいあって、
　　これだけではないと思うんだけど、1ファイルの実行だけならこんな感じになるのかな。

# イメージのビルド
　　さっき作ったDockerfileから実体を作成？

>
```ruby:基本
     $ docker image build -t イメージ名[:タグ名] Dockerfile配置ディレクトリのパス
```
>

　　基本の構文はこれ。イメージ名とタグ名は任意でいいみたい。
　　イメージ名とか、タグ名って何に使われてるんだろ？と思って調べてたら
　　こんな記事を見つけました。
    https://qiita.com/t-yotsu/items/559731aca6300eef78ec

　　で、パスは同じ階層にいるから「.」になるんですな。

```ruby:shell
     $ docker image build -t example/docker:tag .
     Sending build context to Docker daemon  10.24kB
     Step 1/4 : FROM golang:1.9
      ---> ef89ef5c42a9
     Step 2/4 : RUN mkdir /echo
　　　 ---> Using cache
　　　 ---> 46ca04568ee5
　　　Step 3/4 : COPY main.go /echo
　　　 ---> Using cache
　　　 ---> 24719acca39b
　　　Step 4/4 : CMD ["go", "run", "/echo/main.go"]
      ---> Using cache
      ---> 03df9c7950f8
     Successfully built 03df9c7950f8
     Successfully tagged example/docker:tag
```

　　実行したらこんな感じになりました。

　　で、元記事を参考にコンテナの起動まで行いました。
　　その後、いざ実行しようと思ったらポートフォワーディングというのが必要だそうで。
　　これについては次回の記事で書きます。

　　なんか消化不良ですが今回はここまでー。
CentOS上でFabric CAの定義ファイルを取得する方法

# CentOS上でFabric CAの定義ファイルを取得する方法

Hyperledger Fabric CAにはサーバ機能とクライアント機能があり、コマンドラインのオプションや環境変数でふるまいを定義できますが、定義内容が多い場合はyamlファイルで定義する方法があります。

ここでは、元となる（テンプレートとなる）yamlファイルを取得する方法を説明します。

## 確認環境

- CentOS Linux release 7.3.1611 (Core)
- Git 1.8.3.1
- Go 1.11.5
  - 環境変数GOPATHを設定しておく
  - 環境変数PATHに${GOPATH}/binを追加しておく
- Hyperledger Fabric CA 1.4.1

## コマンドをビルド

Fabric CAはdockerコンテナを使ってyamlファイルを取得できますが、ここではネイティブコマンドであるfabric-ca-serverとfabric-ca-clientを使うことにします。

これらのネイティブコマンドは、以下の方法でビルドします。

```bash
## Gitリポジトリから取得する
mkdir -p ${GOPATH}/src/github.com/hyperledger
cd ${GOPATH}/src/github.com/hyperledger
git clone https://github.com/hyperledger/fabric-ca.git

## fabric-ca-serverをビルドする
cd fabric-ca/cmd/fabric-ca-server/
git checkout refs/tags/v1.4.1
go build
cp fabric-ca-server ${GOPATH}/bin

## fabric-ca-clientをビルドする
cd ../fabric-ca-client/
go build
cp fabric-ca-client ${GOPATH}/bin

## バージョンを確認する
${GOPATH}/bin/fabric-ca-server version
${GOPATH}/bin/fabric-ca-client version
```

## yamlファイルを取得

ネイティブコマンドであるfabric-ca-serverとfabric-ca-clientを使って、yamlファイルを生成させます。

```bash
## 任意の作業ディレクトリを作成し、そこに移動する
export WORK_DIR=<任意の作業用ディレクトリ>
mkdir -p ${WORK_DIR}
cd ${WORK_DIR}

## Fabric CA Serverの初期化コマンドを実行し、fabric-ca-server-config.yamlを生成させる
export FABRIC_CA_SERVER_HOME=${PWD}; fabric-ca-server init -b admin-user:admin-pass

## Fabric CA Clientのエンロールコマンドを実行し、fabric-ca-client-config.yamlを生成させる
## Fabric CA Serverに接続できない旨のエラーが出力されるが、fabric-ca-client-config.yamlが生成される
export FABRIC_CA_CLIENT_HOME=${PWD}; fabric-ca-client enroll -u http://admin-user:admin-pass@localhost:7054

## yamlをホームディレクトリにコピーし、作業用ディレクトリを削除
cd ~/
cp ${WORK_DIR}/fabric-ca-server-config.yaml .
cp ${WORK_DIR}/fabric-ca-client-config.yaml .
rm -fr ${WORK_DIR}

## fabric-ca-client-config.yamlが実行可能ファイルになっているため、
## パーミションを修正
chmod 644 fabric-ca-client-config.yaml

## 環境変数を削除
unset WORK_DIR
unset FABRIC_CA_SERVER_HOME
unset FABRIC_CA_CLIENT_HOME
```

以上で、ホームディレクトリに次のyamlファイルが生成されます。これらのファイルをテンプレートにして、Fabric CAのサーバ機能およびクライアント機能ごとに定義ファイルを作成できます。

- fabric-ca-server-config.yaml
- fabric-ca-client-config.yaml
Azure DevOps Server #1-1 継続的インテグレーション（CI）構築

**Chapters**

📘 **Chapter #1**
　📗 **Chapter #1-1**　[継続的インテグレーション（CI）構築](https://qiita.com/tfukumori/items/ef8314857ecb545c4b15)
　📗 **Chapter #1-2**　[継続的インテグレーション（CI）手順](https://qiita.com/tfukumori/items/11d24a5eee8d77a17a80)
📘 **Chapter #2**
　📗 **Chapter #2-1**　[VB6で使用する 環境設定](https://qiita.com/tfukumori/items/37f035694751dc098fcd)
　📗 **Chapter #2-2**　[VB6で使用する プロジェクトの追加](https://qiita.com/tfukumori/items/68aca8cdc04fe76d6eee)
📘 **Chapter #A**
　📗 **Chapter #A-1**　[バージョンアップ TFS 2018 Update 1 → Update 3、検索サービスの分割](https://qiita.com/tfukumori/items/778bb2e3d913106beba9)
　📗 **Chapter #A-2**　[バージョンアップ 2019→2019 Update1](https://qiita.com/tfukumori/items/7f149928a6e413afe755)

---

# TL:DR

- Azure DevOps Serverの環境構築済みの環境において、ビルドサーバー構築の手順
- プロキシ環境下での手順も記載

# ビルドサーバー（パソコンでもOK）で作業を実施する

## (1) エージェントのダウンロード

1. Azure DevOps Serverのエージェントをダウンロードするために、Azure DevOps Serverの以下のアドレスを開く

    ```
    http://(Azure DevOps Serverホスト名):(ポート、既定 8080)/(webアプリケーション名、既定 tfs)/(コレクション名、既定 DefaultCollection)/_settings/agentpools?poolId=1&_a=agents
    ```

    例：`http://myazdevopssv:8080/tfs/DefaultCollection/_settings/agentpools?poolId=1&_a=agents`

1. エージェントのダウンロードをクリックして、エージェントをダウンロード

    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/204150/50a254bf-7135-0c74-f895-7fb7edf9bdf0.png)

## (2) インストール

ビルドサーバーで実行

```
 .\config.cmd
```

## (3) プロキシ関連ファイルの作成

https://docs.microsoft.com/ja-jp/azure/devops/pipelines/agents/proxy?tabs=windows&view=azure-devops

プロキシを設定しないと、nugetが外部に接続できない。

ただその方法として、 `.\config.cmd`の後にプロキシを指定する方法は使用せず、プロキシ関連ファイル（`.proxy`、`.proxybypass`）を配置する。

理由は、`.\config.cmd`の後にプロキシを指定する方法では、インストール中にリポジトリサーバー(Azure DevOps Serverをインストールしたサーバー))に接続できないため。

`C:\agent`に配置する

### .proxy

```
http://(proxy server):(proxy port)
```

### .proxybypass

```
(リポジトリサーバー(Azure DevOps Serverをインストールしたサーバー)のホスト名)
```

例：`myazdevopssv`
Laravel による S3 操作に必要な最小限の IAM ポリシー

## 背景

Laravel には S3 を操作できる便利なライブラリ [Flysystem](https://flysystem.thephpleague.com) が備わっていますが，これを使用するには [AWS IAM ポリシー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies.html) の設定が必要です。その設定方法を解説する記事は Qiita にも数多く見られますが，ほぼ揃って「`AmazonS3FullAccess` をアタッチする」と解説してます。 

しかし `AmazonS3FullAccess` の権限内容を見てみると，実に多くの権限が設定されており，その数はなんと **84 個** 。[Laravel で行う S3 操作](https://readouble.com/laravel/5.8/ja/filesystem.html) はファイル取得/保存/削除くらいなので，ここまで大きな権限が必要とは考えられません。必要以上の権限を与えることは IAM のベストプラクティスに反します。

[IAM のベストプラクティス: 最小権限を付与する](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)

> IAM ポリシーを作成する場合、最小限のアクセス権を付与するという標準的なセキュリティアドバイスに従うか、タスクの実行に必要なアクセス許可のみ付与します。ユーザー (およびロール) が何をする必要があるのかを決定し、それからそれらのタスクのみの実行を許可するポリシーを作成します。

そこで Laravel による S3 操作に必要な最小権限を与える IAM ポリシーについて調べてみました。

## 結論

とは言っても，公式ドキュメントにすべて書いてありました。

[Flysystem: Aws S3 Adapter V3](https://flysystem.thephpleague.com/docs/adapter/aws-s3/)

> The required IAM permissions are:

> ```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1420044805001",
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:GetObject",
                "s3:GetObjectAcl",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:ReplicateObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::your-bucket-name",
                "arn:aws:s3:::your-bucket-name/*"
            ]
        }
    ]
}
```

必要な権限は `Actions` 以下の 7 つの許可です。

`Resource` 以下を操作対象のバケット名とパスに書き換えれば，コピペでいけます。上記の IAM ポリシーを `AmazonS3FlysystemAccess` などの名前で作成し， IAM ユーザや IAM ロールにアタッチしましょう。

以上，権限の付与しすぎに注意しつつ，よい AWS ライフを！
Laravel Mixとは？webpackをより便利に、簡単に。Laravel以外でも使えるよ。

# 概要
・Laravel Mixとは、フロントエンドのアセットをコンパイル、バンドルしてくれるツール
・ツールの中身はwebpackを利用している
・webpack設定ファイルをより分かりやすく簡単に書けるように設定ファイルをラップしている
・lessやsass、babelなどよく使われるローダーが最初から用意されていて、デフォルトで利用することができる
・Laravelを使っていないアプリでも、コンパイル・バインディングのツールとして利用できる

※webpackが分からない方はこちらを参照
[webpackとは？](https://qiita.com/minato-naka/items/0db285f4a3ba5adb6498)

# 使い方
## 初期状態

※npmが分からない方は、先にこちらを参照
[npmとは？【フロントエンドパッケージ管理】](https://qiita.com/minato-naka/items/fc74f6c9439ab59cec63)

Laravelをインストールすると、
package.jsonとwebpack.mix.jsが用意されている。

package.jsonには
Laravel Mix自体やその他必要なパッケージが記述済み。
また、package.jsonのscriptsにはwebpackを実行するためのスクリプトも記述されている。

webpack.mix.jsは、
webpack設定ファイル（webpack.config.js）のラッパー。
ここにコンパイル対象ファイルやバンドル対象ファイルなど
設定を記述していく。

※LaravelではないアプリでLaravel Mixを使う場合でも、
package.jsonとwebpack.mix.jsの2ファイルを用意するだけであとは同じです。
Laravel Mix公式サイトの[Stand-Alone Project](https://laravel-mix.com/docs/4.0/installation#stand-alone-project)を参考に。


## Laravel Mixインストール
`npm install` コマンドを実行すると、
package.jsonに記述されているLaravel Mix自体がインストールされる。
（npmが使える環境である前提）

## 設定ファイルの記述
webpack.mix.jsに、設定を記述する。

sassファイルをコンパイルしたい場合

```js
mix.sass('resources/assets/sass/app.scss', 'public/css');
```

cssファイルをバンドルしたい場合

```js
mix.styles([
    'public/css/vendor/normalize.css',
    'public/css/vendor/videojs.css'
], 'public/css/all.css');
```

jsをコンパイルしたい場合

```js
mix.js('resources/assets/js/app.js', 'public/js');
```

jsファイルをバンドルしたい場合

```js
mix.scripts([
    'public/js/admin.js',
    'public/js/dashboard.js'
], 'public/js/all.js');
```

他にもいろいろ設定できることはある。

## Laravel Mixの実行
`npm run dev` を実行すると、
package.jsonに書いてあるスクリプトが実行され、
設定ファイルに記述したコンパイルやバンドルが実行される。

`npm run production` の場合は圧縮されたファイルが出力される。


# もう少し具体的な機能
知っておいたほうがいい主な機能を抜粋。

## jsのコンパイル
上記の通り、
jsファイルをコンパイルするには

```js
mix.js('resources/assets/js/app.js', 'public/js');
```
と書く。

この処理では
・ES2015記法
・モジュール
・.vueファイルのコンパイル
・開発環境向けに圧縮
のコンパイルが実行される。

## babel実行
jsファイルをバンドルする設定として、
`mix.scripts()`を紹介したが、
この代わりに`mix.babel()`を使うことができる。

これをすると、
バンドルされたファイルはES5記法に変換された状態になる。

IEはES5までしか対応していないため、
もしIEでも動作させる必要があるシステムの場合は
この`mix.babel()`機能を使ってES5記法に変換するほうがいい。

ESのバージョンやbabelというツールについては
この記事を参照。
[ES（ECMAScript）とは？jsがブラウザによって動いたり動かなかったりするのはなぜ？](https://qiita.com/minato-naka/items/73b9d531c871d98a3f22)
[polyfill、babelとは？jsをどのブラウザでも動くようにしてくれる。（IE対応）](https://qiita.com/minato-naka/items/a2645aeb158662a9f0e9)

## キャッシュバスティング

```js
mix.js('resources/assets/js/app.js', 'public/js')
   .version();
```
このように記述すると、
ファイル名の末尾に一意のハッシュ値が付与される。

これによって、
コンパイルのたびにファイル名が変更されるため
CSSやJSなどがブラウザキャッシュに残って変更が反映されないことを防止できる。

このファイルを読み込むbladeファイル側では、
`<link rel="stylesheet" href="{{ mix('/css/app.css') }}">`
のように`mix()`関数を使うことで、
ハッシュ値のついたファイル名でも取得することができる。

# 参考
https://readouble.com/laravel/5.5/ja/mix.html
Debian 10 インストール時のトラブルシューティングメモ

# はじめに
Lenovo ThinkCentre M600 Tiny と Windows 10 Home Edition の組み合わせを使っていましたが、Youtube 視聴、SNS 投稿、写真編集などの作業にもたつきを感じるようになってきました。
OS を Debian 10.0 に入れ替えることにしましたが、そのインストール時のトラブルシューティングのメモです。Debian 10.0 は、日経Linux 2019年 9 月号 に付録のメディアを使用しました。ThinkCentre M600 Tiny のスペックは、インテル® Celeron® プロセッサー J3060 (1.60GHz、2 core)、メモリ4GB です。

# トラブルシューティングメモ

## デスクトップ環境のインストールに失敗する
インストール途中の「ソフトウェアの選択」という画面でデスクトップ環境の種類やWeb サーバー、プリンタサーバーなどを選べるようになっています。
デフォルトのまま次に進むと、延々とダウンロードしたあとにエラーを発生して失敗します。デフォルトのチェックを外し、軽いはずの Mate や Xfce を選んでも同様にエラーを発生して失敗します。
あきらめて、CUI によるログインおよびコマンド操作ができる環境を作ることを優先し、その後デスクトップ環境を追加することにしました。

インストール途中の「ソフトウェアの選択」という画面では、__標準システムユーティリティーだけ__ にチェックを付け、ほかのチェックはすべて外してインストールを完了させます。

リブート後、CUI でログインし、`apt-get update` を実行後、デスクトップ環境のうち Mate を追加するために `apt-get install task-mate-desktop` を実行しました。すると、ダウンロードの最後のほうで、gnome-extra などのダウンロードに失敗していました。
__--fix-missing__ オプションを付けて `apt-get install task-mate-desktop` を再実行することで無事デスクトップ環境のインストールが成功しました。

## r8168 についてのメッセージが出る
「(前略)rtl_nic/rtl8168d-2.fw for module r8169」というメッセージ。
 
このメッセージは、[Debian stretch failed to load firmware rtl_nic/rtl8168g-3.fw (-2)](https://unix.stackexchange.com/questions/384403/debian-stretch-failed-to-load-firmware-rtl-nic-rtl8168g-3-fw-2) を参考に対処しました。Realtek 製のネットワークデバイスに関係するエラーのようですね。下記のように non-free を含む記述行を `/etc/apt/sources.list` に追記した後、

```config:source.list
#realtek firmware
deb http://ftp.ja.debian.org/debian stretch main non-free
deb-src  http://ftp.ja.debian.org/debian stretch main non-free
```

下記を実行して解決しました。
`apt-get update`
`apt-get install firmware-realtek`

dmesg による起動ログの確認方法は、[r8169 Gigabit Ethernet driver の問題：Debian 8,9 (Jessie & Stretch)](https://www.lonnie.co.jp/linux/r8169-driver/) を参考にさせていただきました。起動ログでもエラーが解消できていることが確認できました。なお、私の M600 Tiny では、デバイス名は eth0 ではなく、__eno1__ になっていました。

なお、過去の Version の Debian で r8168-dkms のインストールによる解決方法が紹介されている場合があります。試してみたところ、こちらはインストール中にエラーになりました。

## i915 についてのメッセージが出る
「failed to load i915/kbl_dmc_ver(後略)」のような複数のメッセージ。

これは、[Debian 9.3でKabyLakeドライバの追加 (Linux自作PC 10)](https://ksk-log.com/post/2017/12/2017-12-13-linux-gpu-pc10/) を参考に、`apt-get install fimware-misc-nonfree` を実行して解決しました。

# 目的は達成されたか
11/10 に上記の作業を終えたばかりですが、Youtube, Facebook, Twitter などいつもよく使う Web サイトを閲覧したり、動画を再生した限りでは問題なくさくさく動いています。
Ruby on Rails チュートリアル 第14章 ステータスフィード

#ステータスフィードについて
　ここでは、ユーザーのHomeページで表示されるステータスフィード（タイムライン）の実装及びテストについて説明する。
　ステータスフィードでは現在のユーザーにフォローされているユーザー及び自身のマイクロポストを表示する。まず、フィードの実装に入る前にテストを書いておく。テストでは、1) フォローしているユーザーのマイクロポストがフィードに含まれていること。2) 自分自身のマイクロポストもフィードに含まれていること。3) フォローしていないユーザーのマイクロポストがフィードに含まれていないこと。の3つの要件が満たされているかを確認する。以下がそのようなテストのコードである。

```ruby:test/models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase
  .
  .
  .
  test "feed should have the right posts" do
    michael = users(:michael)
    archer  = users(:archer)
    lana    = users(:lana)
    # フォローしているユーザーの投稿を確認
    lana.microposts.each do |post_following|
      assert michael.feed.include?(post_following)
    end
    # 自分自身の投稿を確認
    michael.microposts.each do |post_self|
      assert michael.feed.include?(post_self)
    end
    # フォローしていないユーザーの投稿を確認
    archer.microposts.each do |post_unfollowed|
      assert_not michael.feed.include?(post_unfollowed)
    end
  end
end
```
上記のテストでは、fixtureファイルでmichaelがlanaをフォローし、archerをフォローしていないことが前提となっており、lanaと自身のマイクロポストがmichaelのフィードに表示されていること、およびarcherのマイクロポストがmichaelのフィードに表示されていないことを確認している。
　つぎに、このテスト内で使用されているフィードメソッドの実装に移る。フィードメソッドの機能としては、micropostsテーブルから、自分がフォローしているユーザーのユーザーIDをもつマイクロポストデータと、自身のユーザーIDをもつマイクロポストデータを取得し、返すことができればよい。これを実装すると以下のようになる。

```ruby:app/models/user.rb
class User < ApplicationRecord
  .
  .
  .
  # ユーザーのステータスフィードを返す
  def feed
    following_ids = "SELECT followed_id FROM relationships
                     WHERE follower_id = :user_id"
    Micropost.where("user_id IN (#{following_ids})
                     OR user_id = :user_id", user_id: id)
  end
  .
  .
  .
end
```
ここで、following_idsはralationshipsテーブルからfollower_idが自身のuser_idであるようなデータのfollowed_idの集合、つまり自分がフォローしているユーザーのidの集合であり、それをMicropostモデルのwhereメソッド内でuser_id INに渡し、フォローしているユーザーのマイクロポストを取得している。
[VSCode拡張] "php"+" tabキー"でphpタグ<?php  ?>を展開できるようにする

**WordPress**を使うことになりそうなので、
VSCodeで`<?php  ?>`を展開するショートカット的な拡張はないのかと漁ってましたら
こんな素敵な記事を見つけて、しかも簡単で、嬉しかったのでメモ程度にまとめます。

[「php」 \+ tabキーでphpタグを展開するスニペットを作成する \- IPSJK](https://ipsjk.nori2tae.com/205)


#コードスニペットとは
>何かの文字をキーにコード一式を登録しておいて、簡単に使い回しできる機能のこと
[VSCodeにコードスニペットを登録して効率的にコーディング！ \| HPcode](https://haniwaman.com/vscode-snipet/)

#登録の仕方
①`command`+`shift`+`p`で「snippets」と検索
② ファイルを選択するよう切り替わるので、今回は**`html.json`（※phpじゃないよ！！！）**を選択
③ **`html.json`**に以下のコードを追加する。

```json:html.json

"php": {
	"prefix": "php", 
	"body": [
		"<?php $1 ?>"
	],
	"description": "php tag"
}

```

`prefix`　
　スニペットを展開する際に入力する文字列を設定する
`body` 
　実際に展開されるスニペットコード。配列形式で複数設定可。
　「\$1」の部分はコード展開後の最初のカーソルの位置を示す。「\$2, \$3…」と複数設定するとTabキーで移動可能となる
`description` 
　スニペットの概要（任意）

簡単〜！！！
これでコーディングが光の速さになりますね！
C#, .NET Core でパスワードなどの文字列をハッシュ化する

## 環境

.NET Core Sdk 3.0.100、C# の言語バージョンは 8 です。

```bash
$ dotnet --version
3.0.100
```

## 自前でハッシュ化する

DB にパスワードを保存する際、セキュリティのため平文のままではなくハッシュ化してから保存したい場合があります。
下記は文字列をハッシュ関数`SHA-256`で暗号化する例です。

```csharp
// using System.Linq;
// using System.Security.Cryptography;
// using System.Text;

string password = "ハッシュ化したいテキスト";

// SHA256 デフォルト実装のインスタンスを呼び出します。
using SHA256 sha256 = SHA256.Create(); 

// 文字列をバイト配列にエンコードします。
byte[] encoded = Encoding.UTF8.GetBytes(password);

// ハッシュ値を計算します。
byte[] hash = sha256.ComputeHash(encoded);

// ハッシュ値を 16 進数文字列に変換します。書き方がちょっと面倒。
// System.BitConverter.ToString(hash).Replace("-", "").ToLower() と同じ。
// 16 進数文字列でなく Base64 文字列に変換する場合 -> System.Convert.ToBase64String(hash) で OK。
// 各要素を 16 進数文字列に変換して結合しています。
string hashed = string.Concat(hash.Select(b => $"{b:x2}")); // -> 93541bd68ccf06f3d4f9cf56a3ca415f1d2d315f3f672ecec9f52b0c7c3ad9fc
```

## `Microsoft.AspNetCore.Cryptography.KeyDerivation`でハッシュ化する

ただし、上記のような１度だけのハッシュ化では脆弱であるため、

- パスワードにソルトを付与して、その結果をハッシュ化する
- ハッシュ化した結果をさらに何重にもハッシュ化する

する必要があります。

そのための便利な関数が用意されてるパッケージをインストールします。

```bash
$ dotnet add package Microsoft.AspNetCore.Cryptography.KeyDerivation
```

```csharp
// using Microsoft.AspNetCore.Cryptography.KeyDerivation;
// using System.Linq;
// using System.Security.Cryptography;

string password = "ハッシュ化したいテキスト";

// ソルトを作成する。
byte[] salt = new byte[128 / 8];
using var rng = RandomNumberGenerator.Create();
rng.GetBytes(salt);

// Pbkdf2 メソッドではハッシュ化する反復回数や作成するハッシュの長さを指定することができます。
// OS をよって最適化された実装が選択され、自前で実装するよりもパフォーマンスが向上するそうです。
// https://docs.microsoft.com/ja-jp/aspnet/core/security/data-protection/consumer-apis/password-hashing?view=aspnetcore-3.0
byte[] hash = KeyDerivation.Pbkdf2(
  password,
  salt,
  prf: KeyDerivationPrf.HMACSHA256,
  iterationCount: 10000,  // 反復回数
  numBytesRequested: 256 / 8);  // ハッシュの長さ

// ハッシュ値を 16 進数文字列に変換します。
string hashed = string.Concat(hash.Select(b => $"{b:x2}")); // -> 93541bd68ccf06f3d4f9cf56a3ca415f1d2d315f3f672ecec9f52b0c7c3ad9fc
```

実際の Web アプリケーションを開発する際には`KeyDerivation.Pbkdf2`を使うことになると思います。
Android 4系で drawableLeft にベクターリソースを使用する

TextViewの`drawableLeft`にベクターリソースを使用していたところ、Android4系でクラッシュしてしまいました。
エラーは以下の通り。

```
 Caused by: android.view.InflateException: Binary XML file line #46: Error inflating class TextView
 ..略
 Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_info_outline_grey_700_24dp.xml from drawable resource ID #0x7f0700e3
```

回避方法は`AppCompatTextView`を`TextView`の代わりに使用して、 `app:drawableLeftCompat`でリソースを指定すること。

参考
https://stackoverflow.com/questions/35761636/is-it-possible-to-use-vectordrawable-in-buttons-and-textviews-using-androiddraw
プルダウン/ラジオボタン検索のテストパターン

検索条件がプルダウン/ラジオボタン形式のときのテストパターンについて、自分の考えを纏めてみました。

##前提の話
プルダウン/ラジオボタン形式の検索条件がどういうものか、以下で説明します。

###プルダウン/ラジオボタン形式の検索条件
プルダウン：フォームをクリックすると項目の一覧が表示され、項目を選択するとフォームに値が設定される
ラジオボタン：選択可能な項目が列挙されていて、項目を選択すると選択状態となる
このとき、他の項目が選択状態であれば、選択が解除される
※（一般的には）左隣にある〇が◎となる

どちらも、複数の選択肢があり、そのうちの一つのみ設定可能なところが特徴です。

※プルダウンの中には、複数の設定が可能なUIとなっている場合もありますが、ここでは単一の選択のみ可能とします。

検索条件が選択肢となる場合の多くは、検索対象も選択肢の項目の場合が多いです。
　※選択肢の内容と、検索対象の項目が一致する
そういった意味では、テストパターンは有限といえます。

##テストパターンについて
自分は、検索条件がプルダウン/ラジオボタン形式のときは、一致している/していないを網羅できるようにパターンを作成しています

###事前準備データ
| |対象項目の設定値|その他（対象に関連の無い項目）|
|:--|:--|:--|
|データA|[未設定]|任意|
|データB|先頭のデータ|〃|
|データC|任意の中間位置のデータ|〃|
|データD|末尾のデータ|〃|
※先頭/中間/末尾は、ID順、画面表示順等の複数パターンがあるが、対象システムを考慮して選択する

###検索結果の確認
**例：部分一致の場合**

| |対象項目の<br>検索条件|その他の<br>検索条件|取得結果|補足|
|:--|:--|:--|:--|:--|
|no.1|[未設定]|[未設定]|A, B, C, D|条件未設定を確認|
|no.2|先頭のデータ|〃|B|先頭データを確認|
|no.3|データCで設定したデータ|〃|C|中間データを確認|
|no.4|末尾のデータ|〃|D|末尾データを確認|
|no.5|上記以外のデータ|〃|ヒットなし|一致なしを確認|

　
ポイントとして、まずプルダウン/ラジオボタン検索に限らないところでは
　●検索条件が複数設定できる場合は、対象以外の検索条件は必ず**<font color="Red">未設定</font>**にし、試験対象に影響が出ないようにする。
　　⇒組み合わせのテストは、それぞれの対象1つずつのテストが完了してから行う。
　●事前準備データの設定値が未設定の場合も考慮する。
　●検索条件が未設定の場合や全て不一致となる場合も考慮する。
辺りを思っています。

プルダウン/ラジオボタン検索に関連するポイントとしては、
　●検索条件/検索対象が有限であるため、その中でも**<font color="Red">比較的障害が出やすいと思われる、先頭/末尾のデータ</font>**で確認を行う
辺りを思っています。

##最後に
プルダウン/ラジオボタン検索の場合、パターンは有限ではありますが場合によってはパターンは膨大になります。
※データがn種類あった場合、未設定を含めると
　用意可能なデータ：n+1種類
　検索条件：n+1種類
　⇒n+1回検索を行い、その度にn+1種類のデータのヒットする/しないを確認する
なので、どこまで効率よくパターンを削れるかが大事だと思っています。

検索画面の試験の場合は、個々の検索条件が仕様通り動作しているかを確認した後に、それぞれの条件を組み合わせた検索についても試験を行う必要があると思っています。流れとしては、
　①個々の検索条件が正しく動作する
　②それぞれの検索条件を組み合わせた検索が正しく動作する
だと思っています。
⇒①の試験で個々の条件の担保を取ったうえで、②にて組合せの試験を行うなど

検索条件を組み合わせる場合の試験パターンについては、以下のページに記載しています。
[複数の条件がAND条件/OR条件で繋がれているときのテストパターン](https://qiita.com/yasuhisa_ito/items/ca7ad58abd2b408110f0)
参考になれば幸いです。
ES（ECMAScript）とは？jsがブラウザによって動いたり動かなかったりするのはなぜ？

# 概要
・ESとはECMAcriptの略
・ESとはJavaScriptの標準規格のこと
・jsはもともと標準規格がなく、各ブラウザで仕様の違いがちょこちょこあったらしい
・ECMA Internationalという団体により、jsの標準規格が作成された
・そのES仕様に従って、各ブラウザベンダーがブラウザに機能を実装する


# 直近のESバージョン
直近リリースされているESバージョンはこんな感じ。

・ES5：2009年末にリリース
・ES5.1：2011年6月にリリース
・ES2015(ES6)：2015年6月にリリース
・ES2016：2016年6月にリリース
・ES2017：2017年6月にリリース
・ES2018：2018年6月にリリース
・ES2019：2019年6月にリリース

ほぼ全部のブラウザで動くのがES5。
いま標準になっているのがES6。
それ以降は毎年新バージョンがリリースされ、
年号をバージョン名としている。


# ESバージョンで何が変わるのか
ESのバージョンが上がると具体的に何が変わるのか。
より書きやすく便利な文法が追加されたり、
便利な標準ライブラリが追加されたりする。

ES5とES6の例でメジャーなものだけをピックアップ。

## アロー関数
ES5ではこのように書いていた。

```js
var arrow = function arrow() {
  return 'アロー関数';
};
```

これをES6ではこのように書くことができる。

```js
var arrow = () => {
    return 'アロー関数';
};
```

## 分割代入
ES5ではこのように書いていた。

```js
var firstName = '田中',
    lastName = '一郎';
```

これをES6ではこのように書くことができる。

```js
var [firstName, lastName] = ['田中', '一郎'];
```

## Math
標準ライブラリとしてMathが追加された。

`Math.abs(x)`で絶対値を返したり、
`Math.ceil(x)`で切り上げしあり、
いろいろ便利な計算処理機能を提供している。


このほかにもいろいろと、
便利な記法や関数、ライブラリなどが追加されている。

# 各ブラウザの対応状況
ES最新バージョンがリリースされたからと言って、
全てのブラウザがその最新ES機能を使えるわけではない。

ブラウザAでは最新ESの機能がすべて実装されているが、
ブラウザBではES5までの機能しか使えない。
のようなことがある。

各ブラウザごとにどのESバージョンに対応しているのかを
このサイトでチェックすることができる。
http://kangax.github.io/compat-table/es6/

または、このサイトでは
使いたい機能をキーワードで検索し、
各ブラウザの対応状況を確認することができる。
https://caniuse.com/#search=arrow


## IEはES5までしか対応していない
ここで重要なのは、
主要ブラウザである
Chrome、FireFox、Safari、Edgeなどは
基本的にES6以上に対応しているのに対し、
IEはES5までしか対応していないということ。

つまり、
上述したarrow関数や、Mathライブラリなど、
ES6の便利な機能を使って開発を進めていたが、
IEで動作確認したら全然動かなかった。
ということが起きてしまう。


# IEへの対応方法
ES6の便利な機能をたくさん使って実装したいが、
IEでも動作する必要がある。
とか
ESの事情など知らずに実装してしまい、
最後に動作確認してみたらIEだけ全然動かなった（知らずにES6で書いてた）。
ということがあるかと思います。

そのような状況を解決してくれる
`polyfill`と`babel`という便利なツールがあります。


ES6を使って効率的に開発を進めたうえで、
`polyfill`や`babel`などのツールを使ってIEに対応する。
というやり方が割と一般的なようです。

具体的な機能、使い方は個別記事を参照。
[polyfill、babelとは？jsをどのブラウザでも動くようにしてくれる。（IE対応）](https://qiita.com/minato-naka/items/a2645aeb158662a9f0e9)


# 参考
https://www.sejuku.net/blog/100946
https://qiita.com/rifutan/items/a55f132d4dae7e2f1941
https://qiita.com/rana_kualu/items/1f98c1a642102f48aa78
webpackとは？

# 概要
webpackとは、モジュールバンドラ。
モジュールバンドラとは、
複数のファイルを１つにまとめて出力してくれるツールのこと。
（複数ファイルをまとめることを「バンドル」と呼ぶ）

主にjsをバンドルする役割が多いみたいだが、
CSSや画像などもバンドルできるらしい。


また、SASSの変換など、
コンパイル機能もあるらしいが、
主な用途としてはバンドル。


# なぜ使うのか
大きな利点としては、２つ。
## 開発効率アップ
機能ごとにファイルを分けて開発をすることによって、
コードが整理されて開発効率、保守性が上がります。

## システムの性能アップ
たくさんのjsファイルを１ページで読み込もうとすると、
リクエストがその数だけ発生し、
時間がかかってしまいます。

１つのファイルにまとめることで、
リクエストも１回だけにし、
性能を高めることができます。


そのほかにもいろいろ利点があるが、割愛。


# 使い方
## 必要なファイル
・バンドル対象のファイル
・エントリーポイントファイル
・webpack設定ファイル

このそれぞれを作っていきます。

## バンドル対象ファイル
このような２つのjsファイルがあり、
それを１つのファイルにまとめたいとする。

```sample1.js
module.exports.sample1 = function() {
		alert("sample1.jsです。");
}
```

```sample2.js
module.exports.sample2 = function() {
		alert("sample2.jsです。");
}
```

## エントリーポイントファイル
先ほどの２つのファイルのまとめ役となる
エントリーポイントファイルを作成します。

```app.js
//まとめたいファイルをインポート
var sample1 = require(./sample1.js);
var sample2 = require(./sample2.js);

//インポートしたファイルの関数を実行できる
sample1.sample1();
sample2.sample2();
```

モジュールを読み込む方法として
requireとかimportがあるが、
その違いについてはこちらの記事で解説している。
[jsのimportとrequireの違い](https://qiita.com/minato-naka/items/39ecc285d1e37226a283)

## 設定ファイル
次に、webpackの設定ファイルを作ります。

```webpack.config.js
module.exports = {
		entry: "./app.js",
		output: {
				path: "./",
				filename: "bundle.js"
		}
}
```

entryにエントリーポイントファイルを書いて、
outputに、バンドルされたファイル名と出力先パスを書くだけです。

実際にはもっといろいろ設定できる項目があります。


## webpack実行
ここまでできたらあとは
コマンド `webpack` を実行するだけです。

すると、
バンドルされた状態のbundle.jsが出力されます。

htmlファイルの`<script>`タグでそのファイルを読み込めば、
バンドルした各ファイルの機能を利用できます。


# もう少し詳しい機能
## モード
設定ファイルには`mode`という項目がある。
`develop``production``none`に設定可能。

これをproductionにすると
圧縮されたファイルが出力される。


## ローダー、プラグイン
違いはよく分からないが、
webpackにいろいろ便利な追加機能を入れることができる。

ES5のコードに変換してくれるbabelやeslintなど。
npmでインストールしたうえで、
webpack.config.jsに設定を書くと、
その機能を実行してくれる。




#参考
https://qiita.com/uchiko/items/9972cfe9341df7ba4a8d
https://qiita.com/bakira/items/3c4e2d10aae085767817
https://qiita.com/kamykn/items/45fb4690ace32216ca25
https://goworkship.com/magazine/how-to-webpack/
https://qiita.com/soarflat/items/28bf799f7e0335b68186
可読性を高めるif文の書き方-java

研修メモ。（自分用）
**※総ツッコミをいただきましたので訂正いたします。
ご指摘に感謝申し上げます。2019/11/14**

チームで開発する場合プログラムの読みやすさつまり可読性は重要となる。
・積極的にコメントを入れる。
・if文の条件は必ずコメントを入れる癖をつけたほうがよい。

例えば以下のような条件の場合

```java:sample
//aがbと等しい　または　cがdと等しいかつ eはfと等しくない　かつ　gはhと等しくない
if (a == b || (c == d && e != f) && g != h) {
 //処理内容
}

```
条件が複数ありややこしいので
条件を整理する。

```java:sample

	        int a = 0;
	        int b = 0;
	        int c = 0;
	        int d = 0;
	        int e = 0;
	        int f = 0;
	        int g = 0;
	        int h = 0;


	        if (a == b || (c == d && e != f) && g != h) {
	            System.out.println("true1");
	        }


	        if (a == b) {
	        	System.out.println("true2");
	        } else if (c == d & e != f) {
	        	if (g != h) {
	        		System.out.println("true2");
	        	}
	        }
```
結果：
true1
true2

```java:sample

// 間違っていた処理
	        if (g != h) {
	            if (a == b) {
	                System.out.println("true2");
	            } else if (c == d && e != f) {
	                System.out.println("true2");
	            }
	        }
	    }
```

処理内容にもよるが、多少行数が増えたとしても
パッと見た簡潔さ、シンプルさを重視する現場は多いとのこと。