OmniAICreator/Qiita-1.07M huggingface dataset:
cocoapodsでFailed to extract git version from gitが出た場合の解決方法

#pod install でエラー
mac初心者なのですが、OSのバージョンを上げたり、Xcodeのバージョンを上げたりしたらpod install等が以下のようにエラーになるようになりました。

> /Library/Ruby/Gems/2.3.0/gems/cocoapods-1.5.3/lib/cocoapods/command.rb:118:in `git_version': Failed to extract git version from `git --version` ("dyld: Symbol not found: _OBJC_IVAR_$_NSTextViewIvars.sharedData\n  Referenced from: /Users/xxxxx/Downloads/Xcode.app/Contents/SharedFrameworks/DVTDocumentation.framework/Versions/A/../../../../SharedFrameworks/DVTKit.framework/Versions/A/DVTKit\n  Expected in: /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit\n in /Users/xxxxx/Downloads/Xcode.app/Contents/SharedFrameworks/DVTDocumentation.framework/Versions/A/../../../../SharedFrameworks/DVTKit.framework/Versions/A/DVTKit\ngit: error: unable to locate xcodebuild, please make sure the path to the Xcode folder is set correctly!\ngit: error: You can set the path to the Xcode folder using /usr/bin/xcode-select -switch\n") (RuntimeError)

#対処法
以下の様のXcodeのパスを指定してあげればOKです。
`sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/`
【Java】StringBuilderの末尾から指定した文字数分を削除する

# はじめに

~~StringBuilderの標準メソッドで用意されていると思っていたのですが、どう探しても見つからなかったので自作しました。~~
↑誤解を招く記載でした……

末尾から指定した文字数を消すことに特化したメソッドが用意されていないかと思ったのですが、探しても見つからなかったので自作しました。です。


# 動作確認環境
- java 1.8.0

# サンプルソースコード①

```java
public class Demo {
    public static void main(String[] args) {
    	StringBuilder sb = new StringBuilder("hoge");

        // 末尾から1文字分を削除
    	sb.setLength(sb.length()-1);

        // 実行結果：hog
    	System.out.println(sb);
    }
}
```

```setLength``` は、シーケンスの文字列の長さを設定するものです。


```length()``` で、いま現在の文字列の長さを返します。上の例だと、4が返ってきています。
あとは、```length()``` から自分が削除したい文字数分を減算するだけです。


注意点としては、0未満の文字列長を指定してしまうと、```java.lang.StringIndexOutOfBoundsException``` とエラーが発生してしまう点です。

```java
StringBuilder sb = new StringBuilder("hoge");
sb.setLength(sb.length()-5);
// エラー：java.lang.StringIndexOutOfBoundsException: String index out of range: -1
```

```setLength``` する前に、```StringBuilder``` の長さを確認するほうがよいかもしれません。

```java
// n文字以上ならば、末尾からn文字削除
if (sb.length() >= n) {
	sb.setLength(sb.length()-n);
}
```

# サンプルソースコード②

```delete(int start, int end)``` を使用する方法です。
コメントにて教えていただきました。

自分も最初に思いついたのですが、開始位置と終了位置どちらも指定する必要があり、可読性が低いのでは…と思い、自分の中で却下しました。
```length()``` を2回書く必要があると思ったので…

そもそもlength()を変数に持たせれば1回書くだけで済むじゃん！可読性悪くないじゃん！と思い直しました。
deleteという文字があれば、文字を削除するということも分かりやすいですよね。

```java
StringBuilder sb = new StringBuilder("hoge");

int n = 2;              // 末尾から削除したい文字数
int size = sb.length(); // length()をint型変数に格納

// 末尾から2文字文を削除
sb.delete(size-n, size);

// 実行結果：ho
System.out.println(sb);
```

注意点は、サンプルソースコード①と同様なので、省略します。

# サンプルソースコード③

```deleteCharAt(int index)``` を使用する方法です。
こちらもコメントにて教えていただきました。

この場合は、**末尾から1文字だけ削除**することができます。
**末尾から複数文字数を削除することはできません**ので、ご注意ください。

しかし、こちらは上2つのサンプルソースコードより、（個人的に）可読性が良いと思います。
自分は、偉そうに公式ドキュメントを示しておきながら、全く気づくことができませんでした。
なので、戒めに記載しておきます。

```java
StringBuilder sb = new StringBuilder("hoge");

// 末尾から1文字分を削除
sb.deleteCharAt(sb.length()-1);

// 実行結果：hog
System.out.println(sb);
```

# 終わりに

もっと良い実装があったら教えてください。

# 参考文献

[StringBuilder (Java Platform SE 8)](https://docs.oracle.com/javase/jp/8/docs/api/java/lang/StringBuilder.html)
とあるjson関連のインデックス

##参考
・[非エンジニアに贈る「具体例でさらっと学ぶJSON]
(https://dev.classmethod.jp/etc/concrete-example-of-json/)
・[Pandasのjson_normalizeを詳しく調べてみる]
(https://qiita.com/simonritchie/items/7e50b47ccadbbb0fba57)
・[pandasのjson_normalizeで辞書のリストをDataFrameに変換]
(https://note.nkmk.me/python-pandas-json-normalize/)
・[Pandas dataframe to json without index]
(https://stackoverflow.com/questions/28590663/pandas-dataframe-to-json-without-index)
・[pandas.DataFrameをJSON文字列・ファイルに変換・保存（to_json）]
(https://note.nkmk.me/python-pandas-to-json/)
【iOS】WKWebViewでの電話/メーラー起動

現在、iOSでWebView一枚を貼り付け、中身の実装はフロントエンジニアの方が担当するという側アプリの開発に携わっております。筆者はiOSエンジニア側です。

# 解決したかった要件
WebView上で「電話」というボタンをタップすると、**設定されている電話番号で電話がかけられる。**

# 生じた問題
**WebView側で長押ししないと電話がかけられない。**タップで電話かけたい。メーラー起動したい。

# フロント側の実装コード
```vuejs:電話かけたい
<a href="tel:000-0000-0000">
   <img src="icon-image.png" />
   <span>電話</span>
</a>
```

# 問題はどこにあったか？
[WKWebViewConfiguraton](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration) の　[dataDetectorTypes](https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/1641937-datadetectortypes) に「phone」などをいれておくと、コンテンツ内に電話番号が直接書かれていた場合に、WKWebView側で認識してリンク変換し、電話をかける操作をしてくれます。

しかし、今回の要件では表示要素そのものは電話番号でなく、「電話」というタイトルのボタンで　href="`tel:000-0000-0000`" という形式だったので、WKWebView側でこのリンクを自動で拾うことができませんでした。

# どうしたのか？
ネイティブ側での対応が必要で、
1. hrefで遷移しようとするフロント側の処理を[WKNavigationDelegate](https://developer.apple.com/documentation/webkit/wknavigationdelegate)の[webView(_:decidePolicyFor:decisionHandler:)](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview)を用いてフック
2. 通常の遷移キャンセル、渡されたリンク　`tel:000-0000-0000` を用いて、[open(_:options:completionHandler:) ](https://developer.apple.com/documentation/uikit/uiapplication/1648685-open) で電話起動
というふうな対応をしました。

こちらのリンクを参考に以下のように実装しました。
https://stackoverflow.com/questions/26501172/launching-phone-email-map-links-in-wkwebview

(色々extenson切ったりしてるのを部分的にかいつまんで載せているので、{}構造がいい加減なのですが、適当に補完お願いします。)

```swift:webview.swift
    
override func viewDidLoad() {
    super.viewDidLoad()
    
    webView.navigationDelegate = self
}

enum URLSchemeType: String {
        case phone = "tel"
        case email = "mailto"
        
        init?(scheme: String?) {
            guard let value = scheme else {
                return nil
            }
            
            switch value {
            case "tel":
                self = .phone
            case "mailto":
                self = .email
            default:
                return nil
            }
        }
    }
}

