OmniAICreator/Qiita-1.07M huggingface dataset:
NVIDIA DriverをUbuntu ServerにNVIDIA公式からインストール(runfile利用)

下記はrunfileによるインストール方法を解説していますが、
[NVIDIAの推奨方法はNVIDIAのリポジトリにあるcuda-driversパッケージを用いる方法](https://qiita.com/ksasaki/items/b20a785e1a0f610efa08)だそうです。
cuda-driversパッケージが使えない場合のみ、runfileを利用してください。

# はじめに

NVIDIAのドライバーをaptでインストールする問題点と、NVIDIA公式からインストールする方法です。
下記は Ubuntu Server 16.04 で実施しています。Ubuntu Desktopだとnouveauとの競合回避等が必要かもしれません。

# aptでインストールする方法と問題点
ubuntu公式のaptだと`nvidia-384`という古めのドライバまでしか手に入りません。(2019/04/10現在)

次のようにppa:graphics-driversリポジトリを追加すると新しいバージョンもインストールできます。

```bash
sudo add-apt-repository ppa:graphics-drivers
sudo apt-get update
sudo apt-get install nvidia-418
```

しかし、この方法だとバージョンによってはうまく動かない等、不安定なことがあります。

```:出るエラー例
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. 
Make sure that the latest NVIDIA driver is installed and running.
```

なので、NVIDIA公式サイトからインストールしましょう

# 公式からのインストール方法(runfile利用)
まずaptでインストールしたnvidia関連のパッケージを削除します

```
apt remove --purge nvidia*
```

https://www.nvidia.co.jp/Download/index.aspx?lang=jp にアクセスしてマシンの情報を入力するとダウンロードリンクに移動します
OSには Linux 64 bit を選択します。

.runという拡張子のファイルがダウンロードできます。それに実行権限をつけて実行すればOKです。

```bash:nvidia-410のサイレントインストールの例
chmod +x NVIDIA-Linux-x86_64-410.104.run
./NVIDIA-Linux-x86_64-410.104.run -s
```

# インストール後の管理
## バージョン確認
aptでインストールしていないため、 `dpkg -l`などの結果にはnvidia driverは表示されません
インストールされているバージョンを確認するにはカーネルモジュールの情報から取得します

```bash:バージョン確認
$ modinfo nvidia | grep version
version:        410.104
srcversion:     3B812B02678A6B43A294F17
vermagic:       4.4.0-62-generic SMP mod_unload modversions 
```

## アンインストール

.runファイルに uninstallオプションがあります

```bash:アンインストール
./NVIDIA-Linux-x86_64-410.104.run --uninstall
```
Salesforce パッケージのインストールの仕方

おひさしぶりです。
Trailheadの学習で、パッケージのインストールの仕方についてやったのですが、そこでちょっとつまづいてしまったので簡単にまとめてみることにしました。
ちな、過去にはこんな記事書いています。

- [第12弾](https://qiita.com/icchy_sh33p/items/ab6069de8a315a2d06b2)
- [第13弾](https://qiita.com/icchy_sh33p/items/4b082101aa1fd41c58a2)
- [第14弾](https://qiita.com/icchy_sh33p/items/fb045fb74f90c68fc31e)

こうして見てみると、結構真面目にまとめていた。過去の自分。

# 基本工程
基本の工程はこんな感じ。
1. インストールしたいパッケージのリンクをクリック
2. シングルサインオン（簡単にいうとアカウントの認証）で認証を試みる
3. インストールの詳細設定と正しいインストール先かを確認してインストールの実行
4. インストールするパッケージのアクセス承認


ざっとこんな感じになるんですが、自分がつまづいたのはここの2番の認証のところでした。ちょっと順番はここから前後しながらやった部分はあるものの、やり方は大きく変わらないと思うので自分のための備忘録も兼ねて、書いていきます

# 0. インストール先になるTrailhead Playgroundを指定
- ハンズオン・チャレンジの中で、選択箇所が出てきたので、今回インストール先として指定したい『My Trailhead Playground 1』を選択すれば完了
    ![](https://i.imgur.com/TTN07fr.png)
- 選択したものが正しいことを確認して、『起動』をクリック
- 起動したTrailhead PlaygroundのURLの前半箇所を記録、メモとして取っておく
    ![TFXqqlg.png](https://qiita-image-store.s3.amazonaws.com/0/274468/f94dd0d3-10ae-227f-6a4d-28d51d51390e.png)
    - このURLの『playful ~ 6』の箇所が、アカウント単位でそれぞれ付与される
    - この文字列は、あとで以下のふたつの工程で使用する
        - アカウント認証をするとき（Salesforceのアカウントをそもそも持っている場合は使用しない）
        - インストール先が正しいのか確認するとき

# 1. + 2. インストールしたいパッケージのリンクをクリック／シングルサインオン（簡単にいうとアカウントの認証）で認証を試みる
## 1. インストールしたいパッケージのリンクをクリック
- 次に、インストールしたいパッケージのリンクにアクセスする。
- 今回は事前にハンズオン・チャレンジに合わせて準備されているため、下の画像の『Install the DreamHouse app package』をクリックすればOK

    ![](https://i.imgur.com/uPm75qZ.png)
- すると、認証画面に。
- ここでSalesforceのアカウントで学習している人はログインを押せばOK（ダメな場合もあるため、そのときは[ここ（ユーザー登録必須）](https://trailhead.salesforce.com/ja/content/learn/modules/trailhead_playground_management/install-apps-and-packages-in-your-trailhead-playground?trail_id=learn_salesforce_with_trailhead)を参照）

でも、SalesforceのアカウントはないからTrailheadをGoogle認証で登録した人の場合は？それが次の2. で解決されますよ。

## 2. シングルサインオンで認証を試みる
- パッケージインストールページに遷移
- ユーザー名は、メールアドレス形式のもの。ただ、G-mailアカウントではないため、そこを修正する必要がある
- 末尾の『〜＠gmail.com』の箇所を『先ほどURLで各アカウントで付与された文字列 ＋ .com』に直す
    ![](https://i.imgur.com/BbBhWT1.png)
- パスワードには、初期設定したものをそのまま入力する。
- するとログインができるため、ログイン。インストール設定画面へ遷移

# 3. インストールの詳細設定と正しいインストール先かを確認してインストールの実行
- インストール設定画面に遷移
    ![](https://i.imgur.com/2Npkz3m.jpg)
- インストール先があっているか、URLに記載されている文字列が先ほど記録したものと一致しているか確認
- この画面で、既存のパッケージのコンポーネント名と同じものをインストールしようとしている場合の対処方法とインストール先について設定する
    - 既存のパッケージのコンポーネント名と同じものをインストールしようとしている場合の対処方法
→『インストールしない』で今回は設定
    - インストール先
→『管理者のみのインストール』で今回は設定
- 設定が完了したら、『インストール』を押す

# 4. インストールするパッケージのアクセス承認
- インストールするパッケージがWebサイトなどとの接続をする場合、該当Webサイトが信頼できるか確認
- 信頼できることが確認できたら、アクセス許可の承認ボックスをチェックして『次へ』を選択
    ![](https://i.imgur.com/4YMRubL.png)

# 5. インストールの実行
- アクセス許可を承認するとインストール実行中の画面に
    ![](https://i.imgur.com/DCF8dFM.png)
- しばらく待っていると、インストール完了画面が表示
    ![](https://i.imgur.com/j5zZite.png)
- インストールが完了したら、正しくインストールしたい場所にインストールできているか確認
- 確認するページは『アプリケーション』内の『インストール済みパッケージ』ページ
    ![](https://i.imgur.com/sCmTsQ1.png)

# 感想
最近、なかなか勉強できていませんでしたが、やっぱり新しいことを知るのは時間もかかるし、苦戦しちゃうけど、それ以上にやっぱり楽しいですね。
社会人2年めになりましたが、マイペースに頑張っていこうと思います
では
【覚書】Windows版 SourceTreeでリモートリポジトリの認証に失敗後、再度認証して欲しいとき

# はじめに
この記事は、Neskyさんの記事『[【覚書】Mac版 SourceTreeでリモートリポジトリの認証に失敗後、再度認証して欲しいとき](https://qiita.com/Nesky/items/7789560a844d284979c3)』に触発されて書きました。

# リモートへのログイン時にありがちな問題
　SourceTreeでは、リモートリポジトリへの初回プッシュなどを通してサーバーへログインするとき、初回のみパスワードを聞かれます。
　しかし、聞いてくれるのは本当に初回だけなので、ここで間違った情報を入力すると、以降永遠にログインに失敗してしまいます。
　これを解消するには、認証情報を直接削除してやり直すしかありません。

### 環境
Windows 10 Pro
SourceTree For Windows 3.1.2

# 対処方法
Windows版の場合、以下のディレクトリに保存されているpasswdファイルを削除すれば、再び認証情報を聞いてくれるようになります。
`C:\Users\(ユーザー名)\AppData\Local\Atlassian\SourceTree`
ドライブレター、ユーザー名は各自読み替えてください。

しかしpasswdを削除すると、保存されている認証情報がすべて消えてしまいます。
それを避けたいならテキストエディタなどで開いて、該当する箇所だけ削除するようにするといいかもしれません。
[読書] レガシーコード改善ガイド

レガシーコード改善ガイドという本を読みました。
良い本だったので、自分が特に参考になった部分をメモとして残したいと思います。
この本を読むきっかけや読み進める上での参考になれば幸いです。
[→書籍情報（Amazon.co.jp）](https://www.amazon.co.jp/%E3%83%AC%E3%82%AC%E3%82%B7%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E6%94%B9%E5%96%84%E3%82%AC%E3%82%A4%E3%83%89-Object-Oriented-SELECTION-%E3%83%9E%E3%82%A4%E3%82%B1%E3%83%AB%E3%83%BBC%E3%83%BB%E3%83%95%E3%82%A7%E3%82%B6%E3%83%BC%E3%82%BA/dp/4798116831)

# なぜ読んだのか、何を得られたのか。
## なぜ読んだのか
 - 自分が業務で扱っているソースコードがとても汚く、モチベーションが下がっていた。
 - 古いバージョンの言語、フレームワークを使用しており、テストコードは動かないことが多かった。
 - その状態を改善することができていない自分自身に苛立っていた。

## 何を得られたのか
 - レガシーコードに対する考え方。
 - レガシーコードに対する具体的な戦法。
 - 自分の仕事に対する姿勢を考え直すきっかけ。

# レガシーコードに対する考え方
## レガシーコードとは単にテストのないコードのことである。
 - テストがあれば検証しながらコードを良くしていくことができる。
 - テストがなければ、コードが良くなっているのか悪くなっているのかが本当にはわからない。

## 編集して祈るか、テストで保護して変更するか。
 - 見た目は醜悪でも、数々のデバッグを乗り越えてきたソースコード。

# レガシーコードに対する具体的な戦法
## 依存関係を排除する。
 - レガシーコードにテストを入れる方法は意外とたくさんある。
 - 最初に小さなリファクタリングをしてからテストを入れるとスムーズ。
 - 依存関係を排除しテストを実装していくことで自然と読みやすいコードになっていく。

# 自分の仕事に対する姿勢を考え直すきっかけ
## 隣の新規開発の芝は実はそれほど青くはない。
 - 仕事にやりがいを持てるのかどうかは、レガシーコードであるかどうかに関係ない。
 - 仕事へのモチベーションは仕事に対する姿勢で決まる。
 - 試しに最も醜悪なクラスをテストで保護してみたらどうか。

# まとめ
 - テストがないなら入れよう。
 - テストを入れることで依存関係の少ない設計になっていく。
 - 依存関係が原因でテストができないなら、最初に小さなリファクタリングをしてテストを入れよう。
 - 今の仕事をやりがいのあるものに変えられるかどうかは、自分にかかっている。
ROSの機械学習用に、OpenPoseから関節角度をTopicで流すパッケージ作った

## 概要
OpenPoseをROSで使いたかったわけですが、自分が欲しいパッケージがまだ無かったようなので作りました。
[:link: :link: :link: my github :link: :link: :link: ](
https://github.com/OkanoShogo0903/ros_openpose_joint_converter)

ROSのOpenPoseドライバとしては[ros-openpose](https://github.com/jacques-saraydaryan/ros-openpose)がありますが、これは関節ごとの画面座標を出力するものでした。

**自作パッケージはros-openposeのデータをより機械学習で使いやすいように関節角度に変換してTopicで投げる**ようにしたものです。

## 例

```
persons: 
  - 
    layout: 
      dim: []
      data_offset: 0
    data: [22, 0, 0, 56, 76, 0, 25, 29, 1, 0, 0, 0, 0, 34, 0, 0]
  - 
    layout: 
      dim: []
      data_offset: 0
    data: [40, 49, 4, 41, 52, 3, 10, 37, 10, 41, 8, 0, 0, 8, 0, 0]
num: 2
```
二人の人間が写っている時のTopic

## 実装した関節角度の計算方法
例えば肘の関節角度が欲しい場合、肘から手首と肩に向かってそれぞれベクトルが得られます。
この時、肘の関節角は２つのベクトルの内積から計算が可能です。
これを主な関節に対して行うことで関節角度を取得しています。
![pic2.jpg](https://qiita-image-store.s3.amazonaws.com/0/177172/18d6846d-e6b6-dfbb-9851-2e3fdfbfe2ba.jpeg)

``` python
    def convertFormat2Vector(self, msg):
        ''' 
        @param msg : ros-openpose format
        @return output : array (16dim)
        '''
        output = np.zeros((0, 16))
        for person in msg.persons:
            angles = []
            ''' 
            confidence: 0.694853901863, part_id: 17
            x: 368
            y: 341
            '''
            for p in parts_id_pair:
                x0 = person.body_part[p[0]].x
                y0 = person.body_part[p[0]].y
                x1 = person.body_part[p[1]].x
                y1 = person.body_part[p[1]].y
                x2 = person.body_part[p[2]].x
                y2 = person.body_part[p[2]].y
                if all([x0, x1, x2, y0, y1, y2]):
                    u = np.array( [ x1 - x0, y1 - y0])
                    v = np.array( [ x2 - x0, y2 - y0])
                    angle = np.round(self.innerProduct(u, v))
                    angles.append(angle)
                else:
                    angles.append(self.MISSING_VALUE)

            print(angles)
            output = np.vstack((angles, output))
            print(output.shape)

        return output


    def innerProduct(self, u, v):
        ''' 
        calcJointAngle
        '''
        i = np.inner(u, v)
        n = np.linalg.norm(u) * np.linalg.norm(v)

        c = i / n
        deg = np.rad2deg(np.arccos(np.clip(c, -1.0, 1.0)))
        return deg

```

## 欠損値の扱い
カメラから体の一部が消えた時は欠損値が出るわけですが、
とりあえずその場合はデフォルトで０が入るようになっています。
一応変えたい場合はlaunchのrosparamをイジればいいように実装されています。

## Topicの説明
Listで16個の値を投げています。
単位はDegreeで、16個の値は下の図のIndexと対応します。
![pic1.jpg](https://qiita-image-store.s3.amazonaws.com/0/177172/5ebf6651-dc4b-8933-be54-ad1c18ae3f5f.jpeg)
乙py式５時間で学ぶプログラミング基礎(python編)

# プログラミング初心者向けの動画講座

短時間でプログラミングを学ぶ事ができる動画講座を作りました。

Youtube:
[乙py式５時間で学ぶプログラミング基礎(python編)](https://www.youtube.com/playlist?list=PLkLiqjLUSj2ARmOIDk-eetfMx4HdahyMA)


この講座ではPython言語を通じてプログラミングの基礎を
習得することが出来ます。

会社で営業とかマーケティングとかを担当しているけど
データを扱うことが増えてきて
手作業ではどうにもこうにも回らくなって来た・・とか

今度プログラミングが義務化されるけれども
全然プログラミングとかしたことないという方

そういう方にはささっとプログラミングの基礎を
学ぶことが出来ます。

YOUTUBEの講座動画と講座資料を載せておきますので
ぜひ参考にしてくださいませ。

資料の場所はここ

Note:
[乙py式５時間で学ぶプログラミング基礎(python編)](https://note.mu/otupy/n/nd4d45b841358)


###講座を終えた後のお役立ちアイテム

Pythonチートシート：
良く使うコードなどをひとまとめにしたチートシートです。
これがあればどう書くか迷うことがなくなります。

Note:
[Pythonチートシート](https://note.mu/otupy/n/n1bedb9f36e54)


###その他

乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython

プログラミングやデータサイエンス、機械学習、クラウドサービス
お笑い、エンタメ、くだらないことなどをよく呟いています。
AndroidNDKのandroideabi-readelfに騙された話

nm,objdump,readelfでシンボルが示すアドレスを確認してみた。

```
$ arm-linux-androideabi-nm -S test | grep func
00000b24 00000034 T _Z4funcv

$ arm-linux-androideabi-objdump -t test | grep func
00000b24 g     F .text  00000034               _Z4funcv

$ arm-linux-androideabi-readelf -s test | grep func
  1937: 00000b25    52 FUNC    GLOBAL DEFAULT   12 _Z4funcv
```

お分かりだろうか。。。
readelfだけ1byteずれているのである。
もちろん正しいのはnmとobjdump。

readelfばかり使っていて１週間ほど悩んでしまった…悲しい…
CCSで文字にグラデーションをかけ影を付ける

#まず初めに

まず、background-clipを使用し、ただ単にグラデーションをかけたものが以下になります。

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

#次に

text-shadowを付けます。すると、以下のようになります。
文字を透明色にし背景色を透過する事によってグラデーションのかかった文字を表示するためtextshadowまでもが透過され以下のように全体的に滲んでしまったり、意図したデザインになってしまいます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="s-chenn" data-slug-hash="dLvYEJ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="text gradation &amp;amp; shadow">
  <span>See the Pen <a href="https://codepen.io/s-chenn/pen/dLvYEJ/">
  text gradation &amp; shadow</a> by S-Chenn (<a href="https://codepen.io/s-chenn">@s-chenn</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#最後に
そこで、もとのテキストにはtext-shadowだけを当て、その上からグラデーションかけたテキストの擬似要素を被せることで、以下の様に文字の周りだけにtext-shadowを付けることが出来ます。

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="css,result" data-user="s-chenn" data-slug-hash="MRpjVp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="gradtion &amp;amp; shadow2">
  <span>See the Pen <a href="https://codepen.io/s-chenn/pen/MRpjVp/">
  gradtion &amp; shadow2</a> by S-Chenn (<a href="https://codepen.io/s-chenn">@s-chenn</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#####※注意点
Internet Explorerではbackground-clipをサポートしていないため、上述の方法は使えません。
ASP.NET Core の Razor ページでダウンロードを実装したい

Bootstrap ガチガチなサイトに、ポツンと Excel ファイルのダウンロードボタンを設置したい!

ASP.NET Core MVC では Controller に介入すれば良いが、Razor ページではどうだったか…

# Razor ページの変更

`Problems.cshtml` の方にダウンロードのリンクを設置します。

```html
  <a asp-page="/Problems" asp-page-handler="Download">Excel</a>
```

`asp-page-handler="Download"` のように追加します。`Download` 以外でも良いです。

詳細につきましては [ASP.NET Core のアンカー タグ ヘルパー](https://docs.microsoft.com/ja-jp/aspnet/core/mvc/views/tag-helpers/built-in/anchor-tag-helper?view=aspnetcore-2.2#asp-page-handler) を参照してください。

# ページ モデルの修正

`OnGetHandlerAsync` メソッドを追加します。`Handler` の部分を先ほどの `Download` に変更して、
`OnGetDownloadAsync` メソッドを書きます。

```csharp
  public IActionResult OnGetDownloadAsync()
  {
    return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "File.xlsx");
  }
```

Razor ページに設置したハイパーリンクは、
`<a asp-page="/Problems" asp-page-handler="Download">Excel</a>`

つぎのようになっていました。
`<a href="/~/Problems?handler=Download">Excel</a>`
iPad AirからGoogle Colabを使ってみた

#### タイトル詐欺なんですが、~~死ぬほど使いにくい。~~

- 十字キーが使えない
- ~~コピペできない~~

#####すみません。コピペはできました(;^^)


キーボードはELECOM Ultra Slim Keyboardを利用。
~~もしかしたらこれの設定の問題かもしれませんので、解決したら報告します。~~
→ 解決しました！！
コピペ問題については設定どころかショートカットキーが違いました。普段はwindows使いなので、
Ctrl+Cでコピーをしようとしてたのですが、iOSなのでCmd+Cでした。
ってことで、iPadとサードパーティ製キーボードを利用している方はお気をつけください。これからもう一回Google Colab使ってみます。

でもやっぱり十字キー使えない。。。。この記事を書くときも、GodNotesも大丈夫なのに。。。。（2019/4/11追記)

本当はGoogle Colab場で実務の現場でデータサイエンスをする際に必須となる基礎集計の自動化クラスを作って公開しようと思っていたのですが。。。。

###今後投稿したいこと

- 基礎集計自動化
- モデル制度評価自動化

Rの方が得意ですが、勉強を含めてPythonのコードを書いていきます。
その他備忘録的なものも書いていきます。
これからWebサービスを作るならLaravelが良さそう 

# はじめに
Webサービスを作ってみたいと思い、どのフレームワークを使うかを検討しました

# シェアを調べる

シェアが高いフレームワークの方がライブラリやスタックオーバー系が充実するので重要です。

Webのフレームワークのシェアをグーグルトレンドで検索します。

最近よく聞気覚えのあるいくつかのフレームワークで調べます。
ここは日本なので日本の人気を確認しましょう。

グーグルトレンドの検索ランキングなのでノイズが入ったりしますがシェアが高いものであれば概ねあっていると思います。

<img width="1166" alt="スクリーンショット 2019-04-10 15.53.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/109862/75d32870-37ca-c22c-2b3b-d05ba2953137.png">
https://trends.google.com/trends/explore?date=all&geo=JP&q=Django,Ruby%20on%20Rails,Laravel,FuelPHP,Flask

Laravelが首位です。


ではPHPライブラリのみで期間を縮めてシェアを確認します

<img width="1162" alt="スクリーンショット 2019-04-10 17.24.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/109862/2db0506d-b66d-d6f5-2ee2-95ab0b790082.png">
https://trends.google.com/trends/explore?date=2010-10-03%202019-04-10&geo=JP&q=CakePHP,Codeigniter,Laravel,FuelPHP,Symfony

やはりLaravelが首位です。

#Laravelは何か？

２、３日触ってみてRoRやFuelとほぼ構想が同じような感じがしました。
規約がRoRよりは少なく学習コストも低い感じがします。

個人的にテンプレートエンジンのLaravelのbladeがコードビハインドではなくhtmlにコードを書くことを推奨しているようにみえるのが違和感ありましたが、時代の変化でしょうか。
https://readouble.com/laravel/5.5/ja/blade.html

これからWebフレームワークを使うならLaravelにしましょ

#Laradocで環境構築

LaravelとDockerで環境が一式パッケージ化がすでにされているものでLaradocがありました。
Dockerで環境構築するならこれが良さそう。
https://laradock.io/
[Swift] [iOS] [令和] 和暦西暦変換は端末日付に依存する

2019年4月8日、iOS 12.3 beta2が開発者向けにリリースされました。
https://developer.apple.com/documentation/ios_release_notes/ios_12_3_beta_2_release_notes
上記リリースノートにある通り、令和に対応したバージョンです。

早速ダウンロードして色々試してみたところ、端末の日付が「2019/4/30以前」と「2019/5/1以降」で、Calendarコンポーネントの挙動が変わりました。

以下のサンプルコードで挙動を確認していて「へぇ」と思いました。
（実務ではレアな実装かと思いますが）

```swift
// 和暦の31/04/01を西暦に変換してみる
var comp = DateComponents()
comp.year = 31
comp.month = 4
comp.day = 1
let date = (Calendar.init(identifier: .japanese)).date(from: comp)
let formatter = DateFormatter()
formatter.locale = Locale.init(identifier: "ja_JP")
formatter.dateFormat = "yyyy/MM/dd"
print("\(formatter.string(from: date!))")
// 端末の日付が2019/4/30以前の場合、平成31年と判断され、"2019/04/01"となる。
// 端末の日付が2019/5/1以降の場合、令和31年と判断され、"2049/04/01"となる。
```

私は（何の根拠もなく）端末の日付設定とは無関係に「iOS 12.3にアップデート後は常に令和n年と判定される」と予想していたので、上記の挙動は予想外でした。

蛇足ですが、令和に未対応のiOS 12.2以前では、端末の日付が2019/4/30以前でも5/1以降でも、31年→2019年、32年→2020年になります。
平成までしかデータが入っていないので当たり前ですね。

環境：
Xcode 10.1
Swift 4.2

※ご注意
あくまでbetaでの情報ですので、最新の情報とは異なっている可能性があります。
【Kotlin】Activityからボタンのクリックを無効にする

Activityからボタンのクリックを無効にするには**`isClickable`**を使います。

```Kotlin:良い例
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        button.setOnClickListener {
            Toast.makeText(applicationContext, "ボタンをクリックしました", Toast.LENGTH_SHORT).show()
        }

        // クリックを無効にする
        button.isClickable = false
    }
}
```

注意点としては、`setOnclickLisnter`の**後に記述すること**。
`setOnclickLisnter`がクリックのフラグを`true`に変更してしまうためです。
[android - Button.setClickable(false) is not working - Stack Overflow](https://stackoverflow.com/questions/18825747/button-setclickablefalse-is-not-working)

```Kotlin:悪い例
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 無効にならない
        button.isClickable = false

        button.setOnClickListener {
            Toast.makeText(applicationContext, "ボタンを押しました", Toast.LENGTH_SHORT).show()
        }
    }
}
```

ちなみに、iOSだと`isEnable=true`を設定したボタンは文字色がグレーになるので非活性だとわかりやすいのですが、
Androidではクリックが有効であれ無効であれ見た目は変わらないので、別途ボタンの色や透明度を変更してあげる必要がありそうです。

## 追記
**`isEnabled`**を使えば、文字色がグレーになることがわかりました！
（`isClickable`と違ってリスナーの影響は受けないようなので、前後どちらに書いても大丈夫です。）


```Kotlin
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // クリックを無効にする + 文字のグレーアウト
        button.isEnabled = false

        button.setOnClickListener {
            Toast.makeText(applicationContext, "ボタンを押しました", Toast.LENGTH_SHORT).show()
        }
    }
}
```

単にクリックを無効化したい場合は`isClickable`を使い、その上でユーザーに使えないよと示したい場合には`isEnabled`を使うと良さそうだなと思いました。
ご指摘頂いた @entan05 さん、ありがとうございました:sparkles:
Commands for most of text editors like ATOM(2)

| Command | Description |
|:--|:--|
| Select + ⌘/ | Toggle commenting out |
| Select + ⇥ | Indent |
| Select + ⇧⇥ | Dedent |
| ⌃G | Goto line number |
| ⌘W | Close a tab |
| \$ echo $PATH | Show the current path |
| $ chmod +x <filename> | Make filename executable |
| $ unzip <filename>.zip | Unzip a ZIP archive |
| ⌘P | Fuzzy opening |
| ⌘1 | Switch focus to tab #1 |
| ⇧⌘F | Global find and replace |
Travis OrgからComへの変更

多くは別記事に任せるとして

## travis cli endpoint変更

orgログアウト、comログインした状態で

```shell
$ travis endpoint --set-default --com
```

とすれば

```shell-session
$ travis endpoint
API endpoint: https://api.travis-ci.com/
```

になります。

たぶんこれでデフォルトcomになるはず...なのだが`travis encrypt`の参照方向がorgのままだった...やっぱり`--com`は必要かもしれない。
ARandRがめっちゃ良いって話

#ARandRがめっちゃ良いって話
こんにちは。そたです。私は普段MacBookProにArchLinuxを入れ、そこでi3wmを動かして暮らしているのですがi3wm環境で外部ディスプレイがいい感じに接続できない！ってなって調べたらいい感じのツールが見つかったので紹介します。
##XRandRが邪悪
はい。自分が最初使っていたのがXRandRコマンドです。「ArchLinux i3 外部ディスプレイ」みたいな感じでググったときに一番最初に出てきたのがXRandRで素直にこれを使っていたのですがこれがもっっっっのすごく使いにくい。なぜならすべての設定をxrandrコマンドのオプションでするから。このコマンドのオプションがうまく反映されなかったりわかりにくかったりと、自分には使いこなせませんでした。
##救世主ARandR
そこでみつけたのがARandR。これは難しいオプションなどもないGUIでディスプレイを設定できるツールです。ちなみにXRandRのWrapperなのでARandRでできることはすべてXRandRでできたりします(ほんまか？)。ディスプレイをドラッグして好きな位置に配置してApplyを押すだけで簡単に任意の位置にディスプレイを配置できます。
##ARandRのインストール
aptなら
```sudo apt install arandr```
pacmanなら
```sudo pacman -S arandr```
でインストールできるはずです。
##最後に
よきLinuxライフを！
DockerによるRuby on Railsの環境構築手順

だいぶ、手間どりましたが、以下のリンク先が一番わかりやすかったので、今後のためにも、まとめたいと思います。
※リンク先の方は丁寧親切です。
https://remonote.jp/docker-mac-rails-postgresql

## 任意の作成したディレクトリー配下に以下の４つのファイルを作成
・ dockerfile
・ Gemfile
・ Gemfile.lock →空のファイルで良い
・ docker-compose.yml

```ruby:dockerfile
FROM ruby:2.6.2
 
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
 
RUN mkdir /blog_app_sample
WORKDIR /blog_app_sample
ADD Gemfile /blog_app_sample/Gemfile
ADD Gemfile.lock /blog_app_sample/Gemfile.lock
RUN bundle install
COPY . /blog_app_sample
```
・今回、blog_app_sampleというアプリを作成する前提。
・rubyのバージョン指定は任意

```ruby:Gemfile
source 'https://rubygems.org'
gem 'rails'
# gem 'rails', '~> 5.2.3'でも良い
```

```ruby:docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```
conposeのバージョンがあるみたい。
また、ymlなので、インデントには注意する。

## アプリケーションの生成
```command
$ docker-compose run web rails new . --force --database=postgresql
```

## Dockerのイメージ構築
```command
$ docker-compose build
```

## config/database.ymlの設定

```ruby:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: blog_app_sample_development

test:
  <<: *default
  database: blog_app_sample_test

production:
  <<: *default
  database: blog_app_sample_production
  username: blog_app_sample
  password: <%= ENV['BLOG_APP_SAMPLE_DATABASE_PASSWORD'] %>
```
defaultのところを追記する

## Dockerの起動
```command
$ docker-compose up
```
これでlocalhost:3000にアクセスすると、いつもの画面が表れる。
※停止は、Ctrl+C

pidの削除はこれ↓

```command
$ rm tmp/pids/server.pid
```

## コマンド実行例

```command
$ docker-compose run web rails g scaffold Blog title:string content:text
```
$ docker-compose run webが頭につく。

## Gemfileを編集した時

```command
$ docker-compose run web bundle install
$ docker-compose build
```
再度、イメージ構築をしないといけない。

https://qiita.com/fuku_tech/items/dc6b568f7f34df10cae7
https://qiita.com/kenzoukenzou104809/items/90dd187a3fb1c8897656

## Herokuへのデプロイ


```command:herokuでのデプロイ手順
# ローカルでWebサーバーが動作している（pidsが存在する）と、herokuでWebサーバーが起動しない可能性があるので、一旦ローカルのサーバーを停止しておきます。また server.pid が存在する場合は消しておきます
$ docker-compose down
$ rm tmp/pids/server.pid

$ heroku container:login
$ heroku login 

$ heroku create

$ heroku container:push web

$ heroku addons:create heroku-postgresql:hobby-dev

# このコマンドは、念のため実行
$ heroku run rails db:migrate

$ heroku container:release web

```
この状態で、「git push heroku master」とすると
恐れく、heroku.ymlが無いとエラーがでるので、
以下のようなheroku.ymlを作成し、「git push heroku master」する


```yml:/heroku.ymlを作成する
build:
  languages:
    - ruby
release:
  command:
    - rake db:migrate
run:
  web: bundle exec puma -C config/puma.rb
```

https://ginpen.com/2018/08/07/docker-rails-example/
https://qiita.com/okyk/items/a374ddb3f853d1688820

![スクリーンショット 2019-08-09 19.13.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114933/97f4311a-23f9-1e90-4db1-4e9b2623aece.png)
Commands for most of text editors like ATOM

|  |  |
|:--:|:--:|
| Command | Description |
| ⌘← | Move to beginning of line (stops on whitespace) |
| ⌘→ | Move to end of line |
| ⌘↑ | Move to beginning of file |
| ⌘↓ | Move to end of file |
| ⇧-move pointer | Select text |
| ⌘D | Select current word |
| ⌘A | Select All (entire document) |
| ⌘X/⌘C/⌘V | Cut/Copy/Paste |
| ⌘Z | Undo |
| ⇧⌘Z or ⌘Y | Redo |
| ⌘S | Save |
| ⌘F | Find |
| ⌘G | Find next |
Railsへのファイルアップロードが遅い時

# 環境

Rails5 (5.0.0.1)
# 発生した問題
Ruby on Railsで作成したWebサービスにおいて、フォームから大容量のファイルをアップロードすると…すごく遅い。
具体的には100MB程度のアップロードに2分とかかかる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/272677/7fc9aeb6-90c6-a77e-b456-f7c94105adc6.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/272677/9baf31bd-bc9a-0a0c-d62f-918ddec6b7cf.png)


# 原因
RailsのHTTP通信には、[Rack](https://github.com/rack/rack) というgemが使用される。
今回の原因はこれが遅いせい。
具体的には、一部のバージョンのRack（今回は2.0.1）において、マルチパート解析が重く、遅い。

## Rackのマルチパート解析が遅いのはなぜか
場所的には[Rack::Multipart::Parser](https://github.com/rack/rack/blob/2.0.1/lib/rack/multipart/parser.rb) 。（今回は2.0.1）

内容的には、大きく2点。

* バッファサイズが **16kbしかない** 。
 * 受信速度が100Mbpsだと、1秒あたり800回にわけてパースしないと追い付かない計算。*ISDN時代なら1秒1回で済んだ*
* の割に1回1回のパースが重い。

現実で言うと、豆や米を計量カップ等ではなく小さじスプーンで測ろうとしていて、手さばきも遅かった感じ。


## Rackのマルチパート解析は2.0系でかなり変わっている
* [2.0.4](https://github.com/rack/rack/commits/2.0.4)において、[パースが少し速くなり](https://github.com/rack/rack/pull/1179)、[バッファサイズが1MBになった] (https://github.com/rack/rack/pull/1192)。
* [2.0.6](https://github.com/rack/rack/commits/2.0.6)において、[バッファサイズが16KBに戻った](https://github.com/rack/rack/commit/37c1160b2360074d20858792f23a7eb3afeabebd)。
 * これは一部のDoS攻撃に弱くなってしまうから（と書いてある）。
 *  `>There is a possible DoS vulnerability in the multipart parser in Rack. `
 * 恐らく、1つのマルチパートリクエストに対していきなり1MBのメモリを確保してしまうと、小粒なリクエストの連続によって大きな負荷がかかりうるということだと思われる。
 * Rackはマルチパート同時受信数に制限をかけるので、合計メモリ使用量が異常増大することはない。リンク先ではCPUに対しての攻撃コストパフォーマンスが問題視されているようだ。
 * 現実で言うと、ハガキの配達に運転手と車を1台ずつ用意してしまう感じ。1枚ずつ大量に送られると大変。

端的に言うと、
[1] 2〜2.0.3はすごく遅い
[2] 2.0.4と2.0.5は速いが一部のDoS攻撃に弱い
[3] 2.0.6は[2]よりは遅いが[1]に比べればかなり速い

# 解決

## Rackを2.0.4以上にする
* Railsのバージョンを引き上げれば勝手にRackのバージョンも上がる。
 * 自社例ではRails5.0.0.1からRails5.0.7.2にしたところ、Rackは2.0.1から2.0.6に。development環境ではかなり速くなった。
 * ![image.png](https://qiita-image-store.s3.amazonaws.com/0/272677/e34886ff-e271-f879-977f-25fa86e3f8a6.png)
 * が、実際デプロイしてみたところ、残念ながら当方heroku環境ではそこまでの効果が感じられなかった。環境によっては他の要因を考慮する必要がありそう。
* マイナーバージョンの範囲内ならRackだけ引き上げちゃっても良いかも。（責任は持ちません）

## マルチパート解析時のバッファサイズを増やす
雑に500kb弱くらいにする例

```Ruby:config/initializers/rack.rb
require "rack/multipart/parser" 

Rack::Multipart::Parser.send :remove_const, :BUFSIZE 
Rack::Multipart::Parser.const_set :BUFSIZE, 500_000
```

ただし前述の通り一部のDoS攻撃で負荷をかけやすくなる。環境と相談してお好みでやってください。

## 理想的には
* Rackのバージョンを上げる
* 可能ならRack::Multipart::Parserに手を加える
    * ある程度のサイズが送られた後にバッファサイズを引き上げる動作に変更すれば、攻撃耐性と動作速度ともに改善しそう。*そこまではしなくていいか…*
conoha wingで、異なるバージョンのPHPを使う

この記事は99%くらい@akspect さんの
[さくらインターネットで、異なるバージョンのPHPを使う](https://qiita.com/akspect/items/3231a957f7af8471efb7)から引用させて頂きました）

##.htaccess
以下の2行を追加して、マルチドメインやサブドメインを設定したディレクトリにupします。

```apache:.htaccess
Action myphp-script /php.cgi
AddHandler myphp-script .php .html
```

##php.cgi
.htaccessと同じ階層に、php.cgiを追加します。
テキストエディタで以下の文言を記載し、php.cgiという名前で保存。
パーミッションは755にします。

```apache:php.cgi
#!/bin/sh

# 使用したいバージョン以外をコメントアウトして下さい
# 以下では php5.6が有効になっています。
#exec /opt/alt/php72/usr/bin/php-cgi
#exec /opt/alt/php71/usr/bin/php-cgi
#exec /opt/alt/php70/usr/bin/php-cgi
exec /opt/alt/php56/usr/bin/php-cgi

```

##動作確認
後は同じディレクトリに以下のようなphpinfoを出力する
phpファイルを入れてブラウザからアクセスすればバージョンが切り替わっていることが確認可能です

```php:test.php
<?php phpinfo(); ?>
```


#参考
[さくらインターネットで、異なるバージョンのPHPを使う](https://qiita.com/akspect/items/3231a957f7af8471efb7)
WindowsでAtomを使ってLaTeX環境を整える

## 背景

エディタもTeXも知らない状況で, LaTeXを使ってレポートを書く際に, 環境構築に苦労する. そこで, Atomを使ってLaTeXがかけるようあ環境を整えた. Atomを使った理由は, Sublimeの人気が落ちていそうな気がしているのと, VSCodeでLaTeXが書きにくかったからである. あとSublimeに飽きてきたのもある. ちょっと重たいのが難点.

## 方法

### TexLiveをインストールする

[http://mirror.ctan.org/systems/texlive/tlnet/install-tl.zip](http://mirror.ctan.org/systems/texlive/tlnet/install-tl.zip)にアクセスしてインストールする. めちゃめちゃ時間がかかる. 3時間くらいかかっていたかも. 全てデフォルトの設定にしておく. 自動的にPATHを通してくれるが, 動かなかった時は[こちら](https://texwiki.texjp.org/?W32TeX#g0475486)を参照してPATHを確認する.

#### 注意点

他にもいろんなtexに関するソフトがあったが, これが一番主流で新しいそうだと勝手に判断した.

### Atomをインストールする

[https://atom.io/](https://atom.io/)にアクセスしてダウンロードする. すでにダウンロードしている場合は, Atomを再起動しないとPATHが反映されないため気をつける.

### Atomにパッケージをインストールする

以下の3つのパッケージをインストールする. 

- [language-latex](https://atom.io/packages/language-latex)
    - `.tex`ファイルのテキストを色分けしてくれるためのもの
- [pdf-view](https://atom.io/packages/pdf-view)
    - Atom上でpdfを出力するためのもの. ちょっと拡大縮小がやりにくい.
- [latex](https://atom.io/packages/latex)
    - compileするためのパッケージ. 
    - Settingsから
        - `Build on Save`を`true`にしておく. 保存したと同時にcompileされる.
        - `Open Result after Successful Build`を`true`にしておく. compileと同時にpdfが開かれる.
        - `Opener`を`pdf-view`にしておく. これでAtom上でpdfが開かれる.
       
### AtomでTeXを編集する

いろいろインストールしたらとりあえずAtomを再起動するのがいいかも. そして適当な`.tex`ファイルを作って, 適当にテキスト編集して保存すると, compileされたものが出現する.

### 感想

TeXLiveがばり重かったので, もっと軽いものが存在するかもしれない...
モーダル実装ならとりあえずmodaalで良いのではという話

## 公式
http://humaan.com/modaal/
https://github.com/humaan/Modaal

## なんでmodaalか

### cdnもあり導入が楽
```
<script src="https://cdn.jsdelivr.net/npm/modaal@0.4.4/dist/js/modaal.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/modaal@0.4.4/dist/css/modaal.min.css">
```
jqueryを読み込んでいる事が前提ですが、上記だけで準備は完了します。

あとは以下の例のようにモーダルで表示させたい要素に合わせてスクリプトを記述すれば完了です。

```
$(document).ready(function () {
  // 動画用スクリプト
  $('.hogehoge').modaal({
    type: 'video'
  });
});
```

### フラットデザインな見た目
一昔前のモーダルプラグインと違って最近のデザインに沿った見た目なので、
cssでのカスタマイズが少なく済みます。

![スクリーンショット 2019-04-10 17.45.16.png](https://qiita-image-store.s3.amazonaws.com/0/120058/be656ab5-5d7f-c65a-e535-8965f3e587fb.png)

自分が実装した直近の例だと、
・インライン再生の予定だったyoutubeがモーダル実装になった。
・一部ページが掲載する内容が少なくなってしまったので、モーダル実装になった。
というような要件の時にカスタマイズせずデフォルトで実装しました。

### よくある要件がデフォルトで実装されている。
モーダルを実装する上で要件とされる事が多い

・モーダルのレスポンシブ対応。
・モーダル展開時のスクロール不可
・画像モーダルのグループ化

が、デフォルトで実装されています。

### 充実したオプション・イベント

かなりの数があるので、使用頻度が多い物だけ紹介いたします。
https://github.com/humaan/Modaal#22-configuration-options

```
$('.fugafuga').modaal({
　// オプション

  // モーダルが表示、非表示されるまでに秒数設定
  animation_speed: 300,
　// overlayの色の設定 
  background: "#000"
　// overlayの透過量
  overlay_opacity: "0.8",
　// 開く前に発火
　before_open: function() {
　　alert('Before open');
　},
　// 閉じた後に発火
　after_close: function() {
　　alert('after close');
　}	
});

//特定の要素を閉じるボタンに設定
$('.piyopiyo').modaal('close');

```

## まとめ
簡単な実装でも細かい要件がある実装でも幅広く使えるプラグインです。
モーダル実装の機会があれば一度使ってみてください。
マイグレショーンファイルを作成する際のnull: false

今回はnull: falseオプションについてです。
このオプションはマイグレーションファイルにてカラムを追加する際によく使います。

役割としては、カラムに何もデータを入れなければエラーが出ますよ、というものです。


#今回出現したエラー

```Ruby:terminal

rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: Cannot add a NOT NULL column with default value NULL: ALTER TABLE "tasks" ADD "user_id" integer NOT NULL

```

今回、userテーブルとtaskテーブルを関連づけるために以下のマイグレーションファイルを作成しました。

関係としては、has_many :tasks、belongs_to :userという１対多の関係性です。

```php:xxxxxxxxxxxxxx_add_user_id_to_tasks.rb
class AddUserIdToTasks < ActiveRecord::Migration[5.2]
  def up
    add_reference :tasks, :user, null :false, index: true
  end

  def down
    remove_reference :tasks, :user, index: true
  end
end
```

として、Taskテーブルにuser_idという外部キーを設置しようとしました。
しかし、何度、マイグレーションファイルを実行してもエラーが出てしまう。

実は以前、同じエラーが出た時にカラムを追加するテーブルにnullなレコードがあったのが原因だったことがありまして、いったん"rails c"で"Task.delete_all"と念の為"User.delete_all"をしてみましたが、一向に改善する気配はありません。



#解決方法
解決方法としては、結論からいうと、null制約のオプションはカラム追加と別に行う、というものでした。

と言いますのも、エラー内容からもしかして、null: falseがなければ実行できるのでは、と思いやってみると、やはりできました。

これは、もしかするとMySQLの特性なのかもしれません（おそらくですが）。

そして、さらにマイグレーションファイルを追加しました。

```Ruby:xxxxxxxxxxxxxx_change_user_id_to_tasks.rb

class ChangeUserIdToTasks < ActiveRecord::Migration[5.2]
  def change
    change_column :tasks, :user_id, :integer, null: false
  end
end
```

これで、無事にuser_idにnull制約をつけることができました。

みなさまの参考になれば幸いです。
A-Frame におけるデスクトップ向けブラウザのクリックイベントの取り方

A-Frame ではいわゆるクリック(カーソルクリック)は目線を合わせてポチみたいな形式であり、普通に書くとデスクトップブラウザでマウスをクリックしても反応しません。なんとかできないかと調べたら公式ドキュメントに書いてました。

https://aframe.io/docs/0.9.0/components/cursor.html のこれ↓です。

>Where the intersection ray is cast from (i.e.,entity or mouse). rayOrigin: mouse is extremely useful for VR development on a mouse and keyboard.

動くやつ作ってみました→ https://jsfiddle.net/vmtgw07h/ (○でカーソルが表示されてますが、それと全く関係なくboxをマウスクリックすると色が変わります)

ソースコード↓

~~~
<script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script>
<script>
    AFRAME.registerComponent('cursor-listener', {
        init: function () {
            var lastIndex = -1;
            var COLORS = ['red', 'green', 'blue'];
            this.el.addEventListener('click', function (evt) {
                lastIndex = (lastIndex + 1) % COLORS.length;
                this.setAttribute('material', 'color', COLORS[lastIndex]);
                console.log('I was clicked at: ', evt.detail.intersection.point);
            });
        }
    });
</script>

<body>
    <a-scene>
        <a-entity camera look-controls>
                <a-entity cursor="rayOrigin: mouse"
                position="0 0 -1"
                geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
                material="color: black; shader: flat">
      </a-entity>
        </a-entity>
        <a-entity id="box" cursor-listener geometry="primitive: box" position="0 1 -5" material="color: blue"></a-entity>
    </a-scene>
</body>
~~~
SESの闇と向き合う - 多重構造の混乱を考察する -

『[今日からはじめる情報設計　センスメイキングするための7ステップ](https://www.amazon.co.jp/%E4%BB%8A%E6%97%A5%E3%81%8B%E3%82%89%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%83%85%E5%A0%B1%E8%A8%AD%E8%A8%88-%E3%82%BB%E3%83%B3%E3%82%B9%E3%83%A1%E3%82%A4%E3%82%AD%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E3%81%9F%E3%82%81%E3%81%AE7%E3%82%B9%E3%83%86%E3%83%83%E3%83%97-%E3%82%A2%E3%83%93%E3%83%BC%E3%83%BB%E3%82%B3%E3%83%90%E3%83%BC%E3%83%88/dp/4802510012/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=)』を参考にして、掲題の件を検証しようと思います。

自身がSESで仕事をしているので、そのことについて書きます。

参考：
　第一章：混乱を見極める

- 自分が直面していると思われる混乱は何か？
    - 仲介業者が２社入っているせいで現場のエンジニアが満足にサービスを顧客に提供できないという混乱。
        - 意思共有ができない。
        - 間に入る会社は、本質的に互いを敵だと思っているようにしか思えない。
        - これは自分の解釈。
- ユーザー
    - あなたのユーザーは誰か？
        - SESの発注元。BtoC向けサービスのB側。
    - 彼らについて何を知っているか？
        - 業態。チーム。案件内容。
        - 開発マネージャはリスクが見えすぎて逆にリスクが取れない。
        - プロジェクトマネージャは顧客が見えるがエンジニアリングについて知識がない。
    - どうすれば彼らをもっとよく知ることができるか？
        - 飲みにでも行こうかと思ったが、飲みの習慣がない。
        - 昼ご飯を一緒に食うかと思ったが、自分にその習慣がない。
        - 業界用語についての知識を深め、顧客と同じ用語を使えるようになった。
    - 彼らならこの混乱をどう説明するか？
        - 「現場のエンジニアを考慮しない不義理な営業」が原因だと思われている。
        - 実際にこう言われた。
- ステークホルダー
    - あなたのステークホルダーは誰か？
        - 顧客（発注元）、請負会社（受注先）、下請けA社、下請けB社、下請けC社（現場のエンジニア所属）。下図を参照
        - ![image.png](https://qiita-image-store.s3.amazonaws.com/0/34636/befe4ea5-1c04-c33b-f636-1852555f8993.png)
    - 彼らが期待していることは何か？
        - 顧客　　：　仕事の継続
        - 発注元　：　仕事の継続
        - 下請けA ：　仕事の離任。その後のことは不明。担当者の認識は不明
        - 下請けB ：　仕事の継続
        - 下請けC ：　仕事の継続
    - ステークホルダーはこの混乱をどう思っているか？
        - 乱暴に解釈すると、下請けAは面倒くさいと思っている。
        - 下請けのエンジニアがギャーギャー言ってきてるのがうざったいと思っているのではないか？
    - 彼らならこの混乱をどう説明するか？
        - 現場のエンジニアが騒いだせいで現場が混乱している。
        - ステークホルダーのうち、誰かを悪者にしてすべて責任を押し付けようとしている。
- 情報
    - あなたはどんな解釈を行っているのか？
        - 現場での仕事はきちんとしている自負があるので、顧客と請負会社との情報連携は合っているはず。B社はエージェントで、直接やりとりもしていて、顔が見える状態。
        - 請負会社とA社との間、A社とB社との間のやりとりが分からない。ここで何かしら解釈の違いが生まれているのではないか？
    - データやコンテンツが不足している状況で、どのような情報が生み出されるか？
        - A社が現場エンジニアを切りたいと思っている。
        - 理由は、ギャーギャー文句ばかり言うので面倒くさいから。
- 現在の状態
    - あなたが対処しようとしているのは、情報過多、情報不足、適切でない情報、あるいはこれらの組み合わせか？
        - 情報不足と適切でない情報、の組み合わせ。


二章以降も検証を続ける。
PyinstallerでFirestoreを使ったPythonスクリプトをEXE化する際のTips

PythonでFirestoreを使うスクリプトをWindowsのローカルで実行するように配布する必要があったので、Pyinstallerを利用しました。
少しハマったポイントがありいろいろと調べたのですが、日本語の情報が少なかったので残しておきます。

そもそも、PythonでFirestoreを使うのであればCloud Functionsを使うべきだと思いますが、事情がありどうしてもローカルで実行する必要がありました、、、

# 環境
- Windows10
- Python 3.6.8
- Anaconda 4.5.12
- Pyinstaller 3.4

# Pyinstaller

Pyinstallerのインストール〜実行までは以下の記事を参考にしました。

[Anaconda環境で作成したPythonプログラムをexe化した話。](https://qiita.com/shikasama/items/d0418fa4a604cfc00337)
[Pyinstaller でリソースを含めたexeを作成する](https://qiita.com/ELIXIR/items/48f276874367b2bc19bd)

# ハマったポイントと解決策
### EXE実行時エラー：Firestoreのライブラリが見つからない

【解決策】hook-google.cloud.pyにfirestoreライブラリを追記する
Python環境のLib\site-packages\PyInstaller\hooksディレクトリにある、hook-google.cloud.pyの末尾に以下記述を追加しました。


```text:hook-google.cloud.py
datas += copy_metadata('google-cloud-firestore')
```


### EXE実行時エラー：「Exception ignored in: 'grpc._cython.cygrpc.ssl_roots_override_callback'」

【解決策】 specファイルにroots.pemの情報を記載する
このときファイルパスをフルパスで指定する必要がありました。

```text:xxxxx.spec
a = Analysis(...
             datas=[
               ('\\path\\to\\dir\\roots.pem', 'grpc\\_cython\\_credentials\\'),
             ],
             ...
```
自分の経験ゼロからのプログラミング学習過程を振り返ってみる。

# はじめに

自分のプログラミング学習過程を振り返る機会があったので、ついでにQiitaに投稿しようと考えました。

ゼロからどうやって学んでいったかを書いているので未経験者にも役立つ話になっているかもしれません。

# なぜゼロから

現在ブイブイいわせているエンジニアさんも元を辿れば未経験でゼロから学びはじめた方です。
どんな方でもゼロの時期があったわけです。
というわけでイチからではなくゼロからどうやって学んだか記述するので、若干長ったらしく感じるかもしれません。

# 学習過程

自分はゼロから学ぶ際に、おおよそ以下の**3つのステップ**を意識して学習していました。

**プログラミング基礎(プログラミング言語)**
↓
**コンピューター基礎**
↓
**専門知識**

**ゼロから学ぶにはやはりなによりもまずはプログラムが書けるようになることが第一だと考え、初めにプログラミング言語を学ぶことになります。**
その後、専門的な知識をつけるための土台となるコンピューターの基礎を学び、最終的には専門的な知識をつけていくことになります。
とりあえず**ゴールは専門知識です。ここからは完全にアナタ次第**となるでしょう。

## プログラミング言語

私はC、Java、Pythonの3つの言語を最初の数ヶ月学びましたが、今となって振り返ると、***最初はPythonの学習のみでよかった***と思います。

他の言語は必要になってから学べば十分です。というのも、時代によって求められるプログラミング言語というのは変わっていくので、どの言語を学んでおいたほうがよいというのはあてにならないでしょう。

もちろんそれはPythonも例外ではありませんが、プログラミングの学習にしばしばPythonが推奨されていることを考えるとPythonのこの立ち位置はしばらく変わらないと考えられます。


おすすめの書籍は今だと、[Python言語によるプログラミングイントロダクション](www.amazon.co.jp/dp/4764905183)が良いと思います。
最初にPythonの基本的な文法などが説明されており、中盤から少し学術的な記述がされています。理系分野を専攻していた場合は十分読めると思いますが、難しいと思った部分は飛ばしてもよいでしょう。

学術的な関心はいいからPythonだけを学びたいという場合はオライリーの[入門Python3](www.amazon.co.jp/dp/4873117380)がおすすめです。
途中、ライブラリやフレームワークの列挙になりますが、飛ばしてもらって構いません。

## コンピューター基礎

プログラムがある程度書けるようになったら次は**アルゴリズム**や**ハードウェア**などのコンピューターの基礎的な知識を学びました。

時間に余裕があるならば、**OS**や**コンパイラ**、**ネットワーク**、**計算理論**などの知識もこの時点で学ぶとよいでしょう。

アルゴリズムのような基礎的な知識はあまり学ばれないこともありますが、次の専門的な知識を学ぶステップにおいて役に立つ事が多いので学ぶに越したことはありません。

勉強方法ですが、例えば私の場合は、

- 理論
    - [アルゴリズムイントロダクション](www.amazon.co.jp/dp/4764904063)
    - [コンピュータの構成と設計](www.amazon.co.jp/dp/B00UJ42A0K)
    - [マスタリングTCP/IP 入門編](www.amazon.co.jp/dp/B00MLUGZKG)
    - [コンピュータネットワーク](www.amazon.co.jp/dp/B076HJDZHQ)
- 演習
    - [アルゴリズムクイックリファレンス](www.amazon.co.jp/dp/4873117852)
    - [プログラミングコンテスト攻略のためのアルゴリズムとデータ構造](www.amazon.co.jp/dp/B00U5MVXZO)
    - [スクリプトエンジン プログラミング](www.amazon.co.jp/dp/4797347627)

のように書籍を分類して「理論を学んだら演習をする」もしくは「理論と演習を同時にやる」といったように学習していました。Amazonのレビューなどでどちらに属する書籍か判断して学習すると良いでしょう。

また正直に言うと、**この学習ステップは真面目にやっていたらかなりの時間がかかる**こと間違いないので、次のステップとある程度並行してやってしまったほうがよいかもしれません。かくいう私もある程度並行してやっていたところがあります。

情報処理試験だと基本情報技術者試験の内容がこのあたりに該当するのではないでしょうか。
応用情報技術者試験も割と当てはまりそうです。

## 専門知識

コンピューターの基礎的な知識を学び終えたら、自分がその道へ行きたい専門的な知識を身に着けることになります。
社会に出て働いているエンジニアはみんなこのステップにいると思います。

また、コンピューター基礎のステップで飛ばしてしまった項目はこの時点で学んでしまいましょう。

おすすめの書籍はオライリーシリーズです。実際の現場で役に立つ知識が学べます。
また、高度情報処理の資格もここで取れるなら取ったほうが後々役に立つでしょう。

# さいごに

これは私の一例ですが、みなさんはどのような学習過程を歩んできたのか少し気になるところです。
これを機にみなさん振り返ってみてどうだったか書いていただけると面白そうです。
[備忘録]DroneをGitHubと連携してSlackに結果を通知する

# githubにpushしたらCIを動かして結果をSlackで受け取りたい
Droneを使ってやってみるよ

# 前提
- Dockerインストール
- GitHubにリポジトリある
- Slackにincoming-webhookを追加

# 流れ
1. GitHubにpush
1. GitHubがWebHookでDroneマネージャーにhttpPOST通知
1. DroneマネージャーがDroneエージェントに通知
1. DroneエージェントがDockerに起動通知
1. Dockerがjob実行用コンテナを起動する
1. 終わったら結果をSlackで通知

# まずプロジェクトにDrone設定を追加
プロジェクトルートに `.drone.yml` を追加
notifyでGitHub連携設定する
こんなかんじ？

```
pipeline:
  build-frontend:
    image: makimatsun/node:8-chrome
    commands:
      - npm install
      - npm run build --prod
      - rm -rf /deploy/frontend
      - mv dist/* /deploy/
    volumes:
      - /tmp/makimatsun-drone:/deploy

  build-docker-frontend:
  (略)

  ansible:
  (略)

  code-analysis:
  (略)

  cleanup:
  (略)

  notify:
    image: plugins/slack
    webhook: https://hooks.slack.com/services/~~~~
    channel: dev-makimatsun
    icon_emoji: ':drone:'
    username: drone
    when:
      status: [success]

  notify-failure:
    image: plugins/slack
    webhook: https://hooks.slack.com/services/~~~~
    channel: dev-makimatsun
    icon_emoji: ':drone_failure:'
    username: drone
    when:
      status: [failure]

```

# Drone側の設定
`https://ci.xxxxxxx/account/repos`で対象のリポジトリをONにする
![image.png](https://qiita-image-store.s3.amazonaws.com/0/331389/5fec9226-40f6-958e-27e0-4595c0bffd78.png)

対象リポジトリのSettingで`Project Settings`の`Trusted`にチェックする
<img width="538" alt="スクリーンショット 2019-04-10 17.27.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/331389/3c7d39f5-ee51-53ec-0e26-799f3b364503.png">
【Unity】イベント登録の方法覚書

#概要
イベントを外部から登録する方法をよく忘れるのでメモ。

#イベントリスナをインスペクタから登録する方法

オブジェクトがクリックされた場合にリスナを実行するコードを例にする。

```C#:CurrentEventProvider.cs

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;

public class ReactionDetector : MonoBehaviour, IPointerClickHandler
{
	[SerializeField]
	private ClickEvent clickHandler;

	public void OnPointerClick(PointerEventData eventData)
	{
		this.clickHandler.Invoke(this.gameObject);
	}

	public void AddClickHandler(UnityAction<GameObject> _clickHandler)
	{
		this.clickHandler.AddListener(_clickHandler);
	}

	[System.Serializable]
	public class ClickEvent : UnityEvent<GameObject> { }
}
```

インスペクターは次のようになる。
![WS000070.JPG](https://qiita-image-store.s3.amazonaws.com/0/196069/c1d8b404-1998-2942-0bbb-7995ab6b0026.jpeg)

#イベントをスクリプトから登録するコード

SliderのonValueChangedイベントにイベントリスナを登録する。
※OnValueChangedイベントは引数を取ることに注意。

```C#
using UnityEngine;
using UnityEngine.EventSystems;

public class HogeController : MonoBehaviour
{
	public Slider bgmSlider;

    void Start() => AddListener();

    private void AddListener() => bgmSlider.onValueChanged.AddListener((value) => OnChangeBgmVolume(value));

    public void OnChangeBgmVolume(float value) => { /* 処理 */ }
}
Zoho Creatorのアプリ間でフォームをコピー作成する

# フォームをコピー作成する方法が見当たらない
**発端**

「とりあえず試しに使ってみて、問題無さそうなら実業務に組み込んでみよう」

試しアカウントでアプリを作成し、フォームビルダーでポチポチとフォームを作成。
実業務に近しいフォームを作ったり。

「よし、使えそうだね！じゃこのアカウントで実装お願い！」

じゃあお試しアカウントのアプリで作ったフォームを、本番アカウントのアプリにコピー…ってあれ？
フォームのコピーって出来ないｨ！？

という事態にぶち当たった。

# アプリ内でコピーする方法はあるが…
それなりに項目が多いフォームだったので、再度ポチポチ作っていくのは非常に面倒くさい…
というわけで、なんかよい方法は無いか探す。
苦手な英語と取っ組み合い、ドキュメントを読み込んでみるもそれっぽい物が見当たらない。
FAQにはそれっぽいものがあった。
https://help.zoho.com/portal/kb/articles/how-can-i-copy-duplicate-a-form-8-1-2019

なるほど！これでアプリ内でのフォームコピーが出来る！やったねたえちゃん！
ちがうんですよ。アプリ内じゃなくてアプリ間でフォームをコピーしたいんすよ。。
アプリそのものを複製することは出来るけど、フォームだけコピーできないかな…

# フォームを定義したスクリプトソース的な何某がある
ワークフローの組み込みでガリガリと記述していたDeluge。
勘でおそらく、フォームを定義しているDelugeソース的な何某がどこかにあるんじゃなかろうか…と踏む。
いやがりました、ここです。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/377342/672fabbc-c389-f982-c5d0-8757bf5f9e72.png)
![キャプチャ14.PNG](https://qiita-image-store.s3.amazonaws.com/0/377342/cbdf4ef4-ec88-5ba7-8ea2-8bf9f494813c.png)


# こいつをコピーすればいける…！
コピー先のアプリに空のフォームを作成。
自動生成されるレポートは、とりあえず消しておく。
![キャプチャ10.PNG](https://qiita-image-store.s3.amazonaws.com/0/377342/aece54bb-7d34-38b0-c725-7fbd3aad9a9f.png)
IDEを開くと、特に項目の定義がないソースが出来ている。
![キャプチャ11.PNG](https://qiita-image-store.s3.amazonaws.com/0/377342/c0dadd1d-0e70-6506-29ed-972f5ee59ddb.png)
コピー元の項目定義部分をごっそりとコピペし保存
![キャプチャ12.PNG](https://qiita-image-store.s3.amazonaws.com/0/377342/8eb829b4-38fc-a3c3-66e4-6fc8de56934e.png)
アプリケーションにアクセスしてみると…
![キャプチャ13.PNG](https://qiita-image-store.s3.amazonaws.com/0/377342/ad90d83e-feb9-61c3-c58d-df4d2650e280.png)
出来た！
これならアプリ間でのフォームは勿論、ユーザー間でコピーすることもできる！

# なんか他にも色々できそう
今回は単純なフォームのコピーでしたが
IDEのソースを見てみると、ワークフローの定義や配置されているボタンの表示文字列等…色々あります。
ビルダーで出来ない調整や設定も、ここを上手く弄れば色々出来そう。
というよりも、慣れたらフォームビルダーよりもこっちで作った方が良いかもしれませんね。

kintoneよりも結構融通が利く感じはします。
以上！
PythonでAzure Text to Speechで合成音声の作成

## なに？

以下の環境下で**Python(Jupyter)でAzure Text to Speechを使って合成音声の音声ファイルを作る**コードです。
Gistとかにでもあげればよいものですが誰かの役に立つかな？と自分のメモ含めQiitaにあげておきます。

- Jupyter notebook
- Python3
- Azure Text to Speechの東日本リージョン

> Azureの契約や設定方法は検索したらすぐに出てきます！リージョンの指定を 東日本 にしておくと下記コードがそのまま動きます

## さっそくコード

```python
text = '音声ファイルにしたい日本語文章を入れてください'
subscription_key = 'xxxxxxxxxx' # APIキーをいれてください

import requests
import xml.etree.ElementTree as ElementTree

fetch_token_url = 'https://japaneast.api.cognitive.microsoft.com/sts/v1.0/issuetoken'
headers = {
    'Ocp-Apim-Subscription-Key': subscription_key
}
response = requests.post(fetch_token_url, headers=headers)
access_token = str(response.text)
print(access_token)

constructed_url = 'https://japaneast.tts.speech.microsoft.com/cognitiveservices/v1'

headers = {
    'Authorization': 'Bearer ' + access_token,
    'Content-Type': 'application/ssml+xml',
    'X-Microsoft-OutputFormat': 'audio-16khz-128kbitrate-mono-mp3',
}

xml_body = ElementTree.Element('speak', version='1.0')
xml_body.set('{http://www.w3.org/XML/1998/namespace}lang', 'ja-JP')
voice = ElementTree.SubElement(xml_body, 'voice')
voice.set('{http://www.w3.org/XML/1998/namespace}lang', 'ja-JP')
voice.set('name', 'Microsoft Server Speech Text to Speech Voice (ja-JP, Ayumi, Apollo)')
prosody = ElementTree.SubElement(voice, 'prosody')
prosody.set('pitch','medium') # high
prosody.set('rate','medium') # fast
prosody.text = text
body = ElementTree.tostring(xml_body)

response = requests.post(constructed_url, headers=headers, data=body)
if response.status_code == 200:
    with open('sample.mp3', 'wb') as audio:
        audio.write(response.content)
        print("\nStatus code: " + str(response.status_code) + "\nYour TTS is ready for playback.\n")
else:
    print("\nStatus code: " + str(response.status_code) + "\nSomething went wrong. Check your subscription key and headers.\n")
```

基本的にはAzureサイト内にあるリファレンスと一緒ですが、Jupyter用に少し書き換えたのとリージョンを変えているくらいです。
上記のコードをJupyterのセルに入力して実行してくれれば`sample.mp3`という音声ファイルができあがります。

**＊注意点＊**

- 1行目の `text` の文章を変えてください。この文章を読み上げてくれます。
- 2行目の `subscription_key` にはAzure Portalから取得できる APIキー（１でも２でも） 入れてください。
- 終盤の `voice.set('name', 'Microsoft Server Speech Text to Speech Voice (ja-JP, Ayumi, Apollo)')` ここで読み上げの音声を指定しています。下記URL参考に変えていただくと男性の声にもできます。
https://docs.microsoft.com/bs-latn-ba/azure/cognitive-services/speech-service/language-support
- 同じく終盤の `prosody.set('rate','fast')` `prosody.set('pitch','medium')` などを変えていただくとゆっくりしゃべらせたりもできます。下記URLあたりをみると色々と設定がのっています。
https://docs.microsoft.com/bs-latn-ba/azure/cognitive-services/speech-service/speech-synthesis-markup 

音声系はいわゆる**SSML(Speech Synthesis Markup Language)**というスキーマですので色々調べるといろいろ出てきます。慣れておくとAmazon EchoんどVUIでも応用可能です。
Powershell備忘録

# logのtail(自動出力)をする

``` shell
Get-Content -Path “full path” -Tail “行数” -Wait
```
参考: [windowsでもリアルタイムでログ監視(tail -f)がしたい！](https://qiita.com/rache/items/7ebde61df17f193d79de)


# 特定のファイルのバージョンを確認する

``` powerShell
Get-Item filePath | Format-List
``` 

参考:[ファイルやディレクトリの表示 Get-Item、Get-ChildItem、Format-List](https://news.mynavi.jp/itsearch/article/hardware/3718)
Node.jsでコマンドライン上の対話型アプリケーション

Node.js v8.11で動作確認しました。

```JavaScript
const readline = require('readline');

const reader = readline.createInterface({
  input: process.stdin,  // 標準入力
  output: process.stdout // 標準出力
});

// Enterキー押下で読み込み
reader.on('line', line => {
  console.log(line);
  reader.prompt();
});

// ctrl+Cで終了
reader.on('close', () => {
  console.log("finish");
});

// コマンドプロンプトを表示
reader.prompt();
```
S3のアクセス制限について纏めてみる

#1.バケットポリシー#

*バケット単位で誰がアクセスできるかを制御する。*

例えば。バケットポリシーが何もない状態でアクセスしても、
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/18394a49-0b2c-fbfb-197e-d5992bff54d7.png)

勿論、アクセスできない。（AccessDenied）

```XML
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>F7D8AC35B037C93B</RequestId>
<HostId>
Vv44X6WjZKKZUMU4B+VJNY0cpvav4Fa9+oYxiHG/GUNZxjQ2wfo2/K++I4enksB7bsFDDkstYY8=
</HostId>
</Error>
```

[アクセス許可]-[バケットポリシー]より定義するとアクセス可能となる。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1554707441515",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::　/*"
        }
    ]
}
```


#2.IAMポリシー#

*IAMポリシーによって、S3を操作できるユーザーを制限する。*


#3.ACL#

*オブジェクト単位でアクセス制御する時に向いている。*

- バケットポリシーやIAMポリシーが優先される。
- 通常はバケットポリシーを使う。（AWS Black1 Belt より）


#4.パブリックアクセス設定#
参考：[S3で誤ったデータの公開を防ぐパブリックアクセス設定機能が追加されました](https://dev.classmethod.jp/cloud/aws/s3-block-public-access/)

誤ってバケット、オブジェクトを公開してしまうという危険性があります。
例えば、ACLで意図しないオブジェクトが公開状態になっているケースを考えたとします。
管理者は気づきづらい状態ですが、この設定を有効にしておくことで非公開にできます。

[アクセス制限]-[パブリックアクセス設定]から設定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/ce48d8ac-7be2-6317-d518-4670a0655311.png)

|パブリックアクセス設定|説明|
|---|---|
|新しいアクセスコントロールリスト (ACL) を介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする|パブリックなACL設定、オブジェクトのアップロードをさせない。|
|任意のアクセスコントロールリスト (ACL) を介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする|パブリックなACL設定をしていても、それを無力化する。|
|新しいパブリックバケットポリシーまたはアクセスポイントポリシーを介して付与されたバケットとオブジェクトへのパブリックアクセスをブロックする|パブリックなバケットポリシーの設定をさせない。|　
|任意のパブリックバケットポリシーまたはアクセスポイントポリシーを介したバケットとオブジェクトへのパブリックアクセスとクロスアカウントアクセスをブロックする|パブリックなアクセス設定をもつバケットに対して、パブリックなアクセス、クロスアカウントでのアクセスを無力化する。|

例えば、[新規のパブリックバケットポリシーをブロックする (推奨)]のチェックを外さないと、
「1.バケットポリシー」を設定しても以下のとおり、アクセス拒否となるので焦らないように。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280929/ca43c709-b27e-277b-ebdf-5063d262ff12.png)


#5.AWSアカウントレベルとIAMユーザーレベル#

|アクセスコントロールタイプ|	AWSアカウントレベルの制御|	IAMユーザレベルの制御|
|---|---|---|
|ACL	|○	|☓|
|バケットポリシー|	○|	○|
|IAMポリシー	|☓	|○|