OmniAICreator/Qiita-1.07M huggingface dataset:
AnsibleでPostgreSQL11をプロビジョニングする(PostgreSQL Moduleの紹介)

# AnsibleでPostgreSQL11を構築する
はじめまして、sinokumaです。
Qiita初投稿です。お手柔らかにお願いします。

## はじめに
こちらは、[Ansible Blogger 2018 （sponsored by Red Hat） Advent Calendar 2018](https://bit.ly/2RKHMCm) 16日目の記事です。
Ansible Blogger 2018 のテーマは2つあります。

1. あなたが好きなAnsible Moduleの紹介
2. そのModuleにまつわる使い方（便利なポイント、Tips、失敗談など）

ということで、私からはPostgreSQL Moduleを紹介します。

## PostgreSQL Module一覧

2018/12時点では、6つのModuleが存在します。

|No.|Module名         |Module概要                               |
|---|-----------------|----------------------------------------|
|1  |postgresql_db    |データベースの追加または削除                  |
|2  |postgresql_ext   |extensionの追加または削除                  |
|3  |postgresql_lang  |手続き型言語の追加または削除　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　|
|4  |postgresql_privs |データベースオブジェクトに対する権限の追加または削除|
|5  |postgresql_schema|スキーマの追加または削除　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　|
|6  |postgresql_user  |データベースユーザ(ロール)の追加または削除　　　　　　　　　　　　　|
参考：[Database modules > Postgresql](https://docs.ansible.com/ansible/2.9/modules/list_of_database_modules.html)

## PostgreSQL Moduleの使い方

私はPostgreSQLのプロビジョニングでこれらのModuleを使っています。
マネージドサービスが普及してPostgreSQLを自前で構築する機会はかなり減少しましたが、手元の開発環境や検証用途で試したい時にPlaybookがあると楽かと思います。
今回は、PostgreSQL11をプロビジョニングするPlaybookを作成しました。

### スキーマの作成

```yaml
- name: Create schema
  become_user: postgres
  postgresql_schema:
    name: "{{ item.name }}"
    owner: "{{ item.owner|default('postgres') }}"
    port: "{{ postgresql_port }}"
  with_items: "{{ postgresql_schemas }}"
```

### データベースの作成

```yaml
- name: Create database
  become_user: postgres
  postgresql_db:
    name: "{{ item.name }}"
    template: "{{ item.template|default('template1') }}"
    lc_collate: "{{ item.lc_collate|default('C') }}"
    lc_ctype: "{{ item.lc_ctype|default('C') }}"
    port: "{{ postgresql_port }}"
  with_items: "{{ postgresql_databases }}"
```

### ユーザ(ロール)の作成

```yaml
- name: Create user
  become_user: postgres
  postgresql_user:
    db: "{{ item.db }}"
    name: "{{ item.name }}"
    password: "{{ item.password }}"
    encrypted: yes
    state: present
    port: "{{ postgresql_port }}"
  with_items: "{{ postgresql_users }}"
```
※ちゃんとやるなら、パスワードはvault等を利用する方が好ましいと思います。

## Module使用時のポイント

### python psycopg2をインストールすること

PostgreSQL Moduleを使用するためには、python psycopg2が必須です。
PostgreSQL本体とあわせてインストールしてください。

```yaml
- name: Install PostgreSQL
  yum:
    name:
      - python-psycopg2
      - postgresql11-server
      - postgresql11-devel
    state: present
```

### portを指定すること

`port: "{{ postgresql_port }}"`

サンプルコードを見てお気付きかも知れませんが、常にport指定しておくことをオススメします。
特に開発や検証用途の場合、ポート番号を変えることで複数のPostgreSQLを1つのサーバに構築するケースが考えられます。
`port`を指定したtask定義にしておくことで、ポート番号を変更するケースにも柔軟に対応できます。

### pg_hba.confを事前に検証すること

これらモジュールをいくら駆使しても、結局PostgreSQLに接続できなければ意味がありません。
Playbookのテストをする前に`pg_hba.conf`の設定が想定どおりかつ問題ないか、`psql`を使って事前に検証しておくとよりスムーズに作業を進められると思います。

ちなみにですが、今回のPlaybookのテストはCentOSのDockerコンテナを使って実施しました(`tests/docker`ディレクトリ参照)。
**Playbookのテストを楽にできる方法が他にあればぜひ教えてください！**

# おわりに
　
いかがでしたでしょうか。この記事が少しでも多くの方の役に立つことができれば嬉しいです。
今回作成したPlaybookは、[sinokuma/postgresql-playbook](https://bit.ly/2Eq9iBp)に公開しておりますので良ければご利用ください。

今後ともよろしくお願いします！
DXライブラリを使ったアプリケーションでWaitForSingleObject関数を使う

「モンスター討伐ゲーム　アンチ核家族化」という私が開発しているゲームがあるんですが、リニューアル版ではキャラクター設定画面にWindowsフォームを使うことにしたので、ゲームとキャラクター設定画面が別プロセスになっちゃってるんです。
そこで問題となったのが、ゲームはDXライブラリを使っていて、また、サブプロセスを作成して待機するにはWin32 API関数のWaitForSingleObject関数で待機する必要があります。
ですが、ここで一つ問題があり、WaitForSingleObject関数内では当然DXライブラリのProcessMessage関数は呼ばれませんので、待機時間が長いと処理が重くなり、結果フリーズするということになってしまいます。
ここで私が考えたのが、DXライブラリを使ったアプリケーションで使えるWaitForSingleObject関数、「DxWaitForSingleObject」関数でした。
それがこちらです。

```cpp:DxWinAPI.cpp
#include "DxLib.h"

DWORD DxWaitForSingleObject(HANDLE hHandle, DWORD dwMilliSeconds) {
	DWORD ReturnCode = WAIT_OBJECT_0 + 1;
	if (dwMilliSeconds == INFINITE) {
		while (ReturnCode != WAIT_OBJECT_0 && -1 != DxLib::ProcessMessage()) {
			if (ReturnCode = WaitForSingleObject(hHandle, 100); WAIT_FAILED == ReturnCode) return ReturnCode;
		}
	}
	else if (dwMilliSeconds > 100) {
		auto GetCurrent = []() {
			return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
		};
		const auto WaitStart = GetCurrent();
		for (long long elapsed = 0; elapsed < dwMilliSeconds && -1 != DxLib::ProcessMessage(); elapsed = GetCurrent() - WaitStart) {
			if (ReturnCode = WaitForSingleObject(hHandle, 100); WAIT_FAILED == ReturnCode) return ReturnCode;
			if (ReturnCode == WAIT_OBJECT_0) break;
		}
	}
	else ReturnCode = WaitForSingleObject(hHandle, dwMilliSeconds);
	return ReturnCode;
}
```
やってることはすごくシンプルで、100ミリ秒を超える時間待機したい場合はWaitForSingleObject関数での待機時間を100ミリ秒とし、有限待機の場合はforで指定時間まで、INFINITEの場合はwhileでシグナル状態になるまで待機させるという方式です。
もちろんループ条件にProcessMessage関数が入ってるので、アプリケーションが終了すればこの関数もループアウトします。
使い方は[こちら](https://msdn.microsoft.com/ja-jp/library/cc429427.aspx)を見てください。これはあくまでもWaitForSingleObject関数をDXライブラリを使ったアプリケーションでも使えるようにしてるだけなので、使い方はWaitForSingleObjectと丸っきり同じです。
AGC029

#はじめに
12月15日のAGCに参加した．
A問題しか解けなかった．．．
パフォは786で，レートが235になった．

#[A問題](https://beta.atcoder.jp/contests/agc029/tasks/agc029_a)

```python:main.py
S = input()
N = len(S)
sum = 0
count = 0
flg = False
S = S[::-1]
 
for i in range(N):
  if S[i] == 'W':
    count += 1
    flg = True
  elif S[i] == 'B' and flg:
    sum += count
print(sum)
```
これは30分くらいかかったが，考え方は結構単純で，最終的には'W'がすべて左に寄り，'B'がすべて右に寄ればよい．
言い換えると，全ての'B'に対して，それより右側に存在する'W'の個数を合計すれば，答えになる．

この記事を書いてて思ったが，flgのフラグ管理は必要ないのでは．．．？
Module not found: Error: Can't resolve '〇〇'

# エラー
```
ERROR in ./node_modules/@stomp/stompjs/lib/stomp-node.js
Module not found: Error: Can't resolve 'net' in '/Users/dragontaro/react/nem-wallet/node_modules/@stomp/stompjs/lib'
 @ ./node_modules/@stomp/stompjs/lib/stomp-node.js 26:13-27
 @ ./node_modules/@stomp/stompjs/index.js
 @ ./node_modules/nem-library/dist/src/infrastructure/Listener.js
 @ ./node_modules/nem-library/dist/src/infrastructure/BlockchainListener.js
 @ ./node_modules/nem-library/dist/src/infrastrcture.js
 @ ./node_modules/nem-library/dist/index.js
 @ ./src/components/Wallet.tsx
 @ ./src/containers/AppContainer.tsx
 @ ./src/index.tsx
 @ multi @babel/polyfill ./src/index.tsx
```

なんかこんなエラーがよくwebpackのときに出てよくわからないな〜って思ってたら、どうも魔法のコードでエラーがでなくなるみたい。

# 解決法

webpack.config.jsに

```webpack.config.js
module.exports = {
  ...
  node: {
    fs: "empty",
    net: "empty",
    tls: "empty"
  }
};
```

こんな感じにエラーがでるやつを書いてやるとエラーは出なくなります。これが本当に解決できているのかは知らないですw
XCTestでアニメーションの結果を待つ便利メソッド

UIテストをやっていると、アニメーションの実行を待ってからアサートを実行したいときがあります✅
しかし、`DispatchQueue`のメソッドを使うと、テストの実行自体が止まってしまってアニメーションが実行されなかったり、アニメーションの完了を待たずにテストが終わってしまったり、メインスレッドでは無いスレッドでは描画ができなかったり、なかなか期待する結果になってくれませんでした😭
この記事では、試行錯誤の結果うまく行った便利メソッドを紹介します💡
もしDispatchQueueでもできるよーってことならぜひコメントにて教えていただけると幸いです🙇

(本当はカスタムトランジションについてまとめようかと思っていたけど、時間が無いのでそれは後日・・・)

# ディレイメソッド
`XCTestExpectation`というものを使います。

```swift
func delay(testCase: XCTestCase, seconds: Float) {
    let delay = testCase.expectation(description: "animation finished")
    DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(seconds)) {
        delay.fulfill()
    }
    testCase.waitForExpectations(timeout: TimeInterval(seconds + 1.0))
}
```
短いコードですが、各要素を見ていきます。

```swift
func delay(testCase: XCTestCase, seconds: Float) {
```
引数にはテストクラスそのものと、ディレイさせたい秒数を渡します。

```swift
let delay = testCase.expectation(description: "animation finished")
```
まずは`XCTestExpectation`を生成します。descriptionは何でもいいです。

```swift
DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval(seconds)) {
    delay.fulfill()
}
```
指定された秒数待ったのち、`fulfill()`を呼び出します。これは期待する結果になったよ、ということを通知するためのメソッドです。
アニメーションはこの待ち時間の間に実行されています。秒数はアニメーションと合わせてください。

```swift
testCase.waitForExpectations(timeout: TimeInterval(seconds + 1.0))
```
念の為、指定された秒数よりちょっと多めに`fulfill()`が来るのを待ちます。タイムアウトの時間が経過してしまうとテストがFailedになってしまいます。

# 終わりに
`XCTestExpectation`について調べてみたら、APIの取得を待つのに使われている例がいくつか見つかりました🔍
自分はアニメーションを待つために使ったのですが、非同期全般使えるので活躍の機会は多そうです🎉

# 参考
[XCTestExpectation](https://developer.apple.com/documentation/xctest/xctestexpectation)
[XCTest入門Part2 (Swift) ~非同期編~](https://qiita.com/okuderap/items/e02b73880b8bc499debe)
[iOS XCTestで非同期処理の完了を待つ](https://hopita.hatenablog.com/entry/2018/08/30/233409)
【AWS】米国リージョンからSimple Notification Service(SNS)を利用してSMSを送ってみる

[こちらで書いた記事](https://qiita.com/t5h/items/78c935cbb76b03d8faa2) を試行錯誤する過程で、可能性の一つとして、海外のSMSが受信できる必要があるかもしれないと思い、そのプランを追加購入したのですが、結果としてアクティベートには必要ありませんでした。

ただ、その過程で海外のSMSを受信できるかどうか、自力で試すことができる面白い方法があることに気がついたのでちょっとご紹介。（ちなみに、オランダのLebaraは、日本からSMSを受信できるプランがありません・・・。なので、日本とやりとりする場合は基本的にメールかiMessageかLINE等を使います）


# 手順
SNSでSMSを送ります。ややこしいわ。

1. AWSのリージョンでアメリカのどこかを指定→Simple Notification Service
![2018-12-16-(2).png](https://qiita-image-store.s3.amazonaws.com/0/103541/6e18e29c-deed-8dc3-eded-7bc05298dfc7.png)

2. 「テキストメッセージの発行 (SMS)」をクリック。
![名称未設定-1.png](https://qiita-image-store.s3.amazonaws.com/0/103541/9e6d6168-c3b5-1a7c-f9f9-d786ae42831a.png)

3. フォームに入力して送信

    |タイトル |入力値|
    |---|---|
    |メッセージの種類 |プロモーション（テストなのでトランザクションでもどちらでも良いです。違いについてはあまり良くわかっていません） |
    |番号 |自分の番号を国番号から入力 |
    |メッセージ |お好きな文言で |
    |送信者ID |これもお好きなIDで |
    ![aws_input.png](https://qiita-image-store.s3.amazonaws.com/0/103541/54c58a9c-62d4-93c3-17bb-95a4d5838f5e.png)

4. 設定等が問題なければ「送信」ボタンをクリックした直後に、端末にSMSが届くはず。   
<img width="375" alt="IMG_0737.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/103541/97ec3057-e363-b5ad-5249-c4711f3aea3b.png">

他の国の場合は、東京リージョンからも送れるかもしれません。
他のDockerコンテナからコンテナ内のMySQLに接続する

情けないながら苦戦してしまいました。

整理のために、謎の技術集団zeneloアドベントカレンダーの16日担当として記しておきます。

## 何がしたいのか？
Dockerコンテナで動かしているアプリケーションから、他のDockerコンテナで動いているmysqlにアクセスしたい。


**I want to connect mysql in a docker container from another container.**

というわけです。（英語でググる人にも引っかかるように書いておく。）

## コードはよ
せっかちさんのためにコードを先に書いておきます。

```yml:docker-compose.yml
version: "2"

services:
  mysql:
    container_name: sample-mysql
    image: mysql
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
      MYSQL_DATABASE: 'sample-mysql-db'
      MYSQL_USER: "root"
    restart: 'always'
    expose:
      - '3306'
    ports:
      - "3306:3306"
    networks:
      - app-net

  app:
    container_name: "sample-application"
    build:
      context: "./"
      dockerfile: "Dockerfile"
    networks:
      - app-net

networks:
  app-net:
    driver: bridge
```

こちらはアプリケーションのDockerfile。
今回はmysqlにつなぎたいだけなので、mysql-clientだけインストールします。

```:Dockerfile
FROM alpine:latest

RUN apk update && \
    apk add mysql-client
```

## 動作確認
```bash:local
$ docker-compose build
// mysqlだけ先に起動しておく
$ docker-compose run -d mysql
// appコンテナの中に入る
$ docker-compose run app sh
```

```sh:application-container内部
$ mysql -h sample-mysql -u root -D sample-mysql-db -p
=> つなげた！
```

解説していきます。

## コンテナ間の通信設定にはネットワーク機能を使う

[Docker コンテナ・ネットワークの理解](http://docs.docker.jp/engine/userguide/networking/dockernetworks.html)

いくらdocker-composeで一緒にコンテナを起動しようとも、 **ネットワークの設定なしではコンテナ間の通信はできません。**

詳しいことは公式ドキュメントを読んでいただきたいですが、今回は `ブリッジネットワーク` を使って、アプリケーションコンテナとmysqlコンテナを通信可能にします。

```yml
networks:
  app-net:
    driver: bridge
```

ちょうどこの部分です。
これにより、 app-net という新しいネットワーク空間を定義できました。

そうしたら、

```yml
services:
  mysql:
    networks:
      - app-net

  app:
    networks:
      - app-net
```

このように書くことで、コンテナがどこのネットワークに属すのかを記述することができます。

あとは、アプリケーション側のコンテナに入り、mysqlに接続します。

```sh
$ mysql -h sample-mysql -u root -D sample-mysql-db -p
```

このとき重要なのは **-h localhostではない点です。**

コンテナ間の通信は **コンテナ名をIPの代わりに指定する** 必要があります。

（これに気づかず、かなり躓いていました。）

すごいざっくりな記事になってしまい恐縮ですが、コンテナ間の通信に困っている人は、とりあえずこの記事で繋げるようにしてもらって、あとは公式ドキュメントを読み漁り理解を深めてください！では！
Extended Syntax

| Element | Markdown Syntax |
|:--|:--|
| Table | | Syntax | Description | |
| | ----------- | ----------- | |
| | Header | Title | |
| | Paragraph | Text | |
| Fenced Code Block | ``` |
| { |
|   "firstName": "John", |
|   "lastName": "Smith", |
|   "age": 25 |
| } |
| ``` |
| Footnote | Here's a sentence with a footnote. [^1] |
|  |
| [^1]: This is the footnote. |
| Heading ID | ### My Great Heading {#custom-id} |
| Definition List | term |
| : definition |
| Strikethrough | ~~The world is flat.~~ |
| Task List | - [x] Write the press release |
| - [ ] Update the website |
| - [ ] Contact the media |
pythonでエクセルファイルの作図をはじめよう

# pythonでエクセルファイルの作図をはじめよう

## 目的

`python`は何かと便利と聞くので使ってみたいと思っていながら一歩を踏みだせない人のために、お手軽なとっかかりを提供したい。

今回はエクセルファイルを読み込んでグラフを描くことを対象にする。

## 方法

* ファイルはエクセルファイルを対象にする→`pandas`で読み込む
* グラフ化は`matplotlib`で行う

## 得られる内容

* `pandas`でエクセルファイルを読み込んで`pandas`の表形式データである`DataFrame`にする方法
* `matplotlib`で上記`DataFrame`から散布図を作成できるようにする。


## pandasで読み込むエクセルファイル

`pandas`はデータ処理に便利な形式を提供してくれるモジュール。欠測値などの処理も便利にやってくれるので、データサイエンスなどでよく用いられている。

一方使いこなすには少し特徴的な処理方法を理解しないといけないので、ここでは深入りはしない。

単にエクセルファイルを読み込み、`python`で扱えるようにするためだけに用いる。

`pandas`にはエクセルファイルを読み込んで`dataframe`という表形式の独自形式に取り込む機能もあるので便利だし、`dataframe`は直観的に分かりやすいので、まずはこの機能だけ利用させてもらおう。

今想定するデータは、気象庁のページからダウンロードできるもの。
観測地点「東京」の2017年1月1日～2018年1月1日までの、平均気温、最高気温、最低気温、降水量、平均湿度を対象とした。

これはもともとダウンロードする際にはcsvファイル。
本末転倒かもしれないが、今回はエクセルファイルの読み込みを対象としたいので、
csvをエクセルで読み込み、それをエクセルファイル(xlsxファイル)として保存した。

さて、`pandas`でエクセルファイルを読み込むには以下のようにする。

```python
import pandas as pd

this_file_name = "met_tokyo.xlsx"   # 読み込みファイル名
this_sh_name = "tokyo_2017"    # 読み込みシート名
this_skiprows = 6                # 最初に読み飛ばす行数
this_usecols = [0,1,4,7,10,15] # dataframe化する列を0始まりのインデックスで指定
this_col_names = ["年月日","平均気温(℃)","最高気温(℃)","最低気温(℃)",
							"降水量(mm)","平均湿度(%)"]  # 使用する列の名前を付ける


xlsx_pd = pd.read_excel(this_file_name, sheetname = this_sh_name,
													names = this_col_names, usecols = this_usecols,
													skiprows = this_skiprows)

```

ここで使用した引数は以下の通り。

* `sheetname` : 読み込み対象のエクセルファイル内のシート名を明示する。
* `skiprows`  : シートの何行目まで読み飛ばすかの指定。今回のデータは6行読み飛ばす。データを見て最初の説明などヘッダー部分を飛ばすことができる。
* `usecols`   : 使用する列を0始まりのインデックスで指定する。列Aが0になる。
* `names`     : 使用する列に付ける名前をリストで指定する。`usecol`の数と一致しなければならない。`usecol`を指定していない場合はデータがある全ての列が読み込まれるが、その数と一致しなくてはならない

他にも様々な引数があるので、必要な時は`help(pd.read_excel)`をしよう。

このように読み込むと`this_col_names`で指定した列名を持った時系列の表形式データをで扱うことができる。
該当箇所をピックアップしたり便利な機能が多い(但しそのための命令はすぐ忘れてしまう)し、欠測値の処理で便利だったりと知っておいて損はない。
グラフ化するために使用する`matplotlib`でも読み込めるので今回は使用することにした。

## matplotlibによるグラフ作成

```python
import matplotlib.pyplot as plt

# 時系列グラフの追加
plt.plot(xlsx_pd["年月日"],xlsx_pd["平均気温(℃)"],label="平均気温"],color="k")
plt.plot(xlsx_pd["年月日"],xlsx_pd["最低気温(℃)"],label="最低気温"],color="r")
plt.plot(xlsx_pd["年月日"],xlsx_pd["最高気温(℃)"],label="最高気温"],color="b")


# 軸ラベルの設定
plt.xlabel("date")
plt.ylabel("temperature")

plt.grid() # 方眼線の追加
plt.legend() # 凡例の追加

```
`plt.plot`はx,yのデータを指定して散布図を作成するのに使用する。今回はxに時間を指定するので時系列グラフを作成することになる。

オプションは沢山あるのだが、ここではシンプルに二つだけ指定している。

* `label` : 凡例を表示させる時の名前を指定する。
* `color` : 線の色。色の名前については[こちら](https://pythondatascience.plavox.info/matplotlib/色の名前)がよくまとめて下さっている。

`plt.grid()`をすると方眼線が表示されて少しみやすくなる。

`plt.legend()`を実行すると初めて凡例がグラフに表示される。


# おわりに

今回は、エクセルファイルの取り込み及び作図という極めてシンプルな作業を紹介したが、作図の基本となるものだと思う。ここから効率的な図化処理のための様々な要素を紹介していきたいと考えている。

今回の内容をjupyter notebookで実行してみたい人がもしいれば、[こちら](https://github.com/eriho/eff_vis_for_eng_res/blob/master/01_read_excel_and_simple_plot.ipynb)からご覧下さい。
fastlane matchからのp12ファイル復元方法とAppCenterへの登録



appcenterのテスター配布には xcode project(or workspace) のスキーマに設定した

provisioningファイル
p12ファイル
が必要になります。

現状、fastlane matchでprovisioningファイルとp12証明書を作成した場合、openSSLの更新を行うとkeychainにexportされないバグがあります。　（2018/12/16現在）

関連Issueはこちら
https://github.com/fastlane/fastlane/issues/12260#issuecomment-379596642fastlaneのmatchでprovisioning

ファイルを自動生成しているが、リポジトリ上のファイルはAES-CBCモードで暗号化されているため、直接使用することは出来ないが、スキーマにmatchのプロビジョニングファイルが使えないのはだるいので、なんとかした話をします。

デクリプトしたのち、これらの.p12ファイルから抽出したpemファイル及びcerから抽出したderファイルを使ってx509でpemを生成して、再度pkcs12を使用して新たなp12ファイルを生成する。これは、githubから復元可能かつp12とは別物なので、再配布可能な秘密鍵になります。パスワードの設定も可能になります。以下生成例

```
openssl aes-256-cbc -k pass -in matchの.p12 -out key.pem -a -d
openssl aes-256-cbc -k pass -in matchの.cer -out temp.der -a -d
openssl x509 -inform der -in temp.der -out cert.pem
openssl pkcs12 -export -out temp.p12 -inkey key.pem -in cert.pem -passout pass:pass
```

以上で作成した証明書とDeveloperアカウントからダウンロードしたプロビジョニングファイルをAppcenterにuploadして無事使用することができます。

追記

2019/06/15時点ではmatchのバグは修正されているようで、keychainsに登録されている秘密鍵からp12証明書を作成することができました。
awkで標準出力から直接データを処理したい(周波数解析編)

# はじめに
[awkで標準出力から～(統計編)](https://qiita.com/thas_i/items/afd406584fd93b4b9d29)の続編になります。なので以下引用。
>お仕事で、データに対してサクッと~~統計値求めたかったり、規格化したかったり、~~<b>周波数解析</b>したかったりする場合があります。
通常であればpythonとかRとかでサクッとやれちゃうんでしょうが、データ取得環境がオフラインでパッケージも入れられないような環境だったり<b>、取得したデータが不等間隔のデータだったり</b>したので、awkでスクリプト作って標準出力のデータをパイプでつなげてサクッと求められるようにしました。

# 不等間隔データの周波数解析
## Lomb-Scargle Periodogram

間隔が不均一なデータの場合、一般的なFFTの方法が採用できません。そこで、今回はLomb-Scargle法を採用しました。簡単に言うと任意周波数のsin関数でフィッティングすることで周波数成分求めようってやつですね。詳しくは下記とか見てください。

1) [Understanding the Lomb-Scargle Periodogram](https://arxiv.org/pdf/1703.09824.pdf)
2) [The Generalized Lomb-Scargle Periodgram: A New Formalism for the Floating-Mean and Keplerian Periodgram](http://www.ioa.s.u-tokyo.ac.jp/kisohp/STAFF/nakada/AGB/Zechmeister09/Zechmeister09.html#top)

結構誰しもが考えそうな手法ですが、自分は$asin(wt-b)+c$の形のまま解こうとして挫折しました。頭悪かったですね。積和変換して$Asin(wt)+Bcos(wt)+C$で最小二乗すればよかったんですね。
(こんなこと言ってますけど実は真面目に式は導出してません…。)

## ソース
とりあえず実装しました。

```awk:fft
awk '{x[NR]=$1;y[NR]=$2;ysum+=$2;}\
   END{yave=ysum/NR;
   for(i=1;i<=NR;i++)YY1+=(y[i]-yave)^2;
   pi=atan2(0,-0);st=1;pt=1;en=100;\
   if(arg_st>0&&arg_pt>0&&arg_en>arg_st){
       st=arg_st;pt=arg_pt;en=arg_en;\
   }
   for(f=st;f<=en;f+=pt){
       C=S=YS1=YC1=CC2=SS2=CS2=0;\
       w=2*pi*f;\
       for(i=1;i<=NR;i++){
          wt=w*x[i];coswt=cos(wt);sinwt=sin(wt);\
          C+=coswt;S+=sinwt;\
          YC1+=(y[i]-yave)*coswt;\
          YS1+=(y[i]-yave)*sinwt;\
          CC2+=(coswt)^2;\
          SS2+=(sinwt)^2;\
          CS2+=coswt*sinwt;\
       }
       CC1=CC2-C*C;SS1=SS2-S*S;\
       CS1=CS2-C*S;D=CC1*SS1-CS1^2;\
       p_u=SS1*YC1^2+CC1*YS1^2-2*CS1*YC1*YS1;\
       p_d=YY1*D;if(p_d==0)p_d=1;\
       p=p_u/p_d;\
       print f,p;\
   }
   }' arg_st=$1 arg_pt=$2 arg_en=$3
```
引数1で開始周波数、引数2で刻み幅、引数3で終了周波数を指定できます。
[ここ]()にも簡単に記載されていますが、最小二乗で無理くり求められるため、平均ナイキスト周波数にも制限されません。細かくしすぎると何が原因か分かりませんがめちゃくちゃ大きい値になったりするので、上手く探索するアルゴリズムが必要です。
awkで$π$を表現する方法を初めて知ったのですが`pi=atan2(0,-0)`なんて書くんですね。

# 実際に使ってみる
データ１
$sin(2πt)+sin(2*2πt)+sin(3*2πt)+sin(4*2πt)+sin(5*2πt)$
-10<t<10, n=10000で試してみました。
![sin1-5.jpeg](https://qiita-image-store.s3.amazonaws.com/0/199202/0e9b8dd7-0d94-170a-875a-04d14730bf06.jpeg)

```shell
cat sin1-5.dat | fft 0.1 0.1 6
```
![sin1-5_fft.jpeg](https://qiita-image-store.s3.amazonaws.com/0/199202/194906bd-7f0b-dcf7-3728-6c224b7e0276.jpeg)

とりあえず等間隔データに対してはばっちりですね。ちなみにスペクトルは相対密度なので、5本ピークがあってそれぞれ0.2なので正しいです。
<br>この時点でちょっとめんどくさくなったので後で不等間隔データの例についは追記します…</br>
FFTとの差分みたいなものも(1)の論文に書かれたような気がするので見てみてください。
気が向けばもう少し例を追加します。

# 最後に
事前にどんなデータか踏まえた上で、手動でナイキスト周波数と分解能を決めてあげる必要がありますが、手軽にサクッと確認する分には十分使えそうです。よかったら使ってみてください。
また、改善箇所などあったら指摘していただけると嬉しいです。
スマホアプリ版FaceRigでLive2Dモデルを表示する方法

スマホ版での導入に関する記事が少ないと感じたので書きます。
PC版はこちらの記事が参考になります→　[facerig+live2dで受肉RTAをした](https://qiita.com/Hirai0827/items/1b58979a9b2b3acbea0b#3facerig%E3%81%AB%E5%8F%96%E3%82%8A%E8%BE%BC%E3%82%93%E3%81%A7%E3%81%BF%E3%82%88%E3%81%86)


# Live2Dモデルを追加するために

PC版FaceRigで動作確認できている場合は、
```Steam/steamapps/common/FaceRig/Mod/VP/PC_CustomData/Objects```
以下にある対象のファイルをそのままzip形式で圧縮してGoogle Driveなどにアップロードし共有リンクを作成する。

アプリ版で外部Live2Dを購入後、リンクを貼り付ける。

## 注意点
<font color="Red">moc3形式はスマホ版FaceEigには未対応</font> (2018/12/15現在)

# その他
なぜかiOSとAndroidでLive2D導入キットの値段が違う、、
(iOS:1200円   Android: 950円)

スマホ版はデフォルトの背景にクロマキー合成に使えそうな背景がないので、動画編集するならパーツで緑背景をつけるのもアリ
コーディング　覚書

自分が忘れないように覚書として投稿していきます。
他にも「こんなことが大切だよ」等ありましたらコメントお願いします。

#変数の宣言と定義は、最初に使用する場所の近くで行う
　離れた場所で宣言した場合、変数を使用するコードが実行されるまでに変更される可能性がある。
　すべての変数を一か所にまとめて宣言すると、
　すべての変数がコード全体で使用されるような印象を与えてしまう。
　（実際には一部でしか使用していないのに。。。）
　
#変数の寿命はできるだけ短く
　変数が誤って、あるいはそうとは知らずに変更される危険性が少なくなる。
　また、コードを正確に把握できる。

　　変数2行目で値を代入し、100行目まで使用しない場合、
　その間に変数が使用されているかもしれないという疑念が起きる。
　99行目で値を代入し、100行目で使用すれば他のことは考えないで済む。
　読み手が一度に頭に入れなければいけないコードの行数が少なければ少ないほど、
　コードは理解しやすくなる。
GolangでWebAssemblyを触る

マグロ大学(近畿大学)アドベントカレンダー16日目の記事です.

ちょっと予定より書く時間がなかったので当初予定していた記事とは違うやつを、、

# Web Assemblyとは
ブラウザで機械語を動かして高速化を図る技術みたいです.
モダンブラウザはだいたい対応してるようです.
CとかRustで書いたコードをWeb Assemblyのバイナリにコンパイルして使えます.
Goでは1.11から対応しています.

# チュートリアル
ブラウザのコンソールに文字をを出力します.

```main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello wasm!")
}
```

.wasmにコンパイルします

```sh
GOOS=js GOARCH=wasm go build -o test.wasm main.go
```

.wasmを読み込むためのhtmlとjsを拾ってきます

```sh
curl -sO https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.html
curl -sO https://raw.githubusercontent.com/golang/go/master/misc/wasm/wasm_exec.js
```

簡易的なwebサーバーを立てます

```server.go
package main

import (
	"flag"
	"log"
	"net/http"
)

var (
	listen = flag.String("listen", ":8080", "listen address")
	dir    = flag.String("dir", ".", "directory to serve")
)

func main() {
	flag.Parse()
	log.Printf("listening on %q...", *listen)
	log.Fatal(http.ListenAndServe(*listen, http.FileServer(http.Dir(*dir))))
}
```

サーバーを起動します.

```
go run server.go
```
localhost:8080/wasm_exec.htmlにアクセスしてRunボタンを押してコンソールにHello wasmと表示されれば成功です.
もしここで`Uncaught (in promise) LinkError: WebAssembly Instantiation: Import #5 module="go" function="runtime.scheduleCallback" error: function import requires a callable`と表示された場合jsファイルを https://raw.githubusercontent.com/golang/go/release-branch.go1.11/misc/wasm/wasm_exec.js に置き換えれば動くかもしれないです.

# DOM操作

GoからJavaScriptを触るにはsyscall/jsを使います.

```go
import "syscall/js"
```
documentオブジェクトの取得

```go
document := js.Global().Get("document")
```

documentのgetElementById("text")メソッドを呼び出す

```go
element := document.Call("getElementById", "text")
```
innerTextの値を取得

```go
text := element.Get("innerText").String()
```
innerTextに値をセット

```go
element.Set("innerText", "Hello World")
```

# 参考
[Go WebAssembly Tutorial - Building a Calculator Tutorial | TutorialEdge.net](https://tutorialedge.net/golang/go-webassembly-tutorial/)
[js - The Go Programming Language](https://golang.org/pkg/syscall/js/)
[misc/wasm: `this._inst.exports.getsp` is not a function · Issue #28924 · golang/go](https://github.com/golang/go/issues/28924)
[サクッと Go → WebAssembly を試す - Qiita](https://qiita.com/cia_rana/items/bbb4112b480636ab9d87)
Laravel GitでクローンしてMAMPで開発

##はじめに

リモートリポジトリにあるLaravelのプロジェクトをローカルのMAMPに入れて表示させるのに少し手間取ったので、備忘録として。

まず、MAMPのhtdocsフォルダに移動

```
$ cd Applications/MAMP/htdocs/
```

##プロジェクトをクローン

```
$ git clone [リモートリポジトリのパス]
```

##composerインストール

git cloneしたプロジェクトには、composerが入っていないので、下記コマンドでインストールします。


```
$ composer install
```

あれ？　こんなエラー出ました。

```
[RuntimeException]
  Could not scan for classes inside "database/factories" which does not appea
  r to be a file nor a folder
```

databaseフォルダの下にfactoriesというフォルダが無いぞ！　と怒られました。
なので、factoriesフォルダを作ります。

```
$ mkdir /database/factories
```

そして、再度composerをインストール。これでエラー出なければOK。

##.envファイル追加・編集

~~.env.exampleファイルをリネームするか、コピーして.envファイルを作る。~~
.env.exampleファイルは残したほうが良いと教えて頂きましたので、
リネームはせずに、コピーして.envファイルを作りましょう。


##アプリケーションキーの設定

```
$ php artisan key:generate
```

`Application key set successfully.`となればOK。

##終わり

`http://localhost:8888/プロジェクト名/public/`

![https___ksysnote.com_wp-content_uploads_2018_09_img_5bab8d5cb1774.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323137/b26ff2d9-afb5-714e-d052-f8fd898d6a4a.png)

はい、表示されました。

とりあえずこれで表示までは出来ました。


##データベースの設定（おまけ）

.envファイルを編集

```
DB_HOST=localhost
DB_PORT=8889
DB_DATABASE=[作ったデータベース名]
DB_USERNAME=root
DB_PASSWORD=root
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
```
JS(ES6) constructorの使い方

#class内で使われるconstrucorの使い方
JavaScriptのクラスについて整理するためにまとめました。

##クラスとインスタンスの関係
クラス(設計図)を元に、インスタンス(もの)を生成する

##コンストラクタとは
クラスにはコンストラクタと呼ばれる機能が用意されている。コンストラクタはインスタンスを生成するときに実行したい処理や設定を追加するための機能。


###①コンストラクタの中に処理を書くバージョン

```
class Students{
  constructor(){
    console.log("学生です");    // インスタンスが生成された直後に実行される
  }
}

const student = new Students();    // クラスから新しいインスタンスを生成する
```

実行結果
`学生です
`

###②コンストラクタの中で、生成したインスタンスに関する情報を追加する。
コンストラクタの中で「this.プロパティ = 値」とすることで、生成されたインスタンスにプロパティと値を追加することができる。

```
class Students{
  constructor(){
    this.name = "田中";    // インスタンスのプロパティの値を指定
  }
}

const student = new Students();
console.log(student.name);
```

実行結果
`田中
`

でもこのままでは、同じStudentクラスから生成されたnameプロパティの値がすべて'田中'になってしまいます。
Studentクラスから生成されたインスタンス(達)のnameプロパティ毎に、それぞれ異なった値を持たせたい。

###③インスタンス毎に異なったプロパティの値を与えたい

```
class Students{
  constructor(name,age){      //　引数を設定
    this.name = name;         // インスタンスのnameプロパティの値を引数から受け取って設定
    this.number = number;     // インスタンスのnumberプロパティの値を引数から受け取って設定
  }
}

const student_1 = new Students('阿部', 18);    //コンストラクタの引数に値を渡す
const student_2 = new Students('伊藤', 17);

console.log(student_1.name);
console.log(student_1.age);
console.log(student_2.name);
console.log(student_2.age);
```

実行結果

``阿部
18
伊藤
17
``
Python3.7.1の環境構築

### 自分用メモ
[python公式](https://www.python.org/downloads/) 
Windows x86-64 web-based installer は後から追加Downloadしてくる。オンラインじゃないとNG
Windows x86-64 executable installer は一括Download。オフラインでも使える
今回は前者を使用

![python_installer.png](https://qiita-image-store.s3.amazonaws.com/0/324264/81c9f868-9b63-c3cc-07f6-93c64d971178.png)
下部の"Add python 3.7 to path"を忘れずに。
これにチェック入れておけばPATHを通してくれる(はず)
pipも入れておくべき。パッケージのインストールが楽になる
デフォルトでチェック入っているので、Cunsmize installationで外さないように

pipの使い方はコマンドプロンプトから
PowerShellからでも可能

```pip install numpy ```
って感じで適宜追加していく
最新版だからいくつか対応していないパッケージがありそう

とりあえず今日はここまで
(自分用メモ) ffmpeg

ffmpegをmacで使った時のメモ書き (Linuxのほうが使いやすい気がする)

# インストール
* brewにて
    * $brew install ffmpeg


# 使い方
* 使用可能なvideo resource一覧の表示
    * e.g. Macのフロントカメラは "[0] FaceTime HD Camera"
    * [メモ] Macの場合はavfoundationが必要らしい. Ubuntuでは不要だったなぁ
        * https://www.ffmpeg.org/ffmpeg-devices.html#avfoundation

```
➜  ✗ ffmpeg -f avfoundation -list_devices true -i ""

ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-opencl --enable-videotoolbox
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
[AVFoundation input device @ 0x7ffa3f402b40] AVFoundation video devices:
[AVFoundation input device @ 0x7ffa3f402b40] [0] FaceTime HD Camera
[AVFoundation input device @ 0x7ffa3f402b40] [1] Capture screen 0
[AVFoundation input device @ 0x7ffa3f402b40] [2] Capture screen 1
[AVFoundation input device @ 0x7ffa3f402b40] AVFoundation audio devices:
[AVFoundation input device @ 0x7ffa3f402b40] [0] Built-in Microphone
```

* Camera viewの表示
    * $ffplay -f avfoundation -framerate 30 -i "0"
    * [注意] framerateが必要
        * (参考) https://stackoverflow.com/questions/37960828/webcam-streaming-from-mac-using-ffmpeg


# 参考
* ffmpeg (API)を用いてWebカメラからキャプチャ
    * https://qiita.com/gwappa/items/d4adc9354fab3fa2c1c9
スマホで撮影した写真を白黒二値化してサーマルプリンタに出力する（完結編）

# はじめに

前記事[「スマホで撮影した写真を白黒二値化してサーマルプリンタに出力する」](https://qiita.com/nak435/items/56ea7e9149f56c2ac19e)では、単純な白黒二値化のアルゴリズムのため、期待外れな印刷結果となった。今回は**誤差拡散法**に変更した内容をまとめます。

# 誤差拡散法

前回の単純な白黒二値化があまりにもがっかりな結果であったので、誤差拡散法で白黒二値化しました。使用したアルゴリズムは[フロイド-スタインバーグ・ディザリング](https://ja.wikipedia.org/wiki/フロイド-スタインバーグ・ディザリング)と言われるもので、Wikipediaに書かれていた擬似コードを参考にJavascriptに書き直しました。

グレースケールのイメージを入力して白黒二値化します。


```javascript:誤差拡散法
//誤差拡散法(Floyd-Steinberg dithering)
const oldImage = grayscaleImage; //グレースケールのイメージ
const newImage = new Array(width * height).fill(0);
for (let y = 0; y < height; y++) {
  for (let x = 0; x < width; x++) {
    let pixel = oldImage[y * width + x];
    let quantError; //誤差
    if (pixel > 127.5) {
      quantError = pixel - 255;
      pixel = 255;
    } else {
      quantError = pixel;
      pixel = 0;
    }
    newImage[y * width + x] = pixel;
    // 誤差拡散
    if (x != width - 1) {
      oldImage[y * width + (x + 1)] += 7 / 16 * quantError;
    }
    if ((x != 0) && (y != height - 1)) {
      oldImage[(y + 1) * width + (x - 1)] += 3 / 16 * quantError;
    }
    if (y != height - 1) {
      oldImage[(y + 1) * width + x] += 5 / 16 * quantError;
    }
    if (x != width - 1 && y != height - 1) {
      oldImage[(y + 1) * width + (x + 1)] += 1 / 16 * quantError;
    }
  }
}
```

結果は以下の通り。左から元画像、中央はグレースケール化画像、右がフロイド-スタインバーグ法による白黒画像です。素晴らしい出来です。元画像のサイズ[2176x4608]を、プリンタの仕様に合わせて384x813にリサイズしています。

![colorGrayBW.png](https://qiita-image-store.s3.amazonaws.com/0/283293/91f93b0c-a682-58d3-88fd-cae85a0ad1de.png)

# 白黒カメラプリンタ

この記事のタイトルである「スマホで撮影した写真を白黒二値化してサーマルプリンタに出力する」アプリを「白黒カメラプリンタ」と名付けました。画面イメージを示します。
（「白黒カメラプリンタ」は **[こちら](https://obniz.io/users/340/repo/bwCameraPr.html)** からどうぞ。別ウィンドウで開きます。obnizを持ってない方でも「obniz idを聞いてくるダイアログでキャンセル」すれば、各イメージの確認はできます。）

<img src="https://qiita-image-store.s3.amazonaws.com/0/283293/8a1aa178-a8e7-d8fa-c6bf-1ed655e978e3.png" width=80%>

~~なお、DP-EH600アクセスライブラリの詳細は、後日別記事で紹介いたします。~~
> 2018.12.23追記
> DP-EH600アクセスライブラリを[**こちら**](https://nak435.github.io/DP-EH600/)に公開しました。
 
 
「印刷」を押すとサーマルプリンタから出力します。（当然ですが、obnizとオンラインになっている必要があります。）
<iframe width="360" height="360" src="https://www.youtube.com/embed/zzF7fRrUTN4?rel=0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

<img src="https://qiita-image-store.s3.amazonaws.com/0/283293/90815ac0-efac-534a-a315-b31ccb79866e.jpeg" width=50%>

この縦長の写真で印刷時間は22〜3秒の性能です。


# まとめ

自分としては当初の目的が達成できたと思っていて大満足です。お正月に家族が揃った時に、これで写真を撮ってその場で印刷して見せてあげようと思います。

> 2018.12.23追記
> 手頃な箱に入れました。obnizは使い廻すので外付けにしてあります。
> ![IMG_5022.JPG](https://qiita-image-store.s3.amazonaws.com/0/283293/f832998e-2d84-01ce-2c4b-69a65462ec8b.jpeg)


(完)
Flask・(Django←予定) 体験記 ~目次ページ~

# ページ概要
本ページは, 「Flask 体験記」のリンクをまとめたものです.

# 「Flask 体験記」とは
三十路過ぎて[Pythonで競技プログラミングに挑戦](https://qiita.com/4no3/items/cb8447beb6c8bd6e30e4)し始めた男が, Python のスキルアップのためにいろいろ体験していく活動のひとつです. ここでは, Web アプリケーションフレームワーク Flask を体験していきます(ゆくゆくは Django もやりたい).

# Flask 体験記バックナンバー
[vol.1 ~下準備~](https://qiita.com/4no3/items/acb906c7eee7a935cfbe)
[vol.2 ~ディレクトリ構成、ファイル同士の関係~](https://qiita.com/4no3/items/5b356bda311c15051def)

# Django 体験記バックナンバー
Coming soon?
【小ネタ】CloudWatch参照中にセッションが切れてしまったら【AWS】

# はじめに
性能評価や不具合原因の調査・分析等の際に、CloudWatchMetrics・CloudWatchLogsなどを駆使して、複数メトリクスを組み合わせ・並べて見ながら調べていく、といったことはままあると思います。
基本的にはAWS Management Consoleは、ログインして何らか操作していればセッションは自動で更新されていきますが、気付いたらログイン画面に戻されてしまった、ということがあるかと思います。

このような場合に備えて、CloudWatch Dashboardを作っておく、URLをコピー＆ペーストして控えておくといった方法がありますが、うっかり何も準備していなければ「もう一回セットアップし直しかあ…」という状態だと思います。

この記事では、こんな場合に簡単にリカバリする方法を紹介します。

# TL;DR
- 他のウィンドウでAWS Management Consoleに再ログインする。
- CloudWatchMetrics/CloudWatchLogsを参照していたウィンドウで「戻る」ボタンを押す。

# 試してみる
## CloudWatchMetricsを表示させた状態でセッションをタイムアウトさせる
まずは、見たい値を参照します。
あるEC2インスタンスのCPUUtilizationと、これに紐づくEBSのメトリクスを見ることにしましょう。
![2018-12-15_15h36_48.png](https://qiita-image-store.s3.amazonaws.com/0/137777/cda2e8eb-f0ed-9f6c-22ba-6ad620eb79c9.png)


この状態で他の作業をしてうっかり長時間経つと、ログイン画面に戻されてしまいますね。
![2018-12-16_21h45_42.png](https://qiita-image-store.s3.amazonaws.com/0/137777/81506a9b-7d03-4a8d-0af5-a4aa9eeb74f1.png)

## 別のタブ／ウィンドウを開き、ログインする。

先ほどのタブをそのままにしておき、新しいタブかウィンドウを開いてログインし直しましょう。
![2018-12-16_21h46_49.png](https://qiita-image-store.s3.amazonaws.com/0/137777/6eede84b-97a9-3a19-a26e-9e23fe3fd524.png)

## CloudWatchMetricsを参照していたウィンドウで「戻る」ボタンを押す
CloudWatchMetricsを参照していたウィンドウに戻り、「戻る」ボタンを押すと、先ほど見ていたグラフに戻ることが出来ます。
![2018-12-16_21h47_28.png](https://qiita-image-store.s3.amazonaws.com/0/137777/c88f9a9b-e34c-ee3b-788a-a9319e3b005b.png)

もし、CloudWatch Dashboardのトップ画面に戻ってしまったら、履歴を元にもう一つ戻りましょう。大抵の場合は、これで元のグラフを表示させることが出来ます。
![2018-12-16_21h47_43.png](https://qiita-image-store.s3.amazonaws.com/0/137777/7a4f8d0c-bd57-4234-8fd5-774ce219ed57.png)
文字につける影の比較

# はじめに
「影をつけてほしい」とよく言われますが、どんな影を望んでいるか、比較できるものを見せないと意思疎通が難しい...🤔

そういう経験を度々するので、iOSで文字に影をつける方法の比較記事を作ってみました。

まとめると、影の主張の強さは、UILabel#shadow > NSShadow > CALayer の順です。

<img width="500" alt="比較" src="https://qiita-image-store.s3.amazonaws.com/0/84185/13f9b20d-44e9-1fa7-dee5-4a850f0a9697.png">

実装コストは、基本的には、UILabel#shadow < CALayer < NSShadow の順に安いです。

以下では、各実装方法と特徴を整理します。

# UILabel#shadowColor

<img width="154" alt="demo1.png" src="https://qiita-image-store.s3.amazonaws.com/0/84185/b8fed131-10fc-9028-f43b-b3dbf5dcf330.png">

ぼやっとした影ではなく、直線的な影です。
UILabelのshadowColor/shadowOffsetを指定する方法です。InterfaceBuilderのshadowプロパティはこの値を指定するものです。
サンプルはoffsetとして{2,2}を指定しているため、右下にズレた影がついています。
とにかく実装が簡単なのが魅力です。

# NSShadow

<img width="154" alt="(2).png" src="https://qiita-image-store.s3.amazonaws.com/0/84185/780a9153-fb04-5db1-6d73-a299b7f2dc7b.png">

よりぼんやりとした影です。後述のCALayerの方法よりもはっきりと影がつきます。白文字のときにこのような黒影を敷くと、白い背景のときに視認性が良くなります。

NSAttributedStringの属性として指定するため、3つの方法のなかでは最も扱いずらいです。
 `@IBInspectable`のプロパティを作ってAttributedStringに属性を追加するサブクラスを作って使うと、IB上で値を指定できて便利ですね。

 ```swift
import UIKit

@IBDesignable class ShadowAttributeSettableLabel : UILabel {
    @IBInspectable var shadowColorForCustom: UIColor = .clear
    @IBInspectable var shadowOffsetForCustom: CGSize = .zero
    @IBInspectable var shadowRadiusForCustom: CGFloat = 0.0
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        guard let text = text, let attributed = attributedText else { return }
        let mutable = NSMutableAttributedString(attributedString: attributed)
        let shadow = createShadow()
        let range = NSRange(location: 0, length: text.count)
        mutable.addAttribute(.shadow, value: shadow, range: range)
        attributedText = mutable
    }
    
    private func createShadow() -> NSShadow {
        let shadow = NSShadow()
        shadow.shadowColor = shadowColorForCustom
        shadow.shadowOffset = shadowOffsetForCustom
        shadow.shadowBlurRadius = shadowRadiusForCustom
        return shadow
    }
}
 ```

# CALayer

<img width="150" alt="(3).png" src="https://qiita-image-store.s3.amazonaws.com/0/84185/30660531-a7e5-09a4-5e44-c98e581cf966.png">

最もぼんやりした影です。
CoreAnimationのCALayerのlayer.shadowColor/shadowOffset/shadowRadius/shadowOpacityを指定する方法です。

layer.shadowColor以外の値はIBのkeypathで指定できます。ColorはUIColorの値になるため、layer.shadowColorはコードでセットする必要があります。ですので、 `@IBInspectable`のプロパティを増やしたサブクラスを作らないとIBで指定できません。

 ```swift
import UIKit

@IBDesignable class ShadowUIColorSettableLabel : UILabel {
    @IBInspectable var shadowUIColor: UIColor = .clear {
        didSet {
            layer.shadowColor = shadowUIColor.cgColor
        }
    }
}
 ```

画像サンプルは、shadowOpacityを0.3とし、色のアルファを1にしたものです。shadowOpacityを1とし、アルファを0.3としたものと同じ仕上がりになるようです。

# おまけ: 全部やると?

<img width="200" alt="concat.png" src="https://qiita-image-store.s3.amazonaws.com/0/84185/51672103-2233-8b8c-77cb-9bb6f9b56fad.png">

別次元の三つの影が一緒に現れた絵になります。
邪悪な感じがしますね。

# 今回のコード
**[CompareShadows](https://github.com/hsylife/CompareShadows)**
https://github.com/hsylife/CompareShadows

# 関連記事
[StoryboardでUILabelの文字に黒影つけたいよね](https://qiita.com/burakon/items/14b668c49291bab198ef)
carrierwave + heroku + rails + Cloudinary 画像投稿

#はじめに
railsでwebアプリを作成中、今回は`AWSS3`ではなく`Cloudinary`を使うことになりました。使ってみた結果、自分的には`Cloudinary`の方が使いやすかったので今度使うときのために、備忘録。
また`AWSS3`の方もまとめてあるのでよかったらどうぞ。=>https://qiita.com/yukiyukimiyaiwa/items/a9e0103c8342b81f6ac1

#前提条件
rails 5.2.1
ruby 2.5.1
Herokuにデプロイできる状態とします
今回は`User`に`image`カラムが追加されているとします

#早速やってみる

##追加・変更記述
```ruby:Gemfile
gem 'cloudinary'
gem 'carrierwave'
gem 'fog'
```
この三つを記述し`bundle install`します。（てっきりfogはAWSS3にアップするためのものかと思ってたけど、cloudinaryでも必要みたい)
`uploader`を作るので

```
$ rails g uploader Image
```
すると`app/uploaders`が作成されて、今回ならそこに`image_uploader.rb`があるはずです。これの記述を変更します

```ruby:image_uploader
class PostUploader < CarrierWave::Uploader::Base
  include Cloudinary::CarrierWave
              .
              .
 # storage :file  
              . 
              .
 
end
```
上記のように`include Cloudinary::CarrierWave`を追加します。また初期設定では`storage :file`が有効化されているので、コメントアウトしてください。
次は`user.rb`を変更

```ruby:user.rb
class User < ApplicationRecord
  mount_uploader :image, UserUploader
                .
                .
end
```
以上のように追加します。
##Herokuの設定
```
$ heroku addons:add cloudinary:starter
```
これでCloudinaryが使えるようになります。
次はHerokuからCloudinaryを開きます。
すると
![スクリーンショット 2018-12-16 21.34.11.png](https://qiita-image-store.s3.amazonaws.com/0/321520/b2dd89fc-dc88-6cd1-99e0-ce092f35be23.png)
というところがあると思います。（近くにAPIkeyとか書いてあるのでスクショはこれが限界。。。）
`YML`をクリックしてアカウントの詳細をダウンロードします。
ダウンロードした`cloudinary.yml`を`config`の下に置きます。
またこのファイルを次のように変更します。(もともと書いてあったcloud_name,api_key,api_secretは環境変数にするのでメモを取っておく。)


```yml:cloudinary.yml
---
development:
  cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %>
  api_key: <%= ENV["CLOUDINARY_API_KEY"] %>
  api_secret: <%= ENV["CLOUDINARY_API_SECRET"] %>
  enhance_image_tag: true
  static_image_support: false
production:
  cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %>
  api_key: <%= ENV["CLOUDINARY_API_KEY"] %>
  api_secret: <%= ENV["CLOUDINARY_API_SECRET"] %>
  enhance_image_tag: true
  static_image_support: true
test:
  cloud_name: <%= ENV['CLOUDINARY_CLOUD_NAME'] %>
  api_key: <%= ENV["CLOUDINARY_API_KEY"] %>
  api_secret: <%= ENV["CLOUDINARY_API_SECRET"] %>
  enhance_image_tag: true
  static_image_support: false
```
環境変数にする理由はAWSS3の時も書きましたが、悪用される危険があるからです。絶対に直接ソースコードに書き込むのはやめましょう。
環境変数の設定は以下のようにしましょう。（もちろん他の方法で環境変数を設定してもOK）

```
$ heroku config:set CLOUDINARY_CLOUD_NAME="メモしたcloud_name"
$ heroku config:set CLOUDINARY_API_KEY="メモしたapi_key"
$ heroku config:set CLOUDINARY_API_SECRET="メモしたapi_secret"
```
あとはローカル環境で試しましょう。

```
$ CLOUDINARY_CLOUD_NAME="メモしたcloud_name" CLOUDINARY_API_KEY="メモしたapi_key" CLOUDINARY_API_SECRET="メモしたapi_secret" rails s
```

これで確認したらおk
ちなみに出力は

```
<%= @user.image.to_s %>
```
で。
`.to_s`はimageカラムの時だけ（なぜかわからんけど。他のカラム名だったらいらない）

#終わり
説明は難しかったけどこっちの方が相性良い気がする。今度からこれ使おう！！！！と思って忘れないうちに殴り書きしました。間違いなどがあったらご指摘お願いします。
Pythonで競プロに挑む日誌 ~目次ページ~（移設済み）

# ページ概要
本ページは, 「Python で競プロに挑む日誌」のリンクをまとめたものです.
→技術的な側面よりも、自身のメモに近かったので、競技プログラミングに関する記事を[はてなブログ](https://darushino.hatenablog.com/)に移行しました。

# 「Python で競プロに挑む日誌」とは
三十路を過ぎたハード屋さんの男が, 何か新しいことに挑戦したくて競プロを始めました. その過程において, 特に記憶に残したいことをアウトプットするために始めた日誌です. 機械学習系の話題にも興味があったので, とりあえず Python で奮闘中です.

# 茶色時代 : 2018年12月～
[Pythonで競プロに挑む日誌 vol.27 ~正規表現~](https://qiita.com/4no3/items/fbf1999c27abce4ef667)

# 灰色時代 : 2018年8月～12月
[vol.26 ~茶色になるまでにやったこと~](https://qiita.com/4no3/items/d1fc2ab82b6063ee3117)
[vol.25 ~Pythonの罠：リスト編~](https://qiita.com/4no3/items/22fe233d1f043dc00460)
[vol.24 ~アルゴリズムはじめました~](https://qiita.com/4no3/items/97fe9476f46f3631eaad)
[vol.23 ~計算量つづき~](https://qiita.com/4no3/items/2bc8fdbc418e495ead01)
[vol.22 ~提出前のテスト~](https://qiita.com/4no3/items/516138d1a8742c94e416)
[vol.21 ~計算量ってナンデスカ~](https://qiita.com/4no3/items/a53041147abd9fef84f4)
[vol.20 ~小分けにして考える~](https://qiita.com/4no3/items/3699bd093d967974e1cb)
[vol.19 ~制約条件を利用する練習~](https://qiita.com/4no3/items/2a7270e0ec27eeff693d)
[vol.18 ~実行時間が満たせない~](https://qiita.com/4no3/items/a8608c693ad6876be9e3)
[vol.17 ~テストケースが思いつかない（解決済み）~](https://qiita.com/4no3/items/63aa57b05de28ca7d7c2)
[vol.16 ~要素が一種類のリストを作る~](https://qiita.com/4no3/items/33d01610c1532885e6d5)
[vol.15 ~zip関数~](https://qiita.com/4no3/items/cf238e77fdd212bca281)
[vol.14 ~max, min 関数の便利な使い方~](https://qiita.com/4no3/items/7849bbcb5419ac8bb462)
[vol.13 ~余剰は便利~](https://qiita.com/4no3/items/b2d1d9c7497dd206f616)
[vol.12 ~eval 関数~](https://qiita.com/4no3/items/44fecd393fc656c74d08)
[vol.11 ~for 文中の "_"~](https://qiita.com/4no3/items/fd824567ab3d229df197)
[vol.10 ~文字列調査~](https://qiita.com/4no3/items/dc610206ea5b6760cfe0)
[vol.9 ~余剰とグループ分け~](https://qiita.com/4no3/items/e02f4f1e4f79371408a1)
[vol.8 ~文字列 replace~](https://qiita.com/4no3/items/431d49d02404c61c65c3)
[vol.7 ~制約条件の利用と, sys.exit() による中断~](https://qiita.com/4no3/items/9a8bb7433786347444c8)
[vol.6 ~集合型の内包表記~](https://qiita.com/4no3/items/07e4dbff6c611182c2cb)
[vol.5 ~リスト操作の基本~](https://qiita.com/4no3/items/45c2131407d34a8520ec)
[vol.4 ~and と or~](https://qiita.com/4no3/items/1035ffb5a4f6374cc9df)
[vol.3-2 ~内包表記の練習~](https://qiita.com/4no3/items/f2ceaf430a44874dfb2a)
[vol.3-1 ~内包表記との出会い~](https://qiita.com/4no3/items/1f19dce079e4a360029d)
[vol.2 ~all, any 関数. generator との出会い~](https://qiita.com/4no3/items/838de0a8867e1e99964d)
[vol.1 ~はじめの一歩~](https://qiita.com/4no3/items/e0d9559852962208b9a6)
インフラ運用で利用している Windows 上のツール紹介

このブログは、[大国魂（ITブログ） Advent Calendar 2018](https://adventar.org/calendars/3489) の16日目です。

# 書いた人について
普段はサーバ、ネットワーク周りのインフラ運用をしています。

# この記事の内容について
サーバ、ネットワーク周りのインフラ運用で利用しているツールを紹介します。

よくある Windows Server の踏み台から各機器にアクセスする構成を想定して、
Windows Server でどんなツールを利用しているかを、利用頻度の高い RLogin、ExPing、WinShot の3点に絞って紹介します。

# RLogin
## 概要
Tera Term や PuTTY 等と同じターミナルソフトです。
基本的な使用方法は以下の記事が詳しいです。
[Windowsターミナルソフト + Rlogin が最高すぎる！！](https://qiita.com/murachi1208/items/d6e4ce7ba75f1625fe51)
[ターミナルソフトウェア RLogin のよく使う機能](https://qiita.com/kitakitash/items/2c60b061c4c490be805b)

本家は以下となります。
不明点はほぼこちらの説明で理解できるかと思います。
[RLogin](http://nanno.dip.jp/softlib/man/rlogin/)

機器に直接(コンソール)接続する際も利用可能なため、
ここ数年はよほどの事情がない限り RLogin 以外を使っていません。

## 便利な点
### 作業効率、操作の観点での利便性
ソフトを複数起動することなく複数の接続先に対する作業をタブで分けたり、画面分割して便利に使えます。
上記に加えて分割・タブの単位で同じコマンドを送信できるので、主に以下のようなシチュエーションでこの機能を使っています。

1.  **ログを見ながら作業したいとき。**
同じホストを縦に2分割で開いて、
片方では作業に関連するログを tail -f しつつもう片方で作業する。
1.  **同じはずの設定などをざっと目 grep したいとき。**
ネットワーク機器含み、設定やログを目grepしたいときに異なるホストを縦分割で作業。
1.  **複数ホストに対して同じ操作をしたいとき。**
個人的な限界は6分割だと思っていますが、
同じ作業を繰り返さず、一括送信で作業回数を減らせます。

### ヒューマンエラー(HE)予防
接続ホスト単位で画面の色、フォント、接続先ホストのタブ分けなどが可能です。

1.  **環境誤りの予防(接続前)**
RLogin 起動時に表示される接続先ホスト一覧を、
「本番」「検証」「開発」
などの、危険を回避したい単位のタブで分けておきます。
2.  **環境誤りの予防(接続後)**
上記の接続先ホスト一覧のタブ単位で画面の色を変えておきます。
また、設定画面の カラー -> 背景設定 からテキスト描画の項目を設定すると、
画面上に IP アドレスやホスト名を表示できるため、より分かりやすいです。
3.  **作業時の予防**
用意した設定をコピペしたい時などの HE 予防です。
設定画面の クリップボード から
[右クリックでペースト] と [常にクリップボードからペーストするテキストを確認する]
設定をしておくことで、ペーストしようとしている内容をペースト前に確認可能です。
特にネットワーク機器で conf t した後の作業は安心感を持って進められます。
サーバだと rm -rf hoge するような場合に安心です。
4.  **コマンド一括送信時の予防**
[RLogin メニューの 編集 -> 見えてるだけに制限] で、
コマンド一括送信の対象を見えているタブだけに絞り込みます。
この設定をしないと見えていないタブにも一括送信されてしまうため、後でヒヤッとするかもしれません。
見えているタブについては、タブのチェックを外すことで一括送信の対象から外せます。

### 引継ぎが簡単
[インストールおよびアンインストール](http://nanno.dip.jp/softlib/man/rlogin/#INSTALL)に記載されているとおり、RLogin.ini を作成しておくことで、
ぼくがかんがえたさいきょうの設定済みホスト一覧や各種設定を新規参入者に簡単に引き継げます。
同じセットアップをみんなやる、というのは効率悪いですからね。
サーバ接続用の鍵ファイルなどを同梱しないように注意しましょう。

# ExPing
## 概要
かわいいチューリップアイコンの ping 疎通確認用ソフトです。
それほど工夫した使い方はしていないので、詳細は説明しません。

## 便利な点

### 複数ホストへの ping 一括送信
1.  **新規 IP アドレス割り当て時の確認。**
便利な点筆頭として、ping の失敗/成功の日時情報が表示されるため、
動かしておけばいつまで ping NG で、いつから ping OK かがはっきりわかります。
2.  **環境メンテナンスをはじめとした、それなりの規模の作業時などの影響確認。**
複数機器にローテーションしながら ping を打てるので、
主要な機器を登録して ping を打ち続けられます。
こうしておくことで、各作業で機器との疎通が止まるような作業がなかったことや、
何らかの問題が発生した際に、いつどの機器に ping が届かなくなったという問題切り分けがしやすいです。

### Ping 対象保存機能
RLogin の接続先ホスト一覧のタブと同じように、「対象」タブの中身を作成して保存しておけます。
作業ごとに ping 対象を切り替えられる(同じ機器のIPを何度も書かなくてよい)ので楽ができます。

# WinShot
## 概要

ホットキーの設定をすることで、アクティブウインドウのスクリーンショット(JPEG)の自動生成が可能です。
ターミナルのログが取れない Web GUI での操作時に、どのような作業をしたかエビデンスとして残せます。

※範囲指定をしての画面ショットは Windows + Shift + s が便利だと思います。
  mspaint を起動して貼り付けて保存するなどひと手間かかりますが。

## 便利な点
### 日時情報を残せる
設定の文字埋め込みタブで キャプチャ画像に文字列を埋め込む にチェックを入れると、
取得したキャプチャ画像の特定の位置(右下で使っています)に取得した日時情報を残せます。
時系列がわかるので、エビデンスとして整理しやすいです。

なお、ファイル名も日時情報に変更可能です。
Windows 10 だと残念ながら(まっとうな手段で)ヘルプファイルを開けないため、
適当にググった情報などを参考に設定いただければと思います。

# 終わりに
以上、よく使う3点のツールと用例紹介でした。
たまに使う DiskInfo などもあるのですが、こういったものの紹介はまたの機会にできればと思います。

また、こういったツールが便利、使い方が便利、などといったこともご教示いただけますとありがたいです。
php-master-changes 2018-12-15

今日は CSV 操作系の関数で不要なエスケープを無効化できるようにする修正があった！

# 2018-12-15
## cmb69: Allow empty $escape to eschew escaping CSV
- https://github.com/php/php-src/commit/3b0f05119383fe21ee75adaed3d0239ba8976aef
- CSV 読み書き系の関数で引数 `$escape` に空文字列を渡せるよう修正
- 以前に[会社ブログで取り上げてた](https://www.infiniteloop.co.jp/blog/2018/10/php-news-4/)やつ
- 結局 [internals の議論](https://externals.io/message/103268#103538)の中で、「読み書きのデフォルト変えると、昔 PHP で吐いたデータが PHP で読めない、みたいな事態になるし、書き込みだけデフォルト変えると一貫性なくなるし、空文字列でのエスケープ無効化指定だけ入れる、でいいんじゃね？それだと互換性も崩れないし RFC もなしでいいしょ」という話になり、[PR:3515](https://github.com/php/php-src/pull/3515) がマージ
Progateコマンドライン編まとめ

##【Progateコマンドライン編まとめ】

linuxをインストールしたので、progateのコマンドライン編をやってみました。

progateのようにlinuxコマンドを学べるサイトないのかな。

```
ファイル作成
$touch 〇〇〇.拡張子
```

```
ファイルの中身を確認する
$cat ファイル名
```

```
フォルダ（ディレクトリ）を作成する
$mkdir ディレクトリ名　（make directoryの略）
```

```
現在のディレクトリを表示 (print working directory)
＄pwd
```

```
現在のディレクトリと、１つ子のディレクトリにあるファイルやフォルダを表示
$ls
```

```
ディレクトリを移動する (change directory)
$cd 移動先のディレクトリ名
```

```
ディレクトリを戻す（一つ親のディレクトリへ移動する）
$cd ..
```

```
ホームディレクトリに戻る
$cd
一番上のディレクトリ＝ルートディレクトリ
[/」と表示される
ホームディレクトリ(ユーザーが作業するときの起点となるディレクトリ）
「~」で表示される
```

```
ファイルを移動させる
$mv 移動させたいファイル名 移動先のディレイクトリ名
```

```
ディレクトリを移動させる
$mv 移動させたいディレクトリ名 移動先のディレクトリ名
```

```
ファイルを削除する
$rm 削除したいファイル名
```

```
ディレクトリを削除する
$rm -r 削除したいディレクトリ名
```

```
空のディレクトリを削除する
$rmdir ディレクトリ名
```

```
ファイルをコピーする
$cp コピーしたいファイル名 新しいファイル名
```

```
プロセス状態を確認する(使用メモリ率やプロセスID、CPU利用率が表示される)
$ps
```

```
rails serverを強制的に切る
$ps aux | grep puma

$kill -9 〇〇〇〇プロセスID
```


```
コンソール内をリセットする
$clear
```

```
コマンドの履歴を表示する(clearしても履歴は確認可）
$history
```
autolayoutとsafearea

# 目的
iPhoneX対応を調査してる段階で、AutoLayoutで、理解を曖昧にしてる部分を見直そうと思った。
ついでに、safeAreaも理解しておかないと、この先に進めなさそうだったので、そこもまとめてみる。

## view表示の大まかな流れ
* Viewの読み込み
* 制約の追加（AutoLayout）
* 制約を元にViewのframeを計算（レイアウト）
* frameの位置に描画（レンダリング）

### 思ったのは

viewDidLayoutSubviewsとかで、レイアウト更新すると、
再度描画し直すので、処理が重くなるっぽい。

最終調整したいなら、viewDidAppearかな？

autolayout使ってるなら、constraintを積極的に使う。

## 流れの説明部分の図


<img width="386" alt="スクリーンショット 2018-11-14 7.05.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/13807/051949e6-7f5d-152e-a36c-91c14652ac8d.png">



## boundsとframeの違いについて
いままでちゃんと理解してなかったので、しっかり理解してみた。

### frame
x,yのポジションは親viewからの位置を示す
サイズはboundsと一緒かな

### bounds
x,yは自分からの位置を示すので、基本(0.0)

### イメージ図
こんな感じ


![frame_vs_bounds.png](https://qiita-image-store.s3.amazonaws.com/0/13807/55936595-43c3-a3c2-800f-ce5db08feb2b.png)


## safeareaに関して
iPhoneXが導入されたことによって、出てきたもの。
iPhoneX以上のサイズのデバイスでは、必須。

### safeAreaの領域

添付の図のような感じ
![スクリーンショット 2018-11-14 17.48.31.png](https://qiita-image-store.s3.amazonaws.com/0/13807/5d5507b6-8eba-fd17-e591-cc54e1d2ee3e.png)


### safeAreaのサイズを取得するために

それ以外の機能も備えてるが、view系のデータをまとめて管理するため、以下のファイルを作成
```
//
//  ViewManager.swift
//  shotworks_customer
//
//  Created by 平塚 俊輔 on 2018/11/12.
//  Copyright © 2018 ‚àö√á≈ì√Ñ‚Äö√¢‚Ä¢‚àö√á¬¨‚àû‚àö‚àÇ ‚Äö√Ñ‚àû‚àö‚àè‚àö¬ß‚àö√£¬¨‚à´‚àö√Ü. All rights reserved.
//

import Foundation


/// view系の値管理
struct ViewManager {
    
    static let rootViewController = UIApplication.shared.keyWindow?.rootViewController
    
    static let statusBarHeight = UIApplication.shared.statusBarFrame.size.height
    
    static var currentWindow: UIWindow? {
        if let window = UIApplication.shared.keyWindow {
            return window
        } else {
            return UIApplication.shared.windows[safe:0]
        }
    }
    
    // デフォルトFloat(44)としてUnwrap
    static func navigationBarHeight(callFrom: UIViewController) -> CGFloat {
        return callFrom.navigationController?.navigationBar.frame.size.height ?? 44
    }
    
    // デフォルトFloat(44)としてUnwrap
    static func tabBarHeight(callFrom: UIViewController) -> CGFloat {
        return callFrom.tabBarController?.tabBar.frame.size.height ?? 52
    }
    
    
    /// topのsafeArea
    static var topSafeArea: CGFloat{
        
        if #available(iOS 11.0, *) {
            return ViewManager.currentWindow?.safeAreaInsets.top ?? 0
        }else{
            return 0
        }
    }
    
    /// bottomのsafeArea
    static var bottomSafeArea: CGFloat{
        
        if #available(iOS 11.0, *) {
            return ViewManager.currentWindow?.safeAreaInsets.bottom ?? 0
        }else{
            return 0
        }
    }
}

```

# 参照
https://qiita.com/shtnkgm/items/f133f73baaa71172efb2
Bigl〇beで借りているルーターのipアドレスを確認する方法

IPアドレスを固定するときにちょっと行き詰ったため備忘録として。

Bigl〇beからルーターを借りたがそのルーターのIPアドレスがわからん状態だった。
それで、機器の外部見たけど、そんな情報載ってなさそうなので安心サポートさんに聞いた。

どうやら「ipconfig /all」をコマンドプロンプトで入力して、「イーサネット アダプター イーサネット」
欄の「自動構成 IPv4 アドレス」ってのがルーターのIPアドレスらしい。

![無題.png](https://qiita-image-store.s3.amazonaws.com/0/157809/d0bd5a07-c415-2dd6-829c-7aa824ae0e94.png)

「ipconfig」のコマンド自体は知っていたんだがな・・・。見るべき項目がわからなかった・・・。