OmniAICreator/Qiita-1.07M huggingface dataset:
Linux　ファイル名に日付を含んでバックアップ

# はじめに
Qiitaに記事を書いてみよう！ということで。
Linuxサーバーで、「ファイル名.日時」の形式でバックアップすることが多かったため、
その記事をチョイスしました。


# 実行した環境
CentOS Linux release 7.7.1908 (Core)


# コマンド
「ファイル名.年月日時分秒」でバックアップする例です。
日時の形式はdateコマンドのフォーマットで調整できます。

###ファイルの場合

```
$ cp -p <ファイル名> <ファイル名>.`date  +%Y%m%d%H%M%S`
```

###ディレクトリの場合（ファイルもOK）

```
$ cp -rp <ディレクトリ名> <ディレクトリ名>.`date  +%Y%m%d%H%M%S`
```


# 面倒な点
このコマンドだと、ファイル名やディレクトリ名を2回打たなければなりません。
コピー先のファイル名を間違えて、「別ファイルのバックアップ」が紛れ込んで痛い目にあったこともあります。
自作のコマンドが置けるのであれば、そのほうが安全です。
（置けない場合は上記コマンドをいつもコピペしていました。。。）


# 自作コマンド化
私の場合、以下のコマンドを「bkcp」という名で /home/<ユーザ名>/bin/ に保存しています。
実際のコピーコマンドもわかるよう、表示するようにしています。

bkcp

```
#!/bin/bash

if [ $# -ne 1 ]; then
  echo "Usage: bkcp filename" 1>&2
  exit 1
fi

CMD="cp -rp $1 $1.`date  +%Y%m%d%H%M%S`"
echo $CMD
`$CMD`
exit 0
```

bkcp実行例

```
$ bkcp testfile
cp -rp testfile testfile.20190924114404
```



# コマンドの拡張例
私の好みは、年月日時分秒を付ける形でファイル名の衝突を考慮しない形ですが、
サーバの運用方法や、チームのルールによって、過去に派生コマンドを作っていました。

- 年月日でバックアップ。年月日がかぶる場合は枝番を付ける。
- 上記のルールに加え、オプションで枝番上書き可能とする。
- dateコマンドのフォーマットを指定可能にする。


# 参考
今回の記事を書くにあたって、改めて参考とさせていただきました。

- [dateコマンドでバックアップファイル作成時にファイル名に日付_時間を付ける (LinuxとWindows用)](https://qiita.com/na0AaooQ/items/c26b637261d9962f981f)
MediaWikiのテンプレートとSubstitutionとの相違点

#Mediawikiで同じようなページを作成する場合

MediaWikiで同じようなページを作成する場合、いちいち共通部分を打ち込むのは面倒で、非生産的です。

これを解決する手段として、MediaWikiには「テンプレート」と"Substitution"があります。

「テンプレート」については色々なところに日本語の解説があるのですが、"Substitution"についてはあまり日本語の解説を見かけないので、ここに記しておきます。

#テンプレートについて
テンプレート(Template)とは、いわゆる雛形のような物です。予め作成しておいた定型文などを、一つの記述で表示することができます。

##作成方法
通常のページと同じです。検索窓に「テンプレート:hogehoge」と入力すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390159/5dfea6de-4f2a-5b21-6b81-f9d8a551406a.png)

こんな感じで表示されるので、赤くなっているリンクをクリックすると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390159/12dd71ba-3424-9c4b-bbb5-26ec39837590.png)

こんな感じで編集画面に飛ぶので、あとは内容を記述して「ページを保存」するだけです。

とりあえず試しに、Hello Worldと記入して保存しておきましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390159/44a30a1b-afb5-980e-0b80-693c57c55dc2.png)


##使用方法
テンプレートを作成しておけば、文中に```{{Template:hogehoge}}```(あるいは```{{テンプレート:hogehoge}}```)と入力すれば、テンプレート"hogehoge"の内容が表示されます。

実際にやってみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390159/7e94cbc6-61c9-f0ba-0a08-7ff3d953268c.png)

これで保存すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390159/7d2bf671-3c4c-acb8-721a-97a117fc797c.png)

無事に表示されました。

ちなみに、テンプレートの内容を変更すると、この「テスト」の記事内容も変わります。

#Substitutionについて
Substitutionには「代用」とか「置換」とかの意味があるようですが、MediaWikiの場合は「置換」が適切な翻訳かと思います。

Substitutionは、指定されたテンプレートを呼び出し、Substitutionを挿入した部分をそのテンプレートで**置き換え**ます。つまり、Substitutionを挿入した部分が、そのままテンプレートの内容に置き換わるということです。

注意したいのが、Substitutionを使用した場合、**その時点でのテンプレートの内容が挿入される**ということです。以降のテンプレート編集内容は、Substitutionには反映されません。

##使用方法
テンプレートと同じように```{{subst:hogehoge}}``と記事中に記入することで使用できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390159/62772002-15b0-d76d-a95a-45dd9420ecae.png)

これを保存すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390159/c5da32f2-e968-9068-b200-9abb9d63bd3e.png)

こんな感じで、内容が置換されます。

#使い所
私自身イマイチ使い所が分からないのですが、今の所、substは新しいページを作成する際に使用しています。

現在、MediaWikiを使って、ある程度形の決まった作業手順書のような物を作成しているのですが、そのページを新規作成する際はsubstで作成し、substの中で違うテンプレートを使用したりして、新規ページを作成する時間を短縮しています。

なにかもっと良い使い所があったら教えて下さい。
MySQLテストデータ生成

MySQLにテストデータを大量に突っ込む際のベストプラクティスをまとめる。

ここら辺を参考にした。
https://qiita.com/tayasu/items/c5ddfc481d6b7cd8866d
https://qiita.com/SuguruOoki/items/8a00c237737d143a529a

```sql:create_table.sql
DROP TABLE IF EXISTS `sample`;
CREATE TABLE IF NOT EXISTS `sample` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`create_date` INTEGER NOT NULL,
`update_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;
```

適当に10件データを登録

```sql:insert.sql

INSERT INTO `sample` (`id`, `name`, `create_date`, `update_date`) VALUES
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP),
(NULL, SUBSTRING(MD5(RAND()), 1, 50), CEIL(RAND() * 2678400 + 1561939200), CURRENT_TIMESTAMP);
```

CROSS JOINでONの条件をいじることでデータを特定の量増やせる。今回は*10してみた。
複数回実行することで、データをスケールさせる。

```sql:multi.sql
INSERT INTO `sample` (`name`, `create_date`, `update_date`) SELECT T1.`name`, T1.`create_date`, T1.`update_date` from `sample` as T1 CROSS JOIN `sample` as T2 ON T2.id IN (1, 2, 3, 4, 5, 6, 7, 8, 9);
```
PHPカンファレンス北海道2019 スライドまとめ

# PHPカンファレンス北海道2019
https://phpcon.hokkaido.jp
2019/09/21 札幌市民交流プラザ で開催

当日のtweetのまとめ
https://togetter.com/li/1407316


※以下、敬称略

# メイントーク

## PHPを学ぶということ
岸田健一郎
https://speakerdeck.com/sizuhiko/phpcondo-2019


## 【ランチセッション】 オミカレのフルリニューアルの裏側を全部見せます！
株式会社オミカレ 前川昌幸
https://speakerdeck.com/maepon/omikarefalsehururiniyuarufalse-li-ce-woquan-bu-jian-semasu

## PHPerのためのPHPUnitとSeleniumを使ったブラウザテストのすゝめ
めもり〜
https://speakerdeck.com/memory1994/phper-falsetamefalse-phpunit-to-selenium-woshi-tuta-burauzatesutofalsesu-me


## PHPでCI/CD 〜 私は最近こんな感じでやってます
渡辺一宏
https://speakerdeck.com/kaz29/201909-phpconbei-hai-dao-phpteci-cd


## SQLアンチパターンの紹介
川井健太(Mister_K)
https://www.slideshare.net/ssuser7f2faa1/introduction-of-sql-antipattern-at-phpcon-hokkaido


## クリーンアーキテクチャの考え方に基づく Laravel との付き合い方
岡田 正平／おかしょい
https://www.slideshare.net/ShoheiOkada/laravel-phpcondo


## Slim v4に学ぶPHP with PSRの今とこれから
山岸 "あかいいぬ" Masaru
https://speakerdeck.com/akaiinu/korekara


## Swooleで実装するPHP非同期処理の世界
小山哲志
https://speakerdeck.com/koyhoge/phpcondo2019-swoole


# Lightning Talk

## pharによるワンバイナリアプリケーションの可能性を探ってみた
goodoo
https://speakerdeck.com/sgeengineer/pharniyoruwanbainariapurikesiyonfalseke-neng-xing-wotan-tutemita


## PHP製バス停検索サービスでのバス情報オープンデータ活用
福田匡彦
https://www.slideshare.net/umineko50/php-175509353