extension WebViewController: WKNavigationDelegate {

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        let app = UIApplication.shared
        if let url = navigationAction.request.url {
            // Handle target="_blank"
            if navigationAction.targetFrame == nil {
                if app.canOpenURL(url) {
                    app.open(url, options: [:], completionHandler: nil)
                    decisionHandler(.cancel)
                    return
                }
            }
            
            if URLSchemeType(scheme: url.scheme) != nil {
                if app.canOpenURL(url) {
                    app.open(url, options: [:], completionHandler: nil)
                    decisionHandler(.cancel)
                    return
                }
            }
            
            decisionHandler(.allow)
        }
    }
}
```

こちらの実装で、うまく起動するのを確認しました。
localhost:3000にアクセスできません

Rails2.5.2をインストールすることに成功しました。しかし、そこからProgateの要領で、にrails new inter(アプリケーション名です）のコードとrails serverをターミナルに打ち込んだのですが、肝心のlocalhost:3000が出てきません。
どうしたらいいですか？
shellで入力したyumとcurlのコマンドの意味

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしています。

今週はPHPのフレームワークphalconをCentOSに導入しました。
実行環境を用意する際にshellにコマンドをコピペして貼り付けていきましたが、入力したコマンドの意味を理解できていなかったので今回はLINUXコマンドについて復習します。

###sudo yum install

https://以下のリポジトリ（開発パッケージ）をインストールするとき、sudo yum installを入力しました。

```
sudo yum install https://...
```

まずsudo(スードゥー)とは、一時的にroot権限でプログラムを実行するためのコマンドです。
rootユーザーとは、強力な権限をもったユーザであり、カレントユーザー(現在ログインしているユーザー)の権限を上回ります。
次にyumとは、ソフトウェアの導入と削除、依存関係の整理などを行うパッケージ管理ツールです。
よって、sudo yum install (リポジトリ名)で、開発パッケージをインストールできます。

###curl

しかし、phalconのリポジトリをインストールするときは、curl -s..... | sudo bash
to
入力しました。

```
curl -s https://...| sudo bash
```

curl(カール)とは、URLを使用してデータ取得するためのコマンドラインツールです。
ハイフンと併用することで様々なオプションを付け加えることが可能です。

###yumとcurlの違い

yumは、rpmのパッケージ管理システムを呼び出すときに使われます。
rpmが個々のパッケージで、yumが全体のパッケージというイメージです。
rpmのみでは依存関係は自動解決されませんので、yumを用いるのが基本です。
一方、curlは、TP, FTPS, HTTP, HTTPSなどの様々な通信プロトコルに対応しています。

ここまでお読みいただきありがとうございました。
GCPとARKitのマルチプレイ機能でコエカタマリン/ほんやくこんにゃくを作ってみた

#はじめに
こんにちは、drama(@1901drama)です！
今回はARKitのマルチプレイ機能を実装したアプリを作ったので、簡単に紹介します。
`※記載間違い等あれば教えてください。`



#出来たもの
色んな人とコミュニケーションをとるのにARを使うと面白そう！という考えから、
ドラえもんに出てくる「コエカタマリン」と「ほんやくこんにゃく」を合わせたようなアプリを作りました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">VOICE その1 <a href="https://t.co/o4VBl9Gh8T">pic.twitter.com/o4VBl9Gh8T</a></p>&mdash; drama (@1901drama) <a href="https://twitter.com/1901drama/status/1095908489568825344?ref_src=twsrc%5Etfw">2019年2月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

　・発言した言葉をオブジェクトとして可視化
　・衝突判定（オブジェクトは、壁・床・言葉にぶつかると爆発します。）
　・英語 ⇔ 日本語の翻訳
　・他のユーザーとオブジェクトを共有できるマルチプレイモード　※精度が安定しないので改善中

↓奥の端末から手間の端末に、
　日本語で「こんばんは」「明日は晴れです」と言ったものを翻訳して飛ばしてます。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">VOICE その2 <a href="https://t.co/cUeNWvylyT">pic.twitter.com/cUeNWvylyT</a></p>&mdash; drama (@1901drama) <a href="https://twitter.com/1901drama/status/1096036257606430724?ref_src=twsrc%5Etfw">2019年2月14日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 


**パブリッククラウド（GCP）も使ったので、処理をざっくり図にまとめました。**
![voice.png](https://qiita-image-store.s3.amazonaws.com/0/222377/1b5da88e-ff20-30ce-61cb-bb1425ece8ac.png)

尚、翻訳機能には「[ Google Translate API in Swift](https://medium.com/@maximbilan/googletranslate-api-in-swift-a36489a84508) 」を利用させて頂きました。超簡単！





#難しかった点
もし同じように初心者から始める人向けに、開発で特にはまった点を書いておきます。


**空間共有**
自分の端末だけであれば、ARkitがある程度よしなに場所を管理してくれるのですが、
他の人と共有するとなると、共通の基準＝原点が必要になります。

今回は、共有するときの始めに原点を相手に送信し、その後に配置するオブジェクトは、原点からの差分で割り出した座標を都度共有するという方法をとってます。（参考リンク内のパターンC）
難しかったのは送信方法でしたが、そもそも座標の考えについてまだ深く理解出来ていないので、もう少し勉強必要です。かつ、共有精度が不安定なので現在、改善中。
>参考：[ ARKitで空間共有して端末間通信する方法22選](https://qiita.com/k-boy/items/e9adf3e4b64be9ed4635)

**衝突判定**
全く知らなかったのですが「衝突は各オブジェクトにマスク値を与えて判定している」そうです。
3Dデザインを全くしたことがなかったので、驚きの実装方法でした。
同じゲームや空間の中でも、
「0001(1)の属性をもつオブジェクト」と「0010(2)の属性をもつオブジェクト」は、住む世界(桁)が違う為、衝突しないということです。※例はやや適当ですが...
>参考：[ SceneKitにおける物体衝突検知を理解する](https://qiita.com/noby111/items/319c727e9527cfbb0692)


#まとめ
ARKitよりもSCNノードに苦戦することが多いので、3Dデザインやエフェクトに詳しくなりたいです。
また、GCPは普段から使っているようなAPIが充実してるうえに、簡単に導入出来るのが素晴らしいです。

ここまで読んで頂きありがとうございました！

**今回のアプリはリリース済みですので、宜しければ感想聞かせてください！**
**[ VOICE (@AppStore)](https://itunes.apple.com/jp/app/voice-ar/id1450717409?l=ja&ls=1&mt=8!)**　※随時アップデートしていきます。
人月別進行管理法

個人的に経験したプロジェクトでしっくりきた進行管理の手法についてまとめてみました。

# 1人月未満
個人で受けた案件や、中規模プロジェクトでアサインされたタスクのマネジメントをするシーンで利用。

BacklogやGithubのIssueで十分。
要件をまとめて、タスクリストを作ってPullRequestに対してPUSHしていくだけで良い。

e.g.

```
お問い合わせページの離脱率を改善するためにいくつかの施策を行う。
対応ブラウザは各種最新とする。

- [ ] ワイヤーフレーム作成
- [ ] ◯◯さんにOKもらう
- [ ] レイアウト調整
- [ ] フォームのバリデーションをリアルタイムに実行できるようにする
- [ ] よくある質問へのリンクを目立たせる
- [ ] 離脱する際にモーダルを表示させる
```
コツは **自分がやるタスクであっても、他人に渡すことができる粒度までタスクを砕くこと。**
ガントやマイルストーンを使うとスケジュール管理をしやすいので、期日や工数はIssueにべた書きしない方が良い。


# 20人月未満
新機能開発や新規案件のマネジメントをするシーンで利用。

Backlogの親子課題でのガントチャートや、GithubのProjectsが便利。
特にGithubのProjectsはオンラインでカンバンとして使えるので進行管理が捗る。
<img width="1437" alt="GithubProjects.png" src="https://qiita-image-store.s3.amazonaws.com/0/45540/371765e2-ca3b-b2e7-df79-97039c5b22ed.png">
コツは **進行のルールを決めること。** カンバンは朝ちゃんと更新しましょうとか。
ルールをしっかり守れば誰かの片手間で進行管理できる。

# 100人月未満
進行管理だけを行うディレクターが必須。

1. 要件定義
2. 設計書作成
3. 見積もり・スケジュール
4. 実装
5. テスト

上記順番でうまく進めないと実装段階でメンバーの不満が爆発する。
（仕様がひっくり返ることが多いのでうまく進めても爆発する :innocent: ）

このぐらいのボリュームのプロジェクトからプロジェクトマネージャーの手腕が問われだす。
DB設計書やワイヤーフレーム等の設計書を書き起こして**メンバーの認識を統一することがめちゃくちゃ大事。**
認識を統一するために用語集を用意しないといけないこともある。

すごい勢いでガントチャートをこねくり回すのでクリティカルパスの設定がしっかりできるツールを使うと良い。
個人的には **xPlan** が優秀だと思う。Backlogはガントの更新が面倒だけどオンラインでの共有がしやすい。

<img width="1186" alt="xPlan.png" src="https://qiita-image-store.s3.amazonaws.com/0/45540/9a0517d4-24a3-4a86-f6f5-99fde5cfe060.png">

プロジェクトの色が出やすくなってくるボリュームなので正直コツが無い。
燃えないようにするために、上流の段階でどれだけゴール近辺のイメージをふくらませることができるかが大事。



# 100人月以上
経験無いので、色々聞いてみたい。
このレベルのディレクターとか正直やりたくないけど。単価次第 :innocent:

# 最後に
初めての投稿ですが、これからもちょこちょこ書き残していこうと思います。
iSCSI Initiator for macOS を使って Mac を iSCSI に対応させる方法

## 前提条件
この記事は、 [iSCSI Initiator for macOS](https://github.com/iscsi-osx/iSCSIInitiator/tree/master) と ELECOM NetStor NSB-7A4BL を使って Mac mini (2018)  / Mac OS Mojave で確認したものです。
Mac OS El Capitan 以降であれば、同じ方法で iSCSI に対応させることが可能です。

## OS X のシステム保護機能 `Rootless` を無効にする
iSCSI 対応には Rootless を切る必要があるため、 Mac をリカバリモードで起動して、コマンドラインで以下を入力します。

```sh
$ csrutil disable
```
上記の設定が終わったら通常のログインを行います。

## iSCSI Initiator for macOS のインストール
[iSCSI Initiator for macOS](https://github.com/iscsi-osx/iSCSIInitiator/tree/master) を zip 形式でダウンロードし、解凍したファイルの `Scripts` ディレクトリに移動した後、以下を実行します。

```sh
Scripts$ sh build.sh && sh install.sh
```

CHAP認証を行っている場合は[iSCSIInitiator Wiki](https://github.com/iscsi-osx/iSCSIInitiator/wiki/Authentication) に従い、CHAPの設定などを行う。

```sh
$ iscsictl add target <target>,<portal>
$ iscsictl modify initiator-config -CHAP-name <username>
$ iscsictl modify initiator-config -CHAP-secret
$ iscsictl modify initiator-config -authentication CHAP
$ iscsictl list initiator-config
```

## iSCSI ディスクへのログインとログアウト
ログイン・ログアウトは以下のコマンドで行う。

```sh
$ iscsictl login <target>
$ iscsictl logout <target>
```

## Mac起動時に自動的に接続する
Mac起動時に自動的に iSCSI ディスクに接続するには、以下を実行する。

```sh
$ sudo iscsictl modify target-config <target> -auto-login enable
```

## 備考
LUNのリストは以下で取得可能。

```sh
$ iscsictl list luns
```
Cron 多重起動 チェック(引数含む)

# Proccess名＋引数での多重起動判定

```bash
#!/bin/bash

