OmniAICreator/Qiita-1.07M huggingface dataset:
有限集合の濃度の存在を証明する

有限集合の濃度の存在を証明する
======
2019/05/01
この文書のソースコードは以下にあります。

https://github.com/suharahiromichi/coq/blob/master/pearl/ssr_ex_card.v


OCaml 4.07.1, Coq 8.9.0, MathComp 1.9.0


# 説明
へんなタイトルですが、MathComp を使った定理の証明の問題です。
有限集合の濃度、すなわち要素の個数は、適当な自然数に一意的に決まります。濃度を ``#| _ |`` で表すとすると、

``∃ i : nat, #| p | = i``

ですね。これ自体は自明なのですが、MathComp で証明しようとすると、取り付く島もないように見えます。
でも、すこし考えてみると、MathComp の場合、集合は有限型(finType)をドメインとするbooleanな関数で表されます。すなわち、``T : finType`` とすると、

``p : pred T``

なお、``pred T`` は単に ``T -> bool`` の Notation (構文糖衣) です。
pが、常にtrueを返す場合が全集合、常にfalseを返す場合が空集合になります。このように、集合pと関数pが同一視されるので、集合pの濃度は、「型Tの要素のうち、関数pがtrueを返す要素の数」ということになります。
このことから、型Tの要素の全体をしめす finType の enum フィールドの中身 (リスト、seq型) について、関数pでフィルタした結果のサイズが決まることを証明すればよいことになります。
型 T から、その enum フィールドの中身を取り出すのは、次のようにします。

``Finite.enum T``

後の証明は、単にリストの要素についての帰納法です。
ほとんど自明であるがゆえに、MathCompにおける実装の裏側を知らないと解けない問題の例といえるでしょうか。


# コード例



```coq:

From mathcomp Require Import all_ssreflect.

Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
(* Set Print All. *)

Section Test.

  Variable T : finType.
  Variable p : pred T.                      (* T -> bool *)

  Lemma ex_card : exists (i : nat), #| p | = i.
  Proof.
    rewrite unlock /card /enum_mem.
    elim: (Finite.enum T).
    - by exists 0.
    - move=> x s /= [i IHs].
      case: ifP => /=.
      + exists i.+1.
          by rewrite IHs.
      + by exists i.
  Qed.

End Test.


```

# 最初に使った箇所
単一化の証明 http://fetburner.hatenablog.com/entry/2015/12/06/224619
Unify.v を MathComp への移植するときに必要になりました。移植例：
https://github.com/suharahiromichi/coq/blob/master/unify/ssr_unify_bool_3.v


```
本番環境に合わせたアセットパイプライン

##アセットパイプラインとは
> JavaScriptやCSSのアセットを最小化 (minify: スペースや改行を詰めるなど) または圧縮して連結するためのフレームワークです。
[Railsガイドより](https://railsguides.jp/asset_pipeline.html)

　Railsではassets/以下にそれぞれimageやjavascript, stylesheetsのフォルダが分けられている。(以下javascriptを例に)
　しかし開発環境だと、javascript/application.js、stylesheets/application.cssこの一つのファイルにまとめて記述をすれば、規模が大きくなるほどどのviewに対しての記述があるのかが分からない。また一つのファイルにまとめて記述すれば、変数名が重複してしまう。
　そのためassets/javascript/users, assets/javascript/notes/などフォルダごとに分けられているのが好ましい。最終的にはこのフォルダごとに分けられたjavascriptのファイルを、最終的に一つのファイルにまとめてviewを表示する(コンパイル)。この仕組みを **アセットパイプライン** という。

##本番環境では
　しかし本番環境(heroku, AWSなど)にデプロイすると処理速度に対する影響を防ぐために
自動でコンパイルが行われない。なので
**①自動でコンパイルを行うよう設定を変える**
**②アセットプリコンパイル(あらかじめコンパイルするファイルを指定する)を行う**
どちらか2つの方法を設定する必要がある。

##①の方法
```
config/production.rb
config.assets.compile = true #=> falseをtrueに
```

##②の方法
```
assets/javascripts/application.jsで

//= require jquery_ujs
// require_tree . => '='を削除
//= require common
```
まずはこれでjavascripts/以下のjsファイルを読み込めなくする。
##**なぜ?**
= require_tree.の状態だと、フォルダごとに分けていたjsファイルをapplication.jsにまとめて記述するので、変数名が重複してしまうから。

##続いて
assets/javascripts/users/form.jsを作成したとする。
そして、そのform.jsを適用したいviewファイルに以下の追記をする。

```
views/users/form.html.slim

~ここにviewのコードが入る~

= javascript_include_tag 'users/form' <= form.jsを適用するよう指定する。
```

そしていざ、本番環境で実装する際にあらかじめjsファイルをコンパイルするよう指定する(プリコンパイル)。

```
config/initializers/assets.rb

Rails.application.config.assets.precompile += %w(users/form.js)
```

以上！

##参考
[Railsガイド](https://railsguides.jp/asset_pipeline.html)
threeとbabylonでcanvas2texture

#概要

threeとbabylonでcanvas2textureやってみた。

#写真

three
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/fd7e181b-f85c-78de-cc62-d11447872eb7.png)

babylon
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/11008ba9-7377-e7ca-5c09-949c2222ca62.png)


#成果物

three
https://embed.plnkr.co/7zmk5bJh8bY146zNA7ay/

babylon
https://embed.plnkr.co/4GSKJOio3qwAjrQQerwg/

以上。
GOOGLE CLOUD CERTIFIED Professional Cloud Developerを受けてきた

GOOGLE CLOUD CERTIFIED Professional Cloud Developerを受けてきました。
取得を考えている方の参考になれば幸いです。

# 試験概要
https://cloud.google.com/certification/cloud-developer
https://cloud.google.com/certification/guides/cloud-developer/

- 時間：120分
- 問題数：50問[^1]

[^1]: 試験ガイドに記載が無いので、問題数は変わるかもしれません

# 事前準備

1. 本を読む
    - [GCPの教科書](https://www.amazon.co.jp/dp/B07S1LG1Y1)
2. courseraでGoogleが提供しているオンライントレーニングを受講する
    - https://www.coursera.org/specializations/developing-apps-gcp
3. 無料の模擬試験を受ける
    - https://cloud.google.com/certification/practice-exam/cloud-developer

オンライントレーニングでも「GCPの教科書」でも、IAMの説明が先にきていました。
試験範囲にも入っているので、よく理解しておいた方が良いと思います。

# 結果
幸い合格でした。

# 受験者のスペック
参考になるかわかりませんが。。。

- クラウド歴：5年
- クラウド関連の保有資格
    - GCP: クラウドアーキテクト＋データエンジニア
    - AWS: アソシエイト×３＋プロフェッショナル×２＋Big Data＋Security＋Network+ML
- 外観：メガネぼーず

# 難易度について

消去法でも解けるような素直な設問が多く、出題範囲が広めの割には難しくは感じませんでした。
また時間はかなり余りました。ちょっと自信がない問題等を見直す時間は十分にあると思います。

# 感想
合格すると認定グッズ（スピーカーかフーディ）が貰えます。
ただ、よくある質問にこんなことが書かれていたので、気になる方はお早めに。

*この特典は変更されることがあります。また、数に限りがありますのでご了承ください。*
Dataset を使った TensorFlow のモデルを SavedModel 形式のファイルから復元して推論を行う（C++編）

# Dataset を使った TensorFlow のモデルを SavedModel 形式のファイルから復元して推論を行う（C++編）

## はじめに

[前回の記事](https://qiita.com/rxoxixyxd/items/bb5955eb97bebd983412) では Python で TensorFlow の Dataset を使用して学習を行い、モデルを SavedModel の形式で保存しました。

今回は、そのモデルを C++ のコードから読み込んで推論を実行してみたいと思います。

本記事で説明しているソースコードは [こちら](https://gist.github.com/ryojiysd/1a04e655b1fc9895a179ba11af39975a) に載せてあります。

## 実行環境

- Windows
- Visual Studio 2015
- tensorflow 1.10.0

## モデルの読み込み

初めにモデルを読み込みます。

```cpp:infer.cpp
  const std::string export_dir = "./model";
  SavedModelBundle bundle;
  SessionOptions session_options;
  RunOptions run_options;

  Status status = tensorflow::LoadSavedModel(session_options, run_options, export_dir, {tensorflow::kSavedModelTagServe}, &bundle);
  if (!status.ok()) {
    std::cout << status.ToString() << std::endl;
    return -1;
  }
```

## 入力データの作成

入力用データ（Tensor 型）を作成します。

```cpp:infer.cpp
  Tensor batch_size(tensorflow::DT_INT64, tensorflow::TensorShape());
  auto dst = batch_size.flat<long long>().data();
  long long bsize = 3L;
  memcpy(dst, &bsize, sizeof(bsize));

  Tensor input(tensorflow::DT_FLOAT, TensorShape({3, 1}));
  auto input_dst = input.flat<float>().data();
  float arr[3] = {2.0, 3.0, 4.0};
  memcpy(input_dst, arr, sizeof(arr));
