OmniAICreator/Qiita-1.07M huggingface dataset:
Mac版PhpStormにPHP CodeSnifferを統合する方法

本稿ではMacのPhpStormにPHP CodeSnifferを統合し、エディタ上でコードの問題点を確認できるようにする設定方法を紹介する。

## phpcsコマンドをインストールする

composerでphpcsをインストールする。

```
composer global require "squizlabs/php_codesniffer=3.2.3"
```

## バージョンを確認する

```shell-session
$ ~/.composer/vendor/bin/phpcs --version
PHP_CodeSniffer version 3.2.3 (stable) by Squiz (http://www.squiz.net)
```

## PhpStormの設定手順

### phpcsの設定をする

「Code Sniffer」の設定画面で「･･･」ボタンを押す:

<img width="1030" alt="Preferences.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/fc95ce03-ccbf-ba0a-ad08-d1e61c47efbf.png">

`phpcs`のフルパスを調べる

```
ls ~/.composer/vendor/bin/phpcs
/Users/suin/.composer/vendor/bin/phpcs
```

「PHP Code Sniffer (phpcs) path」に上で調べたフルパス「/Users/suin/.composer/vendor/bin/phpcs」等を入力し「Validate」を押す。問題なければ「OK」ボタンを押す。

<img width="824" alt="Code_Sniffer.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/7f3408f9-9543-856c-3fbe-d86cdebc157c.png">

### Inspectionsの設定でPHP Code Snifferを有効化する

ここでは下記の2とおりの設定方法を紹介する。

1. PSR2のコーディング標準を使う場合
2. 独自のコーディング基準設定ファイル`phpcs.xml`を使う場合

必要に応じて設定方法を選択してほしい。

#### 1. PSR2のコーディング標準を使う場合

設定の検索窓で「Code Sniffer」を入れ、「Editor」→「Inspections」の「PHP Code Sniffer validation」を探し、それにチェックを入れる。「Severity」(警告度)は「Warning」に変える。「Coding Standard」は「PSR2」にする。

<img width="1030" alt="Preferences.png" src="https://qiita-image-store.s3.amazonaws.com/0/889/9107f8fd-bc04-cff4-a351-38c083f456a0.png">

#### 2. 独自のコーディング基準設定ファイル`phpcs.xml`を使う場合

設定の検索窓で「Code Sniffer」を入れ、「Editor」→「Inspections」の「PHP Code Sniffer validation」を探し、それにチェックを入れる。「Severity」(警告度)は「Warning」に変える。

「Coding Standard」は「Custom」にし、「Custom Coding Standard」ウィンドウを開いたら、「Path to ruleset」にXMLのパスを指定する。

<img width="1032" src="https://qiita-image-store.s3.amazonaws.com/0/889/88e5cad7-be43-877e-5049-5c11ea7e0f0a.png">
Web API ~the good parts~を読んで

# Web API ~the good parts~を読んで