ARGS="${@}"

# check proccess & args
OLDEST=$(pgrep -fo "$0 ${ARGS}")
if [ "$$" ！= "${OLDEST}" ] && [ "$PPID" ！= "${OLDEST}}" ];then
   echo "$0 ${ARGS} is already running"
   exit 1
fi
```

同じスクリプトを引数違いで複数起動するが、それぞれの多重起動を抑止する場合に使う。
(それぞれ別名にすれば事足りるんだけど）
時々使うので備忘録。

参考URLそのままなので説明なし...

参考：
http://memo-off.blogspot.com/2015/08/cron.html
https://qiita.com/nao58/items/bdf97826a3683ccd63fb
Bitriseで1つのトリガーに対して複数のワークフローを実行する

Bitiriseを使っていて、例えば特定のブランチにPushされたときにdebugとreleaseの両方のbuildを実行したい時があるかもしれません。
そのような時にもBitriseでは少し手順を踏みますが実行可能です。

## 手順
1. AccountSettingsに移動し、Securityから`Personal access token`を作成しコピーしておきます
2. Workflow EditorのSecretsに作成した`Personal access token`を設定します
3. トリガー用のWorkflowを作成します
4. `Bitrise Start Build`ステップを追加します
![スクリーンショット 2019-02-14 13.13.49.png](https://qiita-image-store.s3.amazonaws.com/0/121288/dc4d4f77-9373-a35d-d1fc-9a358746c00b.png)

5. `Bitrise Start Build`ステップで`Bitrise Access Token`に先程Secretsに作成したアクセストークンを設定し、`Workflows`に実行したい`Workflow`を設定します。ここには~~カンマ区切り~~(*追記あり)で複数のWorkflowを設定できるみたいです(私は複数設定したところ失敗してしまったため、後述する回避策を用いています)

![スクリーンショット 2019-02-14 13.19.31.png](https://qiita-image-store.s3.amazonaws.com/0/121288/d6643403-90b3-7ecf-5060-b0ebae99ec5b.png)

6. Workflow EditorのTriggersに作成したトリガー用Workflowを設定すれば設定完了です🎉
![スクリーンショット 2019-02-14 13.22.21.png](https://qiita-image-store.s3.amazonaws.com/0/121288/3d4e4bc5-0031-f342-ea36-4b441b3a450b.png)

## 回避策
以下のように`Bitrise Start Build`を複数作成したところ、こちらで期待通りに実行されました
![スクリーンショット 2019-02-14 13.24.04.png](https://qiita-image-store.s3.amazonaws.com/0/121288/190f1209-5a6e-7be3-2ea0-c5630f6fb55c.png)

## 参考
https://devcenter.bitrise.io/builds/triggering-builds/trigger-multiple-workflows/

## 追記
*2019/7/3 追記*
popobotさんより以下の指摘を受けました
https://qiita.com/kariad/items/42e037bb42eee3eff91f#comment-758e5cb4e7204ce10173

正しくはカンマ区切りではなく改行だそうです。
ドキュメントの画像だとカンマ区切りで書いてあるので惑わされました...
bitcoin测试链: Testnet



> ![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169726/3bde7778-917f-d068-79e7-2d757ae8d396.jpeg)

在之前介绍的[bitcoin 地址是如何生成](https://qiita.com/shooter/items/85246781a27a42e3785c)的过程中，
使用私钥`0xccea9c5a20e2b78c2e0fbdd8ae2d2b67e6b1894ccb7a55fc1de08bd53994ea64` 生成了一个主网地址`14xfJr1DArtYR156XBs28FoYk6sQqirT2s `。

我把这个过程分为了 8 个步骤，了解这些步骤，自己就可以在离线环境中生成非常多的冷钱包地址。

其中有个细节，我们在计算完 Hash160 的结果后，`第四步`是加上主网的前缀符 `00`，即`00+2b6f3b9e337cedbb7c40839523fb1100709c12f7`,
大家对这个操作有很多疑问，这个前缀符有什么用？其实比特币的地址类型有很多种，不同类型的地址应用于不同的场景，如何区分呢，自然就是前缀符了。

![addr-prefix](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169726/2476d6dd-934d-365d-c081-a5e4c64c6441.png)


P2PKH 类型的地址最常用，比特币网络的很多地址是这种。可用于转账、发账，支持最最常用的操作，安安静静，低调内敛。

P2SH 类型的地址支持多重签名。

什么是多重签名呢？假设 3 个人管理一个基金会的比特币账户，规定至少 2 个人同意的时候才能动用，我们就可以做一个 3-2 签名的多重签名，也可以做 5-3 签名的，5 个人中只要有 3 个同意，就可以动用。其实还可以做 5-5 签名，只有 5 个人都同意了，才能动用，绝对的民煮。交易所的冷钱包往往都是多重签名地址，利于分权，其实也降低了风险。

以太坊的多重签名，需要编写智能合约，虽然有些麻烦，但能进行更细致的分配。

Testnet 类型的地址，这个很好理解，软件工程中常常有测试环境，区块链也分为主网、测试网，主网是我们在使用的真正的转账网络，测试网主要用于测试，我们可以获取一定数量的测试币，进行调试，而不用花费真金白银，也能提前发现 bug，很像游戏的不删档内测。

同一个私钥生成的测试网地址`mjUcbu6BytKoC7YiEkqPxB1sc6U7nnjFse`。

https://tbtc.bitaps.com/mjUcbu6BytKoC7YiEkqPxB1sc6U7nnjFse

下图是同一个私钥，生成的不同类型地址，这 3 个地址都是 34 位长度，由于大小写字体的字宽问题，在视觉上长度不一致。

| 十进制 | 十六进制 | 地址类型 | 地址首字母 |例子 |
| :------| ------: | :------: | :------: |:------: |
|0 | 00| P2PKH address |1 |14xfJr1DArtYR156XBs28FoYk6sQqirT2s |
| 5 | 05| P2SH address |3 |35egEPVeimCvWAmXeHXcYtAUtdA8RtsNUY |
| 111 | 6F |Testnet address |m 或 n|mjUcbu6BytKoC7YiEkqPxB1sc6U7nnjFse |

以太坊的地址比较统一，主网地址、测试网地址都是同一个类型的。

最近很吸引眼球的吴比特币、澳比特币分叉事件，闹得鸡飞狗跳，吴比特币的前身 BCH 地址跟比特币地址差异很大，其实他们是能互相转换的，为什么呢？因为有相同的 hash160， **地址只是一种方便人可读的呈现方式**。欲要分叉，先改其地址 ......

![bch](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/169726/154eb7c6-bc24-d8d6-fa42-15aeba955571.png)

我们去 https://testnet.manu.backend.hamburg/faucet
得到一些测试币。通过 https://www.blocktrail.com/tBTC/address/mjUcbu6BytKoC7YiEkqPxB1sc6U7nnjFse 查看账户的余额。

## python3 code

```python
## https://github.com/fortesp/bitcoinaddress