```

## Iterator の初期化

Iterator の初期化を行います。"dataset_init" はモデル作成時に指定した initializer の名前です。
また、"input", "target", "batch_size" は同様にモデル作成時に指定した placeholder の名前です。

```cpp:infer.cpp
  status = bundle.session->Run(
      {{"input", input}, {"target", input}, {"batch_size", batch_size}},
      {},
      {"dataset_init"},
      nullptr);
  if (!status.ok()) {
    std::cout << "Failed to run sesssion (dataset_init)" << std::endl;
    std::cout << status.ToString() << std::endl;
    return -1;
  }
```

## 推論の実行

最後に推論を実行します。"output:0" はモデル作成時に指定した出力ノードの名前です。

```cpp:infer.cpp
  std::vector<Tensor> outputs;
  status = bundle.session->Run({}, {"output:0"}, {}, &outputs);
  if (!status.ok()) {
    std::cout << "Failed to run sesssion (output:0)" << std::endl;
    std::cout << status.ToString() << std::endl;
    return -1;
  }

  Tensor a = outputs.at(0);
  const int out_dim = 3;
  for (int i = 0; i < out_dim; i++) {
    std::cout << a.flat<float>()(i) << std::endl;
  }
```

実行すると以下のように Python 版とほぼ同じ推論結果が得られます。

```
2 4.16
3 6.12808
4 8.09616
```
WebExtensions の versioning 記法

少しハマったのでメモ.
基本的なことは以下に書いてある.

- https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/version
- https://developer.mozilla.org/en-US/docs/Mozilla/Toolkit_version_format

## 対象

- Google chrome
- Firefox

## 結論
例えばこんな感じでバージョンを生成すると, とりあえず lint に怒られることはなくなる.

```sh
VERSION=`date -u +%Y.1%m%d.1%H%M`
```

各パートの頭に `0` がつくのを避けるために日付パートと時刻パートが少々不格好になっている. また時刻は UTC を採用.

実行例：

```
$ date -u +%Y.1%m%d.1%H%M
2020.10429.11123
```

## Chrome の場合

- `数字.数字.数字.数字` のように書ける
  - 数字限定であるため git のバージョンハッシュ値が使えない
- 各数字パートは 0 から 65535 まで
- 各パートの頭に `0` があると Extension 登録時に勝手にゼロサプレスされる

## Firefox の場合

- version part を `.` でつなげたものを書ける
- version part は `<number-a><string-b><number-c><string-d>` から成る
  - a,b,c,d 部のいずれか一つでもあれば良い
  - 上の例には `5pre4` が挙げられている
- アスタリスク `*` が使える
- 各パートの頭に `0` があると Extension 登録の際にはじかれてしまう
  - ゼロパディングを許容しない
WebサービスでのID採番方式

WebサービスのID採番方式例について、インターネット上で公開されている情報を整理した。

#### 参考となる記事

DB（採番テーブル・SEQUENCE）、UUID（Version 1/4）、Twitter（Snowflake）、Firebase（PushID）、Instagram、Tomcat・Jetty・Spring Security・RackのセッションID（アクセストークン）については [ID生成大全](https://qiita.com/kawasima/items/6b0f47a60c9cb5ffb5c4) に分かりやすくまとめられている。

また、FlickrとFacebookについては [Facebook, Twitter, Instagram等がどうやってIDを生成しているのか まとめ](https://qiita.com/daisy1754/items/98a6e6b17d8161eab081) にまとめられている。

#### BaaSサービスのユーザーID

今回はユーザーIDの採番ロジックについて調査していたため、BaaSサービスでどのようなユーザーIDを出力しているか追加で調査した。

##### Firebase

28文字の英数字（大文字・小文字を区別する）

ユーザーIDの出力例：

```
718ODO6Sr8TenIJ2DwB8fQTGuWb2
```

※ 実際に出力された値を若干変更している

##### Amazon Cognito

[ドキュメント](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html#amazon-cognito-user-pools-using-the-id-token)によるとUUIDが使われているとのこと（実際に試せていないためバージョンは不明）
rails rspec 非同期通信のためのテストコード[備忘録]

# rails rspec 非同期通信のためのテストコード
非同期通信のためのテストコードを書くときに少し詰まったので解決策をメモしておきます。

## 環境
* rails 2.5.3

##　コード

```
require 'rails_helper'

RSpec.describe 'Messages', type: :request do

  let(:user) { create(:user, :with_message_group) }
  let(:params) { { message: { message: "good"} } } 
  before do
    sign_in(user)
  end

  describe "create message" do

    it "create message" do
      post message_group_messages_path(message_group_id: user.message_groups.first.id), xhr: true, params: params
    end
  end

end
```

ポイントは下のコードの部分です。

```
    it "create message" do
      post message_group_messages_path(message_group_id: user.message_groups.first.id), xhr: true, params: params
    end
```

xhr: trueにすることで非同期通信でテストができます。

また文法の面でも詰まったのでそこも少し。

```
    it "create message" do
      post message_group_messages_path(message_group_id: user.message_groups.first.id), xhr: true, params
    end
```
最初paramsのところをこんな感じに書いていたのですが、シンタックスエラーが出てました。エラー文読んでもわからなくて冷静に見直したら

```
params: params
```
このように書かないといけないですね、気をつけないと。

##　参考
* https://blog.tanebox.com/archives/598/
自動運転シミュレーション その２

# 概要

自動運転シミュレーションで、使えるコースをplunkerで作ってみた。
手動のエージェントと環境を実装してみた。
活用して下さい。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a7bda1ce-b231-f172-78e9-9f7d5d552c73.png)


# 説明

コースの下にある5つのグレーがセンサーです。
手動なので、＜＞をクリックします。
100ｍｓ毎に、agentには、センサーの値が送られます。
その値でagentがアクションを返します。
アクションは、2が真っ直ぐ、0が右、1が左です。

# 成果物

https://embed.plnkr.co/xGimkQYEeNgkxVBymZZg/

以上。
【rails】リロードしないとインクリメンタルサーチが動かない時はこれ(turbolinksの無効化)

インクリメンタルサーチを実装したのに、
リロードしないと反応しないじゃん！！

ってなったので調べました。

原因はrails5で標準インストールされるturbolinksにあるようです。
(turbolinksについてはこちらの記事を→https://qiita.com/saboyutaka/items/bb089e8208239bf6fdc0)


とりあえず、今回はアプリケーション全体でturbolinksを無効化したかったわけではなく、
**リンク先だけで無効化**したかったので、以下のように記述して解決しました。




```index.html.haml
中略
 = link_to edit_group_path(@group) do
   .main-header__edit-btn{"data-turbolinks": "false"}
     Edit
