OmniAICreator/Qiita-1.07M huggingface dataset:
ShellScript 変数 に 格納 された 文字列 を 文字数 を 指定 して 出力 ～${変数:数値A:数値B}～

# 目的

- ShellScriptで変数に格納された文字列を起点となる文字から何文字出力するという方法で出力する。

# 書き方の例

- 変数には任意の文字列が格納されているものとする。
- コンソールに変数を出力するため`echo`コマンドの後に紹介する処理を記載する
- 下記にShellScriptの処理を記載する。

```
echo ${変数:起点文字の番号:起点文字から何文字抜き出すかの数字}
```

# より具体的な例

- 変数`number`に文字列`123456789`を格納する。
- 下記にShellScriptの処理を記載する。  
※>はコンソールの出力を表す。

``` shell
# 変数格納
number="123456789"

# 変数の0文字目から4文字抜き出してコンソールに表示する
echo ${number:0:4}
>1234

# 変数の4文字目から5文字抜き出してコンソールに表示する
echo ${number:4:5}
>56789

# 変数の2文字目から2文字抜き出してコンソールに表示する
echo ${number:2:2}
>34
```

- 変数`string`に文字列`おはようございます`を格納する。
- 下記にShellScriptの処理を記載する。

``` shell
string="おはようございます"

echo ${string:1:1}
>は

echo ${string:3:4}
>うござい

echo ${string:0:4}
>おはよう

echo ${string:4:5}
>ございます
```
minikubeで2つ目のk8sクラスタを起動する方法と、その操作方法

minikubeは複数のクラスタを起動するためにプロファイルオプション(-p)が提供されている。

## cluster2というプロファイル名でminikubeを起動する

```bash
minikube start -p cluster2
```

## コンテキストを切り替える

```bash
minikube profile cluster2
```

## デフォルトのコンテキストに戻す

profile(-p)を指定しないでminikube startした場合、プロファイル名は`minikube`になります。

```bash
minikube profile minikube
```

## 現在選択されているプロファイルを確認する

```bash
minikube profile
```

## プロファイル一覧を取得する

```bash
minikube profile list
```

### 出力例

```
|----------|------------|----------------|-----------|--------------------|
| Profile  | VM Driver  |     NodeIP     | Node Port | Kubernetes Version |
|----------|------------|----------------|-----------|--------------------|
| cluster2 | virtualbox | 192.168.99.102 |      8443 | v1.15.2            |
| minikube | virtualbox | 192.168.99.101 |      8443 | v1.15.2            |
|----------|------------|----------------|-----------|--------------------|
```

## コンテキストを指定してminikubeインスタンスにSSHにする

```bash
minikube ssh -p cluster2
```

## minikubeインスタンスのIPを取得する

```bash
minikube ip -p cluster2
```

## minikubeインスタンスを削除する

```bash
minikube delete -p cluster2
```
TreasureData prestoDBにDBeaverからアクセスする際の設定方法

Treasure DataのPrestoDBを使用しているのですが、DBeaverからアクセス出来ないかなぁと思って調べていろいろやってみた結果、接続方法がわかりましたので自分用にメモを残しておきます。

```
[host] api-presto.treasuredata.com
[port] 443
[database/schema] td-presto/{データベース名}
[user name] {Your API Key}
[password] whatever (ignored)
```
なぜかWindowsからだとスムーズにアクセス出来ないんですよね...なんでだろう :thinking:
【Mac】各種ハッシュ関数を使う方法 - sha256, md5, ... -

#MacでHash値を計算する方法
```:md5
$ md5 ファイル名
or
$ openssl dgst -md5 ファイル名
```

```:sha256
$ shasum -a 256 ファイル名
or
$ openssl dgst -sha256 ファイル名
```

困ったら `-h`オプションつけて何が使えるか見る。

#Happy Hacking :sunglasses: !
【Flutter】ListViewを下から上にスクロールした際にスクロール位置がずれる

# 事象
長めのスクロールをする画面で一番下までスクロールしてから、上に向かってスクロールすると途中でリストのスクロール位置がずれました。
（スクロールの途中で突然違うスクロール位置に飛ばされるような挙動になりました。）

# 原因
ListViewのキャッシュ領域が足りていなかったことが原因でした。

今回のレイアウトは、ListViewの中に複数のStreamBuilderを内包するレイアウトで、各StreamBuilderがセクションの役割を果たし、それぞれ別のデータをAPIから取得する作りになっていました。
電話帳のような画面をイメージしていただけると分かりやすいかもしれません。（実際の電話帳は各セクション毎にデータを取りに行くようなことはしないと思いますが、レイアウトのイメージとしてお考えください。）

```dart
ListView.builder(
  itemCount: 4,
  itemBuilder: (context, index) {
    switch (index) {
      case 0:
        // セクション1（あ行のデータを取得・リストで表示）
        return StreamBuilder();
      case 1:
        // セクション2（か行のデータを取得・リストで表示）
        return StreamBuilder();
      case 2:
        // セクション3（さ行のデータを取得・リストで表示）
        return StreamBuilder();
      case 3:
        // セクション4（た行のデータを取得・リストで表示）
        return StreamBuilder();
      default:
        return Container();
    }
  },
);
```

この画面を一番下までスクロールすると、あ行のリストは画面外へ隠れてしまいます。
この時、キャッシュ領域からもはみ出たあ行のリストのWidgetが破棄されます。
そして、下から上にスクロールするとあ行のリスト（StreamBuilder）が再描画され、データが取得できたタイミングであ行のリストが再表示されるため、突然スクロール位置がずれるような挙動になっていました。

# 対応
ListViewのcacheExtentを指定して、キャッシュ領域を広げました。

```dart
ListView.builder(
  // 250.0はRenderAbstractViewport.defaultCacheExtentより
  cacheExtent: 250.0 * 2.0,
  itemCount: 4,
  itemBuilder: (context, index) {
    switch (index) {
      case 0:
        // セクション1（あ行のデータを取得・リストで表示）
        return StreamBuilder();
      case 1:
        // セクション2（か行のデータを取得・リストで表示）
        return StreamBuilder();
      case 2:
        // セクション3（さ行のデータを取得・リストで表示）
        return StreamBuilder();
      case 3:
        // セクション4（た行のデータを取得・リストで表示）
        return StreamBuilder();
      default:
        return Container();
    }
  },
);
```

ListViewにはデフォルトで`250.0`のキャッシュ領域が確保されています。（`RenderAbstractViewport.defaultCacheExtent`に定義されています。）
`cacheExtent`にdoubleでピクセル数を指定することで、キャッシュ領域を広げることができます。
RenderAbstractViewport.defaultCacheExtentはprotectedで定義されており、直接アクセスすると警告が表示されてしまうため、今回は数値をベタ書きで指定しました。
今回はリストの最大長が分かっており、デフォルト値の2倍あれば足りると分かっていたため2倍にしましたが、リストが可変の場合は中身の要素を見て計算するのが良いと思います。

# 参考
https://medium.com/@greg.perry/decode-listview-a0bc4b90f82d
cacheExtentがどのようなフィールドなのか説明されています。

https://api.flutter.dev/flutter/rendering/RenderViewportBase/cacheExtent.html
デフォルト値が存在することをこのドキュメントで知りました。
LeetCode / Factorial Trailing Zeroes

今日は算数の問題です。大人より小学生の方が解けるかも？

