OmniAICreator/Qiita-1.07M huggingface dataset:
AWS S3バケットへの権限を特定バケットのみに制限する

# S3FullAccesssを使用するのはどうなのか

IAMユーザーでS3へのポリシーをアタッチする際に
「AmazonS3FullAccess」という既存ポリシーを使用すれば
無条件でS３へアクセスできるのですが
どんなバケットにもアクセスできるってなんか不安、、、
というかせっかくIAMを使うのだから権限を狭めて利用したい。


# 参考リンク

AWS公式の
**[ポリシーでのアクセス許可の指定](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/using-with-s3-actions.html)**
ここに色々書いています。
リンク先が突然の英語だったりしてメンタルを削られてしまいます。

# 結論

下記のようにIAMポリシーを設定しました

```json
{
    "Version": "2012-10-17",
    "Id": "policy01",
    "Statement": [
        {
            "Sid": "Statement01",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::バケット名/*"
            ]
        }
    ]
}
```

基本的には公式ページに載っていたものを編集した形となります。
"s3:PutObject","s3:GetObject","s3:DeleteObject"の
３つでとりあえずは事足りる、、、はず
viewからcontrollerを呼び出し

Laravelをあつかっていると
単純にview側(blade)からControllerに戻れないかと思った。

自分の脳内イメージでは
route→Controller→view
の流れで、Controllerでデータを抜き出しviewで表示するイメージ

そのイメージで、view側からデータを取りなおせたらなと思うと、view側(blade)からControllerに戻れないかと言う話だ。


調べたところ
```@inject```というのが出てきた。

blade側での使い方は```@extends```の様に書くけれど、後ろに二つ書くところがある。
１つ目はブレード内の変数の名前
２つ目はメソッドのあるクラスの場所
（ディレクトリーは[.]ではなく[/]で書く、最後の.phpは書かなくていい）
下記の例では、App\Servicesの層にMetricsService.phpを作っている
@sectionの中で呼び出すときは
```{{１つ目に書いた変数->呼び出すメソッド()}}```
で上手くいった。


```blade.php
@extends('front.layout.base')
@inject('metrics','App\Services\MetricsService')
@section('content')
        monthly revenue: {{$metrics-> monthlyRevenue()}}.
@endsection
```

```App\Services\MetricsService.php
<?php
namespace App\Services;
class MetricsService
{
    public function monthlyRevenue()
    {
        return 'hello method';
    }
}
```

laravelの解説では「サービス注入」というそうです
React Native 入門してみた③  Httpアクセス編

[React Native 入門してみた②  画面遷移編 ]()につづいて今回はHttpアクセスについての入門です。

## Httpアクセス
APIから取得し表示する場合のサンプルを試して見ました。
Web開発となんら変わらず実装できました。(特に試さんでもよかったな...)
必要なければ飛ばして下さい。。。

Httpアクセスに人気の高い`axios`を使用します。
実際にHttpアクセスをしたいので、Mockサーバーに`json-server`を使用します。

| ライブラリ名 | バージョン | 備考 |
| -------- | --------|------|
| axios | 0.18.0 |   |
| json-server | 0.14.2 |   |

axiosについては下記記事を参考にして下さい。
- [ ] axiosの記事を添付
 
json-serverについては下記記事を参考にして下さい。
- [ ] json-severの記事を添付


## インストール
まずは、axiosとjson-serverのインストールをします

```
npm install axios json-server 
```

## 実装

### 構成

```
src
├── App.tsx
├── app.json
├── assets
├── babel.config.js
├── mock
      └── db.json
├── node_modules
├── package-lock.json
├── package.json
└── tsconfig.json
```
今回は、json-server用の`mock/db.json`をメインの`App.tsx`を追加・編集します。

#### モックの用意
`json-server`で使用する為のjsonを用意します

```
mkdir mock
touch db.json
```

db.jsonに追加します

```
{
  "movies": [
    {
      "id": 1,
      "name": "The Godfather",
      "director": "Francis Ford Coppola",
      "rating": 9.1
    },
    {
      "id": 2,
      "name": "Casablanca",
      "director": "Michael Curtiz",
      "rating": 8.8
    },
    {
      "id": 3,
      "name": "Inception",
      "director": "Christopher Nolan",
      "rating": 9
    }
  ]
}
```
`json-server --watch mock/db.json`でモックサーバーを起動できます。
`http://localhost:3000/movies`でmoveies一覧を取得できます。

#### 画面の実装
`App.tsx`を修正します
`http://localhost:3000/movies`にアクセスしてmovies一覧を取得し、画面に表示するサンプルを開発します

```App.tsx
import React from 'react';
...
import axios from 'axios';

type Movie = {
  id: number,
  name: string
}

type Props = {}

type State = {
  movies: Array<Movie>
}

export default class App extends React.Component<Props, State> {

  constructor(props: Props) {
    super(props)
    this.state = {
      movies: []
    }
    // Movie一覧取得
    axios.get("http://localhost:3000/movies").then((res) => {
      this.setState({ movies: res.data })
    });

  }

  // Movie一覧描画
  _rederMovies() {
    if (Object.keys(this.state.movies).length <= 0) {
      return null;
    }
    return (
      <View>
        {this.state.movies.map(movie =>
          <Text key={movie.id}>{movie.name}</Text>
        )}
      </View>
    );
  }

  render() {
    return (
      <View style={styles.container}>
        <Text>Movies</Text>
        {this._rederMovies()}
      </View>
    );
  }
}

...

```

#### サンプルコードの解説

```
...
  constructor(props: Props) {
    super(props)
    this.state = {
      movies: []
    }
    // Movie一覧取得
    axios.get("http://localhost:3000/movies").then((res) => {
      this.setState({ movies: res.data })
    });

  }
...  
```
movies一覧を取得するのに`constructor`で、`axios`を使用してmovies一覧を取得、stateに登録しています。
`render`は映画名を`<Text/>`で表示するだけの単純な描画です。
なんら問題なくaxiosで取得できました。

## Next 
続いては、[React Native 入門してみた④  カメラ実装編]()です。
Docker上で移植可能なアプリケーション開発

Docker上で開発環境を構築することで、
複数のマシンから環境を意識することなく
アプリケーション開発 + 移植が行えます。

今回は
Dockerコンテナ上で
Python + Django の開発環境を構築しました。

その環境でPythonサーバーを起動し、
ホストPCのブラウザからアクセスする方法を説明します。

**今回作成したDocke Image**
https://hub.docker.com/r/rimacdocker/django

# 実施したこと
以下の手順でDocker上でDjango開発用Webサーバーを起動しました。