from bitcoinaddress import Wallet

wallet = Wallet()
priv_key = wallet.key.hex

print("priv_key: ", priv_key)
print(wallet)

testwallet = Wallet(hash_or_seed=priv_key, testnet=True)
print(testwallet)
```

---

参考：

https://github.com/liushooter/learn-blockchain/blob/master/gen_addr.rb
https://en.bitcoin.it/wiki/List_of_address_prefixes
https://bch.btc.com/tools/address-converter
https://tbtc.bitaps.com/mjUcbu6BytKoC7YiEkqPxB1sc6U7nnjFse
https://live.blockcypher.com/btc-testnet/address/mjUcbu6BytKoC7YiEkqPxB1sc6U7nnjFse/

https://www.blockchain.com/btctest/address/mjUcbu6BytKoC7YiEkqPxB1sc6U7nnjFse
https://testnet-faucet.mempool.co
質問です。

import UIKit

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate{
  
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var searchBar: UISearchBar!
  
     let PPAP:[String] = ["平泉", "日光東照宮", "国立西洋美術館", "富士山", "京都"]
 
    var searchResults:[String] = []


override func viewDidLoad() {
    super.viewDidLoad()
  
    tableView.register(UITableViewCell.self, forCellReuseIdentifier: "PPAP")
    tableView.dataSource = self
    tableView.delegate = self
    self.view.addSubview(tableView)
    
    searchBar.delegate = self
    searchBar.searchBarStyle = UISearchBar.Style.default
    searchBar.showsSearchResultsButton = false
    searchBar.placeholder = "検索"
    searchBar.setValue("キャンセル", forKey: "_cancelButtonText")
    searchBar.tintColor = UIColor.red
    
    tableView.tableHeaderView = searchBar
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

// lines of cells
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if searchBar.text != "" {
        return searchResults.count
    } else {
        return PPAP.count
    }
}
// add texts of cells
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "PPAP",for: indexPath as IndexPath)
    if searchBar.text != "" {
        cell.textLabel!.text = "\(searchResults[indexPath.row])"
    } else {
        cell.textLabel!.text = "\(PPAP[indexPath.row])"
    }
    
    return cell
}
    
    /// セル選択時（UITableViewDataSource optional）
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        
    }
    
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    
}

// 検索ボタンが押された時に呼ばれる
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    self.view.endEditing(true)
    searchBar.showsCancelButton = true
    self.searchResults = PPAP.filter{
        $0.lowercased().contains(searchBar.text!.lowercased())
    }
        self.tableView.reloadData()
    }

// キャンセルボタンが押された時に呼ばれる
func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    searchBar.showsCancelButton = false
    self.view.endEditing(true)
    searchBar.text = ""
    self.tableView.reloadData()
}

// テキストフィールド入力開始前に呼ばれる
func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
    searchBar.showsCancelButton = true
    return true
   }
 }

上記コードで、セクションを複数にしたいです。
どうすればいいですか？
CloudWatch Logsに貯めたログから Insights を使って データの抽出を行う

## やりたいこと

CloudWatch Logsに取り溜めているログに、APIサーバが受け付けたリクエストのパスと、リクエストを出したユーザIDが記録されているので、特定のAPIを呼び出した日時とユーザIDのリストを作りたいのです。


## CloudWatch Logsに取り溜めているログ

CloudWatch Logsのメッセージには下の様なJOSN形式のログを出力しています。

```json:CloudWatchLogsのmessage
{
    "access_timestamp": "2019-02-13T10:54:25+09:00",
    "level": "info",
    "method": "POST",
    "path": "/path/to/resource/sub_resource",
    "query": {
        "param1": "value1",
        "param2": "value2",
        "param3": "value3",
    },
    "user_id": "dfc269bf-c08a-48a2-a6e3-14dd25f5350a",
    "status": "200",
}
```

### 作りたいもの
上のJSONに対して 目的の *path* を指定して、statusが"200"(成功)のログを抽出して、 `access_timestamp ` と `user_id` のリストを作ります。

```csv
"2019-02-13T10:54:25+09:00","dfc269bf-c08a-48a2-a6e3-14dd25f5350a"
"2019-02-13T10:55:16+09:00","908cbf68-744f-41ea-a202-667b129029ca"
"2019-02-13T10:56:14+09:00","5000adc0-da5d-4d58-aad2-f5d4e8c32426"
```

## aws cli で頑張る

[`aws logs start-query` ](https://docs.aws.amazon.com/cli/latest/reference/logs/start-query.html) で Insights を利用します。


```bash:Insightsの問い合わせを開始
aws logs start-query --log-group-name 'my-log-group' --start-time 1550012400 --end-time 1550014200 \
 --query-string 'fields, @message
| filter ( access_url =~ "/path/to/resource/" and level ="INFO" and method = "POST" and status = "200")
'
```

引数` --query-string` の `filter` では CloudWatchLogsのmessageに記録されている JSON のキーを指定しています。 JSONのキー *access_url* 、 *level*  、 *method*  、 *status*  は自動的に認識されるようです。AWSのコンソールで ロググループ名を指定すると、右側の「検知されたフィールドに」にキー名が表示されるので、確認できます。

![CloudWatchLogsInsightsが認識したプロパティ.png](https://qiita-image-store.s3.amazonaws.com/0/145742/2a2bcc46-2b6b-dc03-7698-3791eaa03856.png)


Insights の処理が終わると `queryId` を得られるので、 `queryId` を指定して、結果を取得します。

```json:queryIdの出力
{
    "queryId": "5000adc0-da5d-4d58-aad2-f5d4e8c32426"
}
```

最後に、jqを駆使して、access_timestampとuser_idを出力します。

```bash:Insightsの結果からaccess_timestampとuser_idを出力
aws logs get-query-results --query-id 5000adc0-da5d-4d58-aad2-f5d4e8c32426 |  \
jq -r  '.results[] | map ( select( .field == "@message")) | .[].value ' | jq -r '[. access_timestamp, .user_id] | @csv'
```
proxyノコトチョットワカルメモ（Ubuntu18.04でのproxy設定について）

## 前提
* コピペで動くようにコマンドはそのまま貼りつけています。
* 本記事内では、proxyサーバーのIPアドレスを「192.168.0.1」、ポートは「1」とします。
* 社内サーバー等にproxy無しでアクセスする場合はno_proxyの設定が必要ですが、本記事では省略します。
* ~/.bashrcやシステム設定に書かずに、以下のパッケージ等で個別に設定します。
 * [apt](#apt)
 * [Docker(pull)](#dockerpull)
 * [Docker(run)](#dockerrun)
 * [Firefox](#firefox)
 * [git](#git)
 * [wget](#wget)
 * [curl](#curl)
 * [pip](#pip)

## 環境等
* 動作確認した環境は下表の通りです。

|            |Name(Version)              |
|:-----------|:----------------:|
|OS          |Ubuntu(18.04)     |
|apt|(1.6.6 (amd64))|
|Docker|(18.06.1-ce)|
|Firefox|(65.0)|
|git|(2.20.1)|
|wget|(1.19.4)|
|curl|(7.58.0)|
|pip|(19.0.2)|

## proxyの設定
### 変数の設定
* **実際に設定するIPアドレスとポートはネットワーク管理者に問い合わせされたい。**

```
export HTTP_PROXY=http://192.168.0.1:1
```

### apt
* 設定ファイルを作成する。

```
echo -e "Acquire::http::proxy \"$HTTP_PROXY\";\\nAcquire::https::proxy \"$HTTP_PROXY\";\\nAcquire::ftp::proxy \"$HTTP_PROXY\";" | sudo tee /etc/apt/apt.conf
```

### Docker(pull)
* ディレクトリおよび設定ファイルを作成し、反映させる。

```
sudo mkdir /etc/systemd/system/docker.service.d
echo -e "[Service]\\nEnvironment=\"HTTP_PROXY=$HTTP_PROXY/\"" | sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf
sudo systemctl daemon-reload
sudo systemctl restart docker
```

### Docker(run)
* オプションと設定ファイルと二種類方法がある。
* 環境変数を設定した後にcommitすると、imageの設定として保存される？ので注意する。
* Ubuntuベースのコンテナでは、proxyを適切に設定した場合パッケージ毎にproxyの設定を行う必要はない...はず。
* proxyを設定する環境変数と各コマンドの調査結果は下記表の通り。(この記事いらない説)

| |http_proxy  |https_proxy|HTTP_PROXY|HTTPS_PROXY|
|:-:|:-:|:-:|:-:|:-:|
|apt|○|☓|☓|☓|
|pip|☓|○|☓|☓|
|git(https://~)|☓|○|☓|○|
|wget(http://~)|○|☓|☓|☓|
|wget(https://~)|☓|○|☓|☓|
|curl(http://~)|○|☓|☓|☓|
|curl(https://~)|☓|○|☓|☓|

#### コマンド実行時にオプションで設定する場合
* 以下の例では、環境変数「HTTP_PROXY」と「http_proxy」に設定し、docker runコマンドを実行している。

```
docker run -it --rm -e HTTP_PROXY=$HTTP_PROXY -e http_proxy=$HTTP_PROXY --name ubuntu1604 ubuntu:16.04
```

#### 設定ファイルで設定する場合
* 以下の例では、環境変数「HTTP_PROXY」と「http_proxy」に設定される。
* 設定ファイル作成後、docker runを実行すると、全てのコンテナに適用されるが、-eオプションで上書きできる。

```
mkdir ~/.docker/
echo -e "{\\n \"proxies\":\\n {\\n  \"default\":\\n  {\\n   \"httpProxy\": \"$HTTP_PROXY\"\\n  }\\n }\\n}\\n" > ~/.docker/config.json
```

### Firefox
* メニューボタンをクリックし、設定を選択する。
* 「about:preferences」ページ下部の「ネットワーク設定」＞「詳細設定」にて設定する。
* 以下、設定例
![firefox_test](https://qiita-image-store.s3.amazonaws.com/0/207420/a10eaca0-40f4-1a74-88e9-852d77e666cd.png)

### git
* 以下のコマンドで設定する。

```
git config --global http.proxy $HTTP_PROXY
```

* 設定ファイルが作成される

```~/.gitconfig
[http]
	proxy = http://192.168.0.1:0