![91iQh271SHL.jpg](https://qiita-image-store.s3.amazonaws.com/0/31272/debe69a8-9fb1-08c3-1f6a-4fea927bc68f.jpeg)


せっかく読んだのでまとめます。
自分が公開するAPIを開発するためだけでなく、サーバーとクライアント側に分れたプロダクトを開発する際にも応用できます。
#### この本を読んで学べる事
・どのようにwebAPIを開発するべきか
・クライアントとサーバーサイドどこでデータを区切るのか
・openでもclosedでも明確でわかりやすく汎用的なwebAPIを作る事が大事(言うは易し)


2章と3章が対になっている


# 1章　webAPIとは?
ここはイントロなので割愛
# 2章 エンドポイントの設計とリクエストの形式
良いエンドポイントとは

* 短いこと

* 読んで理解できる
  ☓ http://xxxxx.com/api/p0101/c0704/lawyer
↑何かの条件で絞り込まれた弁護士がとれそう？
  ○ http://xxxxx.com/api/lawyer/prefecture=1&category=4
↑県とカテゴリーの条件で絞り込まれた弁護士が取れると推測できる

* 大小小文字なし
 ☓　http://xxxxx.com/getLawyer
　文字をつなぐ時はハイフンでつなぐ(googleが推奨)また、ディレクトリを切るとディレクトリを切る必要がなくなる。

* 改造しやすい
☓　https://xxxxx.com/c0500
○　https://xxxxx.com/api/cagegory/1
1の数値を変えたら他のcategoryについての情報がとれそう
* サーバーのアーキテクチャーが反映されていない
☓　xxxx.com/cgi-bin/lawyer/1/pricings
↑サーバーのディレクトリ配置が推測できるためセキュリティーリスクにつながる
○　xxxx.com/lawyer/1/pricings

## 件数の取得位置が明確である
 
|サービス名  |取得数  |相対位置  |絶対位置|
|---|---|---|---|
|twiiter  |count  |cursor  | max_id |
|youtube  |maxResults  |pageToken | publishBefore  |

などがあるが

筆者のおすすめは 
page/per_pageまたはoffset/limitである。

* 統一されたルールで開発されている事が大事

## memo

urlにsearchを入れる入れない問題
一覧を取得するのか検索結果を返すかによるのでサービスを意識すると良い

自社用のAPIを開発するならば、1ページに複数要素がある場合(トップページなど)パーツごとにAPIを作っていると何度も通信を発生させないといけないケースがあるので1リクエストに複数情報を入れるという手もある。		

# 3章　レスポンスデータの設計

## データ形式

海外サービスのほとんどがjson形式だが複数形式をサポートしないといけない場合は urlの後ろに?format=jsonみたいに指定できるようにするとgood

## データはフラットにする

``` json
{
	id: 1,
	name : 'kousuke tanihata',
	profile :{
		gender : 'male'
	}
}

```

↑のように不要なネストを避ける

## ページネーションをどのように表現するか

``` json
{
	profile : 
	{
		id: 1,
		name : 'kousuke tanihata',
	},
	{
		id: 2,
		name : 'j j',
	},
	hasNext : true,
}
```

## エラーがある際はhttp statusを利用する

エラーがあった際はhttp statusをだけでなくにエラーの原因/要因を適切に伝える事が大事

``` json
{
    status : 404,
	error_message : 'idが指定されていません',
}
```

``` json
{
    status : 500,
	error_message : 'サーバーの不具合です。',
}
```

## エラーの詳細を伝える

``` json
{
    'errors'[
        message : 'bad Auth data',
        url : 'doc.fshuh.com/fagahua',
    ]

}
```
↑誤ってhtmlを返さないように設計する
API使用者側がエラーを処理する難易度があがる(経験済み)

# 4章　　httpの仕様を利用する

| 番号代 |意味  |
|---|---|
|100 |情報  |
|200  |成功 |
|300  |リダイレクト	  |
|400  |ユーザー要因のエラー	  |
|300  |サーバー要因のエラー	|

詳細↓
https://gist.github.com/rosylilly/3401612

上記のhttpメソッドを利用する事で getLawyerのようなurlを作成しなくすむ

## 200番台
202　Accepted ファイルアップロード中
204 No Content 削除完了

## 300番台
API設計では極力使わない
使うならドキュメントに書くようにする

##  400番台
405 httpメソッドが間違っている
406 フォーマットがエラー
409 Conflict リソースが競合している(指定されたIDやemailがすでに使用されている)
429 レートリミットを超えている

## 500番台
500　サーバエラー
504 一時的なエラー

リクエストを返す際には必ずメディアタイプを指定する

# 5章　設定変更をしやすいWeb APIを作る

urlを/v1　とか/v2で分けるのがオススメ(versionの区切りをメディアクエリーにすると冗長になる)
ドキュメントに廃止期間を明示する。

# 6章　堅牢なwebAPiを作る~安定性と安全性~
## 安全性
セキュリティー問題について
0,誤った設定で個人情報が公開された状態になっていたケースがある。
1,まずはhttps化しよう
2,xssに気をつける
json を返すならcontent-typeの値がtext/htmlではなく　Content-Type: application/jsonに設定する
Mastodonのメディアファイルをminioに移す

# 前提条件

* Mastodon、minioが構築されていること

# 制約事項

* Mastodon → minio間はローカル接続されていること。

# 目的

* Mastodonのメディアファイル(アバター、ヘッダ、添付画像等)をminioに移したい。
* メディアファイルは、Nginxのリバースプロキシ経由で配信したい。

# 手順

## minio側の準備

### 1. アクセスキー、シークレットキーを準備する

`config.json` に記載されている。

[以前の記事](https://qiita.com/kumasun/items/026608a36460f379478d) の通り構築しているのならば、 `/home/minio/config/` 内に存在する。

そうでない場合は、`~/.minio/config/` に存在するかも？

```json:config.json
{
        "version": "25",
        "credential": {
                "accessKey": "HOGEHOGEHOGEHOGE",
                "secretKey": "FUGAFUGA123FUGAFUGA123FUGAFUGA123FUGAFUGA123"
        },
        "region": "",
        "browser": "on",

          (以下略)
```

なお、このファイルを編集することでキーを変更することが可能。
書き換えたら`minio`の再起動を。

### 2. 専用のバケット(フォルダのようなもの)を準備する

1. にて準備したアクセスキー、シークレットキーを用いて `minio Browser`にログインする。

右下の(+)をクリックし、続けて`Create bucket`をクリックする。

![movie](https://qiita-image-store.s3.amazonaws.com/0/129737/9bd33d9a-96b4-b377-f42b-54a1dc98402f.gif)


`Bucket name`は、それっぽい名前をつける。（外に出るので、かっこいい名前をつけよう！）

この`Bucket name`は、後で使用するので控えておく。


3. バケットに読み書きできるポリシーを設定する

左のバケット一覧より、対象のバケットを選択し、「・・・」をクリック後、`Edit policy`をクリック。

![movie](https://qiita-image-store.s3.amazonaws.com/0/129737/e8dd66de-01d2-3b09-2522-7519ed0ca580.gif)

`Prefix`は空白のまま、右のドロップダウンを`Read and Write`に変更し、`Add`をクリック。(×) で閉じる。



## Mastodon側の準備

### .env.production の編集

S3(Minio)の設定がコメントアウトされた状態なので、これを編集する。

```ini:.env.production
# S3 (Minio Config (optional) Please check Minio instance for details)
S3_ENABLED=true
S3_BUCKET=test
AWS_ACCESS_KEY_ID=HOGEHOGEHOGEHOGE
AWS_SECRET_ACCESS_KEY=FUGAFUGA123FUGAFUGA123FUGAFUGA123FUGAFUGA123
#S3_REGION=
S3_PROTOCOL=https
S3_HOSTNAME=mstdn.example
S3_ENDPOINT=http://10.1.1.5/
# S3_SIGNATURE_VERSION=
```

| .env.production オプション | 設定値 |
|----------|------------|
| `S3_BUCKET` | minio上のバケット名|
| `AWS_ACCESS_KEY_ID` | minioの`accessKey` |
| `AWS_SECRET_ACCESS_KEY` | minioの`secretKey`|
| `S3_PROTOCOL` | Mastodonがサービスを行っているプロトコル(ほとんどの場合 `https`)|
| `S3_HOSTNAME` | Mastodonのホスト名 |
| `S3_ENDPOINT` | minioのURL |

たとえば上記のように設定すると

* Mastodonが表示する画像のURL先： `https://mstdn.example/test/media_attachments/...` 
* Mastodonが画像を転送する先： `http://10.1.1.5/`

となる。


### Nginxの設定追加

`test`配下へのアクセスを全てminioに回さないといけないので、そのあたりの設定を追加する。

```config:(nginx)mastodon.conf
(前略)

  location ~ ^/test{
    # minio Object Storage
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy "";
    proxy_pass_header Server;

    proxy_pass http://10.1.1.5;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;

    tcp_nodelay on;
  }

(後略)
```

### 既存の画像ファイルの転送

Mastodonの `live/public/system` 以下のディレクトリを、まるっとそのまま minioのバケットに放り込む。

### サービス再起動

Mastodonサーバにて、MastodonおよびNginxサービスを再起動する。


## 動作確認する

Mastodonにアクセスする。

画像が表示されていること、画像が投稿できることを確認できたら成功。 :tada:


# あとがき

* 自分用にメモした手順です。必要に応じて読み替えてください。
* こうしたほうがいいよ的なアドバイスを頂けると大変助かります


以上
Droidcamでカメラの画質を変更する

##Droidcamで画質を変更する方法
Linux OSをインストールして、古いパソコンで作業中ですが、Droidcamを使って、スマホのから転送される映像の画質を落とせば、パソコンで表示される映像のズレが小さくなると考えた。
しばらく、映像をうつしぱなしをしていると、この遅れがだんだん大きくなる。メモリの問題や、USBの問題をいまは疑っている。
Laravel で MongoDB のデータをテーブル表示

次のプログラムを改造して、もう少し複雑なことをしてみます。
[Laravel で MongoDB のデータを表示](https://qiita.com/ekzemplaro/items/01ed3383856c782ee77e)

次のようなテーブルの表示です。
![cities_jun1201.png](https://qiita-image-store.s3.amazonaws.com/0/179446/13dc8623-3d0e-7dcd-a1df-bf2ac3419c05.png)


MongoDB のデータは、
>データベース: city
コレクション: saitama
です。

MongoDB のデータ

```text
$ mongosh
(省略)
test> use city
switched to db city
city> db.saitama.find()
[
  {
    _id: ObjectId("61fcc4838ad033156d4d33c2"),
    key: 't1161',
    name: 'さいたま',
    population: 72136,
    date_mod: '2002-5-18'
  },
  {
    _id: ObjectId("61fcc4838ad033156d4d33c3"),
    key: 't1162',
    name: '所沢',
    population: 41378,
    date_mod: '2002-9-12'
  },

(省略)
city>
```

次の３つのファイルを編集します。
>.env
>app/Post.php
>resources/views/index.blade.php

1) データベースの指定
>次の行を編集

```text:.env
// 略
DB_DATABASE=city
// 略
```

2) コレクションの指定

```php:app/Post.php
<?php
namespace App;
class Post extends \Moloquent
{
    protected $collection = 'saitama';
}
```

3) テーブルの表示

```php:resources/views/index.blade.php
<div>全部で{{ count($posts) }}件です。</div>
<p />
<table>
  @foreach($posts as $post)
	<tr>
	<td>{{ $post['key']}}</td>
	<td>{{ $post['name']}}</td>
	<td>{{ $post['population']}}</td>
	<td>{{ $post['date_mod']}}</td>
	</tr>
  @endforeach
</table>
```

次の環境で確認しました。

```text
$ uname -a
Linux iwata 5.13.0-27-generic #29-Ubuntu SMP Wed Jan 12 17:36:47 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

$ php --version
PHP 8.0.8 (cli) (built: Oct 26 2021 11:42:42) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.8, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.8, Copyright (c), by Zend Technologies

$ php artisan --version
Laravel Framework 8.82.0
```
[Deprecated] SwiftGenのConfigFile.md（SwiftGen.ymlの書き方）が、現行バージョンの5.3.0に関する内容ではない

SwiftGen 6系がリリースされて、めでたく`"paths"`keyが`"inputs"`keyにrenameされていましたので本記事はお役御免となりました。
ちなみに、2019/07/06時点でのSwiftGenの最新版は`6.1.0`です。

https://github.com/SwiftGen/SwiftGen/releases/tag/6.0.0

```
The swiftgen.yml config file now accepts multiple outputs for each command, allowing you to generate multiple outputs from the same files and content. This also means that the output parameter is now deprecated, in favour of the outputs parameter, and it may be removed in a future version of SwiftGen. Similarly, the paths parameter has been renamed to inputs for consistency. You can always use swiftgen config lint to validate your configuration file.
```

以下は元記事です。

---
ドキュメントで推奨している通りに`swiftgen.yml`の設定をしたのに、エラーになってハマったのでメモしておきます。

# 環境
|ツール|バージョン|
|:-:|:-:|
|SwiftGen|5.3.0|

# ハマった現象
SwiftGenの`master`にある[ConfigFile.md](https://github.com/SwiftGen/SwiftGen/blob/master/Documentation/ConfigFile.md)に書かれている推奨設定でswiftgen.ymlを作成すると、以下のエラーが発生します。

```
Missing entry for key xxxx.paths.
Command /bin/sh failed with exit code 1
```

# 原因
SwiftGenの`master`にある[ConfigFile.md](https://github.com/SwiftGen/SwiftGen/blob/master/Documentation/ConfigFile.md)が、リリース前の最新バージョンの内容になっていることが原因。
最新バージョンでは現行バージョンの`5.3.0`には存在しない`"inputs"`keyが追加＆推奨されていたため、`5.3.0`では必須の`"paths"`keyが見つからないエラーが発生していました。

|Branch/Tag|URL|
|:-:|:-:|
|master|https://github.com/SwiftGen/SwiftGen/blob/master/Documentation/ConfigFile.md|


```master-example-swiftgen.yml
input_dir: Sources/Resources
output_dir: Sources/Generated/
strings:
  inputs: Base.lproj/Localizable.strings
  outputs:
    - templateName: structured-swift3
      output: L10n-Constants.swift
xcassets:
  - inputs: Logos.xcassets
    outputs:
      - templateName: swift3
        output: Logos-Constants.swift
        params:
          enumName: Logos
  - inputs:
      - Colors.xcassets
      - Images.xcassets
    outputs:
      - templatePath: customswift3
        output: Assets-Constants.swift
```

# 回避方法
現行バージョンのTag `5.3.0`に紐づいた[ConfigFile.md](https://github.com/SwiftGen/SwiftGen/blob/5.3.0/Documentation/ConfigFile.md)の内容は正しいので、こちらを参照してSwiftGen.ymlを作成することで問題なく実行できます。

|Branch/Tag|URL|
|:-:|:-:|
|5.3.0|https://github.com/SwiftGen/SwiftGen/blob/5.3.0/Documentation/ConfigFile.md|

```5.3.0-example-swiftgen.yml
input_dir: Sources/Resources
output_dir: Sources/Generated/
strings:
  paths: Base.lproj/Localizable.strings
  templateName: structured-swift3
  output: L10n-Constants.swift
xcassets:
  - paths: Logos.xcassets
    templateName: swift3
    output: Logos-Constants.swift
    params:
      enumName: Logos
  - paths:
      - Colors.xcassets
      - Images.xcassets
    templatePath: customswift3
    output: Assets-Constants.swift
```

# 備考
本件についてはすでに下記Issueで議論されていたので、近日中にmasterのドキュメントが修正される可能性はありそうです。

* [Configuration file fails: "Missing entry for key xcassets.paths."](https://github.com/SwiftGen/SwiftGen/issues/431)
UIWebViewでスクロールに応じてナビゲーションバー/ツールバーを表示/非表示にする

UIWebView(WKWebViewではない！)を利用している画面で、スクロールに応じてナビゲーションバー/ツールバーを
表示/非表示にする機会があったのでメモ

##パターン1

hidesBarsOnSwipeをtrueにセットするだけでOK
ただし、私の環境(iOS11.3)において、UIWebViewでこれを利用してもアニメーションがおかしくなった...

https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621883-hidesbarsonswipe

```
override func viewDidLoad() {

	self.navigationController?.setNavigationBarHidden(false, animated: true)
	self.navigationController?.setToolbarHidden(false, animated: true)
	self.navigationController?.hidesBarsOnSwipe = true
}
```

##パターン2

UIWebViewにUIScrollViewDelegateをセット
scroll位置を取得し、移動量に従ってsetToolbarHidden/setNavigationBarHiddenにtrue/falseを設定する

```
override func viewDidLoad() {

	self.navigationController?.setNavigationBarHidden(false, animated: true)
	self.navigationController?.setToolbarHidden(false, animated: true)
	webview?.scrollView.delegate = self
}
```

```
extension MyViewController: UIScrollViewDelegate {
    
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        scrollBeginPoint = scrollView.contentOffset
    }
    
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        let scrollEndPoint = scrollView.contentOffset

        if isBarShowing == true && scrollBeginPoint.y < scrollEndPoint.y {
            self.navigationController?.setToolbarHidden(true, animated: true)
            self.navigationController?.setNavigationBarHidden(true, animated: true)
            isBarShowing = false
        } else if isBarShowing == false && scrollBeginPoint.y > scrollEndPoint.y{
            self.navigationController?.setToolbarHidden(false, animated: true)
            self.navigationController?.setNavigationBarHidden(false, animated: true)
            isBarShowing = true
        }
    }
}
```
##パターン3

scrollから値をとるのではなく、Gestureで判定したものから移動量に従ってsetToolbarHidden/setNavigationBarHiddenにtrue/falseを設定する

```
class MyViewController: UIViewController {
	
	var isBarShowing = true
	
```

```
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let upSwipe = UISwipeGestureRecognizer(target: self, action: #selector(didUpSwipe(_:)))
        upSwipe.direction = .up
        upSwipe.delegate = self
        let downSwipe = UISwipeGestureRecognizer(target: self, action: #selector(didDownSwipe(_:)))
        downSwipe.direction = .down
        downSwipe.delegate = self
        self.view.addGestureRecognizer(upSwipe)
        self.view.addGestureRecognizer(downSwipe)
    }
```

```
    @objc func didUpSwipe(_ sender: UITapGestureRecognizer) {
        if isBarShowing {
            self.navigationController?.setToolbarHidden(true, animated: true)
            self.navigationController?.setNavigationBarHidden(true, animated: true)
            isBarShowing = false
        }
    }
    
    @objc func didDownSwipe(_ sender: UITapGestureRecognizer) {
        if !isBarShowing {
            self.navigationController?.setToolbarHidden(false, animated: true)
            self.navigationController?.setNavigationBarHidden(false, animated: true)
            isBarShowing = true
        }
    }
```
Devise_invitationで招待をアクセプトする際に名前も登録できるようにする。

* 以下のサイトが非常に参考になったが、deviseの変数許可の部分ではまったのでメモ。

https://qiita.com/himatani/items/907900f1f0d0e4f379b5


```ruby:app/controllers/application_controller.rb
省略

before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:invite, keys: [:email])
    devise_parameter_sanitizer.permit(:accept_invitation, keys: [:password, :password_confirmation, :invitation_token, :name])
  end
```

参考
https://qiita.com/ry023/items/c6a469f65615f796be45

追加

ちなみに、プロフィール変更の場合は、:account_updateが許可対象になる。
GoのSliceの重複をMapを使って削除する

# GoのSliceの重複をMapを使って削除する

## ポイント
* mapの第二引数は、keyが存在するかどうかの真偽値なのでそれを使う
* Sliceのある値が存在するかどうかをMapで表し、MapのKeyにSliceの実際の値を入れ、Valueに存在することを表すstruct{}{}を入れる


参考: [急いで学ぶGo lang#7 range・Array・slice・map ｜ Developers.IO](https://dev.classmethod.jp/go/golang-7/)

## コード

```go
package main

import "fmt"

func main() {
	list := []string{"Go", "Java", "Python", "Go", "Ruby", "Go"}

	m := make(map[string]struct{})

	newList := make([]string, 0)

	for _, element := range list {
		// mapでは、第二引数にその値が入っているかどうかの真偽値が入っている
		if _, ok := m[element]; !ok {
			m[element] = struct{}{}
			newList = append(newList, element)
		}
	}

	fmt.Printf("mapの中身 %#v\n", m)
	fmt.Printf("重複削除後 %#v\n", newList)
}
```

### 実行結果

```
mapの中身 map[string]struct {}{"Go":struct {}{}, "Java":struct {}{}, "Python":struct {}{}, "Ruby":struct {}{}}
重複削除後 []string{"Go", "Java", "Python", "Ruby"}
```

実際のコードは[こちら](https://play.golang.org/p/_9FCg-f5JEd)


## 参考にさせていただいた記事
[急いで学ぶGo lang#7 range・Array・slice・map ｜ Developers.IO](https://dev.classmethod.jp/go/golang-7/)
LaunchScreen上の画像を変更→画像が反映されない(解決方法)

#最初に
LaunchScreen上の画像を変更した際に、画像が反映されないという現象が起きた。（シミュレーターでは反映されているが、実機上では反映されていない。）
その時の解決方法について書いておきます。

#解決方法
そのプロジェクトをCleanし、そして再度Buildするだけです。

![SS.png](https://qiita-image-store.s3.amazonaws.com/0/204266/5cce6e69-4395-6a57-34b5-62413ce44fd8.png)


上記のようにCleanし、再度Buildすることによって、解決しました。
また、私は念のためBuild FolderもCleanしました。(option + shift + command + k)

#最後に
LaunchScreen上の画像を変更した際に、画像が反映されないことについての解決方法は色々あるようです。他の文献にも、私が書いた解決方法は載っていたのですが、ただCleanしてBuildするという言葉だけでは分からない人もいるのではないかと思ったので、まとめておきました。


#参考文献
[実機でスプラッシュ画像が表示されない時の対処法](https://qiita.com/hikarut/items/21ddb59a9469660b6deb)
dotenvは本番で使う時に

## 環境
- Rails 5.0.3
- ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin17]
- dotenv-rails (2.2.1)


## 背景
使いやすさで、[dotenv](https://github.com/bkeepers/dotenv#why-is-it-not-overriding-existing-env-variables)を使ってる方もいらっしゃると思いますが、本番で使ってしまってハマったことをメモします。

本当に本番の利用は勧めされてないですが、https://github.com/bkeepers/dotenv#can-i-use-dotenv-in-production

## 事故
ステージング環境を増やして、redisのDBを番号を変更した。

```ruby:.env.staging
REDIS_ENDPOINT=redis://staging-host:6379/10 -> REDIS_ENDPOINT=redis://staging-host:6379/1
```

すると、unicornを再起動してもSidekiqのダッシュボードに反映されなく、古いredis DBの方に指していた（Sidekiqのダッシュボードの「完了」のジョブ数からがわかる）。

## 原因
dotenvは再起動する時に、新しい環境変数は読み込めますが、すでにある環境変数だと読み込まず更新されないです。

> By default, it won't overwrite existing environment variables as Dotenv assumes the deployment environment has more knowledge about configuration than the application does. To overwrite existing environment variables you can use Dotenv.overload.

https://github.com/bkeepers/dotenv#why-is-it-not-overriding-existing-env-variables

## 対策
一時対策  `unicorn stop && unicorn start`

- Dotenv.overloadを使う
ただし、それでも開発変数を消す時はすでにあるものをそのまま残してしまう。

```ruby:config/unicorn.rb
before_exec do |_server|
  ENV['BUNDLE_GEMFILE'] = File.expand_path('Gemfile', current_path)
  Dotenv.overload ".env.#{Rails.env}"
end
```

- 本番でDotenvをやめる
[ansible](https://www.ansible.com/)を使う

## 参照
- http://t-cyrill.hatenablog.jp/entry/2015/03/25/024625
GitHub Satellite Tokyo 2018 Day1 基調講演のまとめ

2018/06/12に、GitHub Satellite Tokyo 2018 Day1のイベントに参加してきました！
ページはこちら。https://githubsatellite.com

# 基調講演
GitHubカントリーマネージャー　公家尊裕さん
## GitHubの10年の変化
GitHubサービスは、今年で10年目
Japan Tokyoには3年前にオフィスができた

GitHubユーザの増加：250%
プルリクエストの増加率：550%
OSSユーザの増加：77%

今回のイベント、発表後の２日(!?)で800名の定員登録を達成!


## 複雑化する開発環境
GitHubシニアバイスプレジデント　ジェイソン・ワーナーさん

今、開発現場で起こっていることは何なのか？？？

今の世の中、開発に関するツールはあまりにも多くある
開発のワークフローを定義する時間が必要だが、可能な限り短くしたい

プルリクエストが世界を変えた
開発者コラボレーションを促進する
GtiHub上には開発者コミュニティがたくさんある

開発者が、コードを書くことに集中できる、シンプルな環境を提供できる！

## マイクロソフトによるGitHubの買収
最高技術責任者　榊原彰さん

MSの世界観：
インテリジェントクラウド
インテリジェントパワー

全ての産業はソフトウェア産業になっていく
社会を変えていくのは、Developerである！
Developerをサポートしていく

Mission
Empower All Developer

GitHubはDeveloperのHomeである。マイクロソフトは開発者をサポートする。

GitHubの買収に対するアイクロソフトの行動規範
・独立性を保つ
・開発者はこれまでと同様にコードを書くことができる


#パネルディスカッション
Rubyアソシエーション理事長　まつもとゆきひろさん
GitHubソフトエンジニア　アーロン・パターンソンさん
## RubyとGitHub
RubyのコアはSVNで管理されている
Why?
・歴史は結構古い
・SVN周りに様々なツールを連携させている
　・Redmineとか
・GitHubのアカウントを作りたくない派の人がいる
　・GitHubというソフトウェアはオープンソースではない、という考え
よって、こういう構成
・SVNで中央管理
・GitHubでミラーを公開している

## Rubyのコアチームのコミュニケーションの話
中央リポジトリへのコミット権限あるのは、日本人は100人いない程度
コアコミッターが日本人中心
こんなことを言われた
「Rubyの開発はオープンソースだがクローズな環境だ」
　・コアコミッターが日本人
　・メーリングリストは日本語が中心
こういう風に変えてきている
　・Redmineにディスカッションを載せる
　・それは英語でやっている

## Rubyのこれから
Rubyで書いたソフトウェアが巨大化していくと、動きやメンテナンスが悪くなっていく傾向がある
その問題への対処を、徐々にしていく
Rubyのコアチームのミッションはそのあたりにある

2006年ごろ Ruby on Railesがでた
「ハイプサイクル（ガートナー）」という話

## まつもとさんのプログラミング言語「ストリーム」の話
まつもとさんは、言語デザイナーである

ストリームの誕生
最初は200行程度の文法だけ書いたファイルをGitへ
バックアップするならGitHubだ！
この時、公開リポジトリにした
→数日でスターが1000もついた！
　プルリクエストも多々やってきた

OSSの成功の形として、これまでまつもとさんが思っていたこと
・動くものをベースにディスカッションをするのが良いと思っていた

## RubyのソースコードにスペースとTabが混在する理由
昔は・・・
メモリ制限あって、タブの方がよかった
けど、最近はスペースが多いかも

Tab派とSpace派がいる
同じ行であれば、最後にコミットした人の流派が反映される

# 感じたことのまとめ
Gitは分散バージョン管理システム
GitHubは開発者コラボレーションを促進させる仕掛けがある
・オープンなリポジトリ
・プルリクエスト機能
・コミュニティ
　などなど

エンタープライズでの利用を考えると、コラボレーションの色が薄くなっていきがち。
そもそもリポジトリをクローズにしているから、、、ですよね。

まぁ、それも機能の一側面だし、スタンダードであるとか、他のサービスとの連携であるとか、魅力的な要素ままだまだありそうです。
Unity と Mac で開発する Oculus Go アプリ #8 Debug.Log

Oculus & Unity 初心者が開発するまでのメモ


Unity で作ったアプリにログを埋め込んでも、Oculus Goでは `.apk` としてインストールされるので、UnityのConsoleにはログが表示されない...

サンプルとして、次のログを埋め込んだとする

```c#:C#
Debug.Log("log desu.");
```

このログを見る方法は次の２つ

## CLIで確認

Oculus はAndroidベースなので `adb` コマンドを使う

```bash:terminal
$ adb logcat -s Unity ActivityManager PackageManager
```

そうすると、ログが出てくる

```bash:terminal
$ adb logcat -s Unity ActivityManager PackageManager
 :
06-12 15:05:43.827 10258 10273 I Unity   : log desu.
 :
```

## Android Device Monitorで確認

`Android/sdk/tools/` にある `monitor` を起動する

```bash:terminal
$ $ $HOME/Library/Android/sdk/tools/monitor
```

見やすいように `Filter` を設定
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/33505/0ead16df-184e-cb9a-4a9d-8bad86827139.jpeg">

ログに表示されている
<img width="600" src="https://qiita-image-store.s3.amazonaws.com/0/33505/f02244bf-5cf9-b848-f361-c818f7fdc9b6.jpeg">
bookmarks（20180501-20180531）

# コーディング

■Gitの使い方が学べるGithub公式学習ツール。実際に手を動かしながら進めていくスタイル【GitHub Learning Lab】
https://lab.github.com/

■Windows10でhostsファイルを簡単に編集する2つの方法
https://i-think-it.net/windows10-hosts-easy-edit-two-ways/

■CSS：iOSのフォームのボックスシャドウはbox-shadowではなかった件
http://pressstocker.com/ios-box-shadow/

# デザイン

■Photoshopが不要になる！？無料で使える画像編集ツール「Photopea」
https://ferret-plus.com/10014?utm_campaign=https%3A%2F%2Fferret-plus.com%2F10014&utm_medium=RSS&utm_source=top_rss

# 自己学習

■IT勉強会・セミナーを探すサービス
・TECH PLAY
　https://techplay.jp/
・connpass
　https://connpass.com/

# 回顧

■若い世代が知らない2000年代のHTMLコーディングの地獄
https://ics.media/entry/17960?platform=hootsuite

■auハロプロケータイ図鑑
https://time-space.kddi.com/ketaizukan/index.html?bid=co_prts_kzk_0052
[Django] プロジェクト構成のベストプラクティスを探る - ３．認証情報を環境変数に格納する

## この記事について

Djangoで本番運用やチーム開発を行うに当たって、プロジェクトの初期構成にどのように手を入れたらよいかを、The Twelve Factorsなどを参考にまとめたメモです。

## 認証情報を環境変数に格納する目的

[Twelve Factor Ⅲ．設定](https://12factor.net/ja/config)の推奨に合わせて、設定ファイル上のデータベース(DATABASES)やストレージ(MEDIA_URL)への接続設定を外部より取得するように変更します。

### メリット

- 設定項目の存在は公表しつつ具体的な設定内容を隠匿できる（オープンソース化）

- Githubリポジトリに接続設定を入れてしまって他人に悪用される事故を防げる（要`.gitignore`）。

- 一部のクラウドサービスには環境変数をコマンドラインやWEB UIより設定できる機能があり、これを利用した動的な設定が可能になる。
例：
 - [AWS パラメータストア]
(https://dev.classmethod.jp/cloud/aws/parameter-store-application-config/)

 - [Heroku config vars](https://devcenter.heroku.com/articles/config-vars)

参考：[日経xTech Twelve-Factor App（6）環境の違いを設定で吸収 ](http://tech.nikkeibp.co.jp/it/atcl/column/14/110900092/111700006/)



## 変更方針

本番環境では環境変数を使うとして、開発環境でいちいち環境変数を設定するのは手間です。パッケージ「django-environ」を使うと、開発環境ではテキストファイル「.env」より取得した値を使うことができます。

参考：

- [django-environ](https://github.com/joke2k/django-environ) 
- [Djangoで環境変数？ならdjango-environを使おうか](https://qiita.com/moonwalkerpoday/items/9da47dda80d3ddac9a62)


### 作業手順

[開発と本番の設定ファイルを分離済みである](https://qiita.com/okoppe8/items/e60d35f55188c0ab9ecc)という前提とします。

[開発環境]
#### 手順１

プロジェクトにパッケージ [django-environ](https://github.com/joke2k/django-environ)をインストールします。

```shell
pip install django-environ
```

#### 手順２
プロジェクトルートに「.env」というテキストファイルを作成し、必要な接続設定等を入力します。データベースの接続設定は[dj-database-url](https://github.com/kennethreitz/dj-database-url#url-schema)の記法を使います。

```shell:.env
DEBUG=True

# Postgres
DATABASE_URL=postgres://USER:PASSWORD@HOST:PORT/DBNAME
```

#### 手順３
開発用設定ファイル`project/settings/local.py`の接続設定を、django-environを利用した設定に変更します。

```python:config/settings/logal.py
import environ

root = environ.Path(__file__) - 3 # 
env_file = str(root.path('.env'))
env = environ.Env()
env.read_env(env_file) 

DEBUG = env('DEBUG')

DATABASES = {
    'default': env.db()
}
```

[本番環境]

#### 手順４

開発環境と同様に本番環境の設定ファイル`config/settings/production.py`も変更します。こちらに「.env」の読込設定は不要です。

```python:config/settings/local.py
import environ

env = environ.Env()

DATABASES = {
    'default': env.db()
}

AWS_ACCESS_KEY_ID = env('DJANGO_AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = env('DJANGO_AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = env('DJANGO_AWS_STORAGE_BUCKET_NAME')
``````

#### 手順５

本番環境の環境変数を以下のいずれかの方法で設定します

- OSの設定を使う(`/etc/environment`、`/etc/profile`)

- Webサーバの設定を使う(`httpd.conf`、`Web.Config`)

- クラウドサービスの機能を使う(コマンドライン、Web UI)

- [Dockerの場合] 環境設定オプションを使う(`--env-file .env` )
ownCloud クライアントアプリのファイルのオンデマンド同期機能実装へ

#ownCloud クライアントアプリのファイルのオンデマンド同期機能実装

この記事は、以下のownCloud Blogの内容をピックアップして記載します。

The ownCloud Client Goes Virtual - Sync Your Files on Demand - ownCloud
https://owncloud.org/news/owncloud-client-goes-virtual-sync-files-demand/

## ownCloud 仮想ファイルシステムとは？

簡単言うと、これまでownCloudデスクトップクライアントは同期が実行されると全てのファイルをダウンロードしていましたが、それがなくなり必要なファイルのみダウンロードされるようになります。ファイル名の検索はこれまで通り検索が可能です。

## テストにご参加ください。

以下の[ダウンロードページ](https://owncloud.org/download/#owncloud-desktop-client)からテスト版をダウンロードできます。**(訳注：Testpilot版は、通常ディレクトリとは別ディレクトリにインストールされるので既存のアプリケーションと同居できます。テストにはこちらをおすすめします)**

この機能を有効にするには、config ファイルの[General]の項目に

```
showExperimentalOptions=true
```
を追加してください。

(訳注：C:\Users\XXXXXXXX\AppData\Roaming\ownCloud Testpilot Edition\testpilotcloud.cfg にあるはずです)

## その次はどんな機能が...

* 同期のアンドゥ
* 右クリックで全てのファイルをダウンロード
* 同期せずにファイルの移動
* LibreOfficeのように他のアプリがファイルあるのフォルダーを開いたときにダウロード開始するオプション
* 他にもアイディアはありませんか？
babel-preset-latestからbabel-preset-envへ

#手順
まずはコマンドでアンインストールとインストール

```
npm uninstall babel-preset-latest --save-dev
npm install babel-preset-env --save-dev
```

npmのルートディレクトリ（gulpfile.jsやpackage.jsonがあるディレクトリ）に
.babelrcという設定ファイルがあるので以下のように変更。


```json
{
  "presets": ["latest"]
}

↓

{
  "presets": ["env"]
}
```

#背景
https://www.npmjs.com/package/babel-preset-latest
に行ったら廃止と書かれていたので乗り換えました。
.babelrcの存在を忘れていたので備忘録的にメモ。

自分の環境では無事es6(class構文なども含め)からコンパイルされ動作しました。
EC2にJenkinsをインストールする

PC乗り換えのため、Boostnoteの中を載せていく

## インストール

```
// ルートユーザーになっておく
$ sudo -i

// yumのアップデート
$ yum update

// javaのバージョン確認
$ java -version

// デフォルトで入っているjavaを確認する
$ rpm -qa | grep jdk

// デフォルトのjavaをアンインストール
$ rpm -e 先ほど確認できたjavaを指定

// openJDKをインストール
$ yum install java-1.8.0-openjdk

// yumリポジトリを追加
$ wget -O /etc/yum.repos.d/jenkins.repo http://pkg.jenkins-ci.org/redhat-stable/jenkins.repo

// rpmの公開鍵をインポート
$ rpm --import https://jenkins-ci.org/redhat/jenkins-ci.org.key

// jenkinsをインストール
$ yum install jenkins

// jenkinsを起動
$ service jenkins start

// jenkinsを自動起動させる設定
$ chkconfig jenkins on

// パスワードを確認しておく
$ cat /var/lib/jenkins/secrets/initialAdminPassword
```
Rundeck Javaからジョブへパラメータ渡す方法

## 環境
Rundeck : 2.10.8-1

## Java側
setOptionsメソッドで設定する。

パラメータを2つ渡す場合)

```java
Properties properties = new Properties();
properties.setProperty("arg1", "value1");
properties.setProperty("arg2", "value2");

// Rundeck ジョブ呼び出し
RundeckExecution rundeckExecution = RundeckClient.triggerJob(RunJobBuilder.builder().setJobId("{JobId}").setOptions(properties).build());
```

## Rundeck側
`${option.{Javaで設定したキー名}} ${option.{Javaで設定したキー名}}` で受け取る

パラメータを2つ受け取る場合)
`echo ${option.arg1} ${option.arg2}`
とする

![rundeck.png](https://qiita-image-store.s3.amazonaws.com/0/39442/e2246c88-e5c9-3749-d75e-a95dc0ea6a6d.png)

結果
`value1 value2`
と表示される
リダイレクト先に指定のFlash messagesが表示されているか確認したい

## やりたいこと

ログインに失敗したときにFlash messagesがちゃんと表示されているかのテストをしたい

## 下記のコードじゃうまくいかないんじゃ

```php
    public function testLoginUnregisteredUser()
    {
        $data = [
            'email' => 'thisisunregistereduser@hoge.com',
            'password' => 'thisisunregistereduser',
        ];

        $response = $this->post('login', $data);

        $response->assertStatus(302);
        $response->assertSeeText('アカウントが登録されていません');
    }
```

リダイレクトのレスポンスが302で返されるので`assertSeeText`では確認できません。


## そんなときはassertSessionHasを使うのじゃ

こんなときは直接Sessionを見に行くと吉

```php
    public function testLoginUnregisteredUser()
    {
        $data = [
            'email' => 'thisisunregistereduser@hoge.com',
            'password' => 'thisisunregistereduser',
        ];

        $response = $this->post('login', $data);

        $response->assertStatus(302);
        $response->assertSessionHas('warning', 'アカウントが登録されていません');
    }
```



## 参考にしたページ

[How do I test a view file after redirect?](https://laracasts.com/discuss/channels/testing/how-do-i-test-a-view-file-after-redirect?page=1)
IBM Cloud Privateにインストールされるlogstashのバージョンとプラグイン一覧

訳あって調べてみました。

## 調査バージョン

IBM Cloud Private 2.1.0.3

## イメージ名
ibmcom/logstash:5.5.1

## インストール済プラグイン一覧
logstash-codec-cef
logstash-codec-collectd
logstash-codec-dots
logstash-codec-edn
logstash-codec-edn_lines
logstash-codec-es_bulk
logstash-codec-fluent
logstash-codec-graphite
logstash-codec-json
logstash-codec-json_lines
logstash-codec-line
logstash-codec-msgpack
logstash-codec-multiline
logstash-codec-netflow
logstash-codec-plain
logstash-codec-rubydebug
logstash-filter-clone
logstash-filter-csv
logstash-filter-date
logstash-filter-dissect
logstash-filter-dns
logstash-filter-drop
logstash-filter-fingerprint
logstash-filter-geoip
logstash-filter-grok
logstash-filter-json
logstash-filter-kv
logstash-filter-metrics
logstash-filter-mutate
logstash-filter-ruby
logstash-filter-sleep
logstash-filter-split
logstash-filter-syslog_pri
logstash-filter-throttle
logstash-filter-urldecode
logstash-filter-useragent
logstash-filter-uuid
logstash-filter-xml
logstash-input-beats
logstash-input-couchdb_changes
logstash-input-dead_letter_queue
logstash-input-elasticsearch
logstash-input-exec
logstash-input-file
logstash-input-ganglia
logstash-input-gelf
logstash-input-generator
logstash-input-graphite
logstash-input-heartbeat
logstash-input-http
logstash-input-http_poller
logstash-input-imap
logstash-input-irc
logstash-input-jdbc
logstash-input-kafka
logstash-input-log4j
logstash-input-lumberjack
logstash-input-pipe
logstash-input-rabbitmq
logstash-input-redis
logstash-input-s3
logstash-input-snmptrap
logstash-input-sqs
logstash-input-stdin
logstash-input-syslog
logstash-input-tcp
logstash-input-twitter
logstash-input-udp
logstash-input-unix
logstash-input-xmpp
logstash-output-cloudwatch
logstash-output-csv
logstash-output-elasticsearch
logstash-output-file
logstash-output-graphite
logstash-output-http
logstash-output-irc
logstash-output-kafka
logstash-output-nagios
logstash-output-null
logstash-output-pagerduty
logstash-output-pipe
logstash-output-rabbitmq
logstash-output-redis
logstash-output-s3
logstash-output-sns
logstash-output-sqs
logstash-output-statsd
logstash-output-stdout
logstash-output-tcp
logstash-output-udp
logstash-output-webhdfs
logstash-output-xmpp
logstash-patterns-core
x-pack
Xcodeプロジェクトのgitの修正履歴の名前変更

環境：　Xcode9

デフォルトのままだと、自分の本名がコミット履歴に現れます。それをそのままGitHubにPushすると恥ずかしい事でしょう。それを回避！


手順：

1. 普通にXcodeプロジェクトを新規作成する
2. MacでTerminalを開く
3. プロジェクトのフォルダへ移動
4. 次のコマンドを実行する

git config user.name {好きな名前をつけましょう}
cartopyやってみた。

#概要
cartpyやってみた。

#サンプルコード

```
import cartopy.crs as ccrs
import matplotlib.pyplot as plt

ax = plt.axes(projection = ccrs.PlateCarree(central_longitude = 140.0))
ax.coastlines()
ax.stock_img()
plt.savefig("cartopy0.png")
plt.show()
```

![cartopy0.png](https://qiita-image-store.s3.amazonaws.com/0/18104/62797a6f-6c39-05a4-35a6-b5fd9fa49b67.png)

#サンプルコード

```
import matplotlib.pyplot as plt
import cartopy.crs as ccrs


ax = plt.axes(projection = ccrs.Robinson(central_longitude = 140.0))
ax.set_global()
ax.stock_img()
ax.coastlines()
plt.plot(-0.08, 51.53, 'o', transform = ccrs.PlateCarree())
plt.plot([-0.08, 132], [51.53, 43.17], transform = ccrs.PlateCarree())
plt.plot([-0.08, 132], [51.53, 43.17], transform = ccrs.Geodetic())
plt.savefig("cartopy1.png")
plt.show()
```

![cartopy1.png](https://qiita-image-store.s3.amazonaws.com/0/18104/0e526478-f946-6a8d-e6da-ff605bc64216.png)




#サンプルコード

```
import matplotlib.pyplot as plt
import numpy as np
import cartopy
import cartopy.crs as ccrs

def sample_data(shape = (20, 30)):
    crs = ccrs.RotatedPole(pole_longitude = 177.5, pole_latitude = 37.5)
    x = np.linspace(311.9, 391.1, shape[1])
    y = np.linspace(-23.6, 24.8, shape[0])
    x2d, y2d = np.meshgrid(x, y)
    u = 10 * (2 * np.cos(2 * np.deg2rad(x2d) + 3 * np.deg2rad(y2d + 30)) ** 2)
    v = 20 * np.cos(6 * np.deg2rad(x2d))
    return x, y, u, v, crs

def main():
    ax = plt.axes(projection = ccrs.Orthographic(-10, 45))
    ax.add_feature(cartopy.feature.OCEAN, zorder = 0)
    ax.add_feature(cartopy.feature.LAND, zorder = 0, edgecolor = 'black')
    ax.set_global()
    ax.gridlines()
    x, y, u, v, vector_crs = sample_data()
    ax.quiver(x, y, u, v, transform=vector_crs)
    plt.savefig("cartopy2.png")
    plt.show()

if __name__ == '__main__':
    main()
```

![cartopy2.png](https://qiita-image-store.s3.amazonaws.com/0/18104/e70cf0cc-daaf-486f-e035-1ffb2425a833.png)

以上。
Form_forとかのlabelの名前をlocaleで表す。

### 以下のようなform_forで作成されるlabelの表示名をlocaleに記載する。

```erb:hoge.html.erb
  <div class="form-group">
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>
```

* localeにja.ymlを作成し、以下のようなネストで記載する。

```yml:ja.yml

ja:
  activerecord:
    attributes:
      user:
        name: "名前"
```

ここで、userは、form_forが対象としているモデル名である。
SwiftTourをさっと読む ~Control Flow ~

# Swift4ツアーをさっと読む ~ Control Flow ~

[前回](https://qiita.com/haxpig/items/f61152ac9a015ec3c12a)に続いて今日は[Control Flow](https://docs.swift.org/swift-book/GuidedTour/GuidedTour.html#ID462)。制御文のことですね。
さっと見ていきます。

## 一覧

  - 条件分岐
    - if文
    - switch文
  - 繰り返し
    - for-in文
    - while文
    - repeat-while

## 条件分岐

### if文
#### 基本的な形
  ```Swift:if文
  var age = 20
  if age >= 60 {
    print("Elder")
  } else if age >= 20 {
    print("Adult")
  } else {
    print("Child")
  }
  ```

  条件式は必ず`Boolean`でなければならず、
  暗黙での0との比較は行われない。エラーとなる。

#### if-let
  ```Swift:if-let文
  var optionalName: String? = "haxpig"
  var greeting = "Hello!"
  if let name = optionalName {
    greeting = "Hello, \(name)"
  }
  print(greeting) // "Hello, haxpig"
  ```

  `if-let文`を用いると`Optional Binding`することができる。
  簡単に言えば、変数`optionalName`に値が設定されていれば後続の処理が実行され、スコープ内ではアンラップされた状態で利用ができる。

  ※`Optional`についてはまたの機会。

##### デフォルト値の利用
  ```Swift:デフォルト値の利用
  let nickName: String? = nil
  let fullName: String = "haxpig"
  let greeting = "Hi \(nickName ?? fullName)"
  print(greeting) // "Hi haxpig"
  ```

  `Optional`の変数に続けて`?? デフォルト値`で値がない場合のデフォルト値を設定できる。
  （なんでここで紹介されてるのだろう。）

### switch文
  ```Swift:switchの基本
  switch 比較対象 {
  case パターン1: 処理
  case パターン2: 処理
  default: 処理
  }
  ```

  ```Swift:switch文サンプル
  let vegetable = "red pepper"
  switch vegetable {
  case "celery":
      print("Add some raisins and make ants on a log.")
  case "cucumber", "watercress":
      print("That would make a good tea sandwich.")
  case let x where vegetable.hasSuffix("pepper"):
      print("Is it a spicy \(x)?")
  default:
      print("Everything tastes good in soup.")
  }
  ```

  いずれかのパターンに合致した場合、その処理が行われ、**後続のパターン処理は実行されない**ので、`break`は不要。
  （ただし、処理文がない場合`break`が必要）

  パターンを複数指定したい場合は、カンマ区切り(`,`)で記述できる。

  `case`内のパターン指定に`where`を利用できる

  `default`は必須。
  （ただし`enum`で全パターンを網羅している場合は不要）

## 繰り返し

### for-in文
#### 配列を回す
  ```Swift:配列を回す
  let individualScores = [75, 43, 103, 87, 12]
  var teamScore = 0
  for score in individualScores {
      if score > 50 {
          teamScore += 3
      } else {
          teamScore += 1
      }
  }
  print(teamScore)
  ```

  要素数だけ繰り返す。

#### 辞書を回す
  ```Swift:辞書を回す
  let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25],
  ]
  var largest = 0
  for (kind, numbers) in interestingNumbers {
    for number in numbers {
      if number > largest {
        largest = number
      }
    }
  }
  print(largest)
  ```

  key-valueをペアで取り出し、繰り返すことができる。

### while文
#### while文
  ```Swift:while文
  var n = 2
  while n < 2 {
    n *= 2
  }
  print(n) // 2
  ```

  条件に合致するまで繰り返す。
  処理開始時にも判定する。

#### repeat-while文
  ```Swift:repeat-while文
  var m = 2
  repeat {
    m *= 2
  } while m < 2
  print(m) // 4
  ```

  他言語で言うところの`do-while`。
  処理実行後に判定が行われるため、少なくとも一回実行される。

### インデックス範囲の指定方法
  `x..<y` x以上y未満
  `x...y` x以上y以下

## おわり

  `if-let`や`repeat-while`が一瞬「お？」となりましたが、読めばなるほどですね。
  何か間違いがあればご指摘お願い致します。

  おしまい。
GnurootDebian日本語設定,microSDへの移動

#　はじめに
#### 格安Androidタブレットがサブマシンとして活躍できるGNURootDebianの日本語環境設定方法(CUI)とmicroSDへのデータ移動方法の備忘録です。データ移動方法に関してはAndroidOSのバージョンや機種によって異なるかもしれません。

# 使ったもの
- Android端末(ASUS Zenpad10 301M)
- ADB環境のあるPC
- microSDカード
- GNURootDebian(http://play.google.com/store/apps/details?id=com.gnuroot.debian)

# アプリをmicroSDに移動する
#### 特にTexなんかを入れると内部ストレージがカツカツになるのでGNURootDebianのデータをmicroSDに移動させます。失敗したり、フォーマットされる可能性があるのでSDカード内のデータを事前にバックアップすることを勧めます。
1. まずAndroidタブレットの開発向けオプションを有効にします
  - [設定] > [端末情報] > [ソフトウェア情報] > [ビルド番号]と進み
  - ビルド番号を何回か連打すると開発向けオプションをオンにできるはずです
2.  開発向けオプションでアプリ欄の「外部ストレージへのアプリの書き込みを許可」をオンにする。[デバッグ]欄の[USBデバッグ]もオンにしときます
3.  次にmicroSDをさした端末とADB環境のあるPCと接続し、Windowsならコマンドプロンプトで
 - `adb shell`
 - `> sm list-disks`
 - でsdカードのIDを確認した後
 - `> sm partitiion disk:SDカードのID mixed 50`
 - によりSDカードストレージをアプリ用のストレージとデータ保存用の外部ストレージを半々に分けます。
 - 参考:https://decoy284.net/2016/03/12/android-6-xperia-z5-sdcard-internal-storage/
4.  端末にGNURootDebianをGooglePlayからインストール(まだ開かない)
5.  [設定] > [ストレージ] > [内部共有ストレージ] > [アプリ] > [GNURoot]に進み、使用されているストレージが[内部共有ストレージ]なら[変更]によりSDカードへ移します
6.  設定内の[ストレージ]欄等で成功したのを確認したらGNURootDebianを開きます
7.  自動で初期インストールが始まるので眺めます
8.  最後に設定内の[ストレージ]欄でSDが破損していなかったり、アプリの移動が失敗していなかったら成功です

# 日本語環境のセットアップ
#### デフォルトで日本語を入力することもできなければ出力もされないので設定を行います
`apt-get update && apt-get upgrade
apt-get install -y build-essential nano task-japanese locale apt-utils emacs-nox`
#### 必要ならTexパッケージもインストールします(かなり時間がかかります)
`apt-get install -y texlive-full texlive-lang-japanese`
#### 日本語設定をしていきます
`echo 'export LANG="ja_JP.UTF-8"' >> ~/.bashrc
echo 'export LC_ALL="ja_JP.UTF-8"' >> ~/.bashrc
echo 'export LANGUAGE="ja"' >> ~/.bashrc`
#### /etc/locale.gen内のコメントアウトを外します(#を消す)
```locale.gen
:
en_US.UTF-8 UTF-8
:
ja_JP.UTF-8 UTF-8
:
```
#### ターミナルで以下を実行し設定を反映させ終わりです
`locale-gen`
#### アプリを再起動すれば設定されるはずです
`exit`
# 最後に
言語設定に関してはより良い方法があるのかもしれませんが、初心者なりにまとめさせてもらいました。/homeなど内部ストレージでは実行権限がなく、外部ストレージでは読み取りしかできないので注意が必要です。
最新のLaravelをインストールする

## なぜかhomebrew経由でインストール出来なかった

```
$ brew install homebrew/php/composer
```

上記でなぜかインストールが出来なかったので、`homebrew`は使わない方法でのmacにLaravelをインストールする方法になります。

## composerインストール

```
// curl経由でcomposer.pharをインストール
$ curl -sS https://getcomposer.org/installer | php

// グローバルなコマンドとして登録
$ mv composer.phar /usr/local/bin/composer

// バージョン確認
$ composer -v
```

## laravelインストール

```
$ composer global require "laravel/installer"
```

上記を実行したら、[こちらの記事](https://qiita.com/sayama0402/items/c3f60b6c9b8efea0139b)を参考にlaravelコマンドのパスを通して上げることで

```
$ laravel new アプリケーション
```
が実行出来るようになります。
Neural Joking Machine: Humorous image captioningを読んだ

Kota Yoshida, Munetaka Minoguchi, Kenichiro Wani, Akio Nakamura, Hirokatsu Kataoka
[arxiv](https://arxiv.org/abs/1805.11850), [pdf](https://arxiv.org/pdf/1805.11850.pdf)

#1.どんなもの？
画像を入力するとその画像に対してボケ（ジョーク）を返すネットワーク
#2.先行研究と比べてどこがすごいの？
画像に対してボケを書き込んで投稿するサイト"bokete"のデータベースを利用して面白さの指標を定義して利用する．
#3.技術や手法のキモはどこにあるか？
![image.png](https://qiita-image-store.s3.amazonaws.com/0/252474/7f250a62-ccb2-3fc8-a371-cd7be8d57232.png)
###CNN+LSTM
画像に適したCNNとテキスト処理に適したRNNを組み合わせたものとしてCNN+LSTMによる画像のキャプション生成がある[1]．
CNN+LSTMを用いて画像からボケを生成する．
CNNはResnetを用いて特徴抽出を行う．
###Funny score
面白さを表す指標としてFunny scoreを定義する．
このFunny scoreは画像に対する大喜利の投稿サイト"bokete"の星の数を利用して定義される．
星の数が100個以下ならscoreは損失Lを返し，星が100個以上ならL-1.0を返す．
損失Lはミニバッチの平均としてLSTMで計算される．
#4.どうやって有効だと検証した？
![image.png](https://qiita-image-store.s3.amazonaws.com/0/252474/8af84adc-08d5-20fe-6218-a67add1c4389.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/252474/7ba4316e-b297-284b-80c1-aec8ea091788.png)
bokete　に投稿されたものを人のつけたキャプションとし，人のつけたキャプションと提案手法により生成されたキャプション，STAIR[2]により生成されたキャプションを比較する．
比較方法は16人のアンケートを行い，それぞれが生成したキャプションに面白さの順位をつけてもらった．
この結果から人よりは面白くないがSTAIRよりは面白いキャプションが生成できていることがわかる．
実際にboketeに投稿してみたらSTAIRは平均1.71個の星を獲得したのに対して，提案手法は3.23個獲得できた．

#5.議論はあるか？

#6.次に読むべき論文はあるか？
[[1]Show and Tell: A Neural Image Caption Generator
](https://arxiv.org/abs/1411.4555)
[[2]STAIR Captions: Constructing a Large-Scale Japanese Image Caption Dataset](https://arxiv.org/abs/1705.00823)
地方で学生が技術コミュニティを形成する技術

# 概要
izm さんが地方で勉強会があったときに参加する技術をまとめてくれたので、私は地方で学生が技術コミュニティを作った技術の話でもできれば。
https://gist.github.com/neon-izm/c35a7544a24d109507118aa77f27e031

ちなみに私は5年前ぐらいにIGDA琉球大学というゲーム開発に関するコミュニティを立ち上げて、沖縄で GameJam や勉強会を開催していました。

ちなみに参加者側の視点のやつは、izm さんの gist を読んでね!

**最低限でも名刺をつくるのと、Facebook や Twitter などでつながっておこうね!!**

# コミュニティのリーダーがやること
といっても、コミュニティを作ってもいきなり大きいことは多分ほぼ無理なので、地道に小さいことからやっていきましょう。(大きいコネクションがすでにある人は対象外)

## コミュニティを開く前に
- まずは、その地方に作ろうとしているコミュニティに似ているところが無いかどうか探してみましょう。もしあったらまずそこに参加!そこの参加者が、のちの参加者になったりコアメンバーになってくれたりします。
- IGDA琉球大学を開く前に、沖縄で開催された GameJam に参加してそこで知り合いを増やしていきました。

## まずはコミュニティの方向性を考える
- 一概にコミュニティといってもいろんな方向性があります。そこがブレると参加者もブレるのでテーマを絞りましょう。
- 私がゲームに関する技術コミュニティを開いたときには、ゲーム開発コミュニティが沖縄になかったです。

## 小さくイベントを開催 & コミュニティのWebPage の作成
### イベント開催
- コミュニティを作ったら、まずはイベントを開きましょう。同じような仲間を見つけたら巻き込んでいきましょう。(これが結構疲れる)まずは身内で小さくてもいいのでイベントをやりましょう。
- ちなみに私はゲームジャムを開きました。(参加者12名ぐらい)
- 小さなイベントでしたが、Unity Technologies Japan の方々に協力していただきました。

### 絶対にWebPageを作ってイベントレポートを書く
- WordPress でもなんのブログサービスでもいいので、イベントを開催したら、 **絶対にイベントレポートを書いてください。** このイベントレポートが、後々のコミュニティ活動に響きます。やはり活動実績が有ると無いのでは、前者のほうが第三者も安心してコミュニティに参加できますよね?
- IGDA琉球大学の設立と同時に WordPress でページを作りました。

## 参加経由で 
(ねずみ講形式)
 たくさんの人を巻き込んでいく
- イベントを開くたびに新しいひとを少しでも巻き込んでいくように気をつけましょう。身内で固まりすぎると、今度は第三者が入りにくいような雰囲気になりますので注意。常に新しいひとを巻き込みましょう。その段階で、学生だけでなく社会人も巻き込める可能性があります。
- 一番最初に参加した GameJam で仲良くなった人(社会人)経由で、いろんな会社のいろんな社会人に参加呼びかけしてもらいました。
- IGDA琉球大学と「琉球大学」という名前がついていますが、琉球大学の学生だけでなく近隣の大学の参加者や専門学生など非常にたくさんの学校の参加を広げることができました。

## 学生だけでなく、社会人も巻き込もう
- 学生の技術コミュニティでも、社会人を積極的に巻き込んでいきましょう。やはり、学生と社会人では経験がダンチです。たくさん学べることもありますので、ガンガン巻き込んでいきましょう。社会人を巻き込んでいくと、人が人を呼び、さらにいろんな会社の人とつながりができていきます。

## 参加者のことを考えるのではなく、その地方にとってどう貢献するか考える
- 社会人を巻き込む段階でこのあたりを考えていきましょう。開いたコミュニティはどのようにその地方を活性化していくのか目標を考えていきましょう。(本当は最初からあったほうがブレないとは思うけど)
- これを考えるころには、毎回20~30人近くの方々が参加するようなコミュニティになっていたので、かなり豪華なメンバーが県外から登壇者として参加していただけました。(とりあえず自分がコーディネートしていたイベントレポートなどを貼る)
- http://igda.cr.ie.u-ryukyu.ac.jp/?p=529
- http://igda.cr.ie.u-ryukyu.ac.jp/?p=670
- http://igda.cr.ie.u-ryukyu.ac.jp/?p=783

- これだけのメンバーを学生だけで共有するのはもったいないと思い、沖縄県全体の技術力底上げのためにたくさんのできる限りの人を集めました。
- ちなみにお気持ちとしては、沖縄県の学生が東京に羽ばたいてほしいと思っていろいろ開催していました。(沖縄のITの初任給は高くて20万円いかないぐらい。東京だとサイバーエージェントが34万円(新入社員で入った当時)だから多少はね?)

# 最後に
- 正直設立から運営まで疲れました。が、得るものも非常に大きく、東京に就職してからもその縁があり、たくさんの人にお世話になっています。
- 運営は一人でできません。(マジで)そこで必要なのはたくさんの人を巻き込んでいく力です。たくさんの人を巻き込んでいきましょう。
SlackでチャンネルのURLを取得する

サイドバーのチャンネル名を `右クリック` => `リンクアドレスをコピー` でOK

## Mac版アプリの例

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/f00d5386-4c6c-d065-9168-aab1e6ba1aab.png)

## GoogleChromeの例

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/10b663b8-b2a8-9ba7-4f0c-c6991bffffd3.png)









<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
DonkeyCar 用 ラズパイ boot SD の作り方（旧バージョン2.5.8）

#Raspbian stretch イメージをSDに書き込む
SDは16Gバイト以上

Etcher 等でSDメモリカードに書き込みを行う
ルートディレクトリに「ssh」の空ファイルを作成
接続したい無線LANアクセスポイントのSSIDとPSKを記述した「wpa_supplicant.conf」をbootパーテーションのルートディレクトリに新規作成
RaspberryPi3にセットしてして起動

#設定変更
PCからSSHでpi@raspberrypi.localに接続
またはディスプレイ＆キーボードを接続してターミナルを開く

$sudo raspi-config

4 Localisasion Options
12 Change Timezone
Asias
Tokyo

14 Change Wi-fi Country
JP Japan

5 Interfaceing Option
camera，i2cを有効化
vncを使うなら有効化

7 Advanced Options
A1 Expand Filesystem

Finish
reboot後に再接続
ターミナルにて

#スクリプトファイルを入手
$ wget https://raw.githubusercontent.com/autorope/donkeycar/dev/install/pi/install.sh
$ wget https://raw.githubusercontent.com/autorope/donkeycar/dev/install/pi/opencv.sh

#スクリプトを実行（３～４時間）
$ bash install.sh
$ bash opencv.sh

後は通常通りにDonkeyCarをインストール
Docker環境からローカル環境にアクセスする方法

WebアプリケーションはDocker(docker-compose)で構築しており、ローカル環境のAPIにアクセスしたい場合の方法です。

Docker for Macを利用している想定で説明をします。

例えばAPIをポート3001で立ち上げた場合、`http://localhost:3001`とDocker内で設定しているとうまく接続できません。

`http://docker.for.mac.localhost:3001` と指定するとうまく接続できます。

`docker.for.mac.localhost` はDokcer for Macのver17.06から推奨されているDNSです。
ver18.03からは`docker.for.mac.localhost` の代わりに`host.docker.internal`を利用することが推奨されています。

なお、APIは`127.0.0.1`にbindすることでDockerからでも接続できるようになります。

**参考**
https://docs.docker.com/v17.09/docker-for-mac/networking
https://docs.docker.com/docker-for-mac/networking

by <a href="https://twitter.com/nishina555" target="_blank" rel="noopener">@nishina555</a>
Imageioでの初歩的なエラーを解決したときのお話

間違った知識がありましたら、遠慮なく教えてください。

# 概要
- pythonを利用してHDR画像を読み込み
- imageioのエラーの対処法


# 本編
新環境で、HDR画像を読み込もうとした時の話。
HDR画像のような特殊な拡張子のファイルは、PIL(Pillow)やscipyなどのPythonで画像を扱うときによく使われているようなものでは読み込めないようなので、imageioを利用することにした。

# 遭遇したエラー
- 実行内容

```python:hdr.py
import imageio
hdr = imageio.imread('sample.hdr')
```
- エラー

```python:
Error : could not find a format to read the specified file in mode 'i'
```

そんなformatのものは知らないとか言われてしまった。

# 解決作
必要なライブラリをインストールできていなかっただけのようである。
今回はfreeimageというライブラリをインストールしたら解決しました。
[公式(imageio)](http://imageio.github.io/)
知らずに使ってた【git checkout HEAD -- . 】の「--」ハイフンハイフンと「.」ドットの意味 

知らずに使ってた【git checkout HEAD -- . 】の
「--」ハイフンハイフンと「.」ドットの意味 

# git checkout HEAD -- . 
むかしむかし作業したファイルを元の状態に戻す魔法の呪文として教わった
`git checkout HEAD -- . `
`git checkout -- . `
`git checkout HEAD . `
`git checkout .`
どれも似たような挙動をして作業前の状態に戻してくれる
「--」と「.」ってなんぞや:thinking:

## HEADについて
HEADは現在の作業ブランチの先頭コミットの別称。
たいていのコマンドで省略可能。
よってHEADの有無は省略しているかしていないかだけ。

## checkoutの仕様を理解
### ブランチを切り替えるとき
`git checkout [-q] [-f] [-m] [<branch>]`
ブランチ名を指定するとそのブランチに切り替わる
### ファイルを特定の状態に切り替えるとき
`git checkout [<tree-ish>] [--] <pathspec>…​`
要するに
`git checkout コミットID　パス名`
では作業ツリーの特定のファイルを特定のコミットの状態に切り替えることができる

## 「.」の意味
つまるところこれはパス名である。それだけ。
例えば「\*.cs」で拡張子がcsのファイルだけが対象になる。
「.」は「\*.\*」の略かな
全ファイルが対象ってこと。
拡張子がないファイルも対象になる。

## 「--」の意味
これはcheckoutコマンドのオプションである。
[コミットID]と[パス名]の間に「--」を使って**区切っても良い**
なぜ必要なのかというとブランチ間の切り替えもcheckoutだからである。
ブランチ名として「*master*」があるのにファイル名としても「master」があるとき
`git checkout master`
というコマンドは*master*ブランチへの切り替えとして機能してしまう
masterというファイルだけをもとの状態にしたいときには
`git checkout -- master`
とする。
無論HEADを省略しているから問題になるのであって
`git checkout HEAD master`
とすれば「--」がなくても「master」というファイルは元の状態にもどる。


# 参考
公式リファレンス
https://git-scm.com/docs/git-checkout
自分なりにしっくり来る問題解決フレームワーク

# はじめに

この手の話は色んな書籍、サイトで話が上がっていますしどれが正解でどれが不正解とかないと思っていますが、自分なりに試行錯誤してわりとしっくり来ているフレームワークを紹介します。

# 自分なりにしっくり来るフレームワーク

![スクリーンショット 2018-06-12 12.11.19.png](https://qiita-image-store.s3.amazonaws.com/0/173370/46076761-debb-3787-22b3-d77a30e7974f.png)

# ざっくりな進め方

1. 悩みやイライラ、困っている等の感情が生まれる
2. ゴールと現状を整理する
3. 差分を問題として定義する
4. 問題がなぜ起きているかを `5なぜ` していく(重複は考えずとにかく洗い出す)
5. 4.で重複したものをグルーピングして整理する
6. 5.でまとめたもの全ての課題を整理する
7. 課題解決の為の施策を整理する
8. 費用対効果の高いと判断した施策から行っていく
9. 施策実施後に振り返りを行う(2.とほぼ同義。以降繰り返す)

# ポイント

## `問題` と `課題` を別物として扱っている

Google翻訳等で `課題` を翻訳すると `Problem` となりますが、 `困っていること` = `解決したいこと` がイコールにならないケースもあると思うので明示的に分けています。
よくある `課題解決` という言葉はすでに問題、原因がわかっているうえで、課題と施策をどうしていくかにフォーカスしたものだと考えています。
が、その手前にある原因や問題、場合によってはゴールと現状がふんわりしているケースもそれなりにあって、そういう場合に `課題解決` から始めるのはちょっと危険かなと。

# さいごに

冒頭に記載していますが、問題解決における `これが正解` はないと思っています。
また、今回記載したフレームワークはあくまで上っ面の部分だけなので、具体的な解決方法は別途必要になってきます。(例えば課題→施策ってどうやって出すの？等)
ただ、個人的にはこの型が頭の中にあることで多少問題解決を行ううえで助かっている節はあるかなと思っています。

何度も書いて申し訳ないですが、最後にもう一度書きます。
あくまで `これが正解` というものはないので、問題解決を行う際の選択肢のひとつとして考えて頂けると幸いです。
Web Apps の認証で Azure AD B2C を使用する

いつも忘れるのでメモ

## Azure AD B2C の設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132347/866f5f6a-4065-8381-ae99-9391be2c73df.png)

- アプリケーション ID
    - Web Apps で設定する[クライアント ID]
- キー
    - シークレットを生成。

## Web Apps の設定
![image.png](https://qiita-image-store.s3.amazonaws.com/0/132347/9ce1a9a6-46c5-68e2-f29d-83838cced405.png)

- クライアント ID
- 発行者の URL
    - https://login.microsoftonline.com/<AAD B2C のテナント名>
    - 例)https://login.microsoftonline.com/nomuprob2c.onmicrosoft.com
- クライアント シークレット