```

# 参考リンク
https://ryoutaku-jo.hatenablog.com/entry/2019/01/15/213420

https://qiita.com/Cheekyfunkymonkey/items/216bf7426493e6213927

https://qiita.com/hiroyayamamo/items/b258acbaa089d9482c8a
CocosCreator v.2.1.1備忘録

# 初めに
Cocos2dxやCocosCreatorの過去バージョンのソースコードを参考にし、
いざ実装！　と思ったら命令が存在しない・・・
そんな事が何度かあったので、自分の分かる範囲で対応表を作成しました
色々あってJavaScriptとTypeScriptの両方を使用しているため混在しているかも

動作確認しているバージョンは**v2.1.1**です
また、目的別の早見表もついでに記載しています

# 名前が変わったもの対応表
各々のAPI説明は下記URL
https://docs.cocos.com/creator/2.1/api/en/

| 旧 | v2.1.1 | 備考 |
|:--|:--|:-:|
| cc.eventManager.addListener(～) | node.on(～) |  |
| cc.eventListener.TOUCH_ONE_BY_ONE 等 | cc.Node.EventType.TOUCH_START 等 |  |
| cc.director.getVisibleSize().width | cc.WinSize.width |  |
| cc.director.getWinSize().width | cc.WinSize.width |  |
| cc.Point | cc.Vec2 |  |
| cc.p(x, y) | cc.v2(x, y) |  |
| cc.randomMinus1To1() | 無し | Math.random()使う |
| hoge: {<br>　default: null,<br>　url: cc.AudioClip<br>} | hoge: {<br>　default: null,<br>　type: cc.AudioClip<br>} | 以前はtypeとurlが混在していたが、typeに統一されたっぽい |

# 目的別機能早見表
| 目的 | 機能 | 備考 |
|:-:|:--|:-:|
| ログ出したい | cc.log('hoge=' + hoge)  |   |
| enum使いたい | State = cc.Enum({<br>　hoge: 0,<br>　fuga: 1<br>}) | TypeScriptを使う場合はenum対応しているので普通に使用可能 |
| static使いたい | statics: {<br>　State<br>} |   |
| node取得したい | var hoge = cc.find('Canvas/hoge') |   |
| Component取得したい | hoge.getComponent('fuga') |   |
| Prefabのロードしたい | cc.instantiate(this.prefab) |   |
| node追加したい | hoge.addChild(prefab) |   |
| 自作Action作りたい | var fuga = cc.callFunc(function() { ～ }) |   |
| 動かしたい | node.runAction(cc.sequence(hoge, fuga)) |   |
| アニメーション再生したい | var anim = this.node.getComponent(cc.Animation);<br>anim.play('Jump'); |   |
| BGM再生したい | _bgmId = cc.audioEngine.play(this.audioClip, true) | 返り値は停止時に使用する |

# その他
### SwallowTouchは？
調べた限りでは非推奨な方法（eventManager.addListener）以外では設定出来なさそう
node.on　を使っていると自動的にtrueになっているっぽい（CCNode.js にて確認）
アニメイラストのセグメンテーションがやりたかった話

#はじめに
　GANを学習させていると生成結果が歪むことがありますよね。原因の1つとして背景も含めて学習してしまうということがあると思います。アニメイラストでGANを実装している方できれいな画像が生成されているものを見ると、背景が白1色のデータセットを使ったりしていることが多い印象です。また高解像度の生成に成功した[Progressive Growing of GANs](https://arxiv.org/abs/1710.10196)を見るとデータの前処理として、背景にガウスフィルタをかけてぼやかしたものを使っています。つまり、学習対象とそれ以外を分けて扱えるようにすることが効果的だと考えられます。
　ということでSemantic Segmentationをやろうとしたんですが、いい感じのデータセットがなかったんですよね。なら自分で作るしかないな！と思ったわけですが、手作業でアノテーションするのってかなりしんどいですね。OpencvのGrabcutを使って作成しました。それで100枚終わったところで取りあえず公開しようと。(あわよくば誰か手伝ってくれないかなーなんて)

[GoogleDrive](https://drive.google.com/open?id=1UkwKkUdV87TPaHqRS_UL-Qp71la6DDH5)に置いてあります。

##少し解説
　zipを解凍すると、*.npzファイルがあります。numpy.loadで読み込めます。あとは辞書型と同様にkeyを指定して下さい。以下で各keyについて説明します。

####URL, sec_URL
　元画像はhttp://danbooru.donmai.us にあるものを使っています。URLにはその画像のページのURL, src_URLには画像への直リンクURLの文字列が保存されています。

####fg, bg
　fgは前景, bgは背景です。データはすべて画像のwidth, heightと同じshapeの配列で、該当ピクセルが1それ以外は0のデータになります。
　以下サンプル画像です。赤い部分が該当部になります。

|元画像|fg|bg|
|:-:|:-:|:-:|
|![raw.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194245/778d24c2-783b-209c-3d69-f4fee8f4d27e.jpeg)|![fg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194245/99d9f349-f67e-0bf5-4ebe-a282c8bb112d.jpeg)|![bg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194245/120fc88e-4776-6342-4fff-ee176fc92ec0.jpeg)|

####hair, skin, face
これは単語のままですね。

|hair|face|skin|
|:-:|:-:|:-:|
|![hair.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194245/0cc7859b-c873-9d0e-1a52-f6505c3fe39a.jpeg)|![face.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194245/75f6a068-32bc-0c8a-48d3-a94a35a4a30d.jpeg)|![skin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/194245/48bc96d3-3977-db44-4f24-8b87dbdccecd.jpeg)|

以上の5つにアノテーションしていました。

###おわりに
　データ数100程度ではいいモデルを作るのは難しいですよね。Unsupervised SegmentationやSemi-supervised Segmentationの研究もあるみたいなのでそちらの勉強もしていきたいとおもいます。
ASP.NET MVC で、ファイルのアップロードを実現したい

### 前提・実現したいこと
ASP.NET MVC で、ファイルのアップロードを実現したいです。

- 言語は C# です
- .NET Framework のバージョンは 4.72 です
- Ajax.BeginForm を使い Form を作っています
- アップロードを行うコントローラーは、部分ビューの中に配置しています

### 発生している問題・エラーメッセージ
- アップロードしたいファイルを選択して submit すると、
サーバー側でファイルを受け取る HttpPostedFileBase が、常に null になってしまいます。

- Request.Files も null になります

### 該当のソースコード

```Index.cshtml
    @using (Ajax.BeginForm("Upload", "Test", new AjaxOptions
    {
        HttpMethod = "POST",
        UpdateTargetId = "Result"
    }, new { id = "AjaxForm", enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()
        <div id="Result">
            @Html.Partial("_Page", Model)
        </div>
    }
```

```_Page.cshtml
<input type="file" id="File" name="File" />
<input type="submit" value="アップロード" />

<button type="submit" name="Search">検索</button>
<button type="submit" name="Clear">クリア</button>

```

```TestController.cs
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Upload(string Search, string Clear, HttpPostedFileBase File)
{
    // ここも null になる
    var uploadFile = Request.Files["File"];
}
```

### 試したこと
下記のページにあるように、HttpPostedFileWrapper を使う方法も試してみました。
https://www.ipentec.com/document/csharp-asp-net-mvc-upload-file

しかし、この方法だと、ボタンクリックで submit する時、
Internal Server Error が発生します。

![j.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457163/58605cfe-001a-f6c9-2451-8e7a763eb266.png)

---
おわかりの方がいらっしゃいましたら教えてください。
よろしくお願い致します。
【Heroku】デプロイ（fatal: repository 'app_url' not found）

RailsのアプリをHeroku上にアップする作業の復習中に発生した問題（メモ程度で記載、後程、更新予定）

# Herokuにデプロイしたが　うまく動かない？！

## こんなエラーが
前提
※１ heroku上に 'xxx-yyy-7140' というURIを持つアプリが存在しない
※２ アップしたいのは 'app-exist-2345' というURI

ここで、herokuにデータをpushしようとしたら、gitがないって怒られた。


```
$ git push heroku master
remote: !	No such app as xxx-yyy-7140.
fatal: repository 'https://git.heroku.com/xxx-yyy-7140.git/' not found
```

## 先人の対応
stackoverflowに、同様のケースがあった。

http://stackoverflow.com/questions/28749771/cant-push-to-heroku-after-accidentally-deleting-app-on-heroku

gitのリモートURLを変更する。
```
git remote set-url heroku https://git.heroku.com/boiling-falls-6570.git
```

そして　再度pushする。
```
git push heroku master
```

できた

## （追記）プリコンパイルの必要性

assetsのプリコンパイルも必要。


http://qiita.com/jnchito/items/a1833b48c3b47a955bdf

http://www.workabroad.jp/posts/1164
pryのコマンドを保存して再実行したい気分

## なにこれ

pryのコマンドをファイルに保持し、再度実行することができる。
再実行後は変数に値が入るため、複雑な処理を必要とするデバッグの際に手順をファイル化しておくことが可能。

## 手順

#### スクリプト配置
[このスクリプト](https://gist.github.com/chibicco/f7c139ebe8578ccb57fff45aafeacb14)をプロジェクト直下またはホームディレクトリの `.pryrc` に配置する

#### 記録
```pry
[1] pry(main)> ReRe.start
20190727021128.rb
=> :dubbing
[2] pry(main)> p 1111
1111
=> 1111
[3] pry(main)> user = User.first
=> #<User:0x00007fda
...
[4] pry(main)> ReRe.stop
[5] pry(main)> exit
```

#### 実行
```pry
[1] pry(main)> ReRe.playback("20190727021128.rb")
run command... 
[2] pry(main)> user
=> #<User:0x00007fda
...
```

#### ファイル保存先

実行ディレクトリ以下の `tmp/rere/*.rb`
ethers.js で wei と ether の相互変換

ethers.js で wei と ether を相互に変換するサンプルコードです。

#ether => wei
```js
const ethers = require('ethers');

// 単位 ether の値
let etherString = "4.2"

// 単位 ether から単位 wei に変換（戻り値は BigNumber）
let wei = ethers.utils.parseEther(etherString)

// wei を10進数の文字列に変換
let weiString = wei.toString()
console.log(weiString)
```

#wei => ether
```js
const ethers = require('ethers');

// 単位 wei の値
let wei = ethers.utils.bigNumberify("4200000000000000000");

// 単位 wei から単位 ether に変換（戻り値は String）
let etherString = ethers.utils.formatEther(wei)
console.log(etherString)
```

#Ref.
- https://scrapbox.io/a42/ethers.js_で_wei_と_ether_の相互変換
- https://docs.ethers.io/ethers.js/html/api-utils.html#ether-strings-and-wei
django-restframework-social-oauth2 で twitter login ができる様にする

django-restframework-social-oauth2 は
現在**生の状態だとTwitterログイン機能が使用できない。**
仕方がないのでチョロっといじくり回して認証が通る様にしたので書き残しておく。
ぶっちゃけただのメモレベルなので、参考程度に見て欲しい。

#問題
Twitter API は、リソースにアクセスする際、アクセストークンが**２つ**必要になる
その為、公式ドキュメントに記載のある以下の方法では、トークンが一つしか送れない為、勿論エラーになる

```shell

curl -X POST -d "grant_type=convert_token&client_id=<client_id>&client_secret=<client_secret>&backend=<backend>&token=<backend_token>" http://localhost:8000/auth/convert-token
```

# 解決
token のキーに無理やりアクセストークンを２つ載せ、Twitter oauth のメソッドを一つだけオーバーライドし、トークンを書き換えればいい
書き換えるのは 同モジュール内の backends にある **TwitterOAuth**

```python

from social_core.backends.twitter import TwitterOAuth

class TwitterOAuthModifyToken(TwitterOAuth):
    """Twitter OAuth authentication backend"""

    def user_data(self, access_token, *args, **kwargs):
        oauth_token = access_token.get('oauth_token').split('&')[0]
        oauth_token_secret = access_token.get('oauth_token').split('&')[1].split('=')[1]
        access_token['oauth_token'] = oauth_token
        access_token['oauth_token_secret'] = oauth_token_secret
        return super(TwitterOAuthModifyToken, self).user_data(access_token, *args, **kwargs)
```
POSTする json の書き方はこういう感じ、**%26**はパーセンテージエンコーディングしたアンパサンド

```json
"token": "oauth_token=<oauth_token>%26oauth_token_secret=<oauth_token_secret>"
```

あとは、今作ったコイツを setting.py のバックエンドに指定すれば

```python

AUTHENTICATION_BACKENDS = (
    # Twitter
    'okero.backends.TwitterOAuthModifyToken',
)
```

コレで認証が通る
モジュールの中身を漁る時間がない人はお試しあれ
homebrewでhbaseをinstallしstandaloneモードで立ち上げてhbase shellを起動するまで

installするhbaseの情報を確認。まだ1系がstableのようだ。

```
$ brew info hbase
hbase: stable 1.3.4 (bottled)
Hadoop database: a distributed, scalable, big data store
https://hbase.apache.org
/usr/local/Cellar/hbase/1.3.4 (10,219 files, 345.8MB) *
  Poured from bottle on 2019-07-27 at 00:56:32
From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/hbase.rb
==> Dependencies
Build: ant ✘
Required: lzo ✔
==> Requirements
Required: x86_64 architecture ✔, java = 1.8 ✔
==> Caveats
To have launchd start hbase now and restart at login:
  brew services start hbase
Or, if you don't want/need a background service you can just run:
  /usr/local/opt/hbase/bin/start-hbase.sh
==> Analytics
install: 558 (30 days), 1,918 (90 days), 7,744 (365 days)
install_on_request: 467 (30 days), 1,554 (90 days), 6,130 (365 days)
build_error: 0 (30 days)
```

installする

```
$ brew install hbase
```

java8が必要であるが、もしmacに過去のversionがinstallされていない場合、
adoptopenjdkのjdkをhomebrew caskからinstallして利用する

```
$ brew tap adoptopenjdk/openjdk
$ brew cask install adoptopenjdk/openjdk/adoptopenjdk8
$ /usr/libexec/java_home --version 1.8
```

この段階で`start-hbase.sh`を起動するとうまく起動できないので、
`/usr/local/Cellar/hbase/1.3.4/libexec/conf/hbase-site.xml`に記載されている`hbase.rootdir`で指定されたdirectoryを掘る

```
$ sudo mkdir /usr/local/var/hbase/
$ sudo chown ${USER}:admin /usr/local/var/hbase/
```

起動

```
$ start-hbase.sh
```

hbase shellを起動する

```
$ hbase shell
```

プロンプトが表示されればOK
Object.keysの型がstring[]になってしまう問題の対策


# 問題

以下のようなコードを書くと、`data[key]`でエラーになる。

```ts
const data = {
    apple: 'ringo',
    organge: 'mikan',
    pear: 'nashi'
}

const rows = Object.keys(data).map((key) => {
    return { key, value: data[key] }
})
```

```
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ apple: string; organge: string; pear: string; }'.
  No index signature with a parameter of type 'string' was found on type '{ apple: string; organge: string; pear: string; }'.
```

# 理由

`Object.keys`の返り値が`string[]`になるけど、`data[key]`したときに`data`のindexが列挙型なので、`string`と不一致するため。

# 対策

keyofを使うといい。

```ts
type Data = {
    apple: string,
    orange: string,
    pear: string
}
const data: Data = {
    apple: 'ringo',
    orange: 'mikan',
    pear: 'nashi'
}

const rows = (Object.keys(data) as (keyof Data)[]).map((key) => {
    return { key, value: data[key] }
})
```

`keyof`で指定した型のキーを列挙した型を返してくれる。
`Object.keys(data) as (keyof Data)`することで、`data`のキーの列挙型が帰ってくるので、それを配列にしてから`.map`に渡せば`key`が列挙型になりエラーにならなくなるという
ethers.js で指定言語のニーモニックを生成

ethers.js で指定言語のニーモニックを生成するサンプルコードです。

```js
// ethers.js をインポート
const ethers = require('ethers')

// ランダムなバイト列（32バイト）を取得
let randomBytes = ethers.utils.randomBytes(32);

// 言語を取得
let language = ethers.wordlists.ja;

// 指定した言語のニーモニックを生成
let mnemonic = ethers.utils.HDNode.entropyToMnemonic(randomBytes, language)
console.log(mnemonic)
```


#Ref.
- https://scrapbox.io/a42/ethers.js_で指定言語のニーモニックを生成
- https://docs.ethers.io/ethers.js/html/api-utils.html#random
- https://docs.ethers.io/ethers.js/html/cookbook-accounts.html#random-mnemonic
Git rebaseの使い方


想定するシチュエーション
---

複数人で行う開発では、branchの運用が多いと思います。
特に、Git flowのルールに則った運用が多いのではないでしょうか。

Git flowでは、基本的に開発ブランチとして"develop"ブランチがあり、
そこから派生した"feature"ブランチがあります。
ある程度規模感があって、複数人で同時並行で開発するときには欠かせないのではないでしょうか。

それぞれがdevelopブランチからfeatureブランチを作り、開発を始めますが、
自身が開発している間にも他者がコミット・プッシュ〜プルリクエスト〜developブランチにマージをしています。お互いの開発部分に重なりがある場合、もちろんのこと他者の開発部分を取り込む必要があります。

そんなときにGit rebaseを使います。

1. 自身の修正を退避します

```
git stash
```
2.developブランチに切り替える

```
git checkout develop/***
```
3.developブランチをリモートリポジトリと同期する

```
git pull
```
4.自身のfeatureブランチに切り替える

```
git checkout feature/***
```
5.自身のfeatureブランチにdevelopブランチの内容を取り込む

```
git rebase develop/***
```
6.退避していた修正を戻す

```
git stash pop
```

これでやってるんですが、皆さんはどのようにやってますか？
「これ違う！こうだよ！」ってアドバイス頂けたら嬉しいです。
Linuxのファイルパーミッションのxは何故xか

最近会社で聞かれて即答できなかったことをまとめてみました。

Linuxのファイルパーミッションは"ls"コマンドで確認できます。readは"r"、writeは"w"、executableは"x"です。

こんな説明したところ、executableは何故"e"ではなく"x"なのかと聞かれました。

即答できませんでした。そこで、調べてみた結果をまとめてみました。

# 英語では"ex～"を"X"と略記する

英語では、しばしば"ex～"を"x"と略記します。

[Webster](https://www.merriam-webster.com/dictionary/x)、[Wikipedia](https://en.wikipedia.org/wiki/X#English)などの"x"を読むと、"ex-"や"trans-"や"cross-"の略語として使われることがわかります。

"Christ-"や"crys(tal)"の略語としても使われます。しかしこれらの略語をコンピュータ分野で見ることは少なそうです。

"ex-"を"X"と略記するケースを一般分野で挙げるなら、サイズを表すXL(eXtra Large)が思い浮かびます。

同様にexecutableの"ex-"を"x"と略記することから来ていると考えるのが自然だと思います。

## 実例

コンピュータ分野の実例を挙げてみます。なお、個人的に馴染みのある言葉に限定しています。そのため、ここに挙がっていないものもあります。

### "X"と略記する"ex-"の例

* IPX/SPX - Internetwork Packet Exchange/Sequenced Packet Exchange
* MMX - Multimedia Extensions
* MX - Mail Exchanger
* NXビット - Non Execute bit
* OCX - OLE Control Extension
* PXE - Preboot Execution Environment
* XE - (例えば Oracle Database) Express Edition
* XGA - Extended Graphics Array
* XHTML - Extensible HTML
* XML - Extensible Markup Language
* XOR - Exclusive OR
* XP - Extreme Programming

ここに挙がっている単語でも"E"と略記するケースもあります。"ESSID", "EUC", "EV証明書"など。"Extended"ばかりなのは偶然？

### "X"と略記する"cross"の例

* XSS - Cross-Site Scripting

この略語は初期にはCSSとも略されていました。しかし、[Cascading Style Sheetsの略と紛らわしい](https://www.atmarkit.co.jp/ait/articles/0211/09/news002.html)ため、XSSと呼ばれることが多くなった経緯があります。

同分野の"Cross Site Request Forgery"の略語は、"XSRF"よりも"CSRF"が主流です。"sea-surf"という読み方で読まれることがあるところなど、明らかに"C"が主流といえるでしょう。"XSS"も、紛らわしい用語がなければ"CSS"のままだったのではないでしょうか。

### "X"と略記する"trans-"の例

* XLATE - Translate

この略語には、実はあまり馴染みがありません。調べてみると面白かったので書いておきます。

[RPG](https://ja.wikipedia.org/wiki/RPG_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E8%A8%80%E8%AA%9E))というプログラム言語があります。名前くらいは知っていました。しかし馴染みは全くありません。

このプログラミング言語に[XLATE](https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_71/rzasd/sc0925081029.htm)という関数があります。これがどうやらTranslateを省略したもののようです。[英語のIBMサイト](https://www.ibm.com/support/knowledgecenter/SSAE4W_9.6.0/com.ibm.etools.iseries.langref.doc/evferlsh352.htm)を見ると疑いようがないでしょう。しかし、この省略は想像していませんでした。

### XFER - PC-9800シリーズのスペースキーの右隣のキー

[ヤフオク](https://aucfree.com/items/j500894349)に出品されていた[画像](https://img.aucfree.com/j500894349.3.jpg)を見ると、"XFER"が鮮明に映っています。

[Wikipedia](https://ja.wikipedia.org/wiki/PC-9821シリーズ)には"CROSS reFERence key"の略とあります。[通信用語の基礎知識](https://www.wdic.org/w/TECH/XFER%E3%82%AD%E3%83%BC)には"Transfer"の略とあります。どちらが正しいのでしょうか。とはいえ、どちらにしても"cross"や"trans-"の略であるようです。

# まとめ

"ex-"の略として使われるケースが圧倒的に多いようです。

説明できないような知らないことを調べてみると、色々と知識が広がって面白いです。
WebAuthnでBLEデバイスを使う方法


iOSデバイスを外部認証機器と使うためにはCTAPのBLEの実装が必要ですが、どこのWebAuthnのデモサイトにアクセスしてもBluetooth機器の認証を目にすることができませんでした。

調べてみたところ、Bluetoothの認証が出るか否かはWebAuthnのサーバ側の設定ではなく、アクセス元のブラウザがWeb Bluetooth APIに対応しているか否かで決まるそうです。

# Web Bluetooth APIとは

- WebブラウザがBluetoothを制御するためのAPI
- ChromeやOperaでは利用できるが、FirefoxやIEでは対応は微妙らしい

# ChromeでWeb Bluetooth APIを有効にする方法

Web Bluetooth APIは隠し機能のため、通常の設定メニューには出てきません。

アドレスバーに ```chrome://flags/``` を入力し、「Web Authentication API BLE support」をenableにします。

![スクリーンショット 2019-07-27 0.47.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200963/340418b9-0b55-81c8-e9c3-286ddf2beefa.png "スクリーンショット 2019-07-27 0.47.21.png")

設定を行った上で、[Webauthn.io](https://webauthn.io/)にアクセスすると、次のようにBluetoothセキュリティキーが選択肢に現れます。

![スクリーンショット 2019-07-27 0.46.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200963/065aedbc-e432-10c3-87b7-7288065cc4d9.png "スクリーンショット 2019-07-27 0.46.20.png")

# 注意点

iOSのBluetoothアプリを作成し、chromeのWebauthnと通信が行われるかを確認しましたが、OSのバージョン ~~やBluetoothのバージョン~~ によっては通信ができませんでした。

## クライアント側

### OS
- Windows10 → NG（ChromeでWeb BluetoothをONにしても選択詞が出てこない）
- macOS 10.14.3 → OK
- macOS 10.15 beta4 → NG（BlueTooth Explorerでペアリングができない）

### BlueTooth IF
- 4.0 → OK
- 4.2 → OK  
※後述するBLEのペアリングをすればBlue Toothのバージョンに関わらず通信可能


## 認証機器側

### OS
- iOS 12.4 → OK
- iOS 13 beta 4 → NG（Central側からの通信が受信されない）

今のところ、アプリの実装が試せそうなのは ~~BlueTooth4.2を搭載の~~ macOS 10.14とiOS12端末の組み合わせのみのようです。

# BLEのペアリング方法

おそらくGoogle謹製のTitanを使えばBluetoothセキュリティーキーの選択詞を選んだ後にペアリングができるのでしょうが、自作のアプリではChrome経由でペアリングができません。
BlueTooth Explorerを使えばペアリングすることができました。

## BlueTooth Explorerのインストール方法

- Xcodeを起動
- メニュー > OpenDeveloper Tool > More Developer Toolsを選択
- Safariが起動し、ダウンロードページが開くので Additional Tools for Xcode をダウンロードする（バージョンはXcodeに合わせる）
- dmgファイルを開いたイメージのHardwareディレクトリ配下にあるので/Applicationsにコピーする

## BlueTooth Explorerを使ったBLEペアリング方法

- BlueTooth Explorerを起動
- メニュー > Devices > Low Energy Devices を開く
- 下記のようなウィンドウが開くので、左のペインの自作アプリを選択
- CTAPで規定されたServiceを開き、４つあるいずれかのCharacteristicを開く
- この時点でiOSとmacOS側にペアリングを尋ねるダイアログが表示されるのでOKを選択する

![スクリーンショット 2019-07-31 22.15.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200963/29102e49-9f42-74b0-ecdf-c961222c74e3.png "スクリーンショット 2019-07-31 22.15.54.png")
yumコマンドがtimeoutしたときに解消した方法

※2019/10/02
コマンドの記述ミスを修正。

# はじめに
yum でパッケージをインストールすると、timeout するようになりました。
自宅環境がFirewallやAnti-Virus Softwareが入っているため、そこで遅延が発生していると考えられます。
本来ならきっちり調査すべきなのでしょうが、手っ取り早く解消できたのでそれ以上は追及していません。
将来の自分のために記録を残しておきます。

※ちなみに、Firewallは、ソースIP指定で、Destならびにportを Anyで許可しています。
  pingも問題なく返ってきています。

# 環境
- CentOS 7.6.1810

# 発生事象

yumコマンドが、下記のように失敗します。

```console:CentOS7
$ sudo yum -y install httpd
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile

-- 略 --

Downloading packages:
No Presto metadata available for base
centos-logos-70.0.6-3.el7.cent FAILED
http://ftp.riken.jp/Linux/centos/7.6.1810/os/x86_64/Packages/centos-logos-70.0.6-3.el7.centos.noarch.rpm: [Errno 12] Timeout on http://ftp.riken.jp/Linux/centos/7.6.1810/os/x86_64/Packages/centos-logos-70.0.6-3.el7.centos.noarch.rpm: (28, 'Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds')
他のミラーを試します。
centos-logos-70.0.6-3.el7.cent FAILED
http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos/7.6.1810/os/x86_64/Packages/centos-logos-70.0.6-3.el7.centos.noarch.rpm: [Errno 12] Timeout on http://ftp.yz.yamagata-u.ac.jp/pub/linux/centos/7.6.1810/os/x86_64/Packages/centos-logos-70.0.6-3.el7.centos.noarch.rpm: (28, 'Operation too slow. Less than 1000 bytes/sec transferred the last 30 seconds')
他のミラーを試します。

-- 略 --

```
メッセージを見ると、Timeout とか、遅いとか・・・。

# 解消した方法
yum.confにtimeoutを追加しました。
単位は、秒です。
詳細は、``` man yum.conf ``` に書かれています。

```console:CentOS7
$ sudo vi /etc/yum.conf
timeout=60
```

# 結果
再度、実行します。

```console:CentOS7
$ sudo yum -y install httpd
読み込んだプラグイン:fastestmirror
Loading mirror speeds from cached hostfile

-- 略 --

Downloading packages:
No Presto metadata available for base
centos-logos-70.0.6-3.el7.centos.noarch.rpm                |  21 MB   00:38
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  インストール中          : centos-logos-70.0.6-3.el7.centos.noarch         1/2
  インストール中          : httpd-2.4.6-89.el7.centos.x86_64                2/2
  検証中                  : httpd-2.4.6-89.el7.centos.x86_64                1/2
  検証中                  : centos-logos-70.0.6-3.el7.centos.noarch         2/2

インストール:
  httpd.x86_64 0:2.4.6-89.el7.centos

依存性関連をインストールしました:
  centos-logos.noarch 0:70.0.6-3.el7.centos

完了しました!

```
38秒かかりましたが成功しました。

# 他に試して、ダメだった方法

以下、いくつか試した方法がありましたが、すべてtimeoutでした。

- 完全にrootになって実行。

```console:CentOS7
$ sudo su - 
# yum -y install httpd
```

- よく見かけるやつ。

```console:CentOS7
$ sudo yum clean all
$ sudo yum -y install httpd
```

- 日本のミラーだけ参照する。

```console:CentOS7
$ sudo /etc/yum/pluginconf.d/fastestmirror.conf
include_only=.jp
:wq
$ sudo yum -y install httpd
```
- Proxyは使っていなので、環境変数ではないはず・・・。


# crul を使う

ここまできて、時間がかかるだけでダウンロードはできるとこに気が付きました。

```console:CentOS7
$ curl -O http://ftp.riken.jp/Linux/centos/7.6.1810/os/x86_64/Packages/centos-logos-70.0.6-3.el7.centos.noarch.rpm
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 21.3M  100 21.3M    0     0   578k      0  0:00:37  0:00:37 --:--:-- 5925k
```
ここまでわかれば、解消策まではとんとん拍子でした。

以上です。
ethers.js で Ethereum ウォレットを作成

ethers.js でウォレットを作成して、アドレス、ニーモニック、秘密鍵を取得するサンプルコードです。

```js
// ethers.js をインポート
const ethers = require('ethers')

// ウォレットを作成
let wallet = new ethers.Wallet.createRandom()

// ウォレットのアドレスを取得
let address = wallet.address
console.log("address:", address)

// ウォレットのニーモニックを取得
let mnemonic = wallet.mnemonic
console.log("mnemonic:", mnemonic)

// ウォレットの秘密鍵を取得
let privateKey = wallet.privateKey
console.log("privateKey:", privateKey)
```

# Ref.
- https://scrapbox.io/a42/ethers.js_でウォレットを作成
- https://docs.ethers.io/ethers.js/html/api-wallet.html#creating-instances
Google Colaboratoryのスクラッチコードセルが大変便利だったので是非皆さんに使っていただきたい件

つい、

```python

print(hogehoge)
```

とか

```python

df.head()
```


とか


```python
df.shape
```

とかで汚らしくしてしまう迷える子羊たちは、
ぜひGoogle Colaboratoryのスクラッチコードセルを使っていただきたい。
というお話でした。

※ winショートカットはCtrl + alt + N

![colab.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165789/2a26f37a-ae3e-1555-dc62-80c53e7f079b.gif)
iOS ショートカット で某テーマパークの予約の直リンクを生成する

# はじめに
本投稿は実在するいかなる団体・企業とも云々
某テーマパークのレストラン予約は1か月先までの日程が取れるのですが、毎回争奪戦でおおよそ2分のうちに完売します。
通常、この予約は、
 1. フォームに、日程（ここが1か月先まで）、人数、レストラン名等を入力
 2. 検索実行 (ここが時間かかる)
 3. 検索結果から希望の席と時間を指定 （この段階で確保できる）
 という流れで予約をとります。
しかし、たいていの場合には、朝9時の開始時刻にアクセスが殺到して検索完了がすごく遅くなり、画面遷移したときには「空きなし」となります。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/eac467c2-d012-0cc9-50a4-5981b309ecf6.png)

今回はこのうち、3番の直リンク(URL)を iOS ショートカットAppを利用して自動生成し、Safariで開くところまでを自動化してみましたのでご紹介します。
**※なお、登場するURLはフェイクですので、実際使われる場合には、正しいURLに書き直してください。**
**※また、予約が確実に取れることを保証するものではありません。**

# 詳細画面のURL構成

URLですが、以下のような構成になっていることがわかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/cb7b3814-ca83-fca5-be37-94ff03e7c735.png)

| パラメータ       |       意味 |   
|-----------------|------------------|
| useDate             |予約日付。ここをショートカットで1か月後の日付を指定する|
| adultNum           | 大人の数。自分の家なので固定の数字でOK |
| childNum             |子供の数。自分の家なので固定の数字でOK|
| childAgelnform|子供さんの年齢構成。ここでは03歳と07歳を指定している。%7C区切り|
|restaurantNameCd|見に行くショーレストランのコード|
| wheelchairCount|車いすの数|
| stretcherCount |ストレッチャーの数|
| showWay |不明|
|reservationStatus |空だと空席っぽい|
| wayBack |不明|

ということで、争奪戦で可変になるのは日付くらいなものです。だいたい「この日とこの日でとれたほうでいく」みたいな感じだと思うので。
この日付をショートカットAppで現在日付から自動生成し、URLを構成して、Safariで開くまでを作ってみました。

# ショートカットApp

ここではアプリの詳細は割愛します。様々なクライアントアプリとかWebリクエストを使える自動化ツールみたいなものです。Automatorみたなもの

![20190726_141311000_iOS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/c6cb14cb-4419-058b-91b3-dff2460c5703.png)

大変シンプルです。

1. [日時] のアクションでは現在日付を取得しています。予約の争奪戦が起こるのは実行する日から1か月後の日付です
2. [日付の調整] アクションで、前ステップで取得した日付＋1か月を生成します
3. [日付をフォーマット]では、URLに入れる日付形式MMddに1か月後の日付を直します
4. [URL] アクションではURLの日付部分に[日付をフォーマット]の結果を挿入します
5. 最後に[URLを開く]アクションを実行します。これでSafariで対象のURLが開かれます


4.のステップを拡大するとこのような感じです。
<img width="375" alt="20190726_144807000_iOS.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/e5eb2954-2520-9b70-b6ab-1dd355ad4072.jpeg">
2019も自動生成すればいいのですが、個人利用だったので、べた書きしました。

#まとめ
このように、何かの情報（ここでは現在の日付）から、URLのパターンからアクセスしたいページのURLを自動生成し、ブラウザで開く という非常に生活の役に立つ自動化が、みなさんのiPhoneでもできます。
ぜひ身近な自動化をiPhoneのショートカットAppで試してみてください！
Railsチュートリアル7章最後のHerokuデプロイでpumaに置き換えたときのapp error回避方法

Railsチュートリアルで7章まで進み、
「リスト 7.37: 本番環境のWebサーバー設定ファイル」あたりのところで2点、躓きました。

１：Rails sが起動しない問題
２：pumaに切り替えてHerokuを起動するとApp Errorとなる

##１：Rails sが起動しない問題

rails sするも次のエラーが発生

```
Traceback (most recent call last):
        4: from /home/ec2-user/.rvm/gems/ruby-2.6.3/bin/ruby_executable_hooks:24:in `<main>'
        3: from /home/ec2-user/.rvm/gems/ruby-2.6.3/bin/ruby_executable_hooks:24:in `eval'
        2: from /home/ec2-user/.rvm/gems/ruby-2.6.3/bin/rails:23:in `<main>'
        1: from /home/ec2-user/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/rubygems.rb:303:in `activate_bin_path'
/home/ec2-user/.rvm/rubies/ruby-2.6.3/lib/ruby/site_ruby/2.6.0/rubygems.rb:284:in `find_spec_for_exe': can't find gem railties (>= 0.a) with executable rails (Gem::GemNotFoundException)

```

こちらを参考にしてバージョン指定しつつ、bundlerを入れ直しました。

https://qiita.com/yukiweaver/items/9f07b32f31c7e863fe1c

```
gem install bundler:1.17.3
bundle install
```
これでrails sが動くようになりました。

##２：pumaに切り替えてHerokuを起動するとApp Errorとなる問題

herokuのアドレスを開くもApp error。heroku logsを見ると以下のような記載が。
pumaが設定できてないみたい。

```
[4] * Listening on tcp://0.0.0.0:33175
2019-07-26T12:03:41.606292+00:00 app[web.1]: bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.5.0/bin/puma)
2019-07-26T12:03:41.606355+00:00 app[web.1]: Errno::EADDRINUSE: Address already in use - bind(2) for "0.0.0.0" port 33175
2019-07-26T12:03:41.606359+00:00 app[web.1]: /app/vendor/bundle/ruby/2.5.0/gems/puma-3.9.1/lib/puma/binder.rb:269:in `initialize'
2019-07-26T12:03:41.606361+00:00 app[web.1]: /app/vendor/bundle/ruby/2.5.0/gems/puma-3.9.1/lib/puma/binder.rb:269:in `new'

```
検索して↓以下のサイトの記載内容をやってみたものの、動かず。
https://stackoverflow.com/questions/31039998/address-already-in-use-bind2-errnoeaddrinuse

ツイッターで検索してこちらの記事をやってみる。
https://qiita.com/yokoyan/items/caf005acecb0e6aefbec

動いた！！！

つまり、既存のpuma.rbのコードをコメントアウトせず、Railsチュートリアルに記載されていた以下の部分をpuma.rbの一番下にそのまま突っ込んで保存していたことが原因でした。
「中身は理解しなくても大丈夫です 」と書いてあったけどファイルにはちゃんと目を通そうと思いましたね・・・。

```
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count

preload_app!

rackup      DefaultRackup
port        ENV['PORT']     || 3000
environment ENV['RACK_ENV'] || 'development'

on_worker_boot do
  # Worker specific setup for Rails 4.1+
  # See: https://devcenter.heroku.com/articles/
  # deploying-rails-applications-with-the-puma-web-server#on-worker-boot
  ActiveRecord::Base.establish_connection
end

```
開発環境をDockerにしたら、PDOでcould not find driverが出た

##環境
PHP7.2
MySQL5.7

##問題
LAMP環境からDocker環境に移行した。
その際、PDOによるDB接続を実行した際に、以下のエラーが吐かれた。
ちなみにMySQL。

```
could not find driver
```

ドライバが見つからない、とのこと。
これまでのローカル環境ではインストールされていたが、現在のDockernのコンテナ内の環境にはインストールされていないということなんだろう。

コンテナに入った状態で、以下のコマンドで調べてみる。

```
$ php -m | grep pdo
```

すると、

```
pdo_sqlite
```
sqliteのドライバしか入っていない事がわかった。
から、phpのDockerfileに`RUN docker-php-ext-install pdo_mysql`と追記

```Dockerfile:Dockerfile
FROM php:7.2-apache
RUN apt-get update
RUN apt-get install -y vim
RUN docker-php-ext-install pdo_mysql
```
このDockerfileからビルドし直して、コンテナを再起動すると解決しました。

参考記事
[PDOで could not find driver が出たとき](https://qiita.com/oginom/items/5268fb19eeb80debb0ea)
小型ONUを導入してみた

初投稿なので乱文失礼します。
小型ONUに関する記事がネット上にあまりなかったので、投稿してみます。

我が家はごくごく普通の誤家庭なので、NVR510を導入しています。
今回はNTTから貸出されるHGWを小型ONU(https://www.ntt-west.co.jp/business/service/onu/about.html)
に切り替えた自分への覚書です。

##現在の回線事業者など
ドコモ光
ひかり電話有→NTT西日本


##現在のネットワーク環境
ONU(HGW) PR-500MI (三菱電機製品) 
ルーター　NVR510 (ヤマハ製品)
AP WLX202 (ヤマハ製品)
L2 SWX-2100-8G (ヤマハ製品)

I LOVEヤマハな構成です。

### 構成図
ONU(UNI出し)--NVR510--　SWX2100 --  WLX202
   

#では申込みへ...

##ステップ１　申し込み
どこのブログなどを覗いても書いていますが、本当に申し込みのハードルが高い。。。
今回は、光コラボなのでNTTではなく、ドコモ光に電話します。


「NTT西日本　コラボ事業者向け光サポートセンター」というNTT西の窓口にドコモから電話してもらうことによってこの申込ができる。との情報を得ていたので、まずは151に電話して「NTT貸与機相談センター」という部署に転送してもらいます。

ドコモ→「小型ONUなにそれ？おいしいの？」みたいな反応が帰って来たので、具体的な型番、PR-500系からSFP-ONU[またはRS-500系]に変更したいのでNTT西のサポートセンターに投げてほしい。と相談。
ドコモ→「原則ユーザーの都合では無理。どうしてそんな特殊なことを。。。？？？」と言われるので、小型ONUが収容できる設備があるので、、、と言うと、
ドコモ→「一応NTT西と相談してみるので折り返す。」との連絡を受けます。
####数時間後
契約管理システムでなにか操作をしたのでしょう。「契約書面をご確認下さい。」というSMSが突然届く。。。
小型ONUへの変更書面が電子書面で届くと同時に電話が。。。。
ドコモ→「ドコモ〇〇です。SFP-ONUに出来そうです！」とご連絡をいただき、工事費用などの説明を受ける。。。
ドコモ→「工事費用は7600円+税になります。これで良ければ工事可能です。　無派遣は難しいと思われます。」
私「それでいいです。」
ドコモ→「かしこまりました。工事のオーダーを西日本に投げるのでまた後日連絡します。」

申し込み完了。

##ステップ２　準備
当日の工事までにかんたんに準備をします。
まず、netvolante(ヤマハサービス)の連携を一度解除します。（ヤマハのCSさんによると、この操作を忘れると同じホストが取得できなくなるそうです。）
ひかり電話の設定をWAN→ONUにしておきます。
PPPoE、IpoEなどの接続もWANからONUに。
以上で準備は完了です。

##ステップ３　工事

当日、NTTの工事担当者が到着（協力会社のエ◯シオさんでした。）
「え？こんなルータ見たこと無い！」とか言われつつ、小型ONUの状態で受け渡してほしいと話をして、工事はスタート。
割当られたONUは「OKI製」(沖の製品はONU側にLANのリンク状態を示すステータスランプがついて無いそうです。)
担当者の人も初めての内容らしく、写真をたくさん撮って行かれました〜

##ステップ４　テスト
LAN、ひかり電話、NGN網に異常がないことを開通テストで確認し、工事は無事完了！
工事費は7600円（税別）でした！(やっぱり。高くね。)
コンセントも１口分スッキリ！
停電時のUPSのコンセント1口確保に成功しました！
IPプロトコル

インターネットで通信するためのプロトコル=**TCP/IP**
TCPとIPは層が違うが、2層分合わせて一式とみなす(さらにアプリケーション層も含む)

遠くに繋げるのに必要な要素
- アドレス
- 経路

## TCP/IP
別名:インターネットプロトコルスイーツ
インターネットを構築する上で必要となるプロトコル一式
仕様はオープン

#ネットワーク層・インターネット層
## 特徴
IPアドレスを元にパケットを転送する仕組み
様々な物理層/データリンク層をまたがった広域通信を実現。異なるネットワークを相互接続する。
異なる物理層規格のネットワークを接続する装置=ルーター
ルーター(転送装置)はネットワーク層を処理

## 役割
### データリンクの抽象化
#### データリンクとの違い
イーサネット、無線LAN、PPPなどを上位層に見せない

### IP層の通信方式
#### コレクションレス型通信
通信相手とコネクションを確立しない
簡略化と高速化のため
コネクション確立が必要な場合は上位層が提供(TCP)
> **ベストエフォート**
> パケットを宛先に届けようと最大限頑張るけど、届くかの保証はしない
> **エンド・エンド原理**
> ネットワーク層以下のはできる限り簡素化、複雑な処理(トランスポート層以上)はエンドホストで行う。

#### ルーター
インターネットはルーターで相互接続されている
ルータの仕事: 受け取ったパケットに書かれた宛先のアドレスをみて、パケットを次のルータにフォワード(転送)する。宛先はヘッダに書かれている。
転送するだけで届いたかは確認しない

*ノード=ホスト+ルーター*

## IP層の機能
### IPアドレス
ホストやルータにアドレスが割り当てられる
アドレスはパケットのヘッダに記載される
NIC(Network Interface Card)毎に割り当てられる

> **MACアドレスじゃダメなの？**
MACアドレスは階層性を持たない
もし全てイーサネットでつながれていたら...
280兆個のエントリ数を持つ経路表を管理できれば可能

#### IPアドレスの形式
32bitの2進数
ユーザーフレンドリーではない=>DNS(ex www.waseda.jp)
32bit=4byteの正数値(unsigned int)
人間は8bitずつに区切って10真数に変換して扱う。

##### ネットワーク部とホスト部
ネットワーク部とホスト部にわかれる(境界は自由に決めて良い)
アドレスの階層化・分散管理の実現が目的
ネットワーク部: 組織単位で割り当て
ホスト部: 組織毎のネットワークで割り当て
**プレフィックス表記**
例: 192.168.128.10/24
先頭から24bitがネットワーク部

**サブネットマスク**
M=11111111.11111111.11111111.10000000
MとIPアドレスを論理積演算するとネットワーク部が出てくる

**ブロードキャストアドレス**
ホスト部を全て1にしたもの
同一セグメントに接続された全てのホストにパケットに送信するためのアドレス

**IPマルチキャスト**
特定のグループに所属する全てのホストにパケットを送信する仕組み

#### 経路制御(ルーティング)
宛先IPアドレスのホストまでパケットを届けるための機能
ホップバイホップルーティング
ホップ： データリンク層フレームが伝送される1区間

経路MTU探索
IPによるフラグメンテーションはできれば行いたくない(ルータの負担増加、パケットロス時の無駄)



####
AWS IoTボタンを買ってslackにポストしてみた

zennに移行しました: https://zenn.dev/cumet04/articles/aws-iot-button-slack-post
qiita側の記事を消す予定は特にありませんが、更新することはありません。

---

## あらまし
ふとネットをさまよっていると、こんなものを見つけました。
https://www.amazon.co.jp/dp/B075FPHHGG

「こっ...これは！」

翌日の午前中には届いていました。

## AWS IoT ボタンとは
https://aws.amazon.com/jp/iotbutton/
Amazonダッシュボタンとほぼ同じハードウェアで、AWS IoTにつないで自由なアクションを起こすなどしやすいようになったボタンです。
WiFiなど[^1]でインターネットにつないでボタン押下イベントを送信することができます。

ボタン押下イベントはAWS IoTで取得し、そこからSNSやLambda起動などができます。
Lambdaが起動するということはつまり**なんでもできます**。夢が広がりますね。

## 動かしてみる

本記事では、サンプルとして「ボタンを押したらslackにメッセージをポストする」ということを行います。

### ボタンをAWS IoTに認識させる
最近のこの手のデバイスの初期設定はスマートフォン経由で行うことが多いですが、こちらも例に漏れずアプリから接続します。

スマートフォンのアプリストアよりAWS IoT 1-Clickというものを探し、インストールして起動します。
AWSアカウントを入力してログインし「デバイスIDで登録」よりバーコードスキャンを起動し、IoTボタン裏をスキャンすれば登録できました。

次にPCブラウザにてAWSコンソール > AWS IoT 1-Clickのサービスを開き、デバイスが見えないようであれば[^2]登録画面より登録します。
デバイスIDはスマートフォンアプリ側で確認できる英数16文字のものです。なおこれはAmazonの注文メールにも書いてありました。

サイドメニューの管理 > デバイス にIoTボタンが登録されていればOKです。

### slackにポストするlambda関数を用意する
ボタン押下イベントから発火させる関数を用意します。

slackにてincoming webhookのURLを取得しておき[^3]、そこにメッセージをポストする処理を書きます。
自分はrubyを使うことが多いのでrubyで書きます。最近はランタイムの選択肢が増えてなによりですね。
今回用意したコードは以下のようになりました。

```ruby:lambda.rb
require "net/https"
require "uri"

def lambda_handler(event:, context:)
    uri = URI.parse('https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/xxxxxxxxxxxxxxxxxxxxxxxx')
    res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == "https") { |http|
        http.request(Net::HTTP::Post.new(uri).tap { |req|
            req.body = {
                channel: 'random',
                username: 'dash',
                text: 'time',
            }.to_json
        })
    }
    { statusCode: 200, body: res.to_s }
end
```

テスト実行し、メッセージがポストされていればOKです。

### ボタンから関数を発火させる
AWS IoT 1-clickサービスの画面にもどり、プロジェクトを作成します。
基本的にダイアログに従って適当に入力していけば問題ないです。デバイステンプレートにて作成したLambda関数を指定しておきます。

作成できたらプロジェクトの画面に移り、プレイスメントを作成（デバイスを紐付ける的な）を行います。
プレイスメントに適当な名前をつけ、テンプレートに対してデバイスを選択します。

完了したら、おもむろにボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286162/b4bcd17e-d9aa-774f-c335-b165af79c908.png)


## まとめ
「ボタンを押してLambda関数を発火させる」ことまでできました。

あとはアイデアの赴くままに処理を書けばなんでもできますね。

[^1]: あまり何も確認せずに購入したためWiFi以外が使えるのかは確認できていません。
[^2]: この時点で試行錯誤したため、スマートフォン側を先に完了すればブラウザ側での操作が必要なのかはわかりません。
[^3]: 取得方法はここでは割愛
Auth0のJWT Tokenはデフォルトで10時間でexpireするので注意

## Auth0のJWT Tokenはデフォルトで10時間でexpireするので注意
タイトルの通りです。

この時間はプロジェクトの設定から変更することが可能です。
この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
ESXiにおいてのSNMPの設定をする。（ターゲットの最大数）

ESXiでSNMPの設定を実施したい場合はhostclientからGUIでは出来ない。
そのため[公式ドキュメントの通り記載](https://docs.vmware.com/jp/VMware-vSphere/6.5/com.vmware.vsphere.monitoring.doc/GUID-EA64297A-35FD-4226-A1B2-367C57D38CBD.html)の通りDCUIまたはSSHで設定する必要がある。
※SNMPはv２で設定してみる。

※環境はNestESXiで
VMware ESXi 6.7.0 build-13006603
VMware ESXi 6.7.0 Update 2

#設定してみる

現在の設定値を取得

```
[root@nestesxi01:~] esxcli system snmp get
   Authentication: 
   Communities: 
   Enable: false
   Engineid: 
   Hwsrc: indications
   Largestorage: true
   Loglevel: info
   Notraps: 
   Port: 161
   Privacy: 
   Remoteusers: 
   Syscontact: 
   Syslocation: 
   Targets: 
   Users: 
   V3targets: 
[root@nestesxi01:~] 
```
ドキュメント記載の通りにとりあえず設定値を入れてみる
>書式は”esxcli system snmp set --targets targetのaddress@port/community名”
>このコマンドでターゲットを指定するたびに、指定した設定によって、以前指定された設定が上書きされます。

```
[root@nestesxi01:~] esxcli system snmp set --targets 192.0.2.1@163/westnoc
[root@nestesxi01:~] esxcli system snmp get
[root@nestesxi01:~] esxcli system snmp set --enable true
   Authentication: 
   Communities: 
   Enable: true
   Engineid: 
   Hwsrc: indications
   Largestorage: true
   Loglevel: info
   Notraps: 
   Port: 161
   Privacy: 
   Remoteusers: 
   Syscontact: 
   Syslocation: 
   Targets: 192.0.2.1@163 westnoc
   Users: 
   V3targets: 

```
これで設定はできる。(サービスの有効化も忘れずに)
初期値（インストール時）に戻したい時は

```
[root@nestesxi01:~]  system snmp set -r
```
※他の詳細なコマンドなオプションは以下で確認できます。

```
[root@nestesxi01:~] esxcli system snmp set --help
```

#実際の設定時に困ったこと
残念なことにESXiの仕様としてSNMPのターゲットは最大３つまでしか設定できないようです。

>最大3つのSNMP v1 / v2cターゲットに加えて、最大3つのSNMP v3ターゲットを設定できます。

https://translate.google.com/translate?hl=ja&sl=en&u=https://communities.vmware.com/thread/430388&prev=search
情報が古いですが探し方が悪いのか6．７のドキュメントからは見つけられませんでした。。。

```
[root@nestesxi01:~] esxcli system snmp set --targets 192.0.2.1@163/westnoc,192.0.2.2@163/westnoc,192.0.2.3@163/westnoc,192.0.2.4@163/westnoc,
too many targets specified
```
※おこられる

```
[root@nestesxi01:~] esxcli system snmp set --targets 192.0.2.1@163/westnoc,192.0.2.2@163/westnoc,192.0.2.3@163/westnoc
[root@nestesxi01:~] esxcli system snmp get
   Authentication: 
   Communities: 
   Enable: false
   Engineid: 
   Hwsrc: indications
   Largestorage: true
   Loglevel: info
   Notraps: 
   Port: 161
   Privacy: 
   Remoteusers: 
   Syscontact: 
   Syslocation: 
   Targets: 192.0.2.1@163 westnoc, 192.0.2.2@163 westnoc, 192.0.2.3@163 westnoc
   Users: 
   V3targets: 
```
※３つだと設定できる。

ESXiをSNMPで監視をする際は留意するべきかもしれません。（vCenterで監視するような気がしますが）
parameter、params、ストロングパラメータの意味

##1.parameterとは、
入力フォームなどから送信された個別・具体的な情報のことをいう(個人の名前や年齢、コメント内容など)。

##2.paramsとは、
パラメーターとして、入力された情報をコントローラで受け取れるように、それらに対応した複数のキーを設定したものをいう(個人の名前を受け取りたい場合であれば、nameというキーを設定する)。


##3.ストロングパラメータとは、
指定したキーのみに対応したバリューしかコントローラで受け取らないセキュリティ的な仕組みをいう。また、指定した情報が送信された場合、ビューから送られたパラメーターとコントローラの設定したparamsのキーを、それぞれ対応させ、キーとバリューの関係を新たに形成させる。
mod_wsgiをなぜかpipでインストールできない時

#こんなのが出る
```bash
Collecting mod_wsgi
  Downloading https://files.pythonhosted.org/packages/26/03/a3ed5abc2e66c82c40b0735c2f819c898d136879b00be4f5537126b6a4a4/mod_wsgi-4.6.7.tar.gz (497kB)
    100% |████████████████████████████████| 501kB 2.1MB/s 
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/tmp/pip-build-5WEZrz/mod-wsgi/setup.py", line 168, in <module>
        'missing Apache httpd server packages.' % APXS)
    RuntimeError: The 'apxs' command appears not to be installed or is not executable. Please check the list of prerequisites in the documentation for this package and install any missing Apache httpd server packages.

```
#解決
```bash
sudo apt install apache2-dev
```
#👍
```

Collecting mod_wsgi
  Downloading https://files.pythonhosted.org/packages/26/03/a3ed5abc2e66c82c40b0735c2f819c898d136879b00be4f5537126b6a4a4/mod_wsgi-4.6.7.tar.gz (497kB)
    100% |████████████████████████████████| 501kB 2.5MB/s 
Installing collected packages: mod-wsgi
  Running setup.py install for mod-wsgi ... done
Successfully installed mod-wsgi-4.6.7
```
LINUX コマンド　パーミッション管理コマンド

#パーミッション管理

##chgrp
change group の　略。
###指定したファイルの所有グループの変更（要root権限）
>```
$ chgrp グループ　ファイル名
```

###指定したディレクトリ以下全てのファイルの所有グループの変更（要root権限）
>```
$ chgrp -R グループ名　ディレクトリ名 
```

##chmod
change mode の　略。
###指定したファイルのアクセス権を変更
>```
$ chmod アクセス権　ファイル名
```

###指定したディレクトリ以下全てのファイルのアクセス権の変更
>```
$ chmod -R アクセス権
```

##chown 
change　owner　の　略。
###指定したファイルの所有者の変更（要root権限）
>```
$ chown 所有者　ファイル名
```

###指定したディレクトリ以下全てのファイルの所有者の変更（要root権限）
>```
$ chown -R 所有者　ディレクトリ
```


こちらの書籍を参考にさせていただきました↓
[LPICの基礎が学べる本](https://www.amazon.co.jp/1%E9%80%B1%E9%96%93%E3%81%A7LPIC%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8C%E5%AD%A6%E3%81%B9%E3%82%8B%E6%9C%AC-%E7%AC%AC2%E7%89%88-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B3%B6-%E8%83%BD%E5%92%8C-ebook/dp/B00IWNEWS8)