```

### wget
* 設定ファイルを作成する。

```
echo -e "\\nhttps_proxy = $HTTP_PROXY\\nhttp_proxy = $HTTP_PROXY\\nftp_proxy = $HTTP_PROXY" | sudo tee -a /etc/wgetrc
```

### curl
* 設定ファイルを作成する。

```
echo "proxy = \"$HTTP_PROXY\"" > ~/.curlrc
```

### pip
#### コマンド実行時にオプションで設定する場合
* a

```
```

#### 設定ファイルで設定する場合
Ubuntuを勉強してみる

apt-getコマンドはパッケージの操作・管理を行うコマンド。

APT = Advanced Package Tool

Debian系(DebianやUbuntu)のパッケージ管理システム

コマンド書式

　apt-get [スイッチ] [オプション] [パッケージ]

スイッチ

<table>
	<tr>
		<td>update</td>
		<td>APTライブラリのインデックスを更新する。</td>
	</tr>
	<tr>
		<td>upgrade</td>
		<td>インストール済みパッケージを最新バージョンにする。</td>
	</tr>
	<tr>
		<td>dist-upgrade</td>
		<td>インストール済みパッケージをアップグレードする。</td>
	</tr>
	<tr>
		<td>install</td>
		<td>指定したパッケージをインストールする。</td>
	</tr>
	<tr>
		<td>remove</td>
		<td>指定したパッケージを削除する。</td>
	</tr>
</table>

オプション

<table>
	<tr>
		<td>-d</td>
		<td>パッケージのダウンロードのみを行う。展開・インストールは行わない。</td>
	</tr>
	<tr>
		<td>-f</td>
		<td>パッケージの依存性がおかしくなった場合、その修復を試みる。</td>
	</tr>
	<tr>
		<td>-q</td>
		<td>quietモード。進捗状況を表示しない。</td>
	</tr>
	<tr>
		<td>-u</td>
		<td>アップデートするパッケージの一覧を表示する。</td>
	</tr>
	<tr>
		<td>-s</td>
		<td>インストールするパッケージの一覧を表示する。</td>
	</tr>
	<tr>
		<td>-y</td>
		<td>インタラクティブ（ユーザーへの問い合わせ）に「yes」と答える。</td>
	</tr>
</table>

Ubuntuデスクトップをいれてみる

〇ライブラリのインデックスを更新する。
sudo apt-get update

〇デスクトップパッケージをインストール
sudo apt-get -y install ubuntu-desktop

〇再起動
sudo shutdown -r now
Redmine3 -> 4にアップグレード (sqlite3使用)

## docker-compose

```rb:docker-compose.yml(従来)
redmine3:
  image: redmine:3
  restart: always
  volumes:
    - ./sqlite:/usr/src/redmine/sqlite
    - ./files:/usr/src/redmine/files
  ports:
    - 3000:3000
```

```rb:docker-compose.yml(今回)
redmine4:
  image: redmine:4.0.1
  restart: always
  volumes:
    - ./sqlite:/usr/src/redmine/sqlite
    - ./files:/usr/src/redmine/files
  ports:
    - 3000:3000
```

## パーミッション修正

```sh:
chown -R 999:999 sqlite files
```

書き込みはできるようになった。
(コンテナ内のrubyがid:gid=999:999 で動作するようになった。)

```sh:起動
docker-compose up -d
```
CloudflareのキャッシュクリアをNode.jsから行うメモ


Cloudflareのキャッシュが強いのでキャッシュクリアしたいときがあります。
axiosを使ってAPIを叩いてみましょう。

ちゃんとした手順はこちら([CloudflareのAPIをNode.js+GitLab CIから実行してキャッシュクリアしてみよう](https://dotstud.io/blog/cloudflare-cache-clear-nodejs/))で紹介してます。

```sh
npm i axios
```

```js
'use strict';

if(!process.env.YOUREMAIL || !process.env.APIKEY || !process.env.PURGE_TARGET){
    console.log('環境変数が足りません');
    return;
}

const YOUREMAIL = process.env.YOUREMAIL; //Cloudflareに登録してるメールアドレス
const APIKEY = process.env.APIKEY; //CloudflareのAPI KEY
const PURGE_TARGETS = [process.env.PURGE_TARGET]; //消す対象ページ

const axiosBase = require('axios');
const axios = axiosBase.create({
    baseURL: `https://api.cloudflare.com/client/v4/zones`,
    headers: {
        'Content-Type': 'application/json',
        'X-Auth-Key': APIKEY,
        'X-Auth-Email': YOUREMAIL
    }
})

const main = async() => {
    try {
        //STEP1. ZoneIDの取得
        let res = await axios.get('/');
        const zoneid = res.data.result[0].id;

        //STEP2. キャッシュ削除
        res = await axios.delete(`/${zoneid}/purge_cache`,{
            data: {
                files: PURGE_TARGETS
            }
        });
        console.log(res.data);
    } catch (error) {
        console.log(error.response.data)
    }

}

main();
```
DockerでSSH keyを使ってbitbucketの非公開レポジトリをクローン

# TL;DR
結論からいうと、下記2つコマンドを覚えば話は終わりです。

```sh
$ ssh-keyscan -t rsa bitbucket.org >> /root/.ssh/known_hosts
$ ssh-agent bash -c 'ssh-add /PATH/TO/KEY.pem; git clone git@bitbucket.org:YOUR_NAME/YOUR_REPO.git'
```

# 方法
## キーペアの作成＆登録
記事たくさんあるので、割愛します。

## Dockerfile
あくまでも一例なので、必要に合わせて修正してください。

```dockerfile
FROM ubuntu
# おまじない
RUN apt-get update
RUN apt-get install -y openssl git
WORKDIR /usr/src/app

# known_hostsにbitbucket.orgを登録
# 登録しなければ、キーが正しいであっても通らない
# `Permission denied (publickey).`と怒られる
RUN mkdir /root/.ssh/ && touch /root/.ssh/known_hosts
RUN ssh-keyscan -t rsa bitbucket.org >> /root/.ssh/known_hosts
# GitHubの場合は
RUN ssh-keyscan -t rsa github.com >> /root/.ssh/known_hosts