[https://leetcode.com/problems/factorial-trailing-zeroes/]

Given an integer n, return the number of trailing zeroes in n!.

Example 1:
Input: 3
Output: 0
Explanation: 3! = 6, no trailing zero.

Example 2:
Input: 5
Output: 1
Explanation: 5! = 120, one trailing zero.

Note: Your solution should be in logarithmic time complexity.

nの階乗で得られた数値に、trailing zero、つまり後置の0がいくつあるかを返す問題です。
空間計算量のオーダーを$log(n)$とすることも求められています。つまり、馬鹿正直にnの階乗を計算するのではない方法が求められます。

#### 解答・解説

##### 解法1

まず気付くべきは、「後置の0が幾つ存在するかは、nの階乗の中で10が何回掛けられるかと同値である」です。
次に気付くべきは、10を素因数分解すると2×5ですから、「後置の0が幾つ存在するかは、nの階乗に2が幾つ存在するか（2で何回割り切れるか）と5が幾つ存在するか（2で何回割り切れるか）の最小値と同値である」です。
そして当然、2で割り切れる回数と5で割り切れる回数では後者の方が小さいですから、5で割り切れる回数を計算すれば、それが答えになります。

さて、以上の考察をそのままコードに落とすと、以下のようになります。

```python
class Solution(object):
    def trailingZeroes(self, n):
        """
        :type n: int
        :rtype: int
        """
        ans = 0
        while n > 0:
            n //= 5
            ans += n
        return ans
```

上記コードの中では、5で割り切っているわけではなく5で割った商を足し合わせています。5で割り切るコードよりも短く書けます。横着とも言います。
空間計算量はlog<sub>5</sub><sup>n</sup>になります。

ちなみにPython2だとint同士の割り算はintが返るんですね。上記も n /= 5 としても正解が得られます。知らなかった。。。

##### 解法2

recursiveに書くこともできます。計算量は変わりません。

```python
class Solution(object):
    def trailingZeroes(self, n):
        return 0 if n == 0 else n // 5 + self.trailingZeroes(n // 5)
```
【Xcode】No such module と表示された時の対処

# 結論
ターゲットを増やしたが、Podfileのターゲットを増やしていなかったため
Podfileのターゲットを増やし、再度 `pod install` で解消された

普段触らなすぎて、忘れていました。。。

# 環境
Xcode: 10.1
Swift: 4.2
pod: 1.7.1

# 手順
## Podfileにターゲットを追加
```
platform :ios, '9.0'
use_frameworks!

def install_pods
 pod 'Firebase/Core'
 pod ....
end

target 'すでに存在してるターゲット名' do
 install_pods
end

# 新しいターゲットを追記し忘れていた
target '新しく追加したターゲット名' do
 install_pods
end
```

## インストール実施
`pod install`

# 振り返り
こんなことで3時間ほど費やしてしまった　コンチクショー！（振り返ってない）

# 参考に試したが自分の場合ダメだったこと
- [https://stackoverflow.com/questions/29500227/getting-error-no-such-module-using-xcode-but-the-framework-is-there](https://stackoverflow.com/questions/29500227/getting-error-no-such-module-using-xcode-but-the-framework-is-there)
- [https://github.com/CocoaPods/CocoaPods/issues/7835](https://github.com/CocoaPods/CocoaPods/issues/7835)
- [https://qiita.com/doge_kun55/items/26ac2fa2031ddbeee879](https://qiita.com/doge_kun55/items/26ac2fa2031ddbeee879)
- [https://teratail.com/questions/28627](https://teratail.com/questions/28627)
MacでFinderのアイコンプレビューが表示されないときの対処法

軽く調べた結果がどれも動かなかったときの対処法です。

---

`qlmanage -t` でプレビューが表示されない画像を開いてみます。

```
$ qlmanage -t ~/Desktop/適当な画像.png
```

すると何やら `Google Drive File Stream` 関連のエラーが表示されます。`Google Drive File Stream.app` を削除すると、無事プレビューが表示されるようになりました。以下の回答に感謝。

https://apple.stackexchange.com/questions/338215/mojave-quicklook-stuck-at-loading#answer-338528
分からねえ！！

Node.jsをインストールしたはいいが、おかしい。

$ npm install -g vue-cli

って打ち込んでEnterしたら

npm ERR! code ENOTFOUND
npm ERR! errno ENOTFOUND
以下略。。

って表示が出て何やらできてないっぽい。。。
なんだ？国会図書館のWifi使ったからか？

そこのあなた助けてくだざい。。。

(追記)
家のwifi繋いだら無事できました。
見てくれた皆さまお騒がせしてすいません。
ありがとうございました。
AWS ELB(ALB,CLB,NLB)を1分で掴む

いくつか調べてみました！
優しめのマサカリください！！

## **ELBとは**

- **Elastic Load Balancer = ロードバランサー**

- トラフィックの分散を行う
- サーバへのアクセスを、複数のアベイラビリティーゾーンの複数のEC2インスタンスに分散

## 全3種類
- **NLB** - Network Load Balancer
    - L4 NATロードバランサ
    - TCPに対応

- **ALB** - Application Load Balancer
    - L7リバースプロキシ
    - HTTP,HTTPSに対応

- **CLB** - Classic Load Balancer
    - L4/L7 リバースプロキシ
    - TCP,SSL,HTTP,HTTPSに対応

## 特徴と違い

- **通信経路**
    - ALB,CLBはリバースプロキシのため、行きも帰りもロードバランサを経由
    - NLBは宛先IPをクライアントのIPに変えるため、帰りはLBを通らない

- **アクセス制限**
    - ALB,CLBはポートでのアクセス制限が可能
    - NLBはシンプルな一方でアクセス制限が不可

- **IPアドレス**
    - ALB,CLBはIPアドレスが可変なためDNSの利用が必要
    - NLBは固定IPのためDNSとIPを利用できる

- **アクセスログ**
    - NLBのみアクセスログの出力が非対応

## 特にお世話になった参考文献様

- ELB
    - ネットワーク視点で見るAWS ELB(Elastic Load Balancing)のタイプ別比較[NLB対応] / Classmethhod
        - https://dev.classmethod.jp/cloud/aws/describe-elb-types/
    - ELBの比較表に補足事項を書き加えてみる（NLB編） / Serverworks
        - http://blog.serverworks.co.jp/tech/2018/07/25/elb-comparison/
Xcodeのブレークポイントはドラッグアンドドロップで消せる

# この記事について
これまでXcodeのブレークポイントを削除するときは、ブレークポイントを右クリックして「Delete Breakpoint」を選択して消していたのですが、ドラッグアンドドロップで消せることを知って驚いたので記事にしました。

# ドラッグアンドドロップで消す
消しているところをスクリーンキャプチャしました。
![breakpoint.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98669/8eb1af97-29b5-1b69-11d9-94d515b17ca8.gif)

# 結論
シュッと消せてHAPPY！
Kotlinのsealed classについて調べてみた

この記事は、以下の「Kotlin Reference」日本語版を
元にしています。

#Kotlin Reference　（日本語）
https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/classes.html

###前書き
Kotlin初心者が、書いております。
ここが違う、もっとわかりやすく書いて欲しい等のご指摘いただけると助かります。
内容は、<b>「Kotlin Reference ＋ 調べて参考にした記事数点」</b>　程度です。

##sealed classとは？

英語訳は、
sealed = 印を押した、封印された

そこから考えると
sealed class = 封印されたクラス

直訳だとヒドイので、マイルドにすると制限のあるクラス、、、
<b>「継承を制限されているクラス」</b>ということが言えそうです。

##sealed classの特徴

①<b>「sealed修飾子」</b>をクラス名の前に記述するとクラスを宣言できる。
　sealedクラスはサブクラスを持つことができますが、
　全てシールクラスの中にネストする必要がある。

②sealed classは、ある意味でenum（列挙型）クラスの拡張である。
　enumクラスの値のセットも同じく制限されているが、
　enum定数はシングルインスタンスとしてのみ存在するのに対し、

　sealed classのサブクラスは、状態を保持できる複数のインスタンスをもつことができます。

③状態管理を簡単に表せる、
　また状態に値を持たせられる。（enumではできない）

④When式で分岐する際に、全てのケースをカバー出来る。

参考例：

```kotlin
sealed class Expr {
    class Const(val number: Double) : Expr()
    class Sum(val e1: Expr, val e2: Expr) : Expr()
    object NotANumber : Expr()
}
```

以下に、when式の分岐でelseが不要な例を挙げています。

これはシールクラスの主な利点の一つで、
<b>「Exprクラス」</b>は、<b>「sealed class」</b>として定義されており、
他の場所でそのサブクラスが定義されないことを保証します。 

そのためwhen式の分岐で、すべての場合が考慮されていることを、
コンパイラは知っているので<b>「else」</b>が不要になります。

参考例：

```kotlin
fun eval(expr: Expr): Double = when(expr) {
    is Expr.Const -> expr.number
    is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
    Expr.NotANumber -> Double.NaN
    // 全ての事例を嘗めたため、`else` 句は不要
}
```

メモ：
・インタフェースにはsealedを付けられないようです。
・この制限を緩和して同一ソースファイル内での継承も許可するそうです。（2019年8月28日現在：不可能　Kotlin1.3）
・使い方の参考例で２例ほど取り上げられていました。
　https://blog.takuji31.jp/entry/2017/12/07/183613
　「どういう使い方をしている？」で検索

参考：
Kotlin M13で追加されたsealed class
https://taro.hatenablog.jp/entry/2015/09/17/131439

KotlinのSealed Classを使いこなす
https://blog.takuji31.jp/entry/2017/12/07/183613

KotlinのSealed Classを学ぶ
https://qiita.com/ikemura23/items/c4555600bc512fb3e4cb

Kotlin文法 - クラス、継承、プロパティ
https://qiita.com/k5n/items/35e76d79ee9de4effb89#%E3%82%AF%E3%83%A9%E3%82%B9
ES6のジェネレーター

# ジェネレーターとは
for...ofループの動作を簡単にカスタマイズできる仕組み。

# サンプルコード

## 簡単な例
```javascript
function* colors() {
  yield 'red';
  yield 'blud';
  yield 'green';
}

const myColors = [];
for (let color of colors()) {
  myColors.push(color)
}
```

## iteratorを別に実装する例
```javascript
const testingTeam = {
  lead: '由紀子',
  tester: '隆'
}

const engineeringTeam = {
  testingTeam,
  size: 3,
  department: '開発部',
  lead: '太郎',
  manager: '花子',
  engineer: '次郎'
};

function* TestingTeamIterator(team) {
  yield team.lead;
  yield team.tester;
}

function* TeamIterator(team) {
  yield team.lead;
  yield team.manager;
  yield team.engineer;
  const testingTeamGenerator = TestingTeamIterator(team.testingTeam);
  yield* testingTeamGenerator;
}

const names = [];
for(let value of TeamIterator(engineeringTeam)) {
  names.push(value);
}
```

## iteratorを組み込んだ例
```javascript
const testingTeam = {
  lead: '由紀子',
  tester: '隆',
  [Symbol.iterator]: function* () {
  	yield this.lead;
  	yield this.tester;
  }
}

const engineeringTeam = {
  testingTeam,
  size: 3,
  department: '開発部',
  lead: '太郎',
  manager: '花子',
  engineer: '次郎',
  [Symbol.iterator]: function* () {
    yield this.lead;
  	yield this.manager;
  	yield this.engineer;
  	yield* this.testingTeam;
  }
};

const names = [];
for(let value of engineeringTeam) {
  names.push(value);
}
```
##ツリー構造を再帰で呼び出す例
```javascript
class Comment {
  constructor(content, children) {
    this.content = content;
    this.children = children;
  }
  *[Symbol.iterator]() {
    yield this.content;
    for (let child of this.children) {
      yield* child;
    }
  }
}

const children = [
  new Comment("賛成", []),
  new Comment("反対", []),
  new Comment("うーん", [])
	]
 
const tree = new Comment("いい記事ですね！", children);

const nodes = [];
for (let node of tree) {
  nodes.push(node);
}
```
janus-gateway備忘録

ブラウザのAPIとは大きく異なるので戸惑うことが多かった
#https有効化

```*/{installdir}/etc/janus/janus.transport.http.jcfg
https = true
```

#DataChannel(SCTP)有効化
libusrsctpをインストール
ubuntu16.04(x86_64)でしたが、/usr/lib/にインストールで問題ありませんでした。

#datachannel support not compiled
自分の環境ではlibusrsctpをインストールしているにもかかわらず、datachannelが使えない現象が発生しましたが、

```
make clean && make uninstall
```
で再度ビルドしなおしたところ、動作するようになりました。

#Jitter
RTCPのUnixタイムスタンプの差をとっているので単位はミリ秒

```tex:debugレベル7のログ
[4559978799293996] Incoming RTCP, bundling: this is video (local SSRC: video=1906170550, audio=3486522370, got 1906170550)
   Parsing compound packet (total of 96 bytes)
     #1 RR (201)
jitter=606.000000, fraction=0, loss=0
rtt=4
       RTCP PT 201, length: 56 bytes
     #2 PLI -- PSFB (206)
       RTCP PT 206, length: 12 bytes
     #3 REMB -- PSFB (206)
       -- -- -- REMB: 203009 * 2^3 = 1624072 (2 SSRCs, 1906170550)
       RTCP PT 206, length: 28 bytes
```

#videoroomプラグインでlistの結果がonmessageで帰ってこない？

listの結果はonmessageでなくsuccessコールバックで来るようです。

```
pluginHandle.send({
　"message": {
　　"request" : "list"
　},
　success: function(result) {
　　console.log(result);
　}
});
```

#クライアントAPIでICEがtype=hostしか収集されない
時々、iOSやmacのonicecandidateで度々tye=hostのiceしか作成さないときことがありました。
libniceの問題でmdns candidateが来た場合stunホールパンチが途中で停止していたようです。特定のlibniceでビルドされたJanusでしか発生しません

この問題の回避策としてWebRTCのJavascript apiで下のようにすることでtype=hostが一切無効になり、type=srflxが取得できるようになります。
https://developer.mozilla.org/en-US/docs/Web/API/RTCConfiguration/iceTransportPolicy

```js
iceTransportPolicy: "relay"
```
GCSでCustomer-supplied encryption keys (CSEKs)を使った暗号化を試す

##はじめに
自分の勉強した内容の整理のため書いてます。
GCSでCustomer-supplied encryption keys (CSEKs)を使った暗号化の手順について記載します。

そもそもGCPの暗号化オプションとしては、3つから選択可能です。
https://cloud.google.com/security/encryption-at-rest/

- Default Google encryption
    - Googleが鍵の管理をおこなうため、ユーザによる鍵の管理が不要
    - 自動的にローテーションされる
    - https://cloud.google.com/security/encryption-at-rest/default-encryption/?hl=ja
- Customer-managed encryption keys (CMEKs) via Cloud KMS
    - KMSサービスを使用して鍵を生成し暗号化を行う
- Customer-supplied encryption keys (CSEKs)
    - 鍵をオンプレミスで保存し、クラウド サービスの暗号化に使用します

上記オプションは、GCPのサービスによって選択できるものがことなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/fa7c6b15-47f8-7839-cc00-ee4dff13e769.png)

https://cloud.google.com/security/encryption-at-rest/

https://cloud.google.com/security/encryption-at-rest/default-encryption/#granularity_of_encryption_in_each_google_cloud_platform_product

##CSEK使ってGCSのデータを暗号化する手順

大まかな流れは以下になります。
1.鍵の作成
2.作成した鍵をアップロード
3.暗号化したオブジェクトをダウンロード

以下のマニュアルを参考に試します。
https://cloud.google.com/storage/docs/encryption/using-customer-supplied-keys

###1.鍵の作成
鍵を作成するためのCodeをダウンロードして実行します
https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/storage/cloud-client/encryption.py

```
$ python gen.py 
Base 64 encoded encryption key: *******
```

ファイルアップロード時に鍵を指定する

```
$ gsutil -o "GSUtil:encryption_key=[生成した鍵]=" cp ./CSEK/test.txt gs://[バケット名]/
Copying file://./CSEK/test.txt [Content-Type=text/plain]...
/ [1 files][    4.0 B/    4.0 B]                                                
Operation completed over 1 objects/4.0 B.   
```

鍵を指定しないでダウンロードしてみます

```
$ gsutil cp gs://[バケット名]/test.txt ./CSEK/download/
Traceback (most recent call last):
-略-
    (key_sha256, self.provider, bucket_name, object_name))
gslib.cloud_api.EncryptionException: Missing decryption key with SHA256 hash VaSL3vod5eQDX1bIHMPMka+n/aXy8jOfJXK38EVpwfM=. No decryption key matches object gs://[バケット名]/test.txt
```

エラーになります。

鍵を指定してダウンロードします。

```
$ gsutil -o "GSUtil:encryption_key=[生成した鍵]=" cp gs://[バケット名]/test.txt ./CSEK/download/
Copying gs://[バケット名]/test.txt...
/ [1 files][    4.0 B/    4.0 B]                                                
Operation completed over 1 objects/4.0 B.                                        
```

ファイルの中身が確認できます。

```
$ cat CSEK/download/test.txt 
aaa
```

###投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。
Visual Studioのビルドで、Web のマークを削除してくださいのエラーが出る

ダウンロード、解凍したソリューションを開いてビルドすると、以下のエラーが出る。

`（ファイル名）を処理できませんでした。インターネットまたは制限付きゾーン内にあるか、ファイルに Web のマークがあるためです。これらのファイルを処理するには、Web のマークを削除してください。`
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/be2baba0-ab95-1a10-c3c1-122722daa3d8.png)
## 環境
- OS：Windows10 64bit
- IDE：Visual Studio Community 2019 v16.2.1<br>.NET Framework v4.7.03056

## 対処方法
エクスプローラーから該当するソースファイルのプロパティを開く。『全般』タブの一番下『セキュリティ』欄の『許可する』にチェックを入れ、『OK』をクリックして閉じる。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241999/6c54b487-a9ce-5e69-1966-03234c0b47c2.png)
Visual Studioからソリューションを閉じて、開き直せばOK。
Gitあれこれ

Git(GitHub含む)でのあれこれのメモです。

## GitHubリポジトリにtagの追加/削除を行いたい

```bash

// 追加
$ git tag {tag_name}
$ git push origin {tag_name_a} {tag_name_b}

// コミット指定
$ git tag {tag_name} {commit_hash}

// 削除
$ git tag -d {tag_name}
$ git push origin -d {tag_name_a} {tag_name_b}

// ローカルのタグリスト
$ git tag -l

// タグを打ったコミットを確認
$ git show {commit_id}

// リモートのタグリスト(commitID含む)
$ git ls-remote --tags
```

### 参考
https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E5%9F%BA%E6%9C%AC-%E3%82%BF%E3%82%B0
https://stackoverflow.com/questions/25984310/how-to-see-remote-tags

## マージコミットの巻き戻し

マージコミットの場合は、どのコミットに戻すのか（1つ前のマージコミットかその間にあるコミットか）を指定する。それが *-m* オプション

```sh
$ git log
commit <commit_id>
Merge:<1> <2>
$ git revert --no-edit -m 1 <commit_id>
```

### 参考

- [GitでMerge CommitをRevertする方法](https://qiita.com/awakia/items/5fad0c454ddc7b478ff1)
- [git revert で複数コミットを打ち消す](https://miau.hatenablog.com/entry/20100709/1278699637)
- [【 git revert 】コマンド](https://www.atmarkit.co.jp/ait/articles/2007/10/news010.html)

## 特定コミットにチェックアウトしたい

```sh
$ git checkout <SHA>
```

### 参考

- [コミットを指定してチェックアウトする](https://www.atmarkit.co.jp/ait/articles/2004/30/news017.html#sample1)


## submoduleをリモートブランチの内容に更新したい

submoduleが入っている特定のリポジトリをcloneしてきた以降の話。
`git submodule add`した時はコミットに表現されないので、ブランチを切って行うと履歴に残せる。

```bash

// 対象submoduleの登録
$ git submodule add git@github.com:{user_name}/{repository_name}.git {dirctory_name}
'dirctory_name' already exists in the index

// 一度ディレクトリをアンステージする必要性があるらしい
$ git rm -r {dirctory_name}

// 再度登録
$ git submodule add git@github.com:{user_name}/{repository_name}.git {dirctory_name}
```

## masterの差分を全て取り込む。

```sh
$ git pull origin master
$ git checkout -b branch-b
$ git rebase master
$ git checkout --ours <filename>
$ git rebase --continue
```

## 変更差分でファイル一覧が欲しい

```sh
$ git log --name-only
```

## git操作を巻き戻したい

```sh
$ git reflog
$ git reset --hard HEAD@{5}
```

## 変更されたファイル一覧を取得したい

```sh
$ git log --name-only 

$ git log --name-only --oneline
```
JavaでNotification Hubsを使用してpush通知を送信する

azureのNotification Hubsを使用してpush通知を送信することになったので備忘録。
サーバ側の開発です。(スマホアプリはわかりません。)


#　Java SDK入手
[ここから](https://github.com/Azure/azure-notificationhubs-java-backend)Java SDKを入手
一応公式サイトとのことです。

#　コンパイルとビルド
mavenコマンドを使用するので、mavenインストールしていない場合は[ここを参照](https://qiita.com/Junichi_M_/items/20daee936cd0c03c3115)
pom.xmlがあるフォルダでmavenコマンドを実行するだけ

```
cd NotificationHubs
mvn package
```

そうするとtarget配下にNotification-Hubs-java-sdk-0.1.0.jarできます。
これをパスが通ったフォルダに置いてください。

#使い方
タグを指定して送信することを想定しています。
事前にトークンとタグをNotification Hubsに登録していることが前提です。

トークンはメールアドレスみたいなイメージで
タグはメールアドレスみたいなイメージです。

タグを指定してpush通知を送信すると、そのタグに紐づいているトークンすべてにpush通知を送信してくれます。

##push通知送信（即時送信）
```
String connectionString = "Endpoint=sb://xxxxx.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=~~~~~";
String hubPath = "Notification hubsの名前";

NotificationHub hub = new NotificationHub(connectionString, hubPath);
String message = "push通知";

String body = String.format("{\"data\":{\"message\":\"%s\"}}", message);

// android端末用
Notification notifiation = Notification.createFcmNotifiation(body);

hub.sendNotification(notifiation, "タグ名");
```

##push通知送信（日時指定送信）
```
String connectionString = "Endpoint=sb://xxxxx.servicebus.windows.net/;SharedAccessKeyName=DefaultFullSharedAccessSignature;SharedAccessKey=~~~~~";
String hubPath = "Notification hubsの名前";

NotificationHub hub = new NotificationHub(connectionString, hubPath);
String message = "push通知";

String body = String.format("{\"data\":{\"message\":\"%s\"}}", message);

// android端末用
Notification notifiation = Notification.createFcmNotifiation(body);

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = dateFormat.parse("2020-01-01 00:00:00");

hub.scheduleNotification(notifiation, "タグ名", date);
```

##トークンとタグの登録
事前にトークンとタグをNotification Hubsに登録していることが前提ですと記載しましたが、
サーバ側でもトークンとタグを登録できます。（トークンとタグがわかれば）

```
// Android端末用
Registration reg = new FcmRegistration("トークン");
reg.getTags().add("タグ名");

NotificationHub hub = new NotificationHub(connectionString, hubPath);
Registration registreg = hub.createRegistration(reg);
```

##トークンとタグの削除
トークンとタグを削除する場合はタグを指定するか、RegistrationIdを指定します。

・タグで削除する場合は意図しないトークンも削除されるため、注意が必要です。
・RegistrationIdはトークンとタグの登録で登録結果（上のソースではregistreg ）の中に詰まっています。
　この値でトークンとタグを一意に識別することができます。

```
NotificationHub hub = new NotificationHub(connectionString, hubPath);

// タグを指定して削除
CollectionResult collectionResult = hub.getRegistrationsByTag(tag);
for (Registration registration:collectionResult.getRegistrations()) {
    hub.deleteRegistration(registration.getRegistrationId());
}

// RegistrationIdを指定して削除
hub.deleteRegistration(registreg.getRegistrationId());

```
Ethereum開発言語Solidityの勉強

#はじめに

イーサリアム上のDApp開発するには、Solidity言語を利用します。
スマートコントラクトの開発ではセキュリティーはとても重要です。
開発するには確実にSolidityの仕様を把握する必要があります。

言語を勉強するには、下記のサイトで良いと思います。

- Solidity　https://solidity-jp.readthedocs.io/ja/latest/index.html
- Cryptozombies　https://cryptozombies.io/jp/
- OpenZeppelin  https://github.com/OpenZeppelin/openzeppelin-contract
- Truffle https://www.trufflesuite.com/truffle

#1. Solidity
ドキュメントを読んでスマートコントラクト開発の基礎知識が習得できます。

#2. Cryptozombies
説明を見ながらコーディングをできますので、実践的になります。
solidity文法の理解を深めることができます。

#3. OpenZeppelin 
安全なスマートコントラクトの開発には自らトークン仕様を全部実装するのはお時間かかるし、セキュリティー上も問題になるかもしれません。
OpenZeppelinというライブラリを利用することで迅速に安全なスマートコントラクトを開発できます。

#4. Truffle 
RemixというIDE開発環境がありますが、
Truffleフレームワークを利用すると、テスト・deployも簡単にできます。

また、ローカルネットワークとしてGnacheを簡単にインストールできますので、便利です。

関連知識を把握すると、実際の開発はできると思います。

以上
LAMP環境でOSS mediawiki を動かしてみる

## 環境確認

```
#  OS
$ cat /proc/version
Linux version 4.4.0-75-generic (buildd@lgw01-21) (gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) ) #96-Ubuntu SMP Thu Apr 20 09:56:33 UTC 2017
```
```
#  mysql
$ mysql --version
mysql  Ver 14.14 Distrib 5.7.27, for Linux (x86_64) using  EditLine wrapper
```
```
#  php
$ php -v
PHP 7.0.33-0ubuntu0.16.04.6 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.33-0ubuntu0.16.04.6, Copyright (c) 1999-2017, by Zend Technologies
```

## インストール

## 公式サイトインストール方法を参照
https://www.mediawiki.org/wiki/Manual:Running_MediaWiki_on_Debian_or_Ubuntu/ja

```
# 結構処理長い
$ sudo apt-get update && sudo apt-get upgrade
```

# MediaWiki のインストール
```
$ cd /tmp/
$ wget https://releases.wikimedia.org/mediawiki/1.33/mediawiki-1.33.0.tar.gz
$ tar -xvzf /tmp/mediawiki-*.tar.gz
$ sudo mkdir /var/lib/mediawiki
$ sudo mv mediawiki-*/* /var/lib/mediawiki
```

# Mysql新規ユーザー登録
```
# create a NEW mysql user (new_mysql_user):
$ sudo mysql -u root -p
# Mysqlのrootパスワードを入力
Enter password: 

mysql>  CREATE USER 'new_mysql_user'@'localhost' IDENTIFIED BY 'THISpasswordSHOULDbeCHANGED';
Query OK, 0 rows affected (0.00 sec)
quit;
sudo mysql -u root -p
# Mysqlのパスワードを入力
Enter password: 

mysql> CREATE DATABASE my_wiki;
Query OK, 1 row affected (0.00 sec)

mysql> use my_wiki;
Database changed
mysql> GRANT ALL ON my_wiki.* TO 'new_mysql_user'@'localhost';
Query OK, 0 rows affected (0.00 sec)
mysql> quit;
Bye
```

##  シンボリックリンクを作成

```
$ sudo ln -s /var/lib/mediawiki /var/www/html/mediawiki
```

## apache再起動
```
$ sudo phpenmod mbstring
$ sudo phpenmod xml
$ sudo systemctl restart apache2.service
```

## ここまで終わったらブラウザで対象ページ開いて手順通りにインストールを実行
http://****/mediawiki/

## インストールが完了したらLocalSetting.phpが入手できるので対象ディレクトリに設置

```
$ sudo mv /var/www/LocalSettings.php /var/lib/mediawiki/
```

## インストール完了
http://****/mediawiki/
再度ブラウザで動作をチェックする
alias g='git' してたらgitのバージョンアップで補完できなくなったのでしたこと

# 序文

`git`に対してエイリアス貼っていましたが

```sh
alias g='git'
```

`g checkout`まで記述した後に「ブランチ名」の補完(オートコンプリート)が聞いていたのに、gitのバージョン更新したあたりから効かなくなってしまった。

# 結果

`vim ~/.bash_profile` 
これまでは、この記述だけで補完できていたのに

```sh
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
```

補完効かなくなったので
よくよく調べたら関数の実行まで必要みたいだったので記載したら無事に補完されるようになった。

```sh

source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
__git_complete g __git_main
```
tscの--showConfigオプション。これ、TypeScriptのコンパイル設定を確認するときに便利。

TypeScriptのコンパイルオプションを確認するには、`tsc --showConfig`すると良い。

例えば、次のような`extends`を使った設定ファイルにて、どのような設定が効いているかを知るには、継承元の`tsconfig.base.json`と突き合わせてみなければならない。面倒だ。

```tsconfig.json
{
  "extends": "../../tsconfig.base.json",
  "compilerOptions": {
    "outDir": "lib"
  },
  "exclude": ["test"]
}
```

```tsconfig.base.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["packages/*/src"]
    },
    "outDir": "SHOULD_BE_OVERWRITE",
    "declaration": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "newLine": "LF",
    "noFallthroughCasesInSwitch": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "removeComments": false,
    "sourceMap": true,
    "strict": true,
    "target": "esnext"
  }
}
```

そういう場合では、`tsc --showConfing`を叩くと、`extends`などが評価された状態の設定値を確認できる。

以下が出力結果の例:

```json
{
    "compilerOptions": {
        "baseUrl": "../..",
        "paths": {
            "*": [
                "packages/*/src"
            ]
        },
        "outDir": "./lib",
        "declaration": true,
        "emitDecoratorMetadata": true,
        "esModuleInterop": true,
        "experimentalDecorators": true,
        "module": "commonjs",
        "newLine": "lf",
        "noFallthroughCasesInSwitch": true,
        "noImplicitReturns": true,
        "noUnusedLocals": true,
        "removeComments": false,
        "sourceMap": true,
        "strict": true,
        "target": "esnext"
    },
    "files": [
        "./lib/Applicant.d.ts",
        "./lib/ApplicantRow.d.ts",
        "./lib/Applicants.d.ts",
        "./lib/ApplicantsImpl.d.ts",
        "./lib/ParticipationPage.d.ts",
        "./lib/getConnpassApplicants.d.ts",
        "./lib/index.d.ts",
        "./src/Applicant.ts",
        "./src/ApplicantRow.ts",
        "./src/Applicants.ts",
        "./src/ApplicantsImpl.ts",
        "./src/ParticipationPage.ts",
        "./src/getConnpassApplicants.ts",
        "./src/index.ts"
    ],
    "exclude": [
        "test"
    ]
}
```

`--showConfig`はTypeScript 3.2で導入された。

[TypeScript 3.2 · TypeScript](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html)
【git】Capistrano + Jenkinsのデプロイで、ビルド成功するけどソース反映されていないときの対処法

Jenkinsでデプロイした際に・・・
Gitのマージエラーなどで１回ビルド失敗した後、再度ビルドすると
「ビルド成功した！・・・あれ、ソース反映されてない？」
ってことがたまにあるかと思います。

そういうときはデプロイ先のサーバにログインし、
以下のgitコマンドを打ちます

```
git checkout -f
```

作業ツリーやインデックスの変更やもろもろ残ってたとしても
全て破棄して強制チェックアウトする！！！
というおまじないを使ったあとに、再度ビルドするときちんと反映されます
【Docker】とあるIPセグメントからだけDockerで公開してるサービスにアクセス出来なかったお話【社内ネットワーク】

# まえがき
とあるお仕事で、社内ネットワークにdockerで社内用WEBサービスを立ち上げました。
その社内ネットワークは「A拠点」、「B拠点」がVPSで接続されている構成となっているのですが
自分が所属&dockerホストを配置した「A拠点」からは問題無くWEBサービスへアクセス出来るのに
「B拠点」からはなぜかアクセス出来ないという事象が発生したので、それについてまとめます。

かなり珍しい事象かと思いますが、今後の為に書き留めました。

# 読んだ方がいいかもしれない人

- 社内サービスをDockerで構築しようとしている人
- 社内ネットワークでクラスBのIPが使用されている環境にいる人
- 拠点毎、部署毎など、IPのセグメントが分割されている環境にいる人


# 詳細

## 環境
- 拠点A
  - 172.16.XX.XX/16 のセグメントを利用
  - VPNゲートウェイは172.16.0.1
- 拠点B
  - 172.17.XX.XX/16 のセグメントを利用
  - VPNゲートウェイは172.17.0.1
- Dockerホストマシン
  - 拠点Aのネットワークに配置（172.16.16.33）

## 事象
拠点Aのクライアントマシン（172.16.YY.YY）から、Dockerにて提供されるWEBサービスへのアクセスは出来るが、
拠点Bのクライアントマシン（172.17.XY.ZZ）から、Dockerにて提供されるWEBサービスへのアクセスは出来ない。

## 原因
Docker起動時に構築される「Dockerホストとコンテナを繋ぐブリッジ（docker0）」に割り当てられるIPアドレスがデフォルトだと「172.17.0.1/16」である為
拠点BのVPNゲートウェイのIPアドレスと被ってしまった。

## 解決策
dockerブリッジ(docker0)のipアドレスを変更する。

↓参考
[Dockerでdocker0ネットワークのIPアドレスを変更する](https://qiita.com/winky/items/6d59cea8ae6cf9b2e665)
LINEBotのカルーセル作成でハマった話

#作ろうとしてたもの
写真をとって送信すると、受け取った画像に対して画像検索をして
その画像を同じであろう商品をリストアップして買取価格をカルーセル表示してくれるLinebot

#詰まった点
linesdkが画像を送ってくる仕組みが
メッセージの中にmessage.typeみたいなパラメータを持っていて、
それがimageとかデータが入ってるものだと

```javascript

client.getMessageContent(message.id)
```

みたいな感じで自力でデータを取りに行かないといけない仕組みなんだけど

```javascript

await client.getMessageContent(message.id)
.then(async(stream) => {
  stream.on('data', chunk =>{
     //ここにデータの受け取りの処理を書こうとした。
  });
});
```

こんな感じでデータを取ろうとしてここのデータの引数のchunkに画像データのバイナリが入ってるのかな〜みたいな予測で画像をFirebaseに保存してみた

すると
画像の上の部分だけ保存された変なデータが・・・

色々調べて、非同期の処理が途中で終了してしまってるのかとか色々考えるんだけど、答えなし。

ふとソースを見てみるとstreamとか書いてる。
そういえば昔C#で見たことあるような言葉だなぁと思い検索すると案の定
要はStreamはデータを小分けで送ってくれるような仕組みらしい
便利に使えれば処理のストップがなくて素晴らしいんだけど、
LineSDKのドキュメント、バイナリで返すって書いてるやん、
バイナリをStreamで返すって言ってよ・・・

#修正しました

こんな感じ

```javascript

tempfilepath = "/tmp/example.jpg"
const dest = fs.createWriteStream(tempfilepath, 'binary')
await client.getMessageContent(message.id)
.then(async(stream) => {
  stream.on('data', chunk => dest.write(chunk));
  stream.on('end', async() => {
    dest.end()
    //ここでさっき保存したデータをリードして使う
  });
});	
```
こんな感じで修正しました。
VSCodeを入れた後にとりあえず入れるもの・設定すること．

# はじめに
VSCodeって簡単に設定をいじれるところがいいですけど，結局最初は何をいじればいいかわからないですよね．

そこで僕がとりあえずVSCodeを入れた後に入れるエクステンションや，設定ファイルを公開していきたいと思います．

# 設定

```json:setting.json

{
    "editor.renderWhitespace": "all", //空白の可視化
    "editor.renderIndentGuides": true, //インデントのガイド表示
    "editor.formatOnPaste": true, // ペースト時に自動でフォーマット
    "editor.formatOnSave": true, // ファイル保存時に自動でフォーマット
    "editor.formatOnType": true, // 入力した行を自動でフォーマット
    "editor.dragAndDrop": false, //ドラッグドロップを無効化
    "workbench.startupEditor": "newUntitledFile",
    "files.autoSave": "afterDelay",//オートセーブ
    "files.autoSaveDelay": 1000,//オートセーブのディレイ
    "editor.wordWrapColumn": 80,//行の文字数
    "editor.wordWrap": "bounded",
    "editor.tabSize": 2,
    "editor.quickSuggestionsDelay": 0,//サジェストまでの時間
    "workbench.colorTheme": "Monokai",//配色テーマ
    "editor.suggestSelection": "first",
    "editor.matchBrackets": true,//対応するかっこの強調
    "editor.autoClosingBrackets": "always",//かっこの自動補完
}
```

# 拡張機能
- Bracket Pair Colorizer
    - 対応するかっこごとに色がつくので見やすくなる．
- Rainbow CSV
    - csvファイルが列ごとに違う色になって，見やすくなる．大きいcsvファイルほどきれい．
- vscode-icons
    - アイコンがつく．かわいい．

# キーコンフィグ
```json:keybidings.json
[
    {
        "key": "ctrl+shift+p",
        "command": "cursorUpSelect",
        "when": "textInputFocus"
    },
    {
        "key": "ctrl+shift+n",
        "command": "cursorDownSelect",
        "when": "textInputFocus"
    },
    {
        "key": "ctrl+shift+f",
        "command": "cursorRightSelect",
        "when": "textInputFocus"
    },
    {
        "key": "ctrl+shift+b",
        "command": "cursorLeftSelect",
        "when": "textInputFocus"
    },
    {
        "key": "tab",
        "command": "selectNextSuggestion",
        "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
    },
    {
        "key": "shift+tab",
        "command": "selectPrevSuggestion",
        "when": "editorTextFocus && suggestWidgetMultipleSuggestions && suggestWidgetVisible"
    },
    {
        "key": "ctrl+k ctrl+k",
        "command": "deleteAllRight",
        "when": "textInputFocus && !editorReadonly"
    },
    {
        "key": "ctrl+k",
        "command": "-deleteAllRight",
        "when": "textInputFocus && !editorReadonly"
    },
]

```
- ctrl+shift+(p,n,f,b)系は，選択しながらカーソルを動かしたいので設定しています．
- コードを書いているときにサジェストされるものの移動はtabとshift+tabで上下移動するように設定しています．
- ctrl+k ctrl+kはカーソルより右を切り取るのに，設定しています．

# おわりに

僕がまずはじめに設定するのは，これくらいですかね．

pythonやLaTex,MarkdownやUnityをいじりたいときはもうちょっと入れたりするものもありますが，基本的なものはこれくらいで十分だと思います．

VSCodeはもっともっといじると快適に使えると思うので，いじり倒したいと思います．
私は如何にして JMockit の returns(Object) を安全に置換したか？

テストで使っているJMockitというモックライブラリが古いバージョンだったので、最新バージョンにアップデートする作業をしたのですが、その際にちょっとしたハックをしたので紹介します。

なお、JMockit自体の変更点などについては別記事にしているので、JMockitを使っている方はそちらもご覧ください（→[JMockit と共に生きる者ためのメモ - Qiita](https://qiita.com/tonluqclml/items/5111ef8985c450bce4ca)）

# どんな問題があったのか？

JMockit（の旧バージョン）では以下のように `Expectations` のインスタンスイニシャライザでメソッドを差し替えます。戻り値は `result` または `returns`で指定します。

```java
new Expectations() {{
　 intList.get(0); result = 1;     // intList.get(0) が常に1を返すようになる

　 intList.get(0); returns(1);     // ↑ の別記法（1.30で廃止）

　 intList.get(1); returns(-1, 1); // intList.get(1) が、-1 と 1 を交互に返すようになる
}};
```

ここで、**1引数版**の`returns(v)`は JMockit 1.30 で廃止されてしまいました。
そのため、テストコード中の `returns(v)` は `result = v` に書き換えなくてはなりません。

まず、sed で置換しようとしましたが、**returnsには1引数版と2引数以上版があるので単純に置換することはできません。**

```shell
sed -e 's/returns/result =' // 2引数版も置換してしまう。-e 以外の引数は省略
```

正規表現を工夫したりもしましたが「returnsの引数として別のメソッド呼び出しを指定する」コードがある等して、上手くいきませんでした。

次に IntelliJ のリファクタリング機能を探しましたが、

- インライン化
- メソッド名変更

などはあるのですが「メソッド呼び出しを代入文に変更」という変更はできませんでした[^1]。

[^1]: 商用版では出来たりするかもしれませんが、私が使っていたIntelliJ IDEAでは出来ませんでした。

# どうやって解決したか？

まず、`returns` の呼び出しを自作クラスのメソッドの呼び出しに置換しました。

```
sed -e 's/returns(/test.MyDummy.returns(/g'
```

テストコードはこんな形になります。

```java
new Expectations() {{
　 intList.get(0); test.MyDummy.returns(1);     // returns が自作メソッドのものに置換されている
　 intList.get(1); test.MyDummy.returns(-1, 1); // 2引数版も置換される
}};
```

さらに、自作クラスに以下のようにメソッドを定義します。この時点で、JavaコードとしてはValidになるので、IntellJのリファクタリング機能を使えるようになります。

```java
class MyDummy {
    public static void returns(Object o) {
        result = o;
    }

    public static void returns(Object o, Object o2, Object... args) {
    }
}
```

IntelliJ で、MyDummy.returnsにカーソルを合わせ `Refactor This → inline` でインライン化します。

すると、IntelliJ は、メソッドオーバーロードを理解しているので、1引数版の returns のみをインライン化してくれます。

```java
new Expectations() {{
　 intList.get(0); result = 1;
　 intList.get(1); test.MyDummy.returns(-1, 1);
}};
```

これで「1引数の`returns` → `result`」は完了です。残った `test.MyDummy.returns` は、再びsed で置換して、`returns`に戻します。

```
sed -e 's/test.MyDummy.returns(/returns(g'
```

これで、1引数の`returns`のみが書き換えられた状態になりました。

```java
new Expectations() {{
　 intList.get(0); result = 1;
　 intList.get(1); returns(-1, 1);
}};
```

かかった時間は、考える時間も含めて１・２時間ほどでした（測ってないけど多分）。`returns` は何千箇所もあったので、手作業では何日もかかったことでしょう。

また、使った変換は全て機械的なものだったので、バグは生じませんでした（本当にバグっていないかは、実際にテストをコンパイル・実行して確認できました）。
Laravelで.env が読み込めなくなった

ほんとにメモ程度に。

他の人がenvファイルに更新をしたので
そのまま加筆したら反映されなかったので

```ruby:qiita.rb
php artisan config:cache
php artisan view:clear
```

を実行したところenvファイル自体読み込めなくなり
Undefined index:エラーに、、、

結局
>bootstrap/cache/config.php 
を削除したら正常に読み込めた。


**追記**
コメント頂きました。ありがとうございます
そのままのほうが伝わると思いますので、そのまま引用させて頂きます！！


＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
env()関数は config:cache すると機能しなくなります。
なので、env()はconfigディレクトリ内でしか使っちゃダメ！
config内に書いて、env()はconfig()に置き換えましょう、ということみたいです。

https://qiita.com/mpyw/items/34f37742d9a18b80a08c
＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝


とのことです！！
AWS ALBでお手軽メンテ画面の作成と運用方法

## はじめに
サービスを運用していると定期メンテの際に出しておくメンテ画面が必要ですよね。
メンテページには「○○時までメンテナンスしているから少し待ってね」的な事を時間を指定して書いておきたい。
基本的な事は [クラスメソッドさんのブログ](https://dev.classmethod.jp/cloud/aws/alb-fixed-response/) に書いているのですが、
今回は運用も考えてJenkinsから叩けるように `aws-cli` コマンドを使ってメンテ画面を作って運用する方法を紹介します。

## 端的に紹介すると
- ALBのルールの一つにでメンテ画面を作成  
 └  メンテ開始前にメンテ画面を`aws-cli`で更新
- 運用を考えて3つのルールを作成  
  └ メンテ開始時にルールの優先順位を`aws-cli`で変更   
  └  メンテ終了時もルールの優先順位を`aws-cli`で変更  

## 1.ALBにメンテ画面を作成

[EC2やS3不要！ALBだけでメンテナンス画面を表示するなど固定レスポンスが返せるようになりました！](https://dev.classmethod.jp/cloud/aws/alb-fixed-response/)

ALBからメンテ画面を固定レスポンスとして作りましょう。
普段はサービスに向けたルールよりも優先度を下に設定しておき、メンテ開始時にメンテ画面のルールの優先度を上げる運用にします。

### 1.1メンテ開始前にメンテ画面を更新
メンテ画面でメンテの終了予定期間を表示させたいのでルールを更新します。

```shell
 $aws elbv2 modify-rule --rule-arn xxxx \
 --actions Type=fixed-response,FixedResponseConfig= \
 '{MessageBody=2019/08/28の20:00までメンテです。,StatusCode=503,ContentType=text/html}'
```
[modify-ruleのdoc](https://docs.aws.amazon.com/cli/latest/reference/elbv2/modify-rule.html)

messageBody部分にhtmlを書いてやることでソレっぽい画面を作ります。
ただ、文字制限があるので最低限のページにおさえて置きましょう。


## 2.運用を考えて3つのルールを作成
1つ目はメンテ画面のルール
2つ目はサービスのターゲットグループを指定したルール
3つ目は *特定IPからアクセス出来るサービスのターゲットグループを指定したルール*

メンテナンス時に動作確認を行いたいのであれば、
3つ目のルールを1つ目のルールより優先度を上げると確認が楽になります。

![rule1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210/f228e544-00f9-718c-5990-b2097d91b2e2.png)

![rule2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/210/afa49b15-4600-d0c3-1bea-f9e164dcdb34.png)

### 2.1 メンテ開始時にルールの優先順位を変更
メンテ画面の優先度をサービスへのルールよりも上げています。

```shell
aws elbv2 set-rule-priorities --rule-priorities \
RuleArn=特定IP許可のルール,Priority=1 \
RuleArn=メンテ画面のルール,Priority=2 \
RuleArn=サービスへのルール,Priority=3
```

### 2.2 メンテ終了時にルールの優先順位を変更
メンテ画面の優先度をサービスへのルールよりも下げています。

```shell

aws elbv2 set-rule-priorities --rule-priorities \
RuleArn=特定IP許可のルール,Priority=1 \
RuleArn=サービスへのルール,Priority=2 \
RuleArn=メンテ画面のルール,Priority=3 
```
[set-rule-prioritiesのdoc](https://docs.aws.amazon.com/cli/latest/reference/elbv2/set-rule-priorities.html)

## まとめ
今回、簡単にメンテナンス画面の作成とその運用方法について紹介しました。
コンテナ技術入門 - ハンズオン

Docker / Docker-compose / Kubernetes のハンズオンを通して、コンテナ技術およびCI/CD連携を自習できるコンテンツはこちら。

* [コンテナ技術 ハンズオン Vol.1 Docker操作編](https://qiita.com/syamane/items/65570b41b3d6d32691a5)
* [コンテナ技術 ハンズオン Vol.2 Dockerイメージ編](https://qiita.com/syamane/items/1b552ce28932dbfd3c56)
* [コンテナ技術 ハンズオン Vol.3 Docker Compose編](https://qiita.com/syamane/items/dcea30a7794f9755a59d)
* [コンテナ技術 ハンズオン Vol.4 Docker管理編](https://qiita.com/syamane/items/4b43dec0202deda25403)
* [コンテナ技術 ハンズオン Vol.5 Kubernetes編](https://qiita.com/syamane/items/e5382a8bf9753f6a6c23)
* コンテナ技術 ハンズオン Vol.6 CI/CD連携編（製作中）

いずれも参加者が必要に併せて **自学できる入口に立つ** ことを目的としたコンテンツとなっております。後日に「コンテナ」を扱おうとしたときに、自分で調べて理解でき、実際に扱えるようになることを目指します。

社内のグループやサークルで輪講する場合などに利用して貰えれば幸いです。
Python3でopencvを使おうとしてハマった話

初投稿です。
python3でopencvを使おうとしてハマったので、メモがわりに残します。

#環境

 * Python 3.6.2
 * pyenv-virtualenv
 * macOS 10.14.6

#エラー内容

```
  File "test.py", line 3, in <module>
    import cv2
ModuleNotFoundError: No module named 'cv2'
```
唐突に現れたimport文のModuleNotFoundError
なんかの拍子にopencv-python誤って消してしまったかと思い、確認

```
$ pip list
Package               Version
--------------------- --------
...
opencv-python         4.1.0.25
...
```

普通にある...
とりあえず、直接pythonから叩いてimportしてみよう

```
Python 3.6.2 (default, Nov 18 2017, 21:22:04)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.38)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
>>>
```

うーん、謎が深まった...

#やったこと
いろんな記事見ながらひたすらいろんなことを試した

 * pip使ってもう一度opencv-python入れ直す
 * ```site-packages/cv2```以下の```cv2.cpython-36m-darwin.so```を```cv2.so```にrename
 * ```$ pip install opencv-contrib-python```でopencv-contrib-pythonを入れる(利用法に注意してください。)
 * ```$  brew install opencv3 --with-python3 --without-python --with-contrib```
 
どれもダメでした...

#解決方法
cv2をimportする前にライブラリのパスを通す必要があったらしい
とりあえず下記のコードでなんとか動いた！

```
import sys
sys.path.append('/Users/yuta/.pyenv/versions/lab/lib/python3.6/site-packages')
import cv2
```

#原因
きっとパス関連の何かなのだと思う
詳しいことは勉強不足で結局わからずじまいであった...
~~とりあえず、投稿してみて強い人からコメント来るといいな~~

#参考記事

[未経験大学生によるpython入門日誌-第４話 OpenCV篇](https://techracho.bpsinc.jp/katayama-yuuki/2017_04_13/35124)
[Pythonチュートリアルをやってみる 特別編] (http://nimi0370376.hatenablog.com/entry/2017/07/11/024330)
ローカルアカウントでwinexeを利用する

LinuxからWindowsにリモートコマンドを実行する際に、winexeコマンドを使うことができます。

Windows Server接続時の認証に利用するアカウントとして、以下のいずれかを選択します。
1. 所属ドメインのアカウント
2. ローカルのAdministrator
3. ローカルのアカウント(Administrator以外)

1や2のアカウントを利用する場合、ファイル共有サービス(CIFS:445/TCP)に接続でき、パスワードが正しければコマンド実行を行うことができます。

3のローカルアカウントを利用する場合は、次の準備が必要となります。

1. ローカルアカウントを「管理者」に設定します。
2. ローカルアカウントのリモートUACを無効に設定します。

それぞれの手順を記載します。

1.
「コントロールパネル」-「ユーザーアカウント」-「アカウントの種類の変更」を開き、該当ユーザーのグループメンバーシップを「管理者」に変更します。

2.
管理者権限でregeditを起動し、次の設定を行います。
HKEY_LOCAL_MACHINE - SOFTWARE - Microsoft - Windows - CurrentVersion - Policies - System に移動します。

「編集」-「新規」-「DWORD(32ビット値)」で新しいレジストリを追加します。
名前: LocalAccountTokenFilterPolicy
値: 1

以上の設定を完了後、winexeによるリモートコマンド実行が可能となります。

なお、Windows Defenderによりwinexeサービスの起動が行えない場合、下記の記事を参考にして、winexeサービスを許可してください。

https://www.osstech.co.jp/support/2018-11-01
Rails | Devise: DoubleRenderError

Deviseをいじいじしたあと、サインアップを試みるとこんなエラーが...


**AbstractController::DoubleRenderError in Users::SessionsController#create**
**Render and/or redirect were called multiple times in this action.  Please note that you may only call render OR redirect, and at most once per action. Also note that neither redirect nor render terminate execution of the action, so if you want to exit an action after redirecting, you need to do something like "redirect_to(...) and return".**


## 解決方法
**Devise: コントローラのオーバライドでredirect_toを使わない**

* 原因となった箇所

```ruby

def after_sign_up_path_for
  redirect_to users_path
end
```

* 修正

```ruby
def after_sign_up_path_for
  users_path
end
```

## 理由
```ruby 
redirect_to users_path

# deviseの仕様上、上記の記述は以下と同義となってしまうから

redirect_to(redirect_to(users_path))
```

## 助けられた記事
[Rails, Devise: DoubleRenderError in FailureApp
](https://stackoverflow.com/questions/42327344/rails-devise-doublerendererror-in-failureapp)
DB・全文検索エンジンのデータ同期のススメ

こんにちは。
Web・iOSエンジニアの三浦です。

今回は、DBと全文検索エンジン間でデータを同期する方法について紹介していきます。

# はじめに
今日、データ・ログ分析や、文字通り検索機能を実現するため、SolrやElasticsearchなどの全文検索エンジンが使われることは珍しくありません。

その際、特にデータ分析や検索機能を実現するときは、全文検索エンジンのみにデータが入っているのではなく、DBなどにデータが入っており、それと同期する形で全文検索エンジンにデータを入れることも多いのではないでしょうか。

そうしたとき、現状ではDBと全文検索エンジン間でデータを同期する方法にデファクトスタンダートなどがあまりないように感じます。

そこで今回は、DBと全文検索エンジン間でデータを同期する方法を複数紹介し、適切な選択ができる手助けができればと思っています。

# 方法
## 1. バッチ
### 概要
PHPやPythonなど、好きな言語で書いたプログラムとサーバのcronなどを組み合わせ、定期的にDBと全文検索エンジン間でデータを同期する方法です。

### 利点
- すでに慣れている言語を使えるため、学習コストが低いです。
- 柔軟性が高く、好きに処理を書くことができます。
- 実装方法や言語にもよりますが、メモリ使用量は比較的少なくなります。

### 欠点
- 実装方法や言語にもよりますが、膨大なデータには対応しづらく、スケールしにくいことが多いです。
- cronでの実行の場合、完全なリアルタイムの実現は厳しいでしょう。
- 基本的にクラウドのマネージドサービスはありません。
- 柔軟性が高い一方で、細かいハンドリングまで自分で行う必要があります。

### 使い所
- 比較的データ量が少ないとき
- 使用可能なメモリが少ないとき
- 開発期間が短いとき

## 2. Logstash
### 概要
全文検索エンジンの一つであるElasticsearchの開発元であるElastic社が開発している、パイプラインアプリケーションです。

### 利点
- Javaで構築されていて、比較的動作が高速です。
- Elasticsearchの開発元が開発しているため、Elasticsearchとの親和性が高いです。
- 失敗したときのリトライ処理や最後に取得したデータの保持など、便利な機能がデフォルトで備わっています。

### 欠点
- 学習コストが高いです。
- Javaで構築されているため、メモリをそれなりに使用します。
- マネージドサービスがほぼないなど、あまり利用されている場所が多くありません。

### 使い所
- ある程度のデータがあるとき
- Elasticsearchとの同期処理

## Apache Spark
### 概要
大規模データを分散処理できる、分散処理基盤です。
ビッグデータの解析などにも利用されます。

### 利点
- 分散処理ができ、非常に高速です。
- hadoopの枯れた技術を使用できます。
- AWSのglue、EMRで使われるなど、主要な技術と言えます。
- 今後ますます重要になると考えられるビッグデータの処理など、大規模データ処理に応用できます。

### 欠点
- 学習コストが高いです。
- かなりメモリを使います。

### 使い所
- データ量が非常に多いとき

## サーバーレス
### 概要
AWSにおけるglueやfirehoseなど、自前でサーバーを用意せずに使用できるアプリケーションです。

### 利点
- 簡単な処理であれば、生のアプリケーションを使うよりも面倒事が少ないです。
- マネージングされているため、管理コストが少ないです。
- 機能が提供されていれば、リアルタイム処理が簡単にできます。
- 同じクラウド内のサービスと連携がしやすいです。

### 欠点
- 複雑な処理をしようとすると柔軟性が低くなります。
- 複雑な処理をしようとすると学習コストが高くなります。
- 使った分だけスケールするので、コストの見積もりが難しくなります。

### 使い所
- データの整形処理などが簡単なとき
- 同クラウド内のサービス間の連携

# さいごに
どんなデータをどのように同期するかはもちろん、使用できる環境や開発期間によっても使うべきツールが異なることがわかりました。

ここに上げた以外にも、例えばDB自体にinsertやupdateが走ったときに動くhookをつけ、それをもとに処理させるなどの方法もありますが、自分の開発内容によって適切に変えていきたいところです。
k8s環境変数 envとenvFromの上書き優先度

# 常にenvが優先

一年に一回くらい忘れて調べてるからいい加減メモっておく

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.13/#container-v1-core

>List of sources to populate environment variables in the container. The keys defined within a source must be a C_IDENTIFIER. All invalid keys will be reported as an event when the container is starting. When a key exists in multiple sources, the value associated with the last source will take precedence. Values defined by an Env with a duplicate key will take precedence. Cannot be updated.

- `Values defined by an Env with a duplicate key will take precedence.`
- `Values defined by an Env with a duplicate key will take precedence.`
- `Values defined by an Env with a duplicate key will take precedence.`

そもそもkey被らせるのやめろ
react npm moduleのバージョンを確認する

bashにて
はじめどうして良いか分からずnode_moduleフォルダを開いたりしていたのですが、
調べてみると簡単にインストールしたmoduleのバージョンを確認できました。

## localにインストールされたパッケージ

```bash
$ npm list --depth=0
...@0.1.0 /home/ubuntu/environment/...
├── @material-ui/core@4.3.1
├── classnames@2.2.6
├── immutable@4.0.0-rc.12
├── node-sass@4.12.0
├── prop-types@15.7.2
├── react@16.8.6
├── react-dom@16.8.6
├── react-redux@7.1.0
├── react-router-dom@5.0.1
├── react-scripts@3.0.1
├── redux@4.0.4
├── redux-devtools-extension@2.13.8
├── redux-saga@1.0.5
├── reselect@4.0.0
└── typeface-roboto@0.0.75
```

##参考
https://medium.com/@rukurx/npm%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E3%81%AE%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B-6c82286ceb78
GPUサーバのリソースをモニタリングするPrometheus exporterの作成と運用

# 概要
GPUサーバのリソースを詳細にモニタリングするための、Prometheusのexporterを作成しました。このexporterによって、サーバ内の各GPUを使用しているdockerのコンテナ名やイメージ名、プロセスIDやコマンドを取得できます。また、docker-composeによりサーバへ手軽にデプロイできるようになっています。

[GitHubにてリポジトリを公開しています](https://github.com/yahoojapan/gpu-monitoring-exporter)ので、ぜひお試しください！

# 背景
私が所属する研究開発チームでは、複数台のGPUサーバを運用し、深層学習に基づく自然言語処理や動画像処理の開発や性能評価をしています。各GPUサーバではnvidia-dockerが導入されており、ユーザが自由にコンテナを立ち上げることができるようになっています。このような環境では、他のユーザとリソース（特にGPU）がコンフリクトしていないことを確認する必要があります。もし、GPUリソースがコンフリクトすると、プログラムが実行されなかったり、CPUでの処理に切り替わることで処理時間が大幅に長くなったりして、研究開発の効率が落ちてしまいます。

# 解決策
いちいち各サーバへログインして確認するのは手間がかかるので、監視ツールであるPrometheusを利用してリソースを一覧できるようにします。Prometheusでは、独自にexporter（サーバやシステムの情報を収集するためのエンドポイント）を作成することができます。必要なメトリクスを複数のコマンド (ps, docker, nvidia_smi) を利用して収集します：

| メトリクス     | 収集コマンド |
| -------------- | ------------ |
| コンテナ名     | docker       |
| イメージ名     | docker       |
| コマンド       | ps           |
| ユーザ名       | ps           |
| CPU使用率      | ps           |
| メモリ使用量   | ps           |
| GPU番号・UUID  | nvidia_smi   |
| プロセス名・ID | nvidia_smi   |

# モニタリング例
docker-composeによって、モニタリングに必要なexporterをまとめて立ち上げられるようにしています。実際はこれに加えてansible（構成管理ツール）を導入しており、複数サーバへのデプロイを自動化しています。

監視用のPrometheusサーバでは、Grafanaを用いてリソースを可視化しています。

![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352170/b9545452-1e35-b373-ce07-b8e7137c23f8.png)
試しにtensorflowのコンテナでmnistをやってみたの図。GPUの使用率やメモリ使用率（GPUごと、全体それぞれ）、温度や電力消費量、GPUを使用しているコンテナやイメージの名前、コマンドなどが表示され、リソースの空きが簡単に確認できます。

プロセス一覧（スクリーンショット内、Process Infoの欄）を表示するには、例えば次のようなクエリ (PromQL) を指定します：

```
sum(nvidia_smi_process) by (instance, gpu, pid, command, image_name, container_name)
```

# おわりに
研究開発に用いるGPUサーバにおいて、リソースの空きを簡単に確認できるモニタリングツールを紹介しました。コマンド1つでデプロイできるようになっているので、ぜひお試しください。
YAMAHAルーターへAnsible telnetモジュールを使ってユーザー名なしでログイン

YAMAHAのルーターへ定期的にtelnetでログインして各種ステータスを取得するのをAnsibleで自動化しようとして詰まったのでメモ。

ルーターを用意できていなかったときに、テスト用に立てていたtelnetサーバーへは問題なく処理できていた。
そのうち、ルーターが用意できたのでユーザー名を指定せずに共通ユーザーでログインしようと下記のように設定したら、タスクがいつまでたっても進まなくなった。

```yaml:tasks/main.yml
- name: ルーター情報取得
  telnet:
    password: soge
    prompts:
      - "[$|>]|Password: "
    command:
      - console character en.ascii
      - show status dhcpc
```

このとき、telnetモジュールは、userパラメータを省略すると"remote_user"を使用してアクセスしようとしてしまうので、存在しないユーザーのパスワードを要求される自体に陥っていた。
そこで、下記のように修正することで、ユーザー名なしでアクセスすることに成功した。

```yaml:tasks/main.yml
- name: ルーター情報取得
  telnet:
    user: soge
    login_prompt: "Password: "
    prompts:
      - "[$|>]"
    command:
      - console character en.ascii
      - show status dhcpc
```

「user: ""」と設定するとansibleに怒られるので、これしか方法がない？


参考：
Ansible telnetモジュールでYamahaルータを操作
　https://qiita.com/sat0ken/items/1bb2c6aecc677b9bdc66
Ansible telnet without username login
　https://stackoverflow.com/questions/53777121/ansible-telnet-without-username-login