## 自作して理解するxUnit
東口和暉
https://speakerdeck.com/hgsgtk/self-made-xunit

## 開発をVagrantからDockerへ！
soudai
https://speakerdeck.com/soudai/vagrant-to-docker


## エンジニアがブログや登壇で、アウトプットするとどうなる？
うゐろう
https://docs.google.com/presentation/d/1WfMIaYenrn9Iw5VNz7Jws5MKrMLZqM9vvBdH8Dyv83c/edit#slide=id.g4d8a820d28_0_2

## CPUとは何か
長谷川智希
https://speakerdeck.com/tomzoh/whats-a-cpu

## PHP バグ・脆弱性の温床10連発
うさみけんた
https://www.pixiv.net/fanbox/creator/105589/post/571554

# スポンサーLT

##  BASE株式会社
https://speakerdeck.com/nazonohito51/cakephp2-ide-helper

## PHP技術者認定機構
https://www.phpexam.jp/2019/09/22/phpカンファレンス北海道2019%E3%80%80php技術者認定機構登壇資/


## 株式会社ゆめみ
https://speakerdeck.com/genki_kudo/lightning-talk-session-of-php-conference-hokkaido-japan-2019-sponcererd-by-yumemi-dot-inc

## コネヒト株式会社
https://speakerdeck.com/itosho525/aim-for-the-indispensable-company-for-our-engineer-community

# アンカンファレンス

## テストを助けに使って設計を改善しよう～リファクタリングことはじめ～
77web
https://speakerdeck.com/77web/tesutowozhu-kenishi-tuteshe-ji-wogai-shan-siyou-rihuakutaringukotohazime

## Do You Select PostgreSQL or MySQL ?
soudai
https://speakerdeck.com/soudai/do-you-select-postgresql-or-mysql

## P++とは何だったのか (再放送)
tadsan
https://www.pixiv.net/fanbox/creator/105589/post/531192

## PHP で JVM を実装する (ショートバージョン)
めもり〜
https://speakerdeck.com/memory1994/php-de-jvm-woshi-zhuang-suru-siyotobaziyon

# 懇親会LT

## PHPエンジニアとして圧倒的に成長するたった一つの方法
77web
https://speakerdeck.com/77web/phpenziniatositeya-dao-de-nicheng-chang-surutatuta-tufalsefang-fa

## Hugo・3Dモデル旅行・VR・バーチャルカンファレンス
うゐろう
https://www.nyamucoro.com/entry/2019/09/22/000747

## PHP で Python を動かす (ショートバージョン)
めもりー
https://speakerdeck.com/memory1994/php-te-python-wodong-kasu-siyotohasiyon

## PHPのいろんな機能でFizzBuzz
tadsan
https://qiita.com/tadsan/items/13fd5b66e9ea4627c22c

----

【おまけ】 2019年に開催される全国のPHPカンファレンスのまとめ
https://qiita.com/akase244/items/d74316f6ee8fa464cfa3
【OCI】oracle cloud -仮想クラウド・ネットワーク構築編(インターネットゲートウェイ)-【初心者向け】

# インターネットゲートウェイ
インターネット・ゲートウェイは、
VCNに追加してインターネットに直接接続できるオプションの仮想ルーターです。
ここで作成したインターネットゲートウェイはルート表で使用します。

## 前回の記事でサブネットを作成しました。