# キーをコンテナにコピー
COPY ./*.pem /usr/src/app/git-key.pem
RUN chmod 600 /usr/src/app/git-key.pem

# リポジトリのClone
RUN ssh-agent bash -c 'ssh-add /usr/src/app/git-key.pem; git clone git@bitbucket.org:YOUR_NAME/YOUR_REPO.git'

# 使い終わったキーを削除
RUN rm -rf /usr/src/app/git-key.pem

# 一応確認しておく
RUN cd YOUR_REPO && ls -la
```

# 余談
`ssh-agent`コマンドは踏み台サーバーでログインする時も活用出来ます。

# 参考
https://stackoverflow.com/a/4565746
https://stackoverflow.com/a/23411161
https://stackoverflow.com/a/29380765
https://euske.github.io/openssh-jman/ssh-keyscan.html
https://qiita.com/naoki_mochizuki/items/93ee2643a4c6ab0a20f5
【Vue.js】Vueのコンポーネントはカスタムタグで描画されない

## はじめに
vue-loaderでscoped cssを書くと親のスタイルが子コンポーネントのルート要素に適応される。
これにより稀に困ったことが起こる。

## どんな時に困るのか？
```App.vue
<template>
  <div class="container">
    <sample-component />
    <div>hoge</div>
  </div>
</template>

<script>
import SampleComponent from './SampleComponent.vue'

export default {
  components: {
    'sample-component': SampleComponent
  }
}
</script>

<style scoped>
.container {
  display: flex;
}
</style>
```

```.SampleComponent.vue
<template>
  <div class="container">
    <div>fuga</div>
    <div>fuga</div>
  </div>
</template>

<style scoped>
.container {
  font-size: 100px;
}
</style>
```

上記の場合、`SampleComponent.vue` にも`container`にも `displey: flex` のスタイルがあたってしまう。

![スクリーンショット 2019-02-14 12.10.49.png](https://qiita-image-store.s3.amazonaws.com/0/192435/07f46354-5ddf-d72f-e1a6-fd861ad170fe.png)



## 解決策
scopedと言えど命名規則は決めておく
[Vueコンポーネントに合わせたCSSの命名規則を考えた](https://qiita.com/nakajmg/items/683395c20a3afbdb2d99)

CSS Modulesを使う
Nuxt.js(Vue.js)で動的にimageを変更する方法

# やりたかったこと

Nuxtでimgタグのsrcプロパティーを動的に変更したかった。

## 困ったこと

以下のようなコードではリソースが受け取れず、上手くいきませんでした。

```
<img :src="imgSrc">
.
.
imgSrc: "~/assets/img/image.png"
```

## 解決策

イメージ画像のpathをrequireしてあげる事で解決することができました。
具体的には以下のコードを参照ください。

```html
<template>
  <div>
    <img :src="imgSrc">
  </div>
</template>

<script>
export default {
  data() {
    return {
      imgSrc: require("~/assets/img/image.png")
    }
  }
}
</script>
```

background-imageを動的に変更したいなど色々なシーンで使えると思います。
以上、備忘録でした。
Swiftで日付の経過日数を計算する

ユーザに何らかの通知やアラートを表示する際に、**前回表示した日から○日経過していたら表示する**というような条件を設定することがあると思います。

これを言い換えると、**前回表示した日を表すDateオブジェクトと今日を表すDateオブジェクト間の日数が○より大きい**となります。

2つのDateオブジェクト間の日数は以下のコードで算出できます。


```swift
let elapsedDays = Calendar.current.dateComponents([.day], from: date1, to: date2).day
```

※`eplapsedDays`は`Int?`型になります。

条件が**前回表示した日から90日経過していたら表示する**だったら、

```swift
if epalsedDays > 90 {
    ...
}
```

となります。

**※日付を扱う際にはタイムゾーンへの考慮も必要です。**

## 24時間で1日経過
24時間経たないと1日経過したとはみなされません。

以下の`date1`と`date2`の差は数ミリ秒しかないので、経過日数は0になります。

```swift
let date1 = Date()
let date2 = Date()
let elapsedDays = Calendar.current.dateComponents([.day], from: date1, to: date2).day!

print(elapsedDays)  // 0
```

例えば**前回表示した日から10日経過していたら通知を表示する**というようなケースを考えます。

```swift
// yyyy年MM月01日 12時
let lastDate = DateComponents(calendar: Calendar.current, day: 1, hour: 12).date!

// yyyy年MM月11日 11時
let now = DateComponents(calendar: Calendar.current, day: 11, hour: 11).date!

let elapsedDays = Calendar.current.dateComponents([.day], from: lastDate, to: now).day!

print(elapsedDays)  // 9
```

日付の差だけを見ると感覚的には10日間経ってるような気がしますが、**10日間になるには1時間足りません**。

日付だけで比較したい場合は`Calendar#startOfDay(for:)`を使って時刻を合わせると良いです。

```swift
// yyyy年MM月01日 12時
let lastDate = DateComponents(calendar: Calendar.current, day: 1, hour: 12).date!

// yyyy年MM月11日 11時
let now = DateComponents(calendar: Calendar.current, day: 11, hour: 11).date!

let lastDateStartOfDay = Calendar.current.startOfDay(for: lastDate)
let nowStartOfDay = Calendar.current.startOfDay(for: now)

let elapsedDays = Calendar.current.dateComponents([.day], from: lastDateStartOfDay, to: nowStartOfDay).day!

print(elapsedDays)
```

## 参考
https://stackoverflow.com/a/46770148/5793173
LaravelのFormRequestを使用したバリデーションに独自ルールを追加する

例として、カタカナのみ受け付けるrulesを作成する場合

####1.専用のサービスプロバイダを作成
```
command:php artisan make:provider KatakanaServiceProvider
```

これでApp/Providers配下に、新規にKatakanaServiceProviderが生成される


####2.作成されたファイル内のbootメソッドにバリデーションエラーとなる条件式を記述する


```
public function boot()
     {
         Validator::extend('katakana', function ($value) { |
             return (preg_match('/^[ァ-ヶー]+$/u', $value) === 1);
         }); 
     } 
```
この場合、与えられた値がカタカナのみで構成されていない場合にエラーとしている


####3.config/app.phpファイル内'providers'配列に記述を追加する
```
use Illuminate\Support\Facades\Validator;
~~
'providers' => [
~~
　App\Providers\KatakanaServiceProvider::class,
]
```


####4.フォームリクエストのrulesメソッド内で、通常のルールと同様に使用できる

```
rules => [
  'UserNameFurigana' => 'required|katakana',
]
```
Mac標準Terminalをもっと使おうぜって話

# 前置き

この記事は[お前らのターミナルはダサい](https://qiita.com/kinchiki/items/57e9391128d07819c321)という記事を見て`iTerm`や`Hyper`を使わずにカッコイイターミナルを模索した結果生まれたもので、

この標準ターミナルを

![スクリーンショット 2](https://qiita-image-store.s3.amazonaws.com/0/117659/aad7e104-56b9-0235-4c30-69ffb13df613.png)

こうして見ようという記事です。

<img width="782" alt="スクリーンショット 3.png" src="https://qiita-image-store.s3.amazonaws.com/0/117659/1c61a4e2-6b86-e0e7-d6dd-4b460e143fa1.png">


> 標準ターミナルを改造しますので、可能ならバックアップもしくはターミナル.appをコピーしてお試しください。
> また標準アプリを改造する都合上、予想外のことが起こるかもしれません。
> その際こちらでは責任を取りかねますので、自己責任でお願いいたします。



# 動機

`Shell`や`Prompt`の変更は[お前らのターミナルはダサい](https://qiita.com/kinchiki/items/57e9391128d07819c321)にお任せして、

mac標準ターミナルで`Hyper`のようにタイトルバーを消すことを中心に解説していきます。前記事の作業を終えると多分以下のようになっていると思います。

![](https://user-images.githubusercontent.com/20896810/52757056-c60b8b00-3046-11e9-888b-fafaa5c6630f.png)

ただ、これだとPureのGitHubに乗っている。

![](https://qiita-image-store.s3.amazonaws.com/0/117659/b98e375f-45b8-54b5-dc86-9cce82bf5b62.png)


の画像と違いタイトルバーが残っちゃうんですよね。
それでも、サードパーティーのターミナルは使いたくないなぁということで
じゃあ標準のターミナルを弄っちゃおう！
となりました。



#  実装

macアプリの見た目を改造するのに一番簡単なのは
`nib`ファイルをいじることです。
なので、まずターミナルに割り込んでView構造を把握します。

![](https://qiita-image-store.s3.amazonaws.com/0/117659/f34c12cd-d14d-5378-ba93-711dfe190a62.png)

ふむ、`TTWindowController` -> `TTWindow`だな
なら多分`TTWindow.nib`が存在してそれを弄ればいけるんじゃないか？
と予想を立てます。


そして、`ターミナル.app/Contents/Resources/Base.lproj`の中身を見るとこんな感じ
![](https://qiita-image-store.s3.amazonaws.com/0/117659/22377021-045d-2920-1f9a-e7287d56c446.png)


確かに`TTWindow.nib`がありました。
これを[NibUnlocker](https://www.charlessoft.com/)などを使って`xib`に戻します。



<img width="1432" alt="スクリーンショット 6.png" src="https://qiita-image-store.s3.amazonaws.com/0/117659/e3d4df6d-1d7a-d2dc-d47d-8212e6f1064a.png">


すると、こんな感じの`Xib`として展開されるはずです。
これを改造していきます。



まず、タイトルバーを消すのが目的なので、

<img width="419" alt="スクリーンショット 7.png" src="https://qiita-image-store.s3.amazonaws.com/0/117659/ab758da4-2e76-d941-867e-57fbfe42237f.png">

Hide Title と Tranceparent Title Barにチェックを入れます。



して、これだとWindowの色がAquaの背景色のままなので、
Runtime Attributesを以下のように設定します。
(色はターミナルで設定した背景色に合わせてください。)
<img width="359" alt="スクリーンショット 8.png" src="https://qiita-image-store.s3.amazonaws.com/0/117659/f7eba014-4a99-98f5-f7bb-2d40130a33cb.png">


そして、後はダミープロジェクトを作成してコンパイルすると、
ダミーアプリケーションの中にTTWindowという`nib`があるはずです。
これで`ターミナル.app/Contents/Resources/Base.lproj`にある`TTWindow.nib`を上書きすれば、タイトルバーが消えているはずです。



以上、完！！！
Vue.js の単一ファイルコンポーネントを IntelliJ IDEA 等の JetBrains IDE で書くときの <script> / <style> タグのオートインデントをオフにする方法

# 何をしたいか

Code formatter として prettier を利用する場合、Vue の単一ファイルコンポーネントの `<script>` `<style>` タグの後はインデントしないのがお作法っぽいが、IntelliJ で書いているとオートフォーマットされちゃう。困る。

# どうやるのか

Preference -> Editor -> Code Style -> HTML -> Other にある `Do not indent children of:` に `<script>` `<style>` タグを入れる。

<img width="1526" alt="スクリーンショット 2019-02-14 11.18.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/103206/1d2ef040-f67a-787d-b03c-10c42cf1aaee.png">

# 所感

こんな感じで自動で補完・インデントしてくれるのいいんだけど、IDE固有じゃない設定とコンフリクトするの未だにちょこちょこあるのでもう少しなんとかなるといいな。
DynamoDBのオートスケールしきい値設定をAWS CLIから行う

DynamoDBのオートスケール設定をAWS CLIから行う

今までブラウザのAWSコンソールからポチポチやっていましたが、必要になったので調べました。
オートスケール設定はDynamoDBではなくapplication-autoscaling経由で行うようです。

DynamoDBテーブルの確認

```bash
aws application-autoscaling describe-scaling-policies --service-namespace dynamodb --resource-id "table/テーブル名"
```

オートスケールしきい値設定

```bash
aws application-autoscaling put-scaling-policy --service-namespace dynamodb --policy-name "DynamoDBReadCapacityUtilization:table/テーブル名"  --resource-id "table/テーブル名" --scalable-dimension dynamodb:table:ReadCapacityUnits --policy-type TargetTrackingScaling --target-tracking-scaling-policy-configuration '{ "TargetValue": リードの値, "PredefinedMetricSpecification": { "PredefinedMetricType": "DynamoDBReadCapacityUtilization" } }'
aws application-autoscaling put-scaling-policy --service-namespace dynamodb --policy-name "DynamoDBWriteCapacityUtilization:table/テーブル名"  --resource-id "table/テーブル名" --scalable-dimension dynamodb:table:WriteCapacityUnits --policy-type TargetTrackingScaling --target-tracking-scaling-policy-configuration '{ "TargetValue": ライトの値, "PredefinedMetricSpecification": { "PredefinedMetricType": "DynamoDBWriteCapacityUtilization" } }'
```
Qiitaのバグ？「デザイン」というタグを入れると投稿できない

Qiitaの投稿時に、「デザイン」というタグを入れて投稿または更新しようとすると、500エラーとなり投稿ができません。今日１時間くらい原因がわからず、悲しい気持ちで調べておりました。。。解決方法がわかる方は教えてください。

```json
{"errors":["Internal Server Error"]}
```
Nobleのコードをasync/awaitで記述するメモ


[公式](https://github.com/noble/noble)のサンプルなどがコールバック地獄で結構辛いので、util.promisify()を使ってなんとかできないかと思うのですが、そこまで上手くはいかないです。

bluebirdのpromisifyAllを使うといい感じに出来ました。

> 参考: [Nobleをbluebirdで更にスッキリさせる](https://graspin.studio/recipes/nodejs-ble-tutorial/10)

```sh
npm i bluebird
```

```js
'use strict';

const noble = require('noble');
const Promise = require('bluebird'); //Promisifyで利用

const peripheralUUID = 'xxxxxxxxxxxxxxx'; //各自書き換え
const serviceUUIDs = ['180d']; //各自書き換え
const characteristicUUIDs = ['2a39']; //各自書き換え

//discovered BLE device
const discovered = async (peripheral) => {
    // if(peripheral.advertisement.localName !== 'Heart Rate') return;
    if(peripheral.uuid !== peripheralUUID) return;
    noble.stopScanning(); //スキャン停止
    console.log(`[Found Device] ${peripheral.advertisement.localName}(${peripheral.uuid}) RSSI${peripheral.rssi}`);

    /**
     * ペリフェラルへのアクセス
     */
    const p = Promise.promisifyAll(peripheral); //Promisify
    await p.connectAsync();
    console.log(`[Connect Device] coneccting service & characteristic......`);
    
    /**
     * サービス&キャラクタリスティックへのアクセス
     */
    const services = await p.discoverSomeServicesAndCharacteristicsAsync(serviceUUIDs,characteristicUUIDs);
    const characteristic = services.reduce((pre, current) => (current.uuid === serviceUUIDs[0]))
                            .characteristics
                            .reduce((pre, current) => (current.uuid === characteristicUUIDs[0]));
    const c = Promise.promisifyAll(characteristic); //Promisify
    console.log(`[Connect characteristic] coneccting characteristic's Data......`);

    /**
     * キャラクタリスティックのデータにアクセス
     */
    const toggle = async () => {
        try {
            const data = await c.readAsync();
            let state = data.readUInt8(0);
            console.log(state);
            state = (state === 0) ? 1 : 0;
            await c.writeAsync(new Buffer.from([state]), true);
            setTimeout(() => toggle(), 1000); //1秒ごとに実行
        } catch (error) {
            console.log(error);        
        }
    }
    toggle();
}