1. [コンテナ上でDjango開発環境の構築](#1-コンテナ上でdjango開発環境の構築)
2. [Djangoでアプリケーション作成 + サーバー起動](#2-djangoでアプリケーション作成--サーバー起動)

# ホスト側の環境
MacOS 10.13.1
Docker 18.09.2

# 1. コンテナ上でDjango開発環境の構築
まず、Dockerコンテナ上でDjango開発環境を構築します。
詳細な手順は以下の通り。

1-1. OSイメージの取得、コンテナの起動
1-2. コンテナ上で必要なパッケージ、ライブラリのインストール

## 1-1. OSイメージの取得、コンテナの起動
今回はUbuntuの最新イメージを取得して、コンテナを起動します。

ホスト側8000番ポート:コンテナ側8000番ポート
をポートフォワーディングして起動します。

```
# Ubuntuイメージの取得、コンテナの起動
docker run -p 8000:8000 -it ubuntu
```

### 注意点: ポートフォワーディング
コンテナで起動したサーバーに、ホスト側からアクセスできるように
ホスト側の特定のポート番号と、コンテナ側の特定のポート番号を結んでおく必要があります。

## 1-2. 必要なパッケージ、ライブラリのインストール
Ubuntuイメージを基に、起動したコンテナ上で必要なパッケージ等をインストールします。
Djnagoでの開発に必要なパッケージ、ライブラリは以下の通り。

### インストールしたパッケージ
- Ubunutuパッケージ
  - vim
  - python3
  - python3-pip
 
- Pyhtonライブラリ
 - django

### コンテナ上で実行したコマンド
```
# パッケージマネージャの最新化
apt update
apt upgrade

# Python, Pipのインストール
apt install python3
apt install python3-pip --fix-missing

# Vimのインストール
apt install vim

# Djangoのインストール
pip3 install django
```

# 2. Djangoでアプリケーション作成 + サーバー起動
手順1でDjangoが使えるようになったので、
Djangoアプリケーションを作成して、開発用Webサーバーを起動します。
詳細な手順は以下の通り。

2-1. Dajngoアプリケーションの作成
2-2. 開発用Webサーバーの起動

## 2-1. Dajngoアプリケーションの作成
Djangoコマンドでアプリケーション作成します。

```
# 任意の作業用フォルダを作成 + 移動
mkdir django
cd django

# アプリケーションの作成
django-admin.py startproject dj_sample
```

## 2-2. 開発用Webサーバーの起動
同じくDjangoコマンドで
データベースマイグレーション + Webサーバーの起動を行います。

```
# 作成されるアプリケーションフォルダに移動
cd dj_sample/

# データベースマイグレーションの実行
python3 manage.py migrate 

# 開発用Webサーバーの起動
python3 manage.py runserver 0:8000
```

コマンドを実行するとサーバーが起動するので
ブラウザで`http://127.0.0.1:8000`にアクセスすると
Djangoのサンプルページが表示されます。

### 補足: データベースマイグレーション
Djangoで使うデータベースの定義を自動的に作成、管理する機能です。
この機能により、
直接SQL文を書かずに、データベースに変更を加えることが出来ます。

`python3 manage.py migrate`
上記のコマンドで、
Django内のデータベースの定義に従って、データベースに対するSQL文を発行します。

### 補足: runserver 0:8000
通常、Djangoでローカルマシン上に起動したサーバーを
外から見えるようにするには
IPアドレスを任意のポートに紐付ける必要があります。

今回はコンテナで立てたサーバーに
ローカルマシンからアクセス出来るように
全てのIP(0.0.0.0)を8000番ポートに紐付けています。

ここで紐付けるポートは
1-1. のポートフォワーディング設定で指定した
コンテナ側のポート番号と合わせる必要があります。

# 実行結果
コンテナ上でDjangoを起動して

```
root@86XXXXXXXXXX:~/django/dj_sample# python3 manage.py runserver 0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
June 03, 2019 - 19:10:40
Django version 2.2.1, using settings 'dj_sample.settings'
Starting development server at http://0:8000/
Quit the server with CONTROL-C.
```

ブラウザでhttp://127.0.0.1:8000 にアクセスすると、サンプルページが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/259302/4de8d258-6f83-9274-ee85-26326b64576a.png)

# まとめ
docker上でアプリケーション開発環境を構築することで、
OSやミドルウェアの異なる複数のPCから
同じ環境で開発を行うことが出来ます。

また、本番移行時にもDockerさえ入れれば
開発環境と同じ環境での
アプリケーション稼働を担保出来ます。

もしかすると
アプリケーション開発が捗るかもしれません。
SwiftUIをなる早で試す方法


# SwiftUI発表

WWDC2019の発表いろんなのがありましたね！
途中まではipadの内容に興味を持ってましたが、最後のSwiftUI...この発表で興奮がw
SwiftUIの詳細については[こちら](https://developer.apple.com/xcode/swiftui/)を参考にしてみてください！



# 準備

[Beta Software Downloads](https://developer.apple.com/download/#ios-restore-images-ipad-new)より以下二つをダウンロード

- macOS Catalina 10.15 beta
- Xcode 11 beta

<font color="Red">**Xcode11のcanvas機能を使う場合はmacOS10.15が必要なので忘れずに！**</font>
Twitter見る感じ割と多くの人が忘れがち！僕も忘れてました:sweat_smile:

>To preview and interact with views from the canvas in Xcode, ensure your Mac is running macOS 10.15 beta


# SwiftUI

[SwiftUI Tutorial](https://developer.apple.com/tutorials/swiftui/creating-and-combining-views)

[SwiftUI Document](https://developer.apple.com/documentation/swiftui)


DocumentのTopics>Essentialsに関連したTutorialが紐づいてるので
DocumentベースでTutorialを進めていくのが良さそう感

# Tutorial中の注意

一番最初のTutorialでXcode Projectを作成するところから始まりそのまま次へ次へと進めていくと
定義した覚えがない`ImageStore`が出てきたりします。

<img width="1242" alt="swiftUI_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/4397979f-38bd-9a5d-f9f2-d73d3cb7667d.png">

ここで詰まると抜け出すのが大変(ImageStoreを自分で作る？)なので
各TutorialのProject fileをダウンロードして進めていくのが良さそうです。

<img width="1222" alt="SwiftUI_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75593/b8a87914-ac38-d1bf-3c48-32037dfcbeec.png">

>Download the project files to begin building this project, and follow the steps below.

# その他参考になるまとめ(随時更新)

[GitHubSearchWithSwiftUI](https://github.com/marty-suzuki/GitHubSearchWithSwiftUI)
[SwiftUITodo](https://github.com/devxoul/SwiftUITodo)

[Github](https://github.com/search?l=Swift&q=SwiftUI&type=Repositories)
SwiftUIで検索した結果です。
暇なときに眺めて気になるRepositoryをのぞいて見る用
RailsアプリをHeroku Container Registryでデプロイした時の注意点

## Heroku Container Registryとは

Herokuで簡単にDockerコンテナを実行できるサービスです。

`heroku container:push`
というコマンドでDockerfileイメージをレジストリへビルド&プッシュ、そして
`heroku container:release`
コマンドでプッシュしたイメージを本番環境へ反映させます。

以前書いた **[自動テスト〜自動デプロイまでをDockerコンテナで実行する方法](https://qiita.com/daichi41/items/4b6b02666cf263177c1c)** 

では上手く行かなかったりしますのでメモを残しておきます
また上記記事ではdocker-composeを利用していますが
heorku containerではDockerfileしか使っていないぽいので
docker-composeは開発、テスト環境でのみの実行でした。


## Railsアプリのそのままデプロイすると実は上手く行かない

Dockerコンテナで動作するように作ったRailsアプリをそのまま
container:push、container:releaseしても上手く動作しなかったりします。
いくつか要因があります。


## 原因１： development環境で動作している

実はRAILS_ENVが空になっていてdevelopment環境で動作していたりします。
普通にRailsアプリをherokuへプッシュすると自動的に環境変数を設定してくれているので
意識することは無いので見落としていたりします。
RAILS_ENV=productionで環境変数をセットしましょう。
heroku config:setでセットするのが一番簡単だと思います。
(heroku configをコンテナ内へ渡してくれています）

## 原因２： master.keyをセットしていない

原因１を解決すると今度はこちらの問題が浮上します。
RailsアプリではCookieの改ざん防止にsecret_key_baseという値を使用していますが
こちらはdevelopment, およびtest環境ではこの値が無くても勝手にいい感じに動作してくれます。
ですがproduction環境ではこの値が必要になります。
こちらもcontainerでは無い方のherokuへのデプロイでは自動的に設定してくれますので見落としている可能性があります。

また、Rails5.2以降ではsecret_key_baseはcredentialsファイルのなかに格納されており
これを開くためにmaster.keyの値が必要です。
これはgit管理から外されていると思いますので環境変数RAILS_MASTER_KEYとしてセットしておきましょう。


<br>
<br>

上記２つで本番環境で無事コンテナが動作しました。
初心者らしくherokuでデプロイしていたのですが知識不足が露呈してしまっているので
勉強も兼ねてEC2などを経験してみる方が良さそうですね。
Excel VBAコース第9回内容

全12回 Excel VBAコースの第9回の内容です。

#オブジェクト
オブジェクトとはブックやシート、セルなどVBAから操作可能な「もの」のことです。
オブジェクトにはプロパティとメソッドと呼ばれるものが備わっています。

プロパティ：オブジェクトの情報を取得・設定する
メソッド：オブジェクトに命令を与える

```
'オブジェクト.プロパティの例
Cells(1,1).Value

'オブジェクト.メソッドの例
Cells(1,1).Clear
```

カタカナが分かりにくい人は、「もの．属性」「もの．操作」というイメージで覚えてください。

#コレクション
複数のオブジェクトの集合体をコレクションと呼びます。 
コレクションにもプロパティとメソッドが備わっています。 
コレクションは頂点をApplicationオブジェクトとする階層構造になっています。


【コレクションの階層構造】
　　Application 
　　　　　┗ Workbooks
　　　　　　　　┗ Worksheets
　　　　　　　　　　　┗ Cells
　　　　　　　　　　　┗ Range
　　　　　　　　　　　┗ Shapes
　　　　　　　　┗ Charts



#別のシートから値を取得／別のシートに値を入力する方法
今までセルの値を入力する際に「Cells」や「Range」で書き始めていましたが、
実は、「どのシートのセルなのか」の部分を省略して書いていました。
（省略した場合は、アクティブなシートと暗黙に認識される）

シートを指定したい場合は、Cells等の前にワークシートを記載してあげます。

```
'インデックス(何番目のシートか)を指定する書き方
Worksheets(1).Cells(1,1).Value = "テスト1"

'シート名を指定する書き方
Worksheets("Sheet1").Cells(2,1).Value = "テスト2"
```

上記の方法だと、毎回シートを指定しなければならず、コードが見にくくなるので、
下記のように変数にオブジェクトを指定する方法もあります。

```
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
ws.Cells(3,1).Value = "テスト3"
```

#シートの追加／削除
Worksheetオブジェクトのプロパティやメソッドを使用して、色々な操作ができます。

```
'シートを追加して、シート名を変更する
Worksheets.Add
ActiveSheet.Name = "追加シート"

'シートを削除する
Worksheets("追加シート").Delete
```
window containerで日本語(ja-JP)を使う方法

# windows containerの中でどうしても日本語が使いたい場合
## Set-WinSystemLocale ja-JPしても動かない
windows containerの中で

``` powershell:powershell
Set-WinSystemLocale ja-JP
```
しても変更されません
ホストマシンが

``` powershell:powershell
 Get-WinSystemLocale
```

でja-JPであればそれをそのまま引き継げます
docker runするときにオプションをつけるだけ

``` powershell:powershell
docker run --isolation=process --name test
```

プロセス分離のオプションです。
コンテナの中に入ってみてGet-WinSystemLocaleしてみてください。

##　宣伝
ツイッターもやってます
技術や製品開発に関する事などを呟いてますので、フォローお願いします
https://twitter.com/wkyIghw8MlLpyJE
【Unity(C#)】Meshをぶっ壊す方法

##ぶっ壊すとは？
[こちらのサイト](https://qiita.com/divideby_zero/items/eef7604e306300fd7833)を参考にさせて頂きました。

リンク先ではムニャムニャという表現が使われていますが、今回の私の用途は、
**・爆発した後**
**・燃えた後**
**・風化してボロボロになった後**
なのでぶっ壊すという表現を使っています。

##デモ
今回協力していただくアセットはこれです。→[リンク](https://assetstore.unity.com/packages/3d/props/furniture/gray-furniture-pack-40580)

せっかくきれいに作ってあるのにすみませんぶっ壊します。

早速ですが、こちらです。
![MeshBreak.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/3e4494fb-ded0-343a-b08e-665b96582180.gif)

ぶっ壊れました。
近くで見ると機械的でバグのようにも見え、使いものにならない感じが目立ちますが
少し離れるだけで かなりぶっ壊れた感じが出ます。

##コード
とてもシンプルです。
全ての頂点を取得した後、適当なポジションを追加して再度頂点をセットしているだけです。
パラメータをInspector上でいじればぶっ壊れ具合をいい感じに調整できます。

```C#:変形させたいオブジェクトにアタッチ
using System.Collections.Generic;
using UnityEngine;

public class BreakMesh : MonoBehaviour
{
    [SerializeField]
    float breakValue = 0.1f;

    void Start()
    {
        List<Vector3> vertextList = new List<Vector3>();

        MeshFilter myMesh = this.gameObject.GetComponent<MeshFilter>();

        Vector3[] vertPos = myMesh.mesh.vertices;

        for (int i = 0; i < vertPos.Length; i++)
        {
            vertextList.Add(vertPos[i]);
            vertextList[i] += new Vector3(Random.Range(-breakValue, breakValue), Random.Range(-breakValue, breakValue), 0);
        }

        myMesh.mesh.SetVertices(vertextList);
    }
}
```

##Batching
BatchingというUnityの負荷軽減機能でMeshをまとめて読み込むことができます。
PlayerSettingsからBatching機能のオンオフができます。
![baching.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/e32198d5-26cf-fa40-1af4-5ab9473060fb.png)


StaticBatchingがオンになっている状態で家具をStaticにすると
画像のように文字通りMeshがCombineされました。
![Batching.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/d5b0a63c-2b93-cd6e-fb3e-4d15f9f8c377.png)

この状態で先程のぶっ壊しを実行すると怒られるので
私はぶっ壊したいオブジェクトのStaticをオフにしました。

Batchingが発動する条件については私はまだ曖昧なのでこれから勉強しようと思ってます。
Exception の HResult プロパティのアクセス修飾子について

仕事で .Net Framework 4.0 を触る機会があり、その時に例外の HResult によって処理を切り替える必要があったがアクセスができなかったので理由を調べた。
忘備録として記録をしておく。

## Exception の HResult のアクセス修飾子

Exception の HResult プロパティは .Net Framework のバージョンによってアクセス修飾子が異なる。
.Net Framework 4.5 より前では以下のようにな定義になっている。

```C#
namespace System
{
    public class Exception : ISerializable, _Exception
    {
        // 略

        protected int HResult { get; set; }

        // 略
    }
}
```

そのため HResult には直接アクセスすることができない。

.Net Framework 4.5 以降では以下のような定義に変更されている。

```C#
namespace System
{
    public class Exception : ISerializable, _Exception
    {
        // 略

        public int HResult { get; protected set; }

        // 略
    }
}
```

setter のみ protected になっているため例外のエラーコードに HResult プロパティから直接アクセスが可能になった。

## .Net Framework 4.5 より前のバージョンでライブラリ等を作るときの HResult へのアクセス方法
HResult にアクセスする場合は次のようにリフレクションを使用する。

```C#
try
{
    // 例外発生
}
catch(Exception ex)
{
    var propertyInfo = ex.GetType()
        .GetProperty("HResult",
            System.Reflection.BindingFlags.Instance 
            | System.Reflection.BindingFlags.GetProperty
            | System.Reflection.BindingFlags.NonPublic 
            // この Project のターゲットが .Net Framework 4.5　より前であっても 
            // .Net Framework 4.5 以上のアセンブリが参照される可能性があるので Public を指定しておく
            | System.Reflection.BindingFlags.Public 
        );
    
    var hResult = (int)propertyInfo.GetValue(ex,null);
}

```

ただし、もしライブラリとして作成をする場合は .Net Framework 4.5 以上のプロジェクトから呼ばれる可能性もあるのでコメントのように `System.Reflection.BindingFlags.Public` を指定する。

サンプルコードを[ここ](https://github.com/uttne/Exception.HResult.Sample)に上げておく。


### 参考
* [Exception.HResult Property](https://docs.microsoft.com/ja-jp/dotnet/api/system.exception.hresult?view=netframework-4.8#%E6%B3%A8%E9%87%88)
とあるRailsエンジニアのリモートワークトライアル 2019-06-03 on Twitter

# とあるRailsエンジニアのリモートワークトライアル 2019-06-02 on Twitter
 [*](https://twitter.com/YumaInaura/status/1135201648488439818")
<https://github.com/YumaInaura/YumaInaura/issues/2127>
# とあるRailsエンジニアのリモートワークトライアル 2019-06-02 on Twitter [ポエム] on @Qiita
 [*](https://twitter.com/YumaInaura/status/1135216098180157440")
<https://qiita.com/YumaInaura/items/12782085879c2339793c>
# 僕は世界で一番愚かなプログラマかもしれない。

 [*](https://twitter.com/YumaInaura/status/1135353084970799104")

# 今日はもう当日に乗れる深夜バスの電話受付時間が終わっていてでもセンターならこの時間でも受付可能らしいのでいざ来てみたらあと2時間後が受付開始だからといって途方に暮れるわけではなくどこかカフェに入って仕事するぞ。

 [*](https://twitter.com/YumaInaura/status/1135458947266039809")
![image](https://pbs.twimg.com/media/D8H149XV4AEyXKS.jpg)




# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2136








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
asyncioを用いた２重平行化について


# はじめに

非同期処理を走らせるためにasyncioというモジュールがある。ここでは、その2重平行化の方法について述べる。２重平行化とは、複数個のタスクを平行処理しようとした時に、各タスク内の処理を展開して平行に処理したい場合である。例えば、5個のメインタスクがあり、各メインタスクは3個のサブタスクを持ち、計15個のサブタスクを処理したい場合を考える。この場合に、15個のサブタスクを完全に平行化したい、というのが今回の趣旨である。スクレイピングなんかで便利だと思う。初めて使ったけど、これで合ってるかな？？？

# 通常の平行処理

メインタスクを４つ用意し、各タスクは5, 3, 12, 2秒ずつスリープすることとする。コードは以下となる。当然、12秒したら結果が返ってくる。

```python
import asyncio

async def sleep(s):
    for _ in range(s):
        await asyncio.sleep(1)
    return s

if __name__ == '__main__':
    loop = asyncio.get_event_loop()

    tasks = [sleep(5), sleep(3), sleep(12), sleep(2)]
    futures = asyncio.gather(*tasks)

    loop.run_until_complete(futures)
    ret = futures.result()
    print(ret)

    loop.close()
```

# 2重平行処理

先の5, 3, 12, 2秒を、1秒ずつに分解し、22個のサブタスクを平行で実行してみる。このケースでは、`sleep`関数内でサブタスクを作成し、`yield from`でタスクの集合を返す。それが終了したら、各結果をマージ（ここでは`sum`）して返す。

```python
import asyncio

async def sleep_local():
    await asyncio.sleep(1)
    return 1

def sleep(s):
    subtasks = [sleep_local() for _ in range(s)]
    futures = asyncio.gather(*subtasks)
    yield from futures

    ret = futures.result()
    return sum(ret)

if __name__ == '__main__':
    loop = asyncio.get_event_loop()

    tasks = [sleep(5), sleep(3), sleep(12), sleep(2)]
    futures = asyncio.gather(*tasks)
    loop.run_until_complete(futures)
    ret = futures.result()

    print(ret)

    loop.close()
```
制約は完璧なはずなのに・・・実行するとコンソールに警告が表示されるとき

xcodeで見たときには何も問題ないのに、

何故か実行すると制約が競合してるよと、警告が表示されることがあります。

----
私の場合はこういうときに経験しました。

- stackViewの子供につけた制約 vs stackViewが実行時に子供に勝手につけてくれる制約

stackviewは子供の大きさをいい感じに調整してくれますが、私がつけた制約とぶつかる場合があります

- UICollectionViewViewCellの大きさが一瞬(width:0, height: 0)になったときの問題

こちらは端末によって起きたり、起きなかったりしました。

セルのサイズがまさかの0,0のときがあり、セルサイズ0,0は想定してない制約をつけていたので警告が表示されました。

----

実行時に想定外のことが起きたときの対策として、競合してしまう制約のpriorityを999に設定してあげます。

`制約の警告もう少し親切にしてほしい・・・`
【postgreSQL】psqlでのログイン


備忘録として残します。

普段mysqlなので忘れちゃいますね。

#■やり方

オプションは大文字小文字しっかりと区別するので、下記の通りにすること。


##DB指定してログイン

```shell
#psql -U <ロール名（ユーザ名）> -d <DB名>
psql -U postgres -d testdb
```



##普通にログインしてからＤＢを指定
```shell
#ログインだけ
#psql -U <ロール名（ユーザ名）>
psql -U postgres
```

```shell
#ログイン後にDB指定
#\c <DB名>   mysqlで言うところの USE DB名
\c testdb
```
Delegateを複数に通知する

Delegateを複数オブジェクトに通知（配信）します。
完全に全自動でとは行かないため、コード記述量を出来るだけ少なくする使い回しの効く部品を作ってみます。

## delegate

以下のprotocolの呼び出し複数箇所で受け取ります。

```Output.swift
protocol Output {
    func didFinish(error: Error?)
}

class UseCase {
    let output: Output
    init(output: Output) {
        self.output = output
    }
}
```

## 複数に通知する

このままでは1箇所でしか受け取れません。

`OutputPublisher`を定義しUseCaseからの呼び出しを`OutputPubliser`で一度受け取ります。
そして`OutputPubliser`が複数箇所に通知するようにします。（`Publisher` については後述）

```OutputPublisher.swift
class OutputPublisher: Publisher<Output> {}

extension OutputPublisher: Output {
    func finish(error: Error?) {
        publish { $0.finish(error: error) }
    }
}
```

```swift
let outputPublisher = OutputPublisher()
let useCase = UseCase(output: outputPublisher)
```

## 通知を受け取る

```Something.swift
class Something {
    var subscriver: AnyObject?

    init() {
        subscriver = outputPublisher.addSubscriber(self)
    }
}

extension Something: Output {
    func finish(error: Error?) {
        print(error)
    }
}
```

通知を受け取りたいオブジェクトで`addSubscriber(_:)`します。
戻り値は必ず保持してください。

通知を受け取るのを止めるにはsubscriverをnilにします。
明示的に止める必要がない場合`Something`が消える時にsubscriverも消え、通知が自動で止まります。

## Publisher

複数のSubscriber（Delegateを受け取るオブジェクト）を登録する機能です。
オブジェクトの登録と解除を行うだけですが、循環参照を回避したりするために少し面倒なことになっています。

* NSMapTable  
Subscriberをweakで保持する。
* Disposer  
Disposerが消える時に登録解除を行う。
* Box  
weakで保持できるのはAnyObjectのみ。  
SubscriberがAnyObjectでない場合もNSMapTableに格納するため、Boxに包むようにする。

```Publisher.swift
public class Publisher<Subscriber> {

    private class Disposer {
        private let disposing: () -> Void

        fileprivate init(disposing: @escaping () -> Void) {
            self.disposing = disposing
        }

        deinit {
            disposing()
        }
    }

    private class Box {
        fileprivate var content: Subscriber
        fileprivate init(_ content: Subscriber) {
            self.content = content
        }
    }

    private var subscribers_: NSMapTable<AnyObject, Box> = .strongToWeakObjects()
    private var subscribers: [Subscriber] {
        return subscribers_.dictionaryRepresentation().map { $0.value.content }
    }

    public init() {}

    public func addSubscriber(_ subscriber: Subscriber) -> AnyObject {
        let subscriberKey = UUID().uuidString as NSString
        let box = Box(subscriber)
        subscribers_.setObject(box, forKey: subscriberKey)
        let disposable = Disposer { [weak self, box] in
            _ = box // NSMapTableにweakで参照されるだけだとBoxがすぐ消えるため、Disposerでキャプチャする
            self?.removeSubscriber(subscriberKey)
        }
        return disposable
    }

    private func removeSubscriber(_ subscriberKey: AnyObject) {
        subscribers_.removeObject(forKey: subscriberKey)
    }

    public func publish(_ handler: (Subscriber) -> Void) {
        subscribers.forEach(handler)
    }

}
```

## 補足その1

Delegate用のプロパティはweakで定義されていることがよくあります。
Publisherを生成しweakのdelegateにそのまま設定すると、いきなりPublisherが消えます😇
そのためどこかでPublisherを保持し続ける必要があります。

## 補足その2

Disposer生成時、上記サンプルではself(Publisher)をweakでキャプチャしています。
このselfを普通にキャプチャすると、PuplisherはSubscriberの登録があれば残り続け、登録がなくなると消えるようになります。
Publisherの参照をnilにしても残り続けてよければ、そのように変更します。
MySQLのセッション数を監視する

セッション数を監視します。シェルスクリプトで実装します。

**バージョンの確認**

```sql
> select version();
+-----------------+
| version()       |
+-----------------+
| 10.1.40-MariaDB |
+-----------------+
```


**セッション数の上限を確認**

```sql
> show variables like "max_connections";
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+
```

**現在利用しているセッション数確認**

```
> select count(*) from information_schema.processlist;
+----------+
| count(*) |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)
```

**監視用のシェル作成**

```sh:test.sh
#! /usr/bin/bash
RESULT=`mysql -uroot -pkusakari -s -N < test.sql`
if [ $RESULT -ge $1 ]; then
  echo "FATAL"
else
  echo "NORMAL"
fi
```

**インプット用ファイル**

```sql:test.sql
select count(*) from information_schema.processlist;
```

**実行するコマンド**

```
$ ./test.sh 1
FATAL
$ ./test.sh 0
FATAL
$ ./test.sh 2
NORMAL
```

以上、よろしくお願いいたします
Bootstrap

Bootstapを学ぶので、そののーと

##### よくわかんない単語集
- UIコンポーネント
- コンポーネント

#BootStrap
- フロントエンド開発を効率よく行うためのフロントエンドフレームワーク
- レスポンシブレザインに対応のWebサイトのレイアウトを、簡単にすばやく出来る。
- よく使うレイアウトやUIコンポーネントが用意されていて、簡単に使うことができる
- HTML, CSS, JavaScriptで制作されている。

## 何故BootStrapを使うのか？
- 開発スピード
    - UIコンポーネントを使うことで素早くアイデアを形にできる。
- コスト削減
    - プロのデザイナーをアサインしなくても一定以上のクオリティを担保できる。

## メリット・デメリット
### メリット
- 素早くアイデアを形にできる。
- 素早くアプリケーション全体を構築できる。
- ２カラム、３カラムのページをCSSを書かなくても、HTMLでクラスを指定するだけで出来る。

### デメリット
- 似たようなデザインになりがち。

### 便利系
[公式いろいろ乗ってる](https://getbootstrap.com/docs/4.3/getting-started/introduction/)
[非公式一覧](https://hackerthemes.com/bootstrap-cheatsheet/)


#書いていくよ！！
- BootStrapを使う方法
1. BootStrapのファイルをダウンロードして使う方法
2. CDN(Contents delivery Network)を使って読み込む方法

BootStrapを使うには、、、。
1. CSSの読み込み
2. JSの読み込み
・・・が必要。

##ビューポート
ブラウザのウインドウの表示領域を設定する。
imgタグの下に隙間ができる

#imgタグの下に隙間ができる問題の解決方法
margin, padding共にゼロを指定しているのになぜか隙間ができていた。調べていたらどうやらフォントのベースラインから下端にかけて含まれるスペースのせいとのこと。

####HTML
~~~html
<div class="top">
     <img src="./iamges/sample" height=100px>
</div>
~~~

imgの高さが100pxなのになぜかdiv.topの高さが少しだけ100pxより大きくなってしまう。下記のように指定したら治った。
####CSS
~~~CSS
.top > img {
    vertical-align: top;
}
「Railsは終わった」は初心者に不利益を与えうる可能性がある理由

## 「Railsは終わった」は初心者に不利益を与えうる可能性がある理由
Googleで"Rails"と検索すると「Railsは終わった」という趣旨の記事が上位に表示されます。

<img width="627" alt="Screen Shot 2019-06-03 at 23.49.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250231/6149edea-f62d-76e6-2419-5e2b56cce40f.png">

僕が懸念しているのはRailsを学ぼうとしている初心者の方が不安にならないか、ということです。
Web開発ができるようになりたい初心者にとってはRuby on Railsから学習を始めるのは最善でしょう。日本語の情報も教材も多ので学習効率が高いです。

そもそも同じ技術がずっと使われること自体ありえません。Web開発の根本はあまり変わらないので、まずはRailsを学習してそれを学びましょう。Railsが古くなったら乗り換えれば良いのです。差分の学習は短い時間で済みますからね。
Railsを学習している方、学習しようとしている方は迷わず進んでください〜！

## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
DNSのTXTレコードの設定が上手くいっているか確認する方法


以下のコマンドで調べられます。

```
nslookup -q=txt example.com
```

使用例

```
$ nslookup -q=txt google.com

google.com      text = "v=spf1 include:_spf.google.com ~all"
google.com      text = "globalsign-smime-...."
```
同じものを含む円順列　その４

# 同じものを含む円順列　その４
最後に一般化して，どんな場合でもパッと確認できるように，コード化します。

### 一般化
友田 勝久さんがまとめているものを参考にしました。
http://www.osaka-kyoiku.ac.jp/~tomodak/report/junretsu2012.pdf

$S_1,\,S_2,\,\cdots,\,S_m$の$m$種類の球がそれぞれ$n_1,\,n_2,\,\cdots,\, n_m$個の球が作る円順列の総数を $f(n_1,\,\cdots,\,n_m)$と表すと，

$$f(n_1,\,\cdots,\,n_m)=\frac1N\sum_{k|l}\phi(k)\frac{\left(\frac{N}k\right)!}{\left(\frac{n_1}k\right)!\left(\frac{n_2}k\right)!\cdots\left(\frac{n_m}k\right)!}$$

- $l=GCM(n_1,\,\cdots,\,n_m)$，$N=n_1+n_2+\cdots+n_m$です。
- $\sum_{k|l}$は$l$の正の約数である$k$で和をとります。
- $\phi(k)$はオイラー(Euler)の関数で， $k$以下で$k$と互いに素な自然数の個数を返します。


### コード化
Jupiter notebookでWolfram Engineが使えるようになったので，Mathematicaで作ってみます。数学関数がたくさんあるので，パッとできそうです。

```
f[a_]:=1/(Total[a]) Sum[EulerPhi[k] Multinomial@@(a/k),{k,Divisors@(GCD@@a)}]
```
`a`はリストです。このように関数を定義すると，前回までに紹介した同じものを含む円順列は次のように求められます。

```
f[{4,4}]
f[{4,6}]
f[{2,3,4}]
f[{3,3,3}]
```

こんな感じに次々と求めることができます！

<img width="1436" alt="スクリーンショット 2019-06-03 23.17.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426542/61beceb7-653d-bce0-9736-0272eddbe1d9.png">

これで，生徒からどんな同じものを含む円順列の質問がきても大丈夫です！
パーソナルユース版・Insta360OneXの動画を使ったフォトグラメトリ

[先日紹介したフォトグラメトリの方法][1]は各々の専用ソフトを使用していました。
1. EQ動画を静止画連番に変換・Adobe Premiere Pro・約2500円/月
2. EQ画像を平面画像に変換・PTGui Pro・約5万円
3. 平面画像を3次元再構成・Reality Capture・約4000円/月

今回は、パーソナルユース版のソフトを使う方法を検討しました。
1. EQ動画を平面の静止画連番に変換・Unity
2. 平面画像を3次元再構成・Meshroom
3. 寸法の校正・Blender

残念ながら、結果的にはMeshroomの3次元再構成が想定通りに完了できませんでしたが、行った手順を紹介します。

####1. EQ動画を平面の静止画連番に変換・Unity
360動画を再生しつつ、所定の向きをカメラで撮影し、Unity Recorderで記録しました。
Projectは[こちら][2]を参考にしました。
![190603s1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/12316f58-5aba-9924-ff08-114d16c958d2.png)

フレームレートを固定にするなど工夫したものの、フレーム落ちが発生しましたが、約3000フレームのうち、約1000フレームを記録できました。

####2. 平面画像を3次元再構成・Meshroom
画像ファイルを左側の枠内にドラッグアンドドロップしてSTARTを押すだけで、SfMが実施されます。
![190531s1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/f3b151ef-bfc3-0964-88e0-3756d843f66a.png)

ご覧の通り、ノードエディターが示されており、カメラの内部パラメータ解析、特徴点抽出、イメージマッチングなど、各段階の処理が可視化されています。

残念ながら、今回の検討では全部の向きの画像がレジストレーションに含まれず、通りの右と左がまとまった形で再構成できませんでした。
試行錯誤の多くは、Depth Mapのノードでエラーが発生してジョブが停止しました。[同様な問題はほかの人も起きているようです][3]。
![190531s5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/e7575884-99dd-ef64-26bb-b244eee223f0.png)

ただ、アプリ全体はフリーズせずに、ノードの処理だけが止まるだけなのはありがたいです。

Reality Captureと比べると、試した範囲では、特徴点を手動で入力する機能や寸法の校正機能が見当たらないのが残念です。

モデルはobj形式でした。
![190531s3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/3992a883-1b26-5c37-75c3-6c0825ecf9b7.png)


####3. 寸法の校正・Blender
モデルを読み込んで並べなおし、道幅が5mになるよう寸法を校正しました。

不要な部分の削除に伴ってテクスチャの照合間違いが起きたり、まだまだ改善が必要です。
![190531s4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/c31a3955-8a6a-3c58-971d-d3ec8d396223.png)

####まとめ
パーソナルユースのアプリを使って、Insta360OneXの動画からフォトグラメトリを試みました。
Meshroomはもう少し使い込んでみると、面白そうな気がします。

Reality Captureは非常に良いアプリですが、サブスクリプション特有の将来的な不安があり、
個人的には、何らかの代案を確保しておきたいです。

6/3は「測量の日」ですので、フォトグラメトリ（写真測量）も測定精度を上げていきたいです。

[1]:https://qiita.com/nakmura/items/a043a8213f1c0b379d0c
[2]:https://mono-pro.net/archives/6139
[3]:https://github.com/alicevision/meshroom/issues/409
Windows環境下で，コマンドプロンプトから terraform コマンドが打てるようになるまで

# Windows 環境で terraform コマンドが使えるようになるまで
Windows のコマンドプロンプトから terraform コマンドが打てるようになるまでの手順について整理しました．


# Contents
- [作業環境](#作業環境)
- [terraformのダウンロード](#terraformのダウンロード)
- [環境変数の設定](#環境変数の設定)
- [とりあえずコマンドを打つための対応](#とりあえずコマンドを打つための対応)
- [参照サイト](#参照サイト)


## 作業環境
- OS: Windows 10


## terraformのダウンロード
[terraform の公式サイト](https://www.terraform.io/downloads.html)から， terraform をダウンロードできます．
ダウンロードしたファイルは zip ファイルとなっているので，展開して **terraform.exe** を取得してください．

## 環境変数の設定
次に **PATH** を設定します．
*Windows での PATH について，詳細は[こちら](https://qiita.com/sta/items/63e1048025d1830d12fd)を参照してください．

展開した **terraform.exe** を terraform フォルダに保存し，そのフォルダにパスを通せば，
 terraform コマンドが打てるようになります．

```sh
mkdir C:\User\USER\terraform
copy C:\User\USER\Downloads\terraform.exe C:\User\USER\terraform
SETX /M PATH “%PATH%;c:\User\USER\terraform”
```

PATH が正常に通ったかどうかは，以下のコマンドを実行して確認してください．
任意のディレクトリで実行し， terraform コマンドの詳細が表示されれば， PATH の設定は成功です．

```sh
terraform help
```

## とりあえずコマンドを打つための対応
Windows の pathが正常に通らない場合について，
試行錯誤する中で見つけた とりあえずの対応策 を紹介します．

### とりあえずの対応策
- terraform コマンドを実行したいディレクトリに， **terraform.exe** をコピーする


terraform.exe をコピーすれば，PATH を設定せずとも terraform コマンドが打てるようになります．

## 参照サイト
- [Terraform](https://www.terraform.io/)
- [Terrarorm for さくらのクラウド](https://sacloud.github.io/terraform-provider-sakuracloud/)
やっぱりNが好き

*♪は〜て〜し〜な〜く〜* ：オープニングテーマ(**DAVID By 矢野顕子**)

## 掘りごたつでお茶を入れ、せんべいを頬張るかや乃。やや離れて黙々とノートPCを操作するきみえ。

きみえ「おねえちゃん、やっぱりわかんないよ！」
PCの操作を投げ出し、倒れ込んでしまうきみえ。

かや乃「それくらいわかんないでどうするのよ。」

IT技術者としてそれなりに長く仕事をしているがレガシー対応ばっかりで枯れて行ってしまう自分のスキルに磨きをかけたいきみえが、かや乃に謎の特訓を受けていた。

きみえ「だいたい今時、**C++でBTree**勉強してどうなるって言うの？！」

かや乃「あんたねぇ、基本よ基本。今時のシステムは全部、BTreeで動いてんだから。」
きみえ「だって、見たことないんだも〜ん！！」

かや乃「それにね、Javaばっかりやってないでその上に行きたかったらC++を勉強しなさい！」
きみえ「私はもっとユーザーに近いところのシステムがやりたいの〜」

玄関の扉が開く。
レイ子「ただいま〜！」

レイ子が帰ってきてかや乃の特訓が中断されるので嬉しいきみえ。飛び起きて玄関に向かって声をかける。
きみえ「どうしたの？！」

## 上機嫌にほろ酔いで帰ってくるレイ子。

レイ子「ちょぉっとパーティーの帰りでさぁ〜♪」

憮然とした顔でお茶をすするかや乃。
かや乃「だからここはあんたの家じゃないんだから」
レイ子「わかってるって〜！ほーらおねーちゃんにお土産、もらってきたんだよっ♪」

かや乃「なによ？」
レイ子「さっき知り合った社長さんと仲良くなっちゃってさ〜。よくわからないんだけど、これもらったの」
カバンから怪しい茶封筒を取り出し、かや乃に渡す。

かや乃「なにこれ？」
レイ子「なんか、vine linuxっていうの？私、ワイン苦手なんだけどって言ったんだけど、**99年モノのヴィンテージ**のフロッピーだからって無理やり渡されたのよ〜」

かや乃「ウソっ！？」
レイ子「なんていうか、私も罪な女っていうか〜？なんだか意気投合されちゃって〜」

かや乃「ちょっと私、見てくる！」
茶封筒を抱きしめて自室に行こうとするかや乃をなだめてレイ子は語り出す。

レイ子「ちょっと、ちょっと待ってよ、おねーちゃん。今日の話を聞いて、まず聞いてよ〜」
かや乃「えぇ〜なによ。あんたの話は聞いてもしょうがないからこっちを確かめたいのよ」
立ち上がろうとしたところをレイ子に袖を引っ張られて無理やり座らされてしまうかや乃。

レイ子「今日はちょぉっと内輪だけのプレスパーティーがあったんだけど〜」
かや乃「プレス向けだったら内輪じゃないじゃない。何言ってんのよ？」

レイ子「とにかく〜知り合いの社長から誘いがあって新しいビジネスモデルの発表会に顔だしてきたのよ〜」
きみえ「れいちゃん、大丈夫なの？また変なのに引っかかってんじゃないの〜？」

レイ子「きみちゃんじゃないんだから〜変な男には引っかかったりしませんから〜」
きみえ「うるっさいね〜！ふんだ！」
きみえはPCに再び向かって作業を始める。

レイ子「とにかく、今日は日本の、いや世界の農業に革命を起こすトークンビジネスで、志を共にする世界を本気で変えたい同志を集うパーティーに行ってきたってわけよ」
かや乃「あんたねぇ、十分怪しいわよ。」

レイ子「いや、これは本物なんだってば。ブロックチェーンでDNAの交配記録を」
かや乃「はいはい、わかったから。もうね、あんたそう言うのに出資するのやめなさいよ？」

レイ子「本当にこれで最後だから！いや、これはもう当たるからね！そしたらここに来るのももう最後になっちゃうかもな〜。ごめんね、おねーちゃん♪」
かや乃「もういいわよ、はいはい、わかったから。私はね、さっさとこの封筒の中身確認してくるから。」
かや乃はメゾネットの自室へ封筒を持って急ぎ足で向かう。

## かや乃を横目に見つつ、きみえにささやくレイ子

レイ子「きみちゃん、あんたさ、ちょっと投資しない？」
きみえ「れいちゃんやめてよ。こないだも変なカエルの転売に失敗したばっかりじゃない。あれの埋め合わせどうしてくれんのよ？」

レイ子「あはは〜！あんなの本気で在庫抱えたのびっくりしたわよ！ああ言うのはちょっとずつやるんだから」
きみえ「絶対、需要があるって行ったのれいちゃんじゃん！」
レイ子「需要があるのは当たりでしょ！あんな大量のカエル在庫がはけただけでもよかったと思いなさいよ！だからさ、次は在庫のいらない投資、しよ？」
きみえ「今回はなんなのよ？も〜そういうのやめてよ〜。」
レイ子「今回は農業に革命起こすんだから、カエルの転売とはスケールが違うのよ！」
きみえ「革命ってさ、なんなの？なんの交配記録を残すの？」
レイ子「**ひよこ♪**」
困惑顔でリアクションができないきみえ。しばらく固まってから再びPCに向かう。

レイ子「きみちゃん、ここで毎月1万でも2万でも貯金のつもりでさ、積み立てのつもりでさ？来年には毎月ハワイ行けるかもよ〜？」
PCの手が止まるきみえ。

きみえ「毎月、ハワイ？！」
レイ子「そうだよ〜？毎月、ワイハーでルービーだよ？！」

きみえ「・・・マジで〜？！ワイハーでルービー？！」
満面の笑みのきみえ。

## かや乃「ギャーーー！！！！」

きみえ「何？！」
レイ子「まさか！」
はっと顔を見合わせるきみえとレイ子。

叫びながら階段から降りて来るかや乃
かや乃「フロッピー起動したらハードディスクのフォーマットが勝手に始まったじゃない！！」

レイ子はダッシュで玄関に向かいながら叫ぶ。
レイ子「今時、起動できるフロッピードライブ持ってる方がおかしいのよ！！」

玄関を出たところでレイ子を捕まえて叫ぶかや乃。
かや乃「アキバの中古屋でおととし見つけたフロッピードライブがやっと使えると思ったのにこんちきしょぉぉぉぉ！！！！」
レイ子「ギャァァァァ！！！おねえちゃんそこは！やめぇぇ！！！」

きみえ「わいは〜♪わいは〜♪」
鼻歌を歌いながらPCをいじるきみえ。

きみえ「あ、UT通った。」

*サントワマミ〜♪* ：エンディングテーマ(**サン・トワ・マミー By RCサクセション**)

## あとがき

恩田三姉妹に会いたくて衝動的に書き始めました、が・・・@Yametaro 先生のようにうまいこと(?)プログラムがらみの話が入れられませんでした。先生、すごい。
今回のレイ子とパーティー編、中身が薄いなぁ。。。次回はもうちょっと濃い内容にできるように頑張ります。(ぉ)
IT系の技術トレンドを調べるのに使えるサービス

「ライブラリAとBではどっちが人気あるんだろう？」
とか
「今はどの開発言語が流行ってるんだろう？」
とか
「[先生助けてっ！、10年前までStackOverflowで質問されていたVbScriptが息していないの！！](https://qiita.com/mima_ita/items/b9df72f7e30a614b9920)」
という時に使える、ライブラリや言語などのIT系技術トレンドをチャートで表示するサービスを調べました。(+自作サービス [QiiTrend](https://qiitrend.herokuapp.com/)の宣伝)


# 条件

- 人気の遷移がわかること。つまりトレンドチャートが表示できるもの。
- 過去のある時点のトレンドを調べたブログ記事などではなく、現在の最新情報を使ったサービスであること。
- 複数の対象を比較できること。


# 目的別索引

### とりあえずざっくりトレンドを調べたい

- [Google トレンド](#google-トレンド)

### 開発言語のトレンドを調べたい

- [Github Language Stats](#github-language-stats)
- [QiiTrend](#qiitrend)
- [Stack Overflow Trends](#stack-overflow-trends)
- [Tag Trends](#tag-trends)

### 日本国内での技術トレンドを調べたい

- [QiiTrend](#qiitrend)
- [Google トレンド](#google-トレンド)

### オープンソースの人気の推移を調べたい

- [GitTrends.io](#gittrendsio)

### JavaScriptのトレンドを調べたい

- [npm trends](#npm-trends)



# Qiita のデータを使うもの

## QiiTrend
https://qiitrend.herokuapp.com/

<img width="888" alt="スクリーンショット 2019-06-03 22.26.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35192/09bf0dc8-c2ad-fa34-1fa1-431d0ac51dd8.png">

- 任意の検索条件でQiitaの記事件数をトレンド表示する
- [QiitaトレンドをリニューアルしてQiiTrendを作った](https://qiita.com/tag1216/items/e65496b932ca6790268b)
- [QiiTrendを使ったチャートの例](https://qiita.com/tag1216/items/ae2f197b211213410602)

# Google トレンド
https://trends.google.co.jp/

<img width="888" alt="スクリーンショット 2019-06-03 22.28.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35192/8664bc6a-c3eb-762a-089d-b9801a872130.png">

- 指定のキーワードがGoogleでどれくらい検索されているかをトレンド表示する
- 国や地域でフィルターできる
- 関連キーワードがわかる
- 技術情報限定ではないので[無関係な分野のボリュームが入ることがあるので注意が必要](https://qiita.com/taai/items/bdcdb96513c93f7ba5a6#comment-cd882731bc5423c164b2)

# Github のデータを使うもの

## Github Language Stats
https://madnight.github.io/githut/

<img width="888" alt="スクリーンショット 2019-06-03 22.30.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35192/1d05122e-b202-e9a3-0e2e-90dbfc1f99b6.png">

- 人気上位言語のトレンドを表示する
- 表示するチャートは以下の情報を切り替えることができる
    - Pull Requests
    - Pushes
    - Stars
    - Issues


## GitTrends.io
http://gittrends.io/

<img width="1177" alt="スクリーンショット 2019-06-03 22.31.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35192/abf00c5d-20b4-4b0d-c12b-203cc756b63e.png">


- リポジトリ毎のStar数をチャート表示する
- 複数リポジトリの比較はできない


# Stackoverflow のデータを使うもの

## Stack Overflow Trends
https://insights.stackoverflow.com/trends

<img width="1133" alt="スクリーンショット 2019-06-03 22.32.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35192/1d327d4a-b140-2f06-220c-d5c14e2b3463.png">

- 質問に付けられたタグ毎のトレンドを表示
- 複数のタグを比較できる


## Tag Trends
http://sotagtrends.com/

<img width="1133" alt="スクリーンショット 2019-06-03 22.33.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35192/122ee37c-f8b5-c1d0-0a48-9ac827ee0de6.png">

- 質問に付けられたタグ毎のトレンドを表示
- 複数のタグを比較できる
- 質問件数と全体に対する割合を表示できる

# npm のデータを使うもの


## npm trends
https://www.npmtrends.com/

<img width="1133" alt="スクリーンショット 2019-06-03 22.34.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35192/5d874acb-a07a-ffcd-135f-f29f310d9b5e.png">

- パッケージ毎のダウンロード数をトレンド表示する
UINavigationController タイトルが切れる対策

タイトルで yやtの文字が切れてしまう対策

```swift

self.navigationController?.navigationBar.titleTextAttributes = [
            NSAttributedString.Key.foregroundColor: UIColor.black,
            NSAttributedString.Key.font: UIFont(resource: R.font.hiraKakuProNW6, size: 15.0)!,
            NSAttributedString.Key.baselineOffset: 1
]
```

baselineOffsetでタイトルを少しずらす。
ラベルを貼り付ける手もあり。
競プロで入力どう受け取ればいいの (Python3編)

## これはなに

ついこないだ，競プロに初参戦してみました．
とりあえず腕試しということで，事前知識ほぼ皆無で挑んでみたのですが，入力が受け取れないのなんの．
僕がPythonどちゃくそ初心者というのもありますが，ついさっき[supercell](https://qiita.com/undermountainaf)に色々教えてもらったので，忘れないようにメモっとこうと思います．
~~要するに備忘録~~

## パターンと解法

こんなタイトルの参考書，中学生くらいのときにあったな...

### 数値1つだけを受け取る

まずは1番シンプルなパターンから．
数値`N`が与えられたとします．

```python
N = input()
```
簡単ですね！

### 2つの数値を受け取る

2つの数値`N, M`が`N M`の形式で与えられるとします．
この場合，僕は

```python
i = input().split()
N = int(i[0])
M = int(i[1])
```
みたいな感じでやってました．キモいです．
こういうときは`map()`を使えば解決します．

```python
N, M = map(int, input().split())
```
たったこれだけ！

### 複数の数値を1行で受け取る

$a_0, a_1, a_2, ..., a_n$ という数列が

```
a_0 a_1 a_2 ... a_n
```
というような形式で与えられるとします．
先ほどは受け取る個数がわかっていたので`map()`を使って対応できましたが，今度はいくつの数値を受けとるかわかりません．
こんなときは`list()`を使いましょう！

```python
a = list(map(int, input().split()))
# a[k]にはa_kが入っています
```
簡単！

### 複数の数値を1列で受け取る

$a_0, a_1, a_2, ..., a_{N-1}$ というN個の数値からなる数列が

```
N
a_0
a_1
a_2
.
.
.
a_(N-1)
```
という形式で与えられるとします．
僕の場合，いままではfor文を愚直に回して入力を受け取っていました．
ただ，内包表記を使ったほうが多少速いです．~~Python自体遅いので誤差程度って言ってた．~~

```python
N = int(input())
a = [int(input()) for _ in range(N)]
# a[k]にはa_kが入っています
```
めちゃシンプル！

これらを組み合わせることで様々な入力パターンに対応することができます！

## まとめ

本質ではないところで多少消耗したのでまじつらたん．
アクティビティのライフサイクル Kotlin

# アクティビティのライフサイクル

#### 忘れてしまう人用です

### onCreate(Bundle?)

アクティビティが最初に起動された時に呼ばれる。
レイアウトの作成や、
最初に1回だけ実行される初期処理などがここで行われる。

###onStart()

アクティビティが表示される直前に呼ばれる
ライフサイクルの中で何回も呼ばれる可能性がある

###onRestoreInstanceState(Bundle?)

onSaveInstanceState() メソッドで保存しておいた情報を使って画面の状態を復元するために呼ばれる

必ずは呼ばれない。

なんらかの事情でこのアクティビティを最初期化する場合にのみ呼ばれる。

onCreate()でもonSaveInstanceStateで保存された情報が渡されるので、
必ずもここで復元する必要はない。

###onResume()

アクティビティがユーザーの操作を受け付ける直前に呼ばれる。
例えば、カメラにアクセスを開始したり、
退避しておいたデータを復元する際にしようする。

###onPause()
アクティビティがバックグランドになる直前に呼ばれる。
onResume()と一緒に使われることが多く、
カメラやハードウェアへのアクセスや、
大きなリソースを解放する時に使われる。

アクティビティAからアクティビティBを呼び出す場合、
アクティビティAのonPause()が完了するまでは、
アクティビティBの作成は始まらない。

そのため、onPause()で長時間かかる処理を書かないほうがいい。

###onSaveInstanceState(Bundle?)

アクティビティの状態に関する情報を保存しておくために呼ばれる
必ずは呼ばれない

###onStop()
アクティビティがユーザーから見えなくなった時に呼ばれる。

###onRestart()
onStop()のあと再びアクティビティが再び表示される場合に呼ばれる。

###onDestroy()
アクティビティが破棄される直前に呼ばれる。
kernelsharkの起動方法

#1 kernelsharkとは?
trace-cmdのGUIフロントエンドツールです。
trace-cmdで採取したデータをグラフィカルに表示することができます。
trace-cmdは、[ここ(trace-cmdコマンドの使い方)](https://qiita.com/hana_shin/items/359240688a53c849593b)を参照してください。

本当は、CentOS7でkernelsharkを起動したかったのですが、下記理由で断念しました。
・rpmパッケージがみつからない。
・tar.gzファイルをダウンロード、解凍、makeしたが、コンパイルエラーがとれない。
・gitのソースをmakeしたが、これもコンパイルエラーがとれない。
そこで、CentOS7で採取したtrace-cmdのデータをubuntuのkernelsharkで表示してみました。

なお、公式ページは以下のようです。
まだ、正式版はリリースされていないようです。
http://kernelshark.org/

#2 環境
kernelsharkを実行する環境は以下のとおりです。

```console:カーネル版数
root@server:~# cat /etc/os-release
NAME="Ubuntu"
VERSION="16.04 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
UBUNTU_CODENAME=xenial

root@server:~# uname -r
4.4.0-127-generic
```

#3 事前準備 

##3.1 Xサーバのインストール
kernelsharkが出力するGUIをPCで表示するため、PCにXサーバをインストールする必要があります。
PCへのXサーバのインストール方法は、[ここ(Xクライアント、サーバの動かし方)](https://qiita.com/hana_shin/items/4ccf9d53aecd290d2cbb)を参照してください。
 
##3.2 kernelsharkのインストール
次に、kernelsharkをインストールします。

```
root@server:~# apt-get install kernelshark
root@server:~# kernelshark -v
kernelshark - 0.2.
```

#4 テスト用データ採取(CentOS7で実施)
trace-cmdを使って、テスト用データを採取します。
ここでは、デフォルトGWに対してpingを1回実行して、データを採取しました。


```console:データの採取
[root@server ~]# trace-cmd record -p function_graph -F ping -c 1 192.168.3.1
```

```console:データの確認
[root@server ~]# ls -l trace.dat
-rw-r--r-- 1 root root 6336512  6月  3 22:40 trace.dat
```

CentOSで採取したデータをubuntu(192.168.3.100)に転送します。

```cosnole:データ転送
[root@server ~]# scp trace.dat root@192.168.3.100:/root
```

#5 kernelsharkの起動(ubuntuで実施)

kernelsharkを実行します。
このとき、採取したデータのファイル名を引数に指定します。

```
root@server:~# kernelshark trace.dat
```

kernelsharkを実行すると、以下のような画面が表示されます。
pingコマンドを実行すると、inet_sendmsg関数が呼ばれていることがわかります。
![kernelshark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146813/0c5fa3ed-6d7c-b2ab-dc58-feae8bebc464.png)

なお、`<Task>`列のところが`<...>`となっています。
ubuntuで採取したデータをubuntuで参照すると`ping`と表示されたのですが、
今回は、CentOSで採取したデータをubuntuで表示させたためか、
`<Task>`にコマンド名が表示されませんでした。

#Z 参考情報
[公式ページ](http://kernelshark.org/)
CircleCIとDeployGateで自動化を少し進めてみる

アプリをリリースして、アップデートするたびに手順が多くてめんどくさいと思い、自動化について調べてみて、少しやってみた備忘録です。

####使用ツール

CircleCIとDeployGateを使いました。
流れとしては、githubにソースコードをプッシュもしくはマージされると、ビルドとテストを実行し、問題なければDeployGateで最新の状態のアプリがダウンロード可能になるというものです。

####ツールを使えるようにする

CircleCIとDeployGateをインストールします。
手順は割愛しますが、両方とも無理プランで登録しました。
CircleCIは無料プランだと1コンテナまでなので、必要に応じてプランを上げる必要があるかもしれません。

####ymlの作成
ymlファイルを作成して、DeployGateに上げるまでの手順を記載します。

#####①aliasの作成
場合によっては同じ手順が存在するかと思いますので、呼び出せるようにまとめます。
ymlでは`&name`で名前をつけて`*name`で参照することができる

```ruby:config.yml
aliases:
  android_docker: &android_docker
    docker:
      - image: circleci/android:api-27
        environment:
          TZ: Asia/Tokyo
  steps:
    - restore_cache: &restore_cache
        key: &jars_key jars-{{ checksum "build.gradle" }}-{{ checksum "app/build.gradle" }}
    - run: &download_deps
        name: Download dependencies
        command: sudo chmod +x ./gradlew
    - save_cache: &save_cache
        paths:
          - ~/.gradle
        key: *jars_key
    - run: &build_debug_apk
        name: Build debug APK
        command: ./gradlew assembleDebug
    - run: &test
        name: test
        command: ./gradlew test
    - run: &upload_to_deploy_gate
        name: Upload to DeployGate 
        command: |
          APK_PATH=app/build/outputs/apk/debug/app-debug.apk
          curl -F "file=@app/build/outputs/apk/debug/app-debug.apk" -F "token=${DEPLOY_GATE_API_KEY}" -F "message=Build by CircleCI" (DeployGateのURL)
```
`aliases:`でバージョン指定、`steps:`でのちに行う手順をまとめています。ビルドやデプロイのコマンド等をまとめています。

#####②ワークフローの作成
次に、ビルドしてからDeployGateにアップロードするまでのワークフローを記載します。

```ruby:config.yml
version: 2
jobs:
  build:
    <<: *android_docker
    steps:
      - checkout
      - restore_cache: *restore_cache
      - run: *download_deps
      - save_cache: *save_cache
      - run: *build_debug_apk
  test:
    <<: *android_docker
    steps:
      - checkout
      - restore_cache: *restore_cache
      - run: *download_deps
      - save_cache: *save_cache
      - run: *test
  deploy:
    <<: *android_docker
    steps:
      - checkout
      - restore_cache: *restore_cache
      - run: *download_deps
      - save_cache: *save_cache
      - run: *build_debug_apk
      - run: *upload_to_deploy_gate

workflows:
  version: 2
  build_and_deploy:
    jobs:
      - build
      - test
      - deploy:
          requires:
            - build
            - test
          filters:
            branches:
              only: master
          context: (DeployGateで設定した値)
```

`workflows:`が実行する順序で、Jobsが何をするかの記載です。
今回の場合だと、Githubからチェックアウトし、ビルドとテストを実行し、問題なければDeployGateに上げるという流れにしています。
`workflows:`では実行するための条件を少し加えています。
`requires:`で必要条件を設定しています。
ビルドとテストが成功しないと先に進まないようにしました。
そして、`only:master`でマスターブランチに変更が入った場合のみ実行するようにしています。
最後のcontextはDeployGateで設定するもので、設定したcontextで①で使った`${DEPLOY_GATE_API_KEY}`を設定しています。

簡単に記載しましたが、ドキュメントが詳しいので、ある程度のことは載っていると思います。
また、DeployGateに自動的に更新されたアプリが表示されたときは自動化っていいなあと思いました。
リリースするまでに多くの手順が存在するため、少しでも簡略化できるなら使ったほうがいいなあと思いました。

####参照
[プログラマーのための YAML 入門 (初級編)](https://magazine.rubyist.net/articles/0009/0009-YAML.html)
[CircleCIのドキュメント](https://circleci.com/docs/ja/)
Rails の環境変数の設定方法


Rails 用の環境変数の設定方法について備忘録を含めまとめたいと思います。

今回は環境変数を簡単に扱える Gem である dotenv-rails を使用いたします。

Gemfileにdotenv-railsを追加する。

```:gemfile
gem 'dotenv-rails'
```


```:ターミナル
$ bundle install
```

dotenv-rails を導入すると、.env ファイル内に設定された環境変数を Rails 起動時に、自動読み込みします。

環境変数を設定するために、.env ファイルを新規作成、Gemfile と同じ階層に設置してください。
その後.envファイルに環境変数を記述してください。

```:.env
HEROKU_ID=hoge
HEROKU_PASS=hoge
```

```:hoge.rb
ID = ENV['HEROKU_ID']
PASS = ENV['HEROKU_PASS']
```

また.envに定義されている情報を不正利用されないように、Git の管理から外す必要があります。
そのため、.gitignoreに下記のように記載してください。

```
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
#
# If you find yourself ignoring temporary files generated by your text editor
# or operating system, you probably want to add a global ignore instead:
#   git config --global core.excludesfile '~/.gitignore_global'

# Ignore bundler config.
/.bundle

# Ignore all logfiles and tempfiles.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore Byebug command history file.

.env
```

既にgitにpushしてしまっている場合下記のコマンドで.envをgitの管理から外してください。

` git rm --cached .env`

以上となります。
ご参考になれば幸いです。
仮想環境に「Google Chrome」をインストールして、Railsのテスト実行時のエラーを解決

## はじめに

Ruby on Railsの書籍【[現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/gp/product/4839962227/ref=as_li_qf_asin_il_tl?ie=UTF8&tag=ykms1230e-22&creative=1211&linkCode=as2&creativeASIN=4839962227&linkId=f1654768da91963177a6c0b9a30852e3)】でテスト環境を構築中に下記のようなエラーが発生

```bash
$ bundle exec rspec spec/system/tasks_spec.rb

2019-06-03 17:21:24 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.
Capybara starting Puma...
* Version 3.12.1 , codename: Llamas in Pajamas
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:33289
F

Failures:

  1) タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
     Got 0 failures and 2 other errors:

     1.1) Failure/Error: visit login_path

          Selenium::WebDriver::Error::WebDriverError:
            unable to connect to chromedriver 127.0.0.1:9515



          # ./spec/system/tasks_spec.rb:15:in `block (4 levels) in <top (required)>'

     1.2) Failure/Error: raise Error::WebDriverError, cannot_connect_error_text

          Selenium::WebDriver::Error::WebDriverError:
            unable to connect to chromedriver 127.0.0.1:9515


        ...(省略)...


Finished in 40.99 seconds (files took 1.56 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/system/tasks_spec.rb:21 # タスク管理機能 一覧表示機能 ユーザーAがログインしているとき ユーザーAが作成したタスクが表示される
```

## 環境

Vagrantで仮想環境を構築
Ubuntu VERSION="18.04.1 LTS (Bionic Beaver)"

Rails (5.2.1)
Ruby (2.5.1)
Selenium-webdriver (3.141)
capybara (3.12.0)
rspec-rails (3.8.1)
chromedriver-helper (2.1.0)

## 原因

仮想環境下にGoogle Chromeがインストールされていなかったので、chromedriver-helperがうまく動いてくれなかった。

## 仮想マシンにGoogle Chromeを追加する

**1. Google Chromeのリポジトリを追加**

```bash
$ sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'
```

**2. ダウンロード**

```bash
$ sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
```

**3. パッケージリストをアップデートし、chromeをインストール**

```bash
$ sudo apt update && sudo apt install google-chrome-stable
```

**4. 再度実行**

```bash
$ bundle exec rspec spec/system/tasks_spec.rb

2019-06-03 17:55:54 WARN Selenium [DEPRECATION] Selenium::WebDriver::Chrome#driver_path= is deprecated. Use Selenium::WebDriver::Chrome::Service#driver_path= instead.
Capybara starting Puma...
* Version 3.12.1 , codename: Llamas in Pajamas
* Min threads: 0, max threads: 4
* Listening on tcp://127.0.0.1:37449
...

Finished in 2.97 seconds (files took 2.23 seconds to load)
2 examples, 0 failures
```

これで解決！！
ansibleについて調べてみた

## はじめに
現在エンジニアバイトをしているところでansibleを触る機会がありましたので、思考の整理として記事にしようと思います。ただし**この記事はあくまで「ansibleって何？」程度**のものなので実際の書き方とかはありません。

## ansibleって何？
ansibleとはサーバーの構成管理ツールである。わかりにくいので簡単に言うとサーバー構築を自動化してくれるツールです。

#### ちょっと詳しく書いてく
従来手動でサーバーの設定をかき、環境を立ち上げてきました。しかしこれだと人為的なミスが発生したり、複数のサーバーを構築しようとすると時間がかかったり、サーバーが同一の設定になっていない、設定に変更が起きたとき全てのサーバーに対して変更を加えようとすると時間と手間がかかってしまう問題がありました。そこでサーバー構築の手順をYAML形式でコード化し、実行することで環境を自動で構築してくれるのがAnsibleです。

#### Ansibleで幸せになれること
・サーバーの環境がコードで表し、可視化できるためサーバーの環境がコードを見ればわかり、管理がしやすい。
・環境をコードで管理しているため本番環境、ステージング環境などが全て同じ状態の環境で用意することができる。
・手順書のコード(playbook)さえ作っておけば複数のサーバーに環境を簡単に構築することができる。
・変更に対して手順書のコードさえ書き換えれば容易に変更することができる。
・CIと連携することでデプロイまで自動化することができる。
・手動で環境を構築するわけではないので、ミスが減る。

#### Ansibleの特徴
・YAML形式で記述しているためシンプルに書くことができる。このYAML形式で書かれたコードのファイルをplaybookという
・べき等性という一度行ったことは操作は何度行っても同じ結果が得られること
・pythonコマンドが実行できるサーバーにssh接続できればすぐ使える。サーバー側にツールをインストールする必要がない

## 参考文献
結構読みやすいです！
#### 入門Ansible
https://www.slideshare.net/takushimizu/ansible-26200860

#### AnsibleによるInfrastructure as code入門
https://www.slideshare.net/kk_Ataka/ansibleinfrastructure-as-code

#### Ansible勉強会資料
https://www.slideshare.net/mac008008/ansible-57312145