サブネットの作成を見たい方はこちらから
[サブネット編](https://qiita.com/manaki079/items/20d9aa3b47db3b39fddd)


## インターネットゲートウェイの作成
サブネットを作成したいVCNの詳細ページ
左側のリソース→インターネットゲートウェイをクリック
![instance_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/e5df54a5-29cc-7576-5c0b-c0d5968f1b32.png)
インターネットゲートウェイの作成をクリック
![instance_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/696a335e-7d63-4aef-2f17-4ec9ba0f85ff.png)

| 項目       | 概要|
|:-----------------|:-----------------|
| 名前             | 任意のインターネットゲートウェイ名を入力します。 |
| コンパートメントに作成           | 作成するコンパートメントが間違っていないか確認|

インターネット・ゲートウェイの作成をクリックしたら完了です。
![instance_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/17f4a605-806a-44f9-d053-b5c01546aa9d.png)

## 次回
ネットワーク・セキュリティグループの作成を行っていきます。

[ネットワークセキュリティグループ編はこちら](https://qiita.com/manaki079/items/2a1eac62997ea41ab71e)
GreenSock簡単チュートリアル Timelineで要素を制御する。

# TimelineMaxで要素の動きを制御する。

前章: [GreenSock簡単チュートリアルの続きです。](https://qiita.com/RinT_T/items/7641afd9f861c724fa8b)

![ch3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273658/1546bdb0-1b3d-310a-dbcf-12f885f7ab21.gif)

## 概要

このチャプターでは上記のGIFのような、アニメーションの順番を制御するTimelineMaxについて学びます。

## TimelineMax

```index.js
import { TweenMax, TimelineMax } from "gsap";

TweenMax.set("#box", {
  backgroundColor: "green",
  width: "50px",
  height: "50px",
  x: "50px",
  y: "50px"
});

const timeline = new TimelineMax();

//timeline.to( target:Object, duration:Number, vars:Object, position:* ) 
timeline.to("#box", 0.5, { x: 100 });
timeline.to("#box", 0.5, { y: 100 });
timeline.to("#box", 0.5, { x: 50 });
timeline.to("#box", 0.5, { y: 50 });

timeline.resume();


```

TweenMax.setは前回と同様です。<br> const timeline = new TimelineMax();で新しいインスタンスを生成して使います。<br>timelline.toを順番に記述することで、実行順序を指定し、timeline.resume();で実行しています。<br>ページをリロードすると時計回りに要素が動いたでしょうか？

続いてGIFのようなクリックイベントでアニメーションの実行を制御していきます。

```index.js
import { TweenMax, TimelineMax } from "gsap";

TweenMax.set("#box", {
  backgroundColor: "green",
  width: "50px",
  height: "50px",
  x: "50px",
  y: "50px"
});

const timeline = new TimelineMax({ repeat: -1 });

timeline.pause();//初期状態でtimelineをポーズします。

timeline.to("#box", 0.5, { x: 100 });
timeline.to("#box", 0.5, { y: 100 });
timeline.to("#box", 0.5, { x: 50 });
timeline.to("#box", 0.5, { y: 50 });

//クリックイベントでアニメーションの実行を制御します。
document.querySelector("#box").addEventListener("click", () => {
  if (timeline.isActive()) {
    timeline.pause();
  } else {
    timeline.resume();
  }
});


```

timelineはisActiveメソッドで実行中か否かの判定が可能なのでこちらを利用してstart/pouse機能を実装します。
そのほかにも数多くの機能があるので興味がある人は[公式ドキュメント](https://greensock.com/docs/v2/TimelineMax)で確認してください。

[ここまでのDemoはこちら](https://codesandbox.io/s/greensockch3-1x22s)

次回は複数要素のアニメーションの扱い方を学んでいきます。

![ch4 (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273658/149993fa-d816-9820-ba94-d0a4186ec48d.gif)
GreenSock簡単チュートリアル(TweenMax,TimelineMax)

# GreenSockの使い方を学ぶ

## 概要

本エントリーではgsapの基本的な使い方をデモを交えながら説明します。

## [GreenSock](https://greensock.com/)とは
通称gsap(green sock animation platform)、内包されているライブラリからTweenMaxやTimelineMaxなど呼ばれるアニメーションライブラリです。 <br>煩雑になりやすいアニメーションを簡素に書くことができ、なおかつ軽快な動きでモダンブラウザやie11にも対応しています。<br>そのほかにもアニメーションの指定をjavascriptで管理する特徴があります。<br>※後述しますが、Classの付け外しも可能なので、CSSのみのアニメーションと組み合わせることも可能です。  

基本となるのは[TweenMax,TimelineMax]の二つのライブラリで、liteと付くのはそれぞれの軽量版になります。

gsap
┣Tweenlite
┣TweenMax
┣TimeliteMax
┣TimelineMax

## 環境構築

ディレクトリ構成
App/
┣index.html
┣styles.css
┣index.js
┣package.json

手軽に環境構築が出来るparcelを使用します。

parcel-bundlerのインストール


```
cd App
yarn add -D parcel-bundler  
```

package.jsonにscriptsを追加します。

```package.json

{
  "scripts": {
    "dev": "parcel index.html"
  },
  "devDependencies": {
    "parcel-bundler": "^1.12.3"
  },
}

```

index.htmlを追加し、styles.cssとindex.jsを読み込みます。

```index.html
<!DOCTYPE html>
<html lang='ja'>
<head>
    <meta charset='UTF-8'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <meta http-equiv='X-UA-Compatible' content='ie=edge'>
    <link rel='stylesheet' href='./styles.css'>
    <title>Document</title>
</head>
<body>
    <h1>Hi</h1>
    <script src='./index.js'></script>
</body>
</html>
```

npm scriptを実行します。

```
yarn dev
```

記載されたURLにアクセスすることで、index.htmlが表示されたら成功です。

## gsapのインストール

parcelではimportを解釈して不足しているモジュールをインストールしてくれます。
インストールが確認できたらgaspが正常に動作するか確認しましょう。

```index.js
import { TweenMax, TimelineMax, Elastic } from 'gsap'

TweenMax.to("h1", 1, {x: 100})


```

いかがでしょうか。h1の"Hi"テキストがx方向に移動したら成功です。  
ここまでの[Demo](https://codesandbox.io/s/greensockch1-kl8ez)はこちらです。



## clickイベントを使って要素を動かす。

![ch.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273658/a25e9d1e-12be-f95f-7ccc-3b68e085e738.gif)


このチャプターでは上記のGIFのような、クリックした位置に要素を移動させるアニメーションを作成します。

始めにindex.htmlに#boxを追加します。

```index.html
<body>
	<div id="box"></div>
	<script src="src/index.js">
	</script>
</body>
```

デフォルトのCSSをリセットするためbodyにmargin:0；を設定します。

```styles.css
body {
  margin: 0;
}

```

続いてindex.jsにアニメーションを設定していきます。

```index.js

import { TweenMax, TimelineMax, Elastic } from "gsap";

//TweenMax.set([obj1, obj2, obj3], {x:100, y:50, opacity:0});
TweenMax.set("#box", {
  backgroundColor: "green",
  width: "50px",
  height: "50px",
  xPercent: "-50",
  yPercent: "-50"
});

document.addEventListener("click", event => {
  //TweenMax.to([obj1, obj2, obj3], 1, {x:100});
  TweenMax.to("#box", 0.5, { x: event.x, y: event.y });
});

```

コードの説明です。
<b>[TweenMax.set](https://greensock.com/docs/v2/TweenMax/static.set)</b><br>TweenMax.setは指定した要素の初期値を設定します。<br>第一引数に対象要素、第二引数にプロパティを渡すことができます。<br>プロパティ名にハイフンは使えないので、キャメルケースで記述します。

<b>[TweenMax.to](https://greensock.com/docs/v2/TweenMax/static.to())</b><br>clickイベントを取得しTweenMax.toで指定した要素の動きを設定します。<br>第一引数にObject、第二引数にアニメーション完了までの時間(1/sec),第三引数にプロパティを渡すことができます。
上記の例ではクリックした位置のx,y軸の値を取得しTweenMax.toに設定することで、ポインターを追尾するような処理を実行しています。<br>

ここまでの[Demo](https://codesandbox.io/s/greensockch2-hrzcb)はこちらです。


[次章: GreenSock簡単チュートリアル Timelineで要素を制御する。](https://qiita.com/RinT_T/items/92f4fa3e9d5ede973a6d)
Excelをファイルサーバで誰が開いているか分かるようにユーザ名を変更する方法

Excelを社内のファイルサーバで管理している時などに
複数人で管理していると、開いたときに読み取り専用でロックがかかっている時がありませんか？

ファイル自体をブックの共有設定で共有にする方法もありますが、
少し重くなったりと不便なこともあります。

そんな時にファイルを誰が開いているか分からないと編集できないため
ファイルを開いているユーザ名を表示する設定です。

## Officeのユーザ名設定
```「Excelのオプション」→「基本設定」→「Microsoft Officeのユーザ設定」```

<img width="412" alt="exceloption.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/960e3698-0215-48f2-bee0-fe05ce069bea.png">

でユーザ名を名前に変更するだけです。
これをチーム内で徹底して設定しておけば誰がファイルを開いているかが明確になります。

デフォルトの設定だとここがコンピュータ名になっていたり、アクティブディレクトリを使っていればADのユーザIDになっていたり、
Officeを新規インストールした時にダイアログで求められて入力した値になっていたりします。

※画面はOffice2007のWindows版を対象としていますが、それ以降のバージョンでも大きくは変わらないと思います。
GitHub Actions で lighthouse を実行する

GitHub Actions で lighthouse を実行して結果をダウンロードする方法です。

- [GoogleChrome/lighthouse | GitHub](https://github.com/GoogleChrome/lighthouse)

## Workflow の例

以下のワークフローは、週1回 `https://<target>.com` に対してテストを実行し、結果を artifact としてダウンロードする、という利用ケースです。

```yaml:.github/workflows/lighthouse.yml
name: lighthouse

on:
  schedule:
    - cron: '23 23 * * 0'

jobs:
  test:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2

      - name: Install lighthouse
        run: sudo npm i -g lighthouse

      - name: Run lighthouse
        run: |
          lighthouse \
            --chrome-flags="--headless" \
            --output html --output-path ./report.html \
            'https://<target>.com'

      - name: Upload result
        uses: actions/upload-artifact@master
        with:
          name: report
          path: report.html
```

自分の実行環境だと lighthouse のインストールに22秒、実行に20秒くらいの時間を要しました。

![Run lighthouse on GitHub Actions](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285675/cfdc8e72-19ba-e9f1-0ce0-3e2dcc3bebcb.jpeg)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285675/94374b94-3394-c1b0-1a80-9371143f86ff.jpeg" width="300px" alt="Download artifact of lighthouse result on GitHub Actions">

![qiita3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285675/549770ff-534c-30af-80e8-d5520125c531.jpeg)


## Docker とか不要

GitHub Actions の仮想環境には Google Chrome がプリインストールされていますので、わざわざ headless chrome の Docker image を使ったり、そのためだけの Action を作ったりする必要はありません。

- [Software in virtual environments for GitHub Actions - GitHub Help](https://help.github.com/en/articles/software-in-virtual-environments-for-github-actions)


## 結果を GitHub Pages へデプロイ

`peaceiris/actions-gh-pages` については [peaceiris/actions-gh-pages: GitHub Actions for deploying to GitHub Pages with Static Site Generators](https://github.com/peaceiris/actions-gh-pages) を参照してください。

```yaml:.github/workflows/lighthouse.yml
name: lighthouse

on:
  schedule:
    - cron: '23 23 * * *'

jobs:
  test:
    runs-on: ubuntu-18.04
    steps:
      - uses: actions/checkout@v2

      - name: Install lighthouse
        run: sudo npm i -g lighthouse

      - name: Run lighthouse
        run: |
          lighthouse \
            --chrome-flags="--headless" \
            --output html --output-path /tmp/report.html \
            'https://<target>.com'
          mkdir ./public
          cp /tmp/report.html ./public/report.html

      - name: Deploy
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./public
          keep_files: true
```
Kerasに学習させる画像を回転させて水増しする

　ネットで学習用データを探すと、リンゴみたいな単純なものでも意外と枚数がなく、十分なデータが集まらない。なので、1枚のデータをあれこれ加工することで学習データを水増しします。
　方法はいろいろあるけど、今回は単純に10度回転を繰り返すことで1枚の画像を36枚に水増しします。10倍だぞ10倍

#最初に謝っておく
　Pythonのforループですが、rangeの終点の値になった時点で止まる仕様のようです。前回、`range(1,20):`と書いて、1.jpgから20.jpgまで読み込ませたかったのですが19.jpgで止まっていました。
　1から20まで読み込ませたい場合は`range(1,21):`が正解みたいです。すみませんでした。

#何をするの？
　forループを使って画像を回転させます。10度ずつなのでループ数*10で回転を繰り返し、都度numpy配列に格納していけばOKです。360度回すので`range(0,36)`です。
　ポイントらしいポイントもないですが、強いて言うならforループの外に回転前のデータを残してそれを都度参照するようにしておかないと、意図せずすっごい画像が回り出すことだけは注意でしょうか。

#OpenCVを使った方法
 OpenCVの場合、回転の軸(今回は中心)と角度を指定したあとアフィン変換を実行します。正直分かりにくいですが、細かいステータスを指定できるというメリットはあります。

```python
import cv2
import numpy as np

X = []

img = cv2.imread("apple.jpg", 1)

h, w, _ = img.shape[:3]

cw = w // 2
ch = h // 2
center = (cw,ch)

for i in range(0,36):
    trans = cv2.getRotationMatrix2D(center, i*10.0, 1.0)
    img2 = cv2.warpAffine(img, trans, (w,h))
    X.append(img2) 

```

#pillowを使った方法
　回転させるだけならpillowの方が簡単です。特にこだわりがなければこちらで。
　インストールしてない方はpipでさくっと。

```
$ pip install Pillow
```

　自分の環境によってpip3なりcondaなりに変えてください。インストール終わったら、以下のコードです。

```python
from PIL import Image
import numpy as np

X = []

img = Image.open("apple.jpg")
img = img.convert("RGB")

for i in range(0, 36):
    imr = img.rotate(i*10)
    imr = np.asarray(imr)
    X.append(imr)
```
　なお、`rotate()`は変換元とは別の変数を格納先として指定しないとエラーが出るようです。


#組み込む
　pillowで回転させる処理を含めて、[前回](https://qiita.com/Ka-k/items/71cb3f5347cee909484d)のコードを拡張したものが以下です。

```python

import numpy as np
import cv2
from PIL import Image 
from keras.utils import np_utils

folder = ["apple", "banana"]

X = []
Y = []

for index, name in enumerate(folder):
    for i in range(1,21):
        files = "./" + name + "/" + str(i) + ".jpg"
        image = cv2.imread(files, 1)
        image = cv2.resize(image, (56, 56), cv2.INTER_CUBIC)

        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = Image.fromarray(image)

        for j in range(0,36):
            imr = image.rotate(j*10)
            imr = np.asarray(imr)
            X.append(imr)
            Y.append(index)

X = np.array(X)/255
Y = np_utils.to_categorical(Y, 2)
```

　OpenCVで読み込んだデータは色情報がBGRのため、Pillowに渡すためにBGR→RGBの変換をかませています。
　もちろん、最初からpillowで読み込めば、この処理は不要です。

　これで、データセットの準備はできているはずなので、あとは学習モデルに放り込んで実行してみてください。データの数が36倍(今回の場合は(20+20)*36で計1440個)になっていれば成功です。
【芸術の秋】デッサンのゲームアプリを開発し、二次元画像の類似度判定で高精度を出した話

##はじめに
先日、初めて自作のiOSアプリを公開しましたので、
その宣伝をかねた記事を書きたいと思います。

今回は概要ということで、あまり技術的粒度の細かい話には
なりませんが、もし興味がございましたらお付き合いください。

Qitaへの投稿自体初めてだったりするので、
いろいろ至らないところがあると思いますが、
何卒大目に見ていただければと思います。。

##どんなアプリか
お題を見ながらその通りに絵を描き（デッサン）、
その結果が採点されるアプリです。
ステージクリア型のゲームとして遊ぶことができます。

[ゲームdeデッサン-ゲーム感覚でお絵かきを練習しよう](https://apps.apple.com/us/app/%E3%82%B2%E3%83%BC%E3%83%A0de%E3%83%87%E3%83%83%E3%82%B5%E3%83%B3-%E3%82%B2%E3%83%BC%E3%83%A0%E6%84%9F%E8%A6%9A%E3%81%A7%E3%81%8A%E7%B5%B5%E3%81%8B%E3%81%8D%E3%82%92%E7%B7%B4%E7%BF%92%E3%81%97%E3%82%88%E3%81%86/id1477734039?l=ja&ls=1)

追記：
appliv様でアプリをご紹介頂きました:smile:
https://app-liv.jp/1477734039/

技術的にはSwift/Objective-C（お絵描きアプリ) + OpenCV(画像加工) + 
Dlib（機械学習) + SpriteKit, Scenekit（ゲーム的演出などのフロントサイド） +
firebase（バックエンド）
で構成しています。

正直、iOSアプリ初心者だった私個人でやるには機能を入れ過ぎ、
仕事しながらコツコツ進めて、一度ゲーム性の見直しで作り直しもして
開発作業のみで1年以上かかりました。

##なぜ作ったか
一度個人制作のアプリを作ってみたかったのと、アイディアを形にしたかったからです。
下手の横好きではありますが、イラストを練習していた時期があり、
そのときにデッサンが上手くできると楽しかったため、
この感覚をホットな技術である機械学習を用いて表現したいと思いました。
（私自身が機械学習モデルを作れる訳ではありませんが。。）


##苦労したところ
iOSアプリ開発経験が少なかったため、逐一Google先生に聞いて勉強しながら実装していきました。
しかし、検索してまとまった情報があるものは、開発当時のモチベーションが高かったために何とかなりました。やはり情報が少ないものは厳しかったです。今回のようにやりたいことをどうしたら実装できるか、技術選定から始める必要のある状況だとなおさらでした。なので特に苦労したところは、「機械学習を使い、画像の類似度を判定する」ところです。

###技術検証の日々
docker上でPythonとOpenCVの検証環境を用意し、ORB,AKAZE,aHashなどの、検索して出てくる画像類似度の判定アルゴリズムを色々と試しました。しかし二次元モノクロ画像の比較に対して、どれも期待する精度が出ず。
libpuzzleというCラッパーのライブラリをxcode上でiOS用にビルドしましたが、
これも私の環境では上手くいきませんでした。でたらめに描いた絵も近似と判別してしまいました。

ディープラーニングは、残念ながら実装経験がありません。
一から勉強することを考えましたが、今回は諦め。
最終的に機械学習ライブラリの「Dlib」でhog特徴量での比較をしたところ、これが二次元画像の比較に高い精度を発揮してくれました！

hog特徴量の採用にあたってはこちらの記事を参考にさせていただきました。
[HOG特徴量を用いたポケモンのアイコン画像判別](https://qiita.com/hrs1985/items/118710a673c567a9872c)

前処理として、画像同士の比率を保持し100px×100pxにリサイズした上で、特徴量同士の距離を出しました。二次元2値画像の比較にはこれが適しているようです。
あとでOpenCVのhog特徴量でも試してみましたが、Dlibに及ばないものの、これも精度はよかったです。

##作って良かったこと
これからアプリがヒットするんで！とは言えない。。。

1年以上かけての開発だったため、アプリ開発のノウハウもたまり、
現在の会社ではiosアプリ開発業務に進んで参加しています。
自分はこれまでLL言語に比べて静的型付け言語の経験は少なかったのですが、
今回の開発を通して自信がつきました。Javaを最新の環境で組めるようになり, Kotlinも触っています。
個人開発をやりきることによる意識の変化、あなどれないです。

また自分の中のクリエイティビティを発散させることができました。
ある程度こだわりを入れることができたので、満足です。

##おわりに
アプリはフリー素材を多用しており、提供者様のご厚意がなければ開発できませんでした。
プログラムについても同様です。そのことに大変感謝しています。

今回はコードもない概要になってしまいましたが、今後改めて、技術トピックを記事にしていきたいと思います。
【WEB開発編】モーダルウィンドウの話

# 前書き
モーダルウィンドウを利用することは、WEBアプリケーション開発におけてとても不可欠です。

メッセージ表示などの利用方法は一般的ですが、編集ポップアップとしての利用方法もあります。
その場合は、いろいろな注意点と対策が必要となります。

# 基本知識
### モーダルウィンドウとは
コンピュータアプリケーションソフトウェアのユーザインタフェース設計において、何らかのウィンドウの子ウィンドウとして
生成されるサブ要素のうち、ユーザーがそれに対して適切に応答しない限り、制御を親ウィンドウに戻さないもの。
※[WIKI](https://ja.wikipedia.org/wiki/%E3%83%A2%E3%83%BC%E3%83%80%E3%83%AB%E3%82%A6%E3%82%A3%E3%83%B3%E3%83%89%E3%82%A6)

### モーダルウィンドウ実現方法
#### html5
  ウィンドを実現するために、HTML下記のタグと処理を定義している。
  タグ：
       `<dialog></dialog>`
  モードレスウィンド表示：
       `dialog.show()`
  モーダルウィンド表示：
       `dialog.showModal()`

  ウィンドウを開くと、html上は`<dialog>`⇒`<dialog open>`に変更します。
  
  下記の記事を読んでいただくと、モーダルの基本をもっと深く理解できると思います。
  [モーダルウィンドウの基本](https://webdesignday.jp/inspiration/technique/css/4680/#i-6)

#### jQuery
  jQuery自体はモーダルウィンドウ機能を提供していない。
  jQueryを利用する場合は、下記のいずれか方法でモーダルウィンドウを実現できます。

- [jQuery UI Dialog](http://js.studio-kingdom.com/jqueryui/widgets/dialog)
- [jQuery Modal jquerymodal](https://jquerymodal.com/)
- プラグインなしで、DIV＋CSSを利用して、z-indexを設定することで実現
     - 他に流行っているjavaScriptフレームワークは大体似ている方法で実現

# 一般的な利用場面（利用者に情報をお知らせ）
- 画面ローディング
- メッセージなどの表示（確認、エラー、警告、INFO）

# 編集ポップアップとする利用場面
## 注意点と対策
### セッションタイムアウト発生時
**注意点**
  セッションタイムアウト発生時、編集ポップアップ上にセッションタイム発生のみで親画面画面と連動しない。

**対策**
  編集ポップアップセッションタイムアウト発生⇒ポップアップ閉じる⇒ログインなどの画面に遷移
  のような処理を組み込むことが必要です。
  
### システム例外発生時
**注意点**
  システム例外発生時、親画面に反映しないと親画面の業務処理が続けてしまう可能性ある。

**対策**
  セッションタイムアウト発生時と同じように、システム例外画面に遷移する処理が必要です。
  
### ウィンドウ上の同期処理
**注意点**
  モーダルポップアップ上に基本的に同期処理ができない。
  【理由】モーダルポップアップ同期終了後、親画面を含めすべてリフレッシュされるため、
モーダルポップアップ同期処理後の後続処理ができなくなる。

**対策**
対策1> 同期処理を非同期処理にする。
対策2> 同期処理⇒画面リフレッシュ⇒ポップアップを再度表示
対策3> 同期処理⇒現在ポップアップを閉じる⇒新しいポップアップを表示(例：intra-mart imuiDialog)
  
### 親画面とIDやNAMEは重複する可能性
**注意点**
  HTML上にはID、NAME（チェックボックス、ラジオボタン以外）を重複したら処理が混乱してしまう可能性ある。

**対策**
・ ポップアップのほうにIDやNAMEの前にプリフィックスなどをつけて親画面と区別するように工夫する。
・ ポップアップからさらにポップアップを出したい場合、javaScript側にスタックなどの仕組みが必要となる。

# 分からないことがあったら
この文章の内容について不明な点があれば お気軽にコメントしてください。
Bashで文字列の構造体をファンクションに渡したい

自身の備忘を兼ねて記載を行っています。
「とりあえず動いた」程度のソースなどもございますので参考程度にブラシアップ頂けると幸いです。
また、誤りやもっとよいコーディングやきれいな書き方があるなどご指摘頂けるととてもうれしいです。

## 今回のお題
別のお題で作成した構造体、ファンクションに渡してそちらで処理させたいと思い作成
(普通に引数として渡すと、第一引数、第二引数・・・etc となるため)

* 別のお題：[Bashで文字列の構造体を使いたい](https://qiita.com/kazuki_hamatake/items/8bf0bb859b10e1b2b926)

## では、ソースです。
```sh:sample02.sh
#! /bin/bash

# 構造体
LOOP_LISTS=(
	ABCDEFG
	hijklmn
	1234567
	あいうえお
)

# 構造体を使って処理を行わせたいファンクション
function fLoopEcho () {
	# 引数の1つ目(構造体の名前)を変数「arrayname」に格納
	local arrayname=$1
	
	# evalコマンドを使って文字列を評価
	# (今回の場合は構造体名から構造体自体を取得するために利用)
	eval ref=\"\${$arrayname[@]}\"

	i=1
	# 構造体の中身をループで一つづつ表示
	for STRUCT_LIST in ${ref[@]}; do
		# 同一の処理(今回は表示)
		echo "${i}：${STRUCT_LIST}"
		let i++
	done
	
	return
}

# メイン処理
# ファンクションの呼び出し元
# ！！！ 構造体としてではなく名前の文字列として渡す
fLoopEcho LOOP_LISTS

```

```sh:実行結果
$ sh sample01.sh
1：ABCDEFG
2：hijklmn
3：1234567
4：あいうえお
２番目指定：hijklmn
```
python3の勉強がてら、カレンダー整形問題を解いてみた話

# 前提
- python3の勉強中の身です。

- 文章を公開するのも練習中です。

- 環境
    - windows10 WSL ubuntu
    - python3.6

# カレンダー整形問題とは
会社の同僚が教えてくれた問題。
ネットで調べると [ここ](https://blog.jnito.com/entry/2013/05/01/082049)が出てきた。

## 問題
>次のような形式でカレンダーを表示させてください
     April 2013
 Su Mo Tu We Th Fr Sa
     1  2  3  4  5  6
  7  8  9 10 11 12 13
 14 15 16 17 18 19 20
 21 22 23 24 25 26 27
 28 29 30

どうもRubyの練習問題らしい。
しかしRubyは勉強してないし、ちょうどpythonを独学で始めたのでやってみた。

## 私の解答
最初は配列とか準備しようかと思ったけれど、
配列で処理しようと思うと、1週間の週数で増減が必要だし、もっとスマートにしたかった。
結局、初日の曜日と月の日数がわかれば後は開始位置を決めて７単位で改行入れたらいいと
気が付いたので、こうなった。

```python:todayCalendar.py
import calendar
import datetime


gyo = ''
span, last_day = calendar.monthrange(datetime.date.today().year, datetime.date.today().month)

print('{:^20}'.format(calendar.month_name[datetime.date.today().month] + '.' + f'{datetime.date.today().year}'))
print('')
print('Su Mo Tu We Th Fi St')
print('')


for i in range(span + 1):
    gyo = gyo + '   '

for day in range(1, last_day + 1):
    gyo = gyo + '{:>3}'.format(day)
    if (day + span + 1) % 7 == 0:
        print(gyo[1:])
        print('')
        gyo = ''

print(gyo[1:])

```

ヘッダ部分はロジック化してない。

#2019.09.24追記
コメントでいろいろご教授いただきました。
shiracamus さん、konandoiruasa さん　ありがとうございます

##3行で解決するpython！
なんとたった3行でカレンダーをきれいに表示できる

``` python
import calendar
calendar.setfirstweekday(6)
print(calendar.month(2019, 9, l=2))
```

##よりよいと思われる回答
さすがに３行が回答です！って言ってもアルゴリズム問題に対する回答としては不適切かと思うので、
コメントでもらった内容を取り入れつつ再チャレンジ。

```python:todayCalendar.py
import calendar
import datetime


gyo = ''
today = datetime.date.today()
span, last_day = calendar.monthrange(today.year, today.month)

print(f'{today:%B.%Y}'.center(20))
print('')
print('Su Mo Tu We Th Fi St')
print('')


for i in range((span + 1) % 7):
    gyo += '   '

for day in range(1, last_day + 1):
    gyo += f'{day:>3}'
    if (day + span + 1) % 7 == 0:
        print(gyo[1:])
        print('')
        gyo = ''

print(gyo[1:])
```

paizaで実行確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364570/682548eb-182b-2220-eb6b-41241f6873dd.png)

無事に日曜始まりにも対応できていますね。

##shiracamusさんによる回答（コメントより）

```python:shiracamusさん
import calendar
import datetime


today = datetime.date.today()
span, last_day = calendar.monthrange(today.year, today.month)
span = (span + 1) % 7  # set the first week a day Sunday

print(f'{today:%B.%Y}'.center(20))
print()
print('Su Mo Tu We Th Fi St')
print()
line = '   ' * span
for column, day in enumerate(range(1, last_day + 1), span):
    line += f'{day:>2} '
    if column % 7 == 6:
        print(line)
        print()
        line = ''

line and print(line)
```

全体的にpython使いこなしている感がありますね・・・！
教えていただきありがとうございました。
ある日突然会社からTeamsで毎朝挨拶しましょうと言われたときに行うべきこと

# 冒頭

ある日会社から突然

「わが社でも社員同士の交流を深めるためにTemasを使っていこうと思う。まずは挨拶をみんなするとこから始めよう」

・・・みたいなことを言われたら、皆さんどうしますか？？

そう。まずはBOTを作ろうと思いますよね！！

というわけで、Microsoft Office365 の機能を使うと、3分で BOT を作れるので、紹介したいと思います。

# Microsoft Flow

Office365 のツールの一つに Microsoft Flow というのがあります。
これは、ざっくしいうと Office365 のマクロツールみたいなものです。

今回はこれを使って、毎朝 Teams に挨拶を投稿する BOT を作りたいと思います。

# BOT 作成3分クッキング！

1. Office365 より Flow のアプリを選択する

2. 左側のメニューより作成を選択
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/d82c9818-0a17-a741-edec-b1f1b619912c.png)

3. スケジュールされたフローを選択
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/62a657f2-ffee-dfe5-7405-2f1d9fda17a8.png)

4. スケジュールを月～金曜日に指定する
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/09872b08-4ac1-78fd-2a1b-e36eeae38f49.png)
細かい時間などの内容はこの次の工程で設定します。

5. Recurrence を選択して、詳細なBOTが投稿する時間を設定します
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/169131d8-08e9-213a-5c44-8333f886c40b.png)
この設定では、月～金曜日の毎朝 9:10 に起動するものとなります。

6. アクションを追加し、Teams を選択します。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/c8adcc66-2b33-6db8-29a7-1036fbdd22bb.png)

7. Temas の投稿するので「メッセージを投稿する(V3)(プレビュー)」を選択します
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/715af436-45f4-bc90-956b-68367991cd1e.png)
※ 2019/9/24時点では、メッセージ投稿用のモジュールはまだプレビュー版っぽい？

8. 投稿するチーム、チャンネル、メッセージ内容を設定します。
![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/afee0286-817d-3204-25c3-630cd81084a2.png)

これであとは保存ボタンを押せば完了です。
成功すれば、設定した時間に以下のように Teams に挨拶が投稿されます！

![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81768/3fcbdcdf-47f1-5717-4dac-8e68cb1fd417.png)

# まとめ
これで、挨拶を万が一忘れることもなく、安心な毎日を送れますね！
めでたしめでたし・・・
Bashで文字列の構造体を使いたい

自身の備忘を兼ねて記載を行っています。
「とりあえず動いた」程度のソースなどもございますので参考程度にブラシアップ頂けると幸いです。
また、誤りやもっとよいコーディングやきれいな書き方があるなどご指摘頂けるととてもうれしいです。

## 今回のお題
任意の件数のデータについて同一の処理を行いたく、構造体で実現しようと思い作成

## では、ソースです。
```sh:sample01.sh
#! /bin/bash

# 構造体
LOOP_LISTS=(
	ABCDEFG
	hijklmn
	1234567
	あいうえお
)

i=1
# 構造体の中身をループで一つづつ表示
for LOOP_LIST in ${LOOP_LISTS[@]}; do
	# 同一の処理(今回は表示)
	echo "${i}：${LOOP_LIST}"
	let i++
done

# 構造体の中身を指定で表示(１番目のデータは「0」になる)
echo "２番目指定：${LOOP_LISTS[1]}"
```

```sh:実行結果
$ sh sample01.sh
1：ABCDEFG
2：hijklmn
3：1234567
4：あいうえお
２番目指定：hijklmn
```
WindowsからMacに乗り換えたときの戸惑いメモ

# Windowsとの違いに戸惑う

Windows95〜10までWindows(＋CentOSも少し)しか使っていなかったが、Macを使うことになった。
困ったところ・戸惑ったところをメモしておく。
### 前提条件
2019年9月購入のMac(macOS Mojave)
キーボードはJIS配列
ちょっとだけCentOSを触ったことがあるので、Linuxのコマンドは多少わかる


## 基本操作
#### 文字入力の切り替え
「半角／全角キー」の代わりに、スペースキー横の「英数」「かな」で切り替える

#### スクロール
二本指でタッチパッドを滑らせる

#### 右クリック
二本指でクリック

#### アプリ起動
__2019.10.1追記 twitterやコメントでおすすめ方法を教えていただきました。__
⌘+[spaceキー]で、Spotlight検索が立ち上がる。
そこにアプリ名を入力する。
Launchpadから開くより早い！

#### アプリを全画面で使うときの切り替え
__2019.10.1追記__
Windowsのようにタスクバーが常に出ていて、全画面の作業ウィンドウを切り替えられるわけではない(Dockはあるけど)
３本指で上にスライド ：　Win+Tab的な感じになる
その状態で３本指で右や左にスライド　：　全画面表示しているアプリが切り替えられる


## ターミナル
#### "端末"、"コマンドプロンプト"はどうやって立ち上げるのか
~~「Dock」内の「Launchpad」→「その他」→「ターミナル」~~
⌘+[Space] → 「ターミナル」と入力 → エンター

#### 文字が小さい
ターミナルのウィンドウをアクティブにすると、画面上部のメニューバーがターミナル用になる。
「メニューバー」→「表示」→「大きく」



## Finder
エクスプローラーに該当するモノ
「Dock」内の「Finder」から起動できる

#### ホームディレクトリを表示する
ホームディレクトリ（Userフォルダ）がFinderのサイドバーから飛べないので、サイドバーに表示させる

「Dock」内の「Finder」→
メニューバーの「Finder」→
「環境設定」→
「サイドバー」→
よく使う項目の「"自分のUser名"」にチェックを入れる


#### 拡張子を表示する
「Dock」内の「Finder」→
メニューバーの「Finder」→
「環境設定」→
「詳細」→
「すべてのファイル名拡張子を表示」にチェックを入れる

## その他設定
#### 隠しフォルダを表示する
[【Mac】隠しファイル・隠しフォルダを表示する方法](https://qiita.com/TsukasaHasegawa/items/fa8e783a556dc1a08f51)



気づいたことがあれば随時追加します。
GCEでinode数を拡張した時のコマンドメモ



```bash
$ lsblk # デバイス名を確認
$ sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard -i 2048 /dev/sdb # 2048 の数値を小さくすると、inode数が増える
$ sudo mkdir -p /mnt/disks/data1 # 以下マウント設定
$ sudo mount -o discard,defaults /dev/sdb /mnt/disks/data1
$ sudo chmod a+w /mnt/disks/data1
```


```bash
# Diskのサイズを拡張時
$ df -h # 事前確認
$ sudo resize2fs /dev/sda1
$ df -h # 増えていることを確認
```
CSS 背景 画像 レスポンシブ iphone ipad pc

iphone , ipad , pc ...
サイズがバラバラ。
しかし、1枚の画像でヘッダ画像にしたい場合がある。


# 完成

PCから見た場合
![pc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/df6c9013-77e1-d73e-4f1f-007b5370bbfb.png)

スマホから見た場合
![sumaho.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/63872fb3-e5bd-88b1-19d5-e1b8ad60473f.png)

ね。どちらから見てもデザインも文字も崩れてないでしょ。


# 画像を作成しよう

横幅 1200
高さ 250

で作成。



# 魔法の式

padding-top に
(画像の高さ / 画像の横幅) × 100
で計算した値を入れればOK




CSS


    .box{
    
        width: 100%;
        height: 0;

        /* (画像の高さ / 画像の横幅) × 100 */
        padding-top: 20.8333333%;
        background: url('/img/gazou.png');
        background-repeat: no-repeat;
        background-position: center center;
        background-size: cover;
    }


HTML

```

<div class="box"></div>

```

これでOK。
大学では教えてくれなかったAPIの話：WebAPIの使い方・作り方

## いきさつ

Web系やスマホアプリにおいて，サーバサイドならAPIを作成，フロントならAPIを呼び出す操作が必要になるかと思います．
しかし，大学の授業等でAPIに関する解説がなく，自分で調べることになりました．
後輩が同じような苦労をせずに済むように記事にまとめます．

## 用語説明
詳細については，もっと詳しくわかりやすい記事がたくさんありますので調べましょう．

### API とは
> APIとは、あるコンピュータプログラム（ソフトウェア）の機能や管理するデータなどを、外部の他のプログラムから呼び出して利用するための手順やデータ形式などを定めた規約のこと。

出典：[APIとは - IT用語辞典 e-Words](http://e-words.jp/w/API.html)

実際には，他のプログラムを呼び出すための呼び出し口（=境界面）を指してAPIという言葉が用いられる場合が多いように感じます．
（例：××のAPIを呼ぶ，など）

また，APIにもいろいろあるでしょう．
外部のプログラムを呼び出すと言っても，

1. 何を呼び出すのか（ライブラリ，外部サーバ上のアプリケーション，etc）
1. どのようなルール（プロトコル）で呼び出すのか

などの点で様々な種類があります．


例えば，Python向けの機械学習ライブラリscikit-learnを呼びだすAPIや，
[API Reference — scikit-learn 0.21.3 documentation
](https://scikit-learn.org/stable/modules/classes.html)

Twitterに投稿されたデータにアクセスするためのAPI，
[TwitterのAPIについて - Twitter Help Center
](https://scikit-learn.org/stable/modules/classes.html)

Qiita上のデータを参照するためのAPIだって存在します．
[Qiita API v2ドキュメント - Qiita:Developer](https://qiita.com/api/v2/docs)

### WebAPI とは
APIのうち，サーバ上のデータやプログラムを，HTTP(今時はHTTPS)プロトコルを用いて呼び出すものを指します．
（このプロトコルは，Webサーバとやりとりするためのプロトコルですね）
返るデータは，JSON形式である場合が多いように思います．

## WebAPIの使い方・作り方
話を簡単にするため，ここではWebAPIに対象を絞って用い方を記します．

### 使い方（呼び出し方）
例として，Qiita APIのうち認証なしで利用できるものを使います．
例えばユーザデータを取得する場合，上記のドキュメントには，ホスト`qiita.com`で`GET /api/v2/users/:user_id`せよとあります．`:user_id`の部分はQiitaのIDで置き換えます．
具体的には，私のユーザデータを取得する場合，次のようにします．

- curlコマンド

```shell
$ curl -L qiita.com/api/v2/users/ryhoh
{"description":"学部4年生．求職中．\r\n何でも屋さん．表向き，専門は機械学習ってことになってる．","facebook_id":"","followees_count":1,"followers_count":5,"github_login_name":"ryhoh","id":"ryhoh","items_count":6,"linkedin_id":"","location":"","name":"","organization":"関西大学 総合情報学部 総合情報学科","permanent_id":286106,"profile_image_url":"https://avatars3.githubusercontent.com/u/16788328?v=4","team_only":false,"twitter_screen_name":null,"website_url":""}
```

- JavaScript

```html
<script>
fetch('https://qiita.com/api/v2/users/ryhoh')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(JSON.stringify(myJson));
  });
</script>
```

（JavaScriptはほとんどわからないので [Fetch を使う - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API/Using_Fetch) を参考に作成）

正直，確認するだけならブラウザで開いでも見える（HTTPSだし）．

また，データの送信を目的にPOSTメソッドを用いる場合もありますが，その場合も似たような形で行えるため省略します．

### 作り方
アクセスされたらcontentsとしてHello world!を返すだけのAPIです．

- PHP

```php:index.php
<?php

header('Content-Type: text/html; charset=UTF-8');

$res = [
    'contents' => 'Hello world!',
];

print json_encode($res, JSON_PRETTY_PRINT);
```

ターミナルで`php -S IPアドレス:ポート番号`として実行し，そこにブラウザでアクセスするか，上記の方法で呼び出してあげれば，返ってきたデータを見ることができるかと思います．
Unity：ローディング画面を作る（定番、クルクル）

# はじめに

*こんにちは、のんびりエンジニアのたっつーです。*
*[今回の記事](https://www.fast-system.jp/unity-loading-screen-howto/)を紹介しているのでよろしければ見てください。*

今回は、定番のローディング画面（通称：クルクル）をUnityで作る方法をご紹介いたします。

出来上がりはこんな感じです。
ぜひ挑戦してみてください。

![loading-anime3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/2e975649-26d0-3a9a-3567-4490cf6f4990.gif)

# 作り方・使い方

作り方は簡単で、以下の画像を円形状に塗りつぶし範囲を、アニメーションに指定すると簡単に出来上がります。

## ローディング画像のインポート

まず、 プロジェクトに***ローディング画像をインポート***してください。

[CircleLoading.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/7b72a65b-9f71-b569-9449-c3acc6ffd2e8.png)
![image-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/f243207c-f3fa-f0ad-cf60-50123bfa1c4c.png)

次に、「CircleLoading」画像を選択して、インスペクターから***Texture Typeを「Sptrite（2D and UI）」に変更***して、***「Apply」を選択***してください。
![image-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/2cdb59b8-ed8b-54a4-85f5-ad72cc020ab5.png)

## ローディング画像の配置

次に、シーン上に、***Imageオブジェクト（CreateObject > UI > Image）を追加*** して、Image スプリプとの***Source Imageに「CircleLoading」画像を設定***してください。
![image-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/387a2c58-beaa-4d5e-9b47-6b84d8acd820.png)

すると、シーン上での Image オブジェクトにローディング画像が表示されます。
![image-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/6b216fc8-39f9-4f83-b118-96c9ea4f5296.png)

## ローディング画像のクルクル設定

続いては、この画像をクルクル表示するように、設定＆アニメーションを付けていきます。
Imageスクリプトの、***ImageType の設定を「Filled」***に変更してください。
![image-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/8847b64d-7aee-95ef-650d-d35878c02409.png)

現状の設定だけでも、「Fill Amound」の設定をスライダーで変更してやれば、クルクルッぽくみせれますが、毎回スクリプトでこの値を変更するのもめんどくさいので、これをアニメーションファイルで設定していきたいと思います。
![loading-anime.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/5ce9f8ef-25bb-5b58-25be-fc02e6a42f51.gif)

## クルクル設定をアニメーション化する
***メニューから「Window > Amination > Animation」を選択***して、アニメーション作成ウィンドウを表示します。

***アニメーションウィンドウの「Create」ボタンを押下***して、***Assetsフォルダに「loading」でファイルを作成***しましょう。

以下、loadingファイルが作成された画面になります。
![image-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/e2ff4680-1edb-76ae-13aa-f58d3f5ddfd1.png)

次に、 ***「Add Property」を選択***して、 ***「Image.Fill Amount」「Image.Fill Clockwise」の２つを追加***してください。
![image-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/006c355f-b243-3851-fdd5-4c809e906031.png)

この２つのプロパティに以下のように***アニメーションを作成***します。
![loading-anime2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/63505cd4-a4f7-a6b4-cc94-18c5ac8e30ed.gif)

次に、このアニメーションを常に実行するために、***ImageオブジェクトにAnimationスクリプトを追加***して、***loadingアニメーションを設定***します。
![image-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/7e1bd6f6-607b-2a5e-fd96-84824adb47de.png)

# 実行結果
お疲れ様です、以上でローディング画面のクルクル画像が出来上がったかと思います。画像１つでクルクルが作成できるのはうれしいですよね。
ぜひ皆さんも活用してみてください！

![loading-anime3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227880/4025de65-7e72-647f-8bcc-ebf86f97c0c5.gif)


# 終わりに

*よければ ブログ「[Unity+AssetStoreおすすめ情報](https://www.fast-system.jp/)」の方にも色々記載しているのでぜひご参照いただければと思います。*
Hugo + GitHub Pages にカスタムドメインを設定する場合，Hugoの baseurl 設定に気をつけて (初心者向け)

Hugo, GitHub Pages, web 初心者である自分がHPを作ろうとして，つまずいたのでメモ．

## 現象
- こちらのQiita記事[^1]の手順を参考にしながら，GitHub Pagesにカスタムドメイン設定 & httpsでデプロイした．
- しかしlocalhostではうまく表示されていたのに，web上ではcssや画像が描写されない．(泣)
- chromeのコンソールで確認すると，「CORSエラー」，「httpとhttpsの混在エラー」が出ていた．

![error](https://user-images.githubusercontent.com/20534543/65470820-bfc87180-dea7-11e9-9550-7e061d63372a.png)

## 原因
Hugo設定ファイルである `config.toml` の `baseurl` に，GitHub Pages (project page) のドメインURLを指定したままだった．

```config.toml
baseurl = "https://xxxxx.github.io/xxxxx/"
```

## 解決策
`baseurl` に，カスタムドメインのURLを指定する．

```config.toml
baseurl = "https://(COSTOM-DOMEIN)/"
```

これですべて解決した．あっけない．．．

## 振り返ってみて
知識ある人にとっては，今回のことはアタリマエのことで躓くところではないんだろうなと思った．
もっと勉強せねば．


[^1]: [Hugoでプロジェクトを作成しHugoのテーマを適用させGitHub Pagesで公開しお名前.comでドメインを取得しSSL化するまで](https://qiita.com/hirotatsuuu/items/c8b29f90a631301e9d2a)
Unreal Engineのインストールについて

初心者で申し訳有りません。ダメ元で伺います。
解説本に依ると、Unreal Engineのトップ画面に「黄色いインストールボタン」がある筈なんですが、現在の4.23.0画面には有りません。
Unreal Engineのインストール方法をお教え頂ければ幸いです。
ーーーーーーーーーーーーーーーーーーーー
sato0127@jasmine.ocn.ne.jp
yusuke
NimがついにVersion 1.0.0 正式リリースに！

ついに！
Backerとしても支援し始めていた**Nim**が
v0.20.2を経て**v1.0正式リリース**となりました！嬉しい！
以下に公式チームからのお知らせが掲載されています。

**公式ブログ**：https://nim-lang.org/blog/2019/09/23/version-100-released.html

1.0になったことで長期の互換性を保証するみたいですね。
バグ修正と新機能追加を、互換性を損なわない形で行っていくようです。

コミュニティとしてのサポート体制も整ってきていて、
少し前まではかなり動作が遅かったフォーラムも爆速になっています。
**Nimフォーラム**：https://forum.nim-lang.org/

あとはIRCのノードとチャンネルまできっちり載ってますね！（IRC好きなので）
**IRCノード**：irc.freenode.net
**チャンネル**：#nim

もう環境は整った！ということで皆さんガシガシ
Nimを使って日本語ドキュメントも増やしていきましょう！

Nimは**組み込みやkernel開発**も可能で、
機械学習のライブラリ(arraymancer等)なんかもどんどんと揃ってきています。
他の言語とのベンチマークを見たい方は
h-miyakoさんの素晴らしいブログがあるのでこちら↓
http://h-miyako.hatenablog.com/entry/2015/01/23/060000

ちなみにMacOSへのインストールの場合は、
今のところはHomebrewを使わず（インストールした場合はアンインストールして）
choosenimでバージョン管理をするようにすると良いと思います。

```terminal
# choosenimのインストール
$ curl https://nim-lang.org/choosenim/init.sh -sSf | sh

# 以下で環境パスに設定
$ export PATH=$HOME/.nimble/bin:$PATH

# Nimの安定バージョン最新をインストール
$ choosenim update stable
```

現在、技術書典8で**「実践Nim入門」**とした技術書を販売するべく
鋭意執筆中なので、期待せずにお待ち下さい笑
現在暫定の目次は以下（GUI周りは別の内容に変わりそうです。）
ブログ：https://blog.pianopia.net/2019/08/29/nim01/

弊社ではNiｍ推しでいきたいなあ。
AWS SDK for Ruby V3のAws::S3::ClientとAws::S3::Resourceの違いに正面から向き合う

AWS SDK for Ruby V3を使おうとすると、`Aws::S3::Client`と`Aws::S3::Resource`という2つのインターフェースに出くわします。
今まで目を背けて雰囲気で使い分けていましたが、ちゃんと向き合ってみることにしました。

## TL;DR
- ClientはAPIをそのままSDK化したもの
- ResourceはClientをラップしたもので、リソースにフォーカスして再構築している
- たいてい同じことはできるけど、Resourceのほうが直感的、Clientのほうが細かいことができる

## 公式の説明
aws-sdkのgemのREADMEにありました。
https://github.com/aws/aws-sdk-ruby#resource-interfaces

> Resource interfaces are object oriented classes that represent actual resources in AWS. Resource interfaces built on top of API clients and provide additional functionality. Each service gem contains its own resource interface.

(Google翻訳)
リソースインターフェイスは、AWSの実際のリソースを表すオブジェクト指向クラスです。 APIクライアント上に構築され、追加機能を提供するリソースインターフェイス。 各サービスgemには、独自のリソースインターフェイスが含まれています。

この文章から分かるように、実はS3だけでなく、ほかのサービスにもClientとResourceが存在します。EC2とかRDSとかIAMとかSQSとかSNSとかDynamoDBなどなど。ここではS3に限って説明しますが、基本的な考えは同じです。

## 具体的に比べてみる
指定バケットに入っているオブジェクトのキー名一覧を表示する操作で比較してみましょう。

Client

```ruby
client = Aws::S3::Client.new
client.list_objects_v2(bucket: 'bucket_name').contents.each do |object|
  puts object.key
end
```

Resource

```ruby
resource = Aws::S3::Resource.new
bucket = resource.bucket('bucket_name')
bucket.objects.each do |object|
  puts object.key
end
```

行数自体はClientの方が少ないですが、Resourceの方が何をしているのか直感的にわかりやすくないでしょうか？
Resouceの説明に「AWSの実際のリソースを表すオブジェクト指向クラス」とありましたが、BucketオブジェクトやObjectオブジェクトといった実際リソースを表すクラスを作って操作しています。人間にとっては分かりやすいです。
Clientは`list_objects_v2`の返り値に対して`contents`なんてわけのわからないものを挟んでますが、こんなのいちいち返り値を確認しないと書けないわけで、ちょっと使いづらい。

## Clientの存在意義
じゃあもうResourceだけでいいじゃん、ってなりそうですが、Clientにも存在意義はあります。

コードを見てもらえれば分かると思いますが、ClientはAPIをそのままSDK化したものです。
https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/lib/aws-sdk-s3/client.rb

すべてのメソッドが同じ形で2行で終わってるのが分かると思います。
たとえば`list_buckets`はこんな感じです。

```ruby
    def list_buckets(params = {}, options = {})
      req = build_request(:list_buckets, params)
      req.send_request(options)
    end
```

`send_request`を見てみると、

```ruby
    def build_request(operation_name, params = {})
      handlers = @handlers.for(operation_name)
      context = Seahorse::Client::RequestContext.new(
        operation_name: operation_name,
        operation: config.api.operation(operation_name),
        client: self,
        params: params,
        config: config)
      context[:gem_name] = 'aws-sdk-s3'
      context[:gem_version] = '1.48.0'
      Seahorse::Client::Request.new(handlers, context)
    end
```
ということで、`Seahorse::Client::Request.new(handlers, context)`の部分でAPIを呼んでいます。

Resourceのほうが便利で分かりやすいですが、Clientの方がAPIに近いので細かいことができます。
マルチパートアップロードを例に取ると、Resourceは1つのメソッドにまとまっていますが、Clientはマルチパートアップロードを開始、パートのアップロード、マルチパートアップロードの完了/中止と、複数のメソッドを組み合わせて実現することになります。書くのは大変ですが、間に独自処理を入れたりできそうですね。

## まとめ
好きな方を使えばいいと思います╭( ･ㅂ･)و ̑̑
【Docker修行④】管理・分析ツールの「dive」を利用したDockerイメージの効率的な高速化と最適化

- 1年にも満たないエンジニア生活のため、雲の上の存在だと思っていて距離を取っていた「Docker」の習得を目指す記事第四弾。
- 「利用するツールやサービスの増大による最大の利点は、けがれなき無垢なロゴキャラとの対面である」という気高き名言の情報元を、長時間調査。
- 今回は、管理・分析ツールを利用した、効率的なDockerイメージの縮小化・最適化を図ることにしよう。

## 概要や特徴
- Go製のDockerイメージの分析・最適化ツール
- 作成イメージの容量解析や構造情報の詳細化等、構成の理解やイメージ効率化に役立つ。
- 主な特徴としては下記。
    - 階層(レイヤー)ごとの詳細情報の可視化。
    - イメージ容量(サイズ)の最適化・無駄情報の可視化。
    - イメージの作成(ビルド)と分析の同時実行。
    - CIシステム統合による、イメージテスト(解析)の実行。

## 結果
- 下記のように作成イメージを指定するだけで、各イメージやレイヤー(階層)の容量やフォルダ構造等の詳細情報を管理・確認することができる。

<img width="649" alt="dive.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/7f44621a-2ceb-6980-6760-17b38823bb1b.png">

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/c54778ea-15c2-0e08-253c-11ca14559ae3.png)

## 環境
- Mac OS X 10.13.4
- Homebrew 2.1.4
    - **※Homebrew未導入の場合、[こちら](https://brew.sh/index_ja)を参考にインストールする。**
- Docker version 18.09.2

## インストール

### Mac

- Macでのdiveインストールは、下記のコマンドをうつ。

```bash
$ brew install dive
```

### Windows

- Windowsでのインストールは、[こちらのリリースページ](https://github.com/wagoodman/dive/releases)から最新のバージョンをインストール。

### その他環境

- その他環境(Linux)でのインストールは、[こちら](https://github.com/wagoodman/dive#installation)を参考にする。

## 基本利用

### 分析画面構成
- diveでのDockerイメージ分析の流れとしては主に下記。
    - 1. イメージ指定したdiveコマンドで分析画面を起動
        - 例: `dive sample_app:latest`
    - 2. 起動後、各構造情報やイメージサイズを確認
    - 3. 確認後、無駄容量の削減や効率化等の最適化を考える。
- これらの流れの際に確認する「分析画面」の基本的な構成は下記。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/336499/c54778ea-15c2-0e08-253c-11ca14559ae3.png)

|エリア|内容|
|:---:|:---:|
|「**Layers**」|各レイヤー(階層)ごとの容量・出力情報|
|「**Layer Details**」|各レイヤー(階層)ごとの詳細情報|
|「**Image Details**」|イメージの詳細情報<br>「**Image efficiency score**」はイメージ効率<br>「**potential wasted space**」は無駄容量<br>「**Total image space**」は総容量|
|「**Aggregated Layer Contents**」|各レイヤー(階層)のフォルダ情報|

### コマンド
- diveを利用してDockerイメージ分析を行う際の基礎的なコマンドとしては下記。

|コマンド|内容|
|:---:|:---:|
|`dive イメージ:タグ名`|作成イメージの分析画面起動。<br>**※指定するイメージは`docker images`等で確認。**<br>例: `dive nginx:1.15.6`<br>例: `dive sample_app:latest`|
|`dive build -t タグ名 作業パス`|イメージのビルド(作成)と分析を同時に行う。<br>イメージをビルド(作成)するためにDockefile等が必要<br>例: `dive build -t latest .`|
|`dive version`|バージョン確認|
|`dive help`|ヘルプページ確認|

### 分析画面ショートカット
- 分析画面では、主にキーボード操作によるもののため、基本的な操作一覧は下記。

|キー|内容|
|:---:|:---:|
|`tab`|詳細画面とファイル構造画面の切り替え|
|`Ctrl + F`|ファイルフィルタ。検索が可能。|
|`Ctrl + L`|階層(レイヤー)変更の表示|
|`Ctrl + M`|変更ファイルの表示|
|`Ctrl + B`|属性の表示切り替え|

## まとめ
- 今回は、ツールを利用した縮小化や最適化ということで、今まで重量級の無駄容量を抱えさせていたことを、反省と同時に一種の恋愛感情を感じながら記事を書く。
- 「将来的に、人類最適化ツールが出現したら、髪は残してくれるだろうか」というような夢想を、日常の八割の時間を利用して、全力で脳内議論。
- 次回は、徐々に理解できてきているインフラ関連技術のより魅力的なサービスを調査することにしよう。

## 参考サイト
- https://github.com/wagoodman/dive  
→こちらの記事を参考にしました。大変お世話になりました。
- https://www.gekal.cn/blogs/2019/03/21/docker-layer-explore-dive.html  
→こちらの記事を参考にしました。大変お世話になりました。