//BLE scan start
const scanStart = () => {
    if(noble.state !== 'poweredOn'){
        noble.on('stateChange', scanStart)
    }else{
        noble.startScanning();
        noble.on('discover', discovered); //Discover
    }
}
scanStart();
```
Kotlin 1.3のCoroutineの使い方⑧（Globalのコルーチンってデーモンみたい）

# 検証環境
この記事の内容は、以下の環境で検証しました。

* Intellij IDEA ULTIMATE 2018.2
* Kotlin 1.3.0
* Gradle Projectで作成
* GradleファイルはKotlinで記述（KotlinでDSL）

# 準備
詳細は下記の準備を参照してください。
https://qiita.com/naoi/items/8abf2cddfc2cb3802daa

# Global coroutines are like daemon threads
[前回](https://qiita.com/naoi/items/036d4ab3a53d21fbecd8)に引き続き、[公式サイト](http://kotlinlang.org/docs/reference/coroutines/basics.html#global-coroutines-are-like-daemon-threads)を読み解いていきます。

今回のタイトルは読んだままです。
早速読み進めます。

> The following code launches a long-running coroutine in GlobalScope that prints "I'm sleeping" twice a second and then returns from the main function after some delay:

意訳込みですが

>サンプルコードでは長期間動作するGlobalScopeのコルーチンを実行しています。1秒間に2回「I'm sleeping」が表示されます。

そのサンプルコードが以下です。

```kotlin
import kotlinx.coroutines.*

fun main() = runBlocking {
    //sampleStart
    GlobalScope.launch {
        repeat(1000) { i ->
            println("I'm sleeping $i ...")
            delay(500L)
        }
    }
    delay(1300L) // just quit after delay
//sampleEnd    
}
```

確かに、約2秒後ぐらいにメッセージを表示していますね。
もし、GlobalScopeのコルーチンをjoinすると1000実行されるまで動き続けるのでしょう。
タイトルどおり、デーモンみたいですね。

# まとめ
GlobalScopeを利用するとデーモンみたいになるといった事がわかりました。
MAYAのMELでWindowを表示させてみよう

#概要
MayaのMELは高機能なので色々と出来ます。
逆に色々出来すぎるだめ、ネットで検索しても
なかなか細かいことが載ってなかったりします。

今回は「Windowを表示しMeshのみを羅列する」スクリプトを
自分の勉強がてら書いてみました。

ご参考になれば幸いです。

#MELコード

```Window.mel
// Meshを検索する関数
global proc SearchMesh(){
    string  $obj;
    $allObjects = `ls -l`;
    // Meshだけを探す
    for ( $obj in $allObjects ) {
        if ( `nodeType $obj` == "mesh" ) {
        // Meshの名前をプリント
        print ($obj + "\n");
    }
}
}
// Window表示
string $window = `window -title "Mesh Search" // Windowのタイトルを指定
       -iconName "Short Name"
       -minimizeButton off // Windowミニマムボタンをなくす
       -maximizeButton off // Window最大化ボタンをなくす
       -widthHeight 250 100`; // Windowサイズを指定
columnLayout -adjustableColumn true;
       // Mesh検索ボタン
       button -label "Search Mesh" -command ("SearchMesh");
       // クローズボタン
       button -label "Close" -command ("deleteUI -window " + $window);
setParent ..;

// ウィンドウを表示させる
showWindow $window;


```

#作成したウィンドウ
![MeshSearch-MEL-Sample2.png](https://qiita-image-store.s3.amazonaws.com/0/49072/6cb41794-fd6c-bf92-42bc-fada15d9f135.png)

#結果
![MeshSearch-Result.png](https://qiita-image-store.s3.amazonaws.com/0/49072/09d5612e-fc37-eb37-578a-32040798b484.png)

#解説
``ls コマンドが Maya内にあるすべてのものを列挙するコマンド``
``window コマンドが Window を作成するコマンド``
``button コマンドが ボタンを作成するコマンドで引数に [-command]をつけるとボタンを押下したときに実行されるものを指定``
Deviseの設定手順（Rails）

#はじめに
アプリを作成するにあたって、Deviseをインストールしたのでその手順をメモします。

#[Devise](https://github.com/plataformatec/devise)とは
認証機能を簡単に実装できるgemです。
railsチュートリアルではイチから作成していたことを考えると、Deviseは手間や安全性の面からかなり使い勝手はよさそうです。
しかし公式ドキュメントにも記載あるように、Deviseを理解するためにはrailsチュートリアル等を利用してシンプルな認証機能の仕組みを理解する必要があります。

#バージョン

```
ruby   : 2.5.1
rails  : 5.2.2
device : 4.6.1
```

#手順
rails newは完了したところから始めます。

###gemのインストール

```ruby:Gemfile
gem 'devise'
```
Gemfileに追加したら`bundle install`をします。


###初期設定
次に以下のコマンドを実行すると以下のメッセージが渡されますので、ひとつひとつ対応します。

```ruby
$ rails generate devise:install
      create  config/initializers/devise.rb
      create  config/locales/devise.en.yml
===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here
     is an example of default_url_options appropriate for a development environment
     in config/environments/development.rb:

       config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

     In production, :host should be set to the actual host of your application.


  2. Ensure you have defined root_url to *something* in your config/routes.rb.
     For example:

       root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb.
     For example:

       <p class="notice"><%= notice %></p>
       <p class="alert"><%= alert %></p>

  4. You can copy Devise views (for customization) to your app by running:

       rails g devise:views

===============================================================================
```
#####1.デフォルトURLの設定
Ensure you have defined default url options in your environments files. 
指示に従い、config/environments/development.rbに以下を追加します。

```ruby:config/environments/development.rb
Rails.application.configure do
  # 省略
  config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end
```

#####2.ルートURLの設定
Ensure you have defined root_url to *something* in your config/routes.rb.
先に適当なコントローラを作成したうえで、ルートURLを設定します。

```
$ rails g controller home index show
```
```ruby:routes.rb
Rails.application.routes.draw do
  root to: 'home#index'
  get 'home/show'
end
```
#####3.flashメッセージの設定
Ensure you have flash messages in app/views/layouts/application.html.erb.
こちらも指示に従って以下のようにします。

```ruby:app/views/layouts/application.html.erb
# 省略
  <body>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
#　省略
```
#####4.Device用のViewファイルを生成
You can copy Devise views (for customization) to your app by running
認証周りの基本viewはgem内にあるので以下コマンドで生成まとめて生成します。

```
$ rails g devise:views
```

###Userモデルの作成
モデルを作成するとマイグレーションファイルが生成されるためmigrateします。

```
$ rails g devise User
$ rails db:migrate
```

###rails sで確認
`http://localhost:3000/users/sign_up`で以下のようにブラウザが開けばとりあえず最初の設定は終了です。
<img width="296" alt="スクリーンショット 2019-02-13 22.19.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/358444/0a69e0fc-c6ba-b1a1-4d05-c0d5f20af325.png">

##参考サイト
[[*Rails*] deviseの使い方（rails5版）](https://qiita.com/cigalecigales/items/f4274088f20832252374)
iOS パブリックベータのインストール方法

# パブリックベータ版のインストール
shshが発行中であれば、ファームウェア（ipsw）を選択して最新以外のバージョンのiOSをインストールすることができます。

## 必要なもの
- iTunesがインストールされたパソコン
- shsh発行中のバージョンのファームウェア（ipsw）
	- ベータ版のファームウェアをダウンロードできるサイト  
	[Beta Firmware - The iPhone Wiki](https://www.theiphonewiki.com/wiki/Beta_Firmware)
    - shsh発行中の確認ができるサイト  
      ~~[iOS Beta IPSW Real-Time
Signing Status](http://xsf1re.cf/tsschecker/1211b3.php)~~  
    [TSS Server](https://tsssaver.1conan.com/isitsigned.php)

## インストール方法
- iTunesでバックアップしてipswを指定して復元します。  
	Windowsの場合は[Shift]、MacOSの場合は[Option]を押しながら**「復元」**をクリックするとファームウェアを選択することができます。

- iOSの復元が終わったらバックアップから復元します。  
「復元」や「アップデート」、「バックアップから復元」など紛らわしい表記で全く意味が違うので注意が必要です。  
iOSを工場出荷状態に復元したら、バックアップからアプリや写真、連絡先などのデータを復元します。  
もちろん、新しいiPhoneとして使用することも可能です。
[ProjectNorthStar] LCDパーツ


[![tipmona](https://img.shields.io/badge/tipme-%40tipmona-orange.svg)](https://twitter.com/share?text=%40tipmona%20tip%20%40Cj-bc%2039)  [![monya/mona](https://img.shields.io/badge/tipme-%40monya/mona-orange.svg)](https://monya-wallet.github.io/a/?address=MBdCkYyfTsCxtm1wZ1XyKWNLFLYj8zMK3V&scheme=monacoin)  [![tipkotone](https://img.shields.io/badge/tipme-%40tipkotone-orange.svg)](https://twitter.com/share?text=%40tipkotone%20tip%20%40Cj-bc%2039)


現状確認できているレシピに使われているLCDパーツのリスト
各レシピ毎に使用できるLCDが異なり、一部使用不可能なものもあるので気をつけてください。

# VS035ZSM-NW0

- 本家で使われているもの
- 販売元のBOEは大口の注文に対してのみ販売を行うそうです。(exiii情報)

# 3.5-inch LCD

## 各種情報

- Amazon: https://www.amazon.co.jp/gp/product/B01N5HW3BP/
- ラズベリーパイ用のディスプレイの流用。
- 解像度は後述の3.81-inch AMOLEDに劣る...のかな？
- 価格: ¥2,980(2019/02/14現在。上記amazonリンク)

## これを使用している記事

- [exiiiさんの最初のエントリ](https://exiii.jp/2018/07/19/project_north_star_jp-2/)
- [showroom tech blogの@izmさんのエントリ](https://tech.showroom.co.jp/entry/2019/01/28/175438)

# 3.81-inch AMOLED

- Alibaba: https://www.alibaba.com/showroom/3.81-inch-amoled.html
- いくつか種類があるが、どれのことを指してるのかはわからない...
  - (exiii v2では1080x1200のもののようです。)
- 複数個でまとめうりが多く、バラ売りのものとなると以下のリンクから見れるぽいです。
https://www.alibaba.com/trade/search?IndexArea=product_en&SearchText=3.81_inch_amoled&atm=&viewtype=G&f0=y&moqf=MOQF&moqt=MOQT1
- 価格: USD 30~100?(2019/02/14現在。二番目のAlibabaリンクに掲載されているものより。)
  - 価格帯が上下しまくってるのでよくわからない。情報求（買わないけど）

## これを使用している記事

- [1-10/ProjectNorthStar_1-10_custom](https://github.com/1-10/ProjectNorthStar_1-10_custom)
- [exiiiさんのv2エントリ](https://exiii.jp/2018/11/27/project-north-star-simplified-v2-jp/)

# sharp 2.89"

- これ以外の名前や詳細情報は不明
- Discordにてexiii社の方が動画を投稿していた
aws ec2-userのUIDが501になる場合がある

ssm-userが作成される順序に変更があり、ec-userのUIDが500から501になる現象を確認しました。
手元で発生したのは下記のプラットフォーム更新ですが、実際には2.11.5->2.11.6で変わっていたと思われます。

Multi-container Docker running on 64bit Amazon Linux/2.11.8

```
ssm-user:x:500:500::/home/ssm-user:/bin/bash
ec2-user:x:501:501:EC2 Default User:/home/ec2-user:/bin/bash
```

Multi-container Docker running on 64bit Amazon Linux/2.11.5 

```
ec2-user:x:500:500:EC2 Default User:/home/ec2-user:/bin/bash
ssm-user:x:501:501::/home/ssm-user:/bin/bash
```

UIDハードコードして何かしている人は要注意です。