OmniAICreator/Qiita-1.07M huggingface dataset:
DMARCとは（初心者向け）

前回、SPFとDKIMについて書いたので、ついでにDMARCもまとめておきます。

### １．DMARCって？
SPFとDKIMの欠点を補うための送信ドメイン認証です。
認証に失敗したメールをどうするか、送信側で決めることができます。
SPFとDKIMの両方を使うことを前提にした仕組みですが、いずれかに対応していれば導入できます。
メール送信側で、事前に以下の3パターンからポリシーを定義しておきます。

 ①none(何もしない)
 ②quarantine(迷惑メールフォルダなどに隔離する)
 ③reject(受信を拒否する)

### ２．DMARCのメリット
DMARCには、大きく分けて2つの機能があります。

①ポリシー設定
・認証が失敗した場合の受信側の挙動が制御できる

②レポーティング機能
・関連するすべてのメールプロバイダから日次レポート(XML形式)を受け取ることができる
・エラー情報(SPFとDKIMの認証結果)と統計情報(どういうメールがどういう認証結果なのか)が分かる
・なりすましメールの送信元が分かる
・最新の情報が把握できるため、ポリシーの最適化ができる


### ３．DMARCの実装方法
ポリシーはDMARCレコードとして、送信側でDNSサーバにTXTレコードを設定します。
以下がオプション(抜粋)です。

・v=DMARC1 DMARCレコードのバージョン(現状DMARC1しかないよう)です。レコードの最初に指定が必要です。
・p=none 認証に失敗したメールのアクションです。none,quarantine,rejectのどれかを指定します。
・rua=mailto:〜 統計情報のレポートメールを受信するメールアドレスを指定します。
・ruf=mailto:〜 エラー情報のレポートメールを受信するメールアドレスを指定します。

例：ドメインがexample.jpの場合
>_dmarc.example.jp text = “v=DMARC1; p=none; rua=mailto:report@example.jp 

### ４．メール送受信の流れ
送信ドメイン認証を使った、メール送受信の流れです。 

######1.DNSサーバにSPF,DKIM,DMARCレコードを追記します。
######2.メールを送信します。
######3.SPFとDKIMの認証を行い、失敗したらポリシーに従って処理します。
######4.認証結果をレポートに書き込み、さらに隔離、受信拒否の場合は認証失敗としてレポートに書き込みます。
######5.日次で受信側からレポート用アドレスへ、レポートメールを送信します。

---

★懸念★
・DMARCを使うには受信側もDMARCをサポートしている必要がある。
・国内ではDMARC普及率が低い※ので、レポート結果のドメインの種類が少ない。
・ドメインごとにレポートを送受信するため、負荷が掛かる。
・受信するべきメールが受信できなくなる可能性を考慮して、認証失敗しても受信拒否するケースは少ないのでは。 

※「一般財団法人インターネット協会主催の迷惑メール対策カンファレンス」P15
2017年時点でDMARCの普及率は19.66%とのこと。
https://www.iajapan.org/anti_spam/event/2017/conf_16-17th/pdf/OD-05_D3-06_kitazaki.pdf
Windowsでwarファイルを手軽に扱う

エクスプローラーでwarファイルをダブルクリックしてzipファイルのように中身を見ることができるようにするには、コマンドプロンプトを管理者権限で開いて以下のコマンドを実行します。

```
assoc .war=CompressedFolder
```
jarファイルをエクスプローラーで開けるようにするコチラの記事を参考にさせていただきました→ https://qiita.com/kitoo/items/6761fd74e8347962171a
【メモ】Jsonファイルでネストした要素を削除する方法

## 実行環境
Windows 10
Visual Studio Code
Python3.7

## ネスト構造になっているjsonファイルから特定の要素を消したいぜ

Python3を使ってネスト構造になったjsonファイルから要素削除したいぜ！ってことでやってみました。



```json
[
    {
        "age": 19,
        "height": 181.4,
        "sex": "male"
    },
    {
        "age": 29,
        "height": 161.0,
        "sex": "female"
    },
]
```

上記のようなinput.jsoファイルがあったと仮定します。
ここで、年齢（age）が29歳の人の要素は要らねぇ！ってなったとします。
その時、以下のコードで削除でき、かつ、削除した新しいoutput.jsonファイルを作成できます。


```py
# coding: utf-8
import json

f = open('input.json', 'r', encoding="utf-8")
jsonData = json.load(f)

for i in range(len(jsonData)):
    if json.dumps(jsonData[i]['age'], sort_keys = True, indent = 4, ensure_ascii=False) == "29":
        jsonData[i].clear()
    
    print(json.dumps(jsonData[i], sort_keys = True, indent = 4, ensure_ascii=False))

f.close()

f = open('output.json', 'w', encoding="utf-8")
json.dump(jsonData, f, indent='\t', ensure_ascii=False)
```

ちなみに、これの実行結果はこうなります。

```json
[
    {
        "age": 19,
        "height": 181.4,
        "sex": "male"
    },
    {},
]
```

見て貰ったらわかりますが、{}が消えてないんですよね。
そこのやり方わからなかったので、もしわかる人いたら教えてください。


### ポイント
```py
print(json.dumps(jsonData[i], sort_keys = True, indent = 4, ensure_ascii=False))
```

print文の一番最後にある「ensure_ascii=False」は日本語の文字化けを解消するためのコードです。
日本語がjsonファイルに入らないなら不要...なはずです。
日本語がある場合は絶対に要ります！

私はjsonファイルの書き込む所でこれを書き忘れていた為に、ず～っと文字化けが治らず苦労しました。
ssh 呼び出しのバッチが動かないトラブルを調べた話【vol.2】(解決編)

株式会社オズビジョンのユッコ (@terra_yucco) です。
[ssh 呼び出しのバッチが動かないトラブルを調べた話【vol.1】](https://qiita.com/terra_yucco/items/b688bb613184ab89d34e) の続きの記事 (解決編) となります。

# 仕込んだ処理で得られたログ

かなり抜粋しましたが `END,255` となっている処理の中では ssh 関連のエラーメッセージが出ています。

```
[2019-06-25 20:53:01][913] START,-,host_user_batch01 /path/to/starting_sh/user_log.sh action
[2019-06-25 20:53:01][913] command,ssh -i /path/to/key root@host_user_batch01 /path/to/starting_sh/user_log.sh action
[2019-06-25 20:53:02][913] ssh_exchange_identification: Connection closed by remote host
[2019-06-25 20:53:02][913] END,255,host_user_batch01 /path/to/starting_sh/user_log.sh action
```

## エラーメッセージ

>ssh_exchange_identification: Connection closed by remote host

※ちなみにこれは stderr じゃなくて stdout に出ていました...。

## このメッセージ

- [ssh_exchange_identificationと言われてknown_hosts消したりhosts.allowいじっても直らない時に確認してほしいこと](https://qiita.com/uutarou10/items/f8391965adc6b4c312d1)
    - IP が変わっている
- [.ssh/configの設定でエラー: ssh_exchange_identification: Connection closed by remote host](https://qiita.com/sot528/items/03b860a1310072e95c16)
    - ホスト名が数字で始まっている

など、様々なケースがあるようなのですが、今回の場合には sshd の接続数上限でした。

## sshd の設定

```terminal
$ sshd -T | grep max
x11maxdisplays 1000
maxauthtries 6
maxsessions 10
clientalivecountmax 3
maxstartups 10:30:100
```

`sshd -T` では `maxstartups`
`/etc/ssh/sshd_config` では `MaxStartups`

### MaxStartups

この設定の意味は以下のとおりです。

`a:b:c`

**認証前接続において**
最初の a 本の接続は 100% 受け入れ
c 本になるまでの接続は b% の確率で受け入れる
c 本以上の接続は 100% 拒否

## 今回の原因

サーバのスペックが上がったことにより、同時に ssh 接続を要求する接続数が一気に跳ね上がり、鍵交換を待つプロセス数が上限を突破したものと思われます。
設定 `10:100:10` とかでした。要するに一気に 11 本以上殺到したら確実に 1 本は弾かれる。

## 対処

以下の対処で 255 のログは出なくなりました。

```terminal
$ echo "MaxStartups 100:30:150" >> /etc/ssh/sshd_config
$ service sshd restart
```

# Conclusion

- `ssh_exchange_identification: Connection closed by remote host` と言われた場合には接続数上限超過のケースもある
- 上限超過した場合 ssh は 255 を返す
送信ドメイン認証とは（初心者向け）

忘れたころに見返すための未来の自分へ向けて。

### １．送信ドメイン認証って何？
なりすましメールかどうかをチェックすることです。

送信元のドメインが本物であることを確認する仕組みです。
認証方法はいくつか種類がありますが、ここではよく使われている「SPF」と「DKIM」について記載します。

### ２．なんで認証が必要なの？
差出人が偽物だと分かれば、フィッシング詐欺や迷惑メールを事前に防ぐことができます。
認証が失敗した場合は、メール配信をブロックしたり、SPAMマーキング（件名に「\*\*\*SPAM***」がつくらしい）して配信したり、迷惑メールフォルダに入れたりします。
逆に認証が成功していれば、これは正しい差出人からのメールですよ～と証明されていることになるわけです。（万全とは言えませんが）

### ３．なりすましのやり方
そもそも、なりすましメールはどのようにしてなりすましているのか。

結論から書くと、ヘッダFromとエンベロープFromを異なるアドレスにしておけば、差出人が詐称できるのです。

---
・ヘッダTo
メーラー（GmailとかOutlookとか）でメールを見た時の「宛先」や「Cc」に表示されるアドレスです。
そこに"表示される"だけで、ヘッダToには実際の宛先と異なるアドレスを書くこともできます。
宛先にメーリングリストを入れた場合が一般的ですね。

・エンベロープTo
これが実際の宛先です。上記の通り、ヘッダToと異なる場合もあります。
ヘッダToにメーリングリストが入れてあるなら、エンベロープToにはメーリングリストに入っている複数のアドレス（実際にメール送信される人数分のアドレス）が入ります。
メールを送るときTo、Cc、Bccに入れたアドレスは、すべてエンベロープToに設定されます。

・ヘッダFrom
メーラーでメールを表示したときの「差出人」に表示されるアドレスです。
これも表示用なので、本当の差出人とは違うアドレスにもできます。

・エンベロープFrom
実際の差出人です。ヘッダFromと異なる場合もあります。
バウンスメール（何らかの理由で送信できなかったメール）が返ってくるアドレスでもあります。
宛先のアドレスを間違えたまま送ってしまった、実在しないドレスに送ってしまった、などでしょうか。
ちなみにFromアドレスはエラーの時以外は使われません。

---
なお、エンベロープとは封筒という意味です。
そのためメール送受信の仕組みを理解するにあたって、メールはよく封筒と便箋に例えられます。
エンベロープTo、Fromは封筒に書いてある宛先と差出人、ヘッダTo、Fromは封筒の中の便箋に書いてある宛先と差出人です。

流れとしては、送るときは宛先と差出人を書いた封筒に便箋を入れ、受け取るときには封筒を破棄して便箋だけ渡すイメージです。
だから受信側にはBccが分からないようになっているのです。
（このイメージを最初に教えてもらったときは、むしろややこしくて覚えにくい…と思ったので省略）

### ４．なりすましを防ぐ
メールを受信したときに、エンベロープFromを見て差出人のドメイン名を特定し、本当にそのドメイン名が使っているメールサーバから来たものかをチェックします。

######・SPF
メールの送信元が正規の差出人かどうかをチェックする仕組みです。
あらかじめ、「このドメインはこのサーバから送りますね～」という情報を持ったSPFレコードを、DNSサーバに登録しておきます。
そのあと、受信したメールサーバがSPFレコードを見て送信元をチェックするやり方です。

######・DKIM
メールに電子署名を添付して正当性を証明する仕組みです。
暗号化した電子署名を送信するメールに添付して、正規の差出人であることやファイルが改ざんされていないことを証明します。

なお、共通鍵暗号方式は鍵をメールに添付して送信してしまうと盗聴される恐れがありますが、公開鍵暗号方式はそのデメリットをカバーできます。
電子署名は「正規の差出人だけが秘密鍵を持っている」「対となる公開鍵でしか復号化できない」という特徴が証明になるからです。

送信側は、公開鍵を送信元ドメインのDNSサーバに公開し、秘密鍵で電子署名をメールに添付して送信します。
受信側は、送信元ドメインのDNSサーバへ正規の差出人であるかどうかを問い合わせし、認証OKが返ってくれば、ようやくメールが受信されます。
Linuxでテキストを編集するための最低限の知識

#はじめに
この投稿ではLinuxでテキストを編集するための最低限の知識をお伝えします。

なぜこのような投稿をするかと言いますと、先日とあるハンズオンセミナーに参加しました。そのセミナーの前提知識としてLinuxでテキスト編集ができることと記載されており、windowsしか触ってこなかった私はとても焦りました。そこで実際にセミナーで必要となった内容を記載して備忘兼共有しておきたいと思います。

#テキストファイルを作成したいディレクトリに移動する

最初にカレントディレクトリのファイルやフォルダを確認するために「ls」を入力してEnter押下します。
カレントディレクトリにあるフォルダやファイルが表示されます。

```
cloudshell:~ (platinum)$ ls
envs  hello-world  python-docs-samples  README-cloudshell.txt
```


今回は「hello-world」ディレクトリにテキストファイルを作成したいと思うので「cd hello-world」を入力して「hello-world」に移動します。コマンドプロンプトと同じ感覚です。

```
cloudshell:~ (platinum)$ cd hello-world
cloudshell:~/hello-world (platinum)$
```


#テキストファイルを新規作成する

ファイル名が「test.txt」のテキストファイルを新規作成してみます。
「vi test.txt」を入力すると以下のようなテキストエディタが起動します。

```
cloudshell:~/hello-world (platinum)$ vi test.txt
```

```
~
~
~
~
~
"test.txt" [New File]
```
####文字を入力する
文字を入力するには入力モードに切り替える必要があります。
エスケープ押下後に「i」を押下すると下部に「-- INSERT --」と表示され文字が入力できる状態になります。
その状態で「テストテキスト」と入力してみます。

```
テストテキスト
~
~
~
~
-- INSERT --
```



####範囲選択してコピー・ペーストする
エスケープを押し「-- INSERT --」が表示されていない状態に切り替えます。
その後、選択を開始したい位置にキャレットを移動し「v」を押下します。
下部に「-- VISUAL --」が表示されビジュアルモードに切り替わります。
あとは方向キーで範囲を選択し「y」でコピー、「p」でペーストできます。

```
aaa
bbb
ccc
~
~
-- VISUAL --
```


#テキストファイルを保存する

エスケープ押下→「:wq」の順で入力すると下の方に「:wq」が表示されます
その状態でEnter押下すると保存されてコマンド入力に戻ります。
エスケープを押すことでいろんなことができるようです。
保存後に再度「vi test.txt」を実行すると保存した内容を編集することができます。

```
テストテキスト
~
~
~
~
:wq
```


#保存内容を確認する

「cat test.txt」を入力してEnter押下します。
すると以下のようにテキストファイルの内容が表示されるので簡単に内容を確認できます。

```
cloudshell:~/hello-world (platinum)$ cat test.txt
テストテキスト
cloudshell:~/hello-world (platinum)$
```

#その他の覚えておくと良いこと

- ファイル名やディレクトリ名を入力するタイミングでタブを押下すると以前に入力していた内容が補完されます。例えば「cat test」でタブを押下すると「cat test.txt」にしてくれます。
- コマンドプロンプトと同じですが、方向キーの上下で実行したコマンドの履歴を呼び出せます。
- rmコマンドでファイルを削除できます。今回のファイルを消す場合は「rm test.txt」
- コマンドプロンプトと同様に「cd ../」で一つ上の階層に移動できます。

#最後に
上記のコマンドを覚えておくだけで設定ファイルを変更したり保存したりできるようになるので焦らずにハンズオンセミナーなどに参加できるようになります。
GOのインストール(開発環境の設定)についてのYoutubeへの動画の投稿!

この動画では、
(1)  Goのダウンロード とインストール  (2) #GOPATHのセット (3) プログラムの実行  (4) 実行ファイルを作る (5) ダウンロード #パッケージ (6) GOPATHの説明
を解説してるのでもしよかった見てください!

動画は日本語バージョンと英語バージョンがあります。日本語のバージョンでは英語のバージョンよりももっと詳しく説明しているので日本語バージョンがおすすめです。

動画(日本語バージョン)↓↓↓↓↓
https://youtu.be/jdUJLojDiKw
動画(英語バージョン)↓↓↓↓↓
https://youtu.be/ACdrOOkcvow
nodejs request のチートシート

## request とは？

#### Deprecated!

2020-2-11 に廃止されました:sob:
https://www.npmjs.com/package/request

#### 導入
```:command
npm info request # バージョン確認
npm install request
```


#### 書式
```javascript
const request = require('request');

request(options, function (error, response, body) {
  // リクエスト結果の処理
});
```
他の書式もあるけど、optionでいろいろ変えられる書式がすき:heart:

http リクエストを投げるモジュール。
options の設定により、様々なリクエストが投げられる。
[公式](https://github.com/request/request#requestoptions-callback) もあった ← 知らずにハマったこと数知れず:sweat_smile:

ネストが深くなるのがいやなので、いつもpromiseしてます。これもついでにチートシート

```javascript
function httpRequest(options) {
  return new Promise((resolve, reject) => {
    request(options, function (error, response, body) {
      let ret = {
        headers: response.headers,
        body: body,
        error: error,
        href: response.request.uri.href, // promise.all したときリクエスト元を特定するために設定
        status: response.statusCode,
      }

      if (error) {
        reject(ret);
      } else {
        resolve(ret);
      }
    });
  });
}

Promise.resolve()
  .then(function(value) {
    var header = {
    }
    var data = {
    }
    var options = {
    }
    return httpRequest(options); // リクエスト1回目

  })
  .then(function(value){
    // リクエスト結果の処理
    return httpRequest(options); // リクエスト2回目
  })
  .then(function(value){
    // リクエスト結果の処理
  })
  .catch(function(reason) {
    // エラー、rejectしたときの処理
  });

```



## チートシート

```javascript
  process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; // オレオレ証明書ドメインへリクエストするとき。curl の --insecure と同じ

  var jar = request.jar(); // cookieを使うとき

  var header = {
//    'Content-type': 'application/x-www-form-urlencoded', // form のときつけてくれる
//    'Content-type': 'application/json',  // jsonのときつけてくれる
    Authorization: 'Bearer beabea', // Basic 認証はここに書いてはいけない
  }
  var data = {
    honya: 'honya data',
  }
  
  var options = {
    url: 'http://example.com',
    method: 'GET', 
    headers: header,
    followAllRedirects: true, // 3xxが返ってきたとき、リダイレクトする。
    jar: jar,  // cookieを使うとき
    auth: [ // Basic認証するとき
      user: 'username',
      password: 'password',
    ],
    qs: data, // GET のとき query stringをurlにつけてくれる
    form: data, // form-urlencoded で送るとき。Content-type ヘッダもつけてくれる
    json: data, // jsonで送るとき。Content-type ヘッダもつけてくれる
    proxy: 'http://userid:passuwd@proxy.com:8080/', // proxyがあるとき
  }

```
ハマるたびに追加していきます。

## めんどくさいときは、機能を探す

わーめんどくさーいと思ったときはゴリゴリ書かずに、機能を探しましょう

#### 今までのハマり

- jar を知らず、ヘッダからset-cookieを取り出して、次のリクエストに入れてた。（動く）
- basic認証するとき、Authorizatioinヘッダにbase64した値を設定してた。（動かない）
- getパラメータをhttp_build_queryみたいな関数を作って、urlにつけてた。（動く）
- followAllRedirects を知らず、3xx が返ったときは、またリクエストしてた。（動く）

#### request-promise

request-promiseを使ってみたところ、bodyしか返さない上に、4xxはcatchに飛ぶので使いにくかった。

#### axios

オレオレ証明書ドメインへリクエストするときの設定が効かない。
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0

証明書を検証しないようにするには、記述をまるっと変える必要があった。
Go 標準ライブラリ tar パッケージの使い方

# tar ファイルの書き込み
書き込むには，まず， [Writer.WriteHeader](https://go言語.com/pkg/archive/tar/#Writer.WriteHeader) でヘッダを書き込みます。
ヘッダには，最低限，Name（ファイル名）とSize（ファイルサイズ）を指定します。
なぜなら，Sizeを超えた内容を書き込むとエラーとなるため，Sizeを指定しないとファイル内容を全く書き込めません。
Sizeは，int64(len(ファイル内容))で指定するのが最も確実で簡単です。

```go
    var buf bytes.Buffer
    tw := tar.NewWriter(&buf)
    body := "ファイル内容"
    // ヘッダ
    hdr := &tar.Header{
        Name: "ファイル名",
        Size: int64(len(body)),
    }
    // ヘッダを書き込む
    if err := tw.WriteHeader(hdr); err != nil {
        log.Fatal(err)
    }
    // ファイル内容を書き込む
    if _, err := tw.Write([]byte(body)); err != nil {
        log.Fatal(err)
    }
    // 閉じる
    if err := tw.Close(); err != nil {
        log.Fatal(err)
    }
```

複数のファイルを書き込む場合，WriteHeader と Write を繰り返します。
最後に， Close を呼び出して閉じます。

# tar ファイルの読み込み

Reader の Next() を呼び出して， tar ファイル内の複数のファイルに一つずつアクセスします。
Next() でヘッダを読み込めます。
Reader は， io.Reader インターフェースを実装しているので，通常のファイルを読み込むのと同じように Reader が使えます。

```go
tr := tar.NewReader(&buf)
for {
    hdr, err := tr.Next() // 最初のファイルを読み込む時にも，Next()を呼び出す必要がある。
    if err == io.EOF {
        break // アーカイブの終わり
    }
    if err != nil {
        log.Fatal(err)
    }
    // hdr.Name がファイル名
    // tr が io.Reader インターフェースを満たしているので， tr をそのまま使ってファイル内容を読み込む。
}
```

# 参考
[archive/tar パッケージ](https://go言語.com/pkg/archive/tar/)
[Package archive/tar](https://golang.org/pkg/archive/tar/)
非同期処理の順序制御

非同期処理の順序制御。良く使うパターンなので、切り出してみました。

たとえば、ユーザ入力要素(inputとか)が変更されると、APIにアクセスして、返ってきた値を、反映させるような場合。API処理にかかる時間は不定なので、戻ってくる順番がずれて、表示がおかしくなる場合があります。これを防ぐ処理です。

```js
class AsyncOutOfOrderError {}
class AsyncCommitter {
  requestId = 0;
  commitId = 0;
  async run(callback) {
    this.requestId += 1;
    const currentRequestId = this.requestId;
    const value = await callback();
    if (currentRequestId <= this.commitId) {
      throw new AsyncOutOfOrderError();
    }
    this.commitId = currentRequestId;
    return value;
  }
}
```

使うときは、

```js
try {
  const value = await this.asyncCommitter.run(async () => {
   // ここに制御対象の処理
  });
  // ここに正常に終了したときの処理
} catch (error) {
  if (!(error instanceof AsyncOutOfOrderError)) {
    throw error;
  }
  // ここに順番がおかしくなったときの処理（あれば）
}
```

もしかしたら、```run(callback, onSuccess, onErrror)``` とかの方が使いやすいかもしれません。

皆さん、これに相当する処理、どうさされてますか？同等の機能を持つライブラリを知っている人がいたら教えてもらえると幸いです。
Windows10のPCでLinux(ubuntu)動くようにするやつ(備忘録)

# こんな話
- windows10のPCでlinux動くようにする手順を忘れないようにメモしておく
    - あれ、何て名前だったっけ、、、、あー、、、、
    - それそれ、WSL(WindowsSubsystemforLinux)
    - 備忘録書く時点で忘れはじめるのもうだめ
    - こんな感じでタスクバークリックとかですぐubuntu触れるやつのことね
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185123/06a8d945-f68b-51a5-5439-79792291c14b.png)
- Qiitaリハビリしたくなったんで付き合ってよ

# いいこと

- Linux普段触るひとならWindowsマシンでsshとか開発とかするのこっちが楽だよ
    - CommandPromptとかPowershellとか覚えたくないし。。。
    - でもsshとかapt installとかしたいし、、、
    - Macは最初からCLIコンソールあるのずるい...ずるくない？
- お勉強用にクラウドにLinuxサーバ用意したりしなくていい
    - お金かからない(クラウドも無償枠あるけど)
    - 通信が重くなったりして泣かずに済む
    - ネットがなくても触れる

# やりかた

- 設定→アプリ→アプリと機能まで進む
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185123/3401e7b5-871d-e60b-a01f-a7138331a972.png)

- 右側にあるプログラムと機能をクリック

- 左側にあるWindowsの機能の無効化または有効化をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185123/cba35f52-44cb-311b-4eb1-4afd4b67a90d.png)

- 一覧からWindowsSubsystemforLinuxを探してチェックを入れる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185123/b4e1734a-991c-3551-9b22-e2267b194e28.png)

- 再起動する

- MicrosoftStoreを起動してubuntuで検索
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185123/3b2b7346-1728-f541-fb47-4bc624dc50fa.png)

- 三つUbuntuって出てるので、好きなUbuntuを選ぶんじゃ
    - Ubuntu：その時の最新安定版Ubuntu、選ばないならとりあえずこれにしとけ
    - Ubuntu18.04：2018年4月リリースのやつ
    - ubuntu16.04：2016年4月リリースのやつ
- Ubuntu以外がいいやつは「WindowsでLinuxを実行する」をクリックするんだ

- 入手を押してインストールな
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185123/7da24727-539c-9061-4313-b202f752dfa5.png)

- 出来たら実行してな
    - Windowsキー押して出てくるプログラム一覧におるよ
    - 右クリック→タスクバーに固定しておくと次から楽よ

- 初回起動時はセットアップ走るからちょっと待ってね
    - 終わったらユーザ名とパスワードどうするか聞かれるから好きなの入れてね

- できあがり Let's Ubuntu !

# おわりに

- もうこんな手順いろんなところにすでにあるよね
- Qiitaリハビリで書いたんで許してや
- すごく平たく書いたのでもしかすると超初心者とかに役にたっとるかもしらんね
    - 役に立ったらいいね押しといてや。ちょっと嬉しい。
- リハビリ第2弾でWSLにvisualstudiocodeのリモート機能でつなぐやつ書く。。かも
    - vscodeのエディタでWSLのubuntuのファイル編集したりできるやつ、これ便利よ
Ionic Nativeをブラウザで動かす(mock)

* 公式(参考のリンク先)の通りなので、リンク先のメモとなります
  * v3で試しました

# 何？

* `ionic serve`してブラウザで動作させるときにIonic Native部分が動作しないので、mock化して動かす方法です

# やり方

1. 自作のmockを使う
1. Ionic Native Mocksを使う

* 具体例は以下を見ること
  * https://ionicframework.com/docs/v3/native/browser.html
  * https://blog.ionicframework.com/ionic-native-mocks/
  * https://github.com/chrisgriffith/ionic-native-mocks
RSpecを起動ようとしたら、「unknown command: Cannot call non W3C standard command while in W3C mode」と言われて怒られた


# 導入

以下の書籍を読みながら、RSpecについて学んでいます。

[現場で使える Ruby on Rails 5速習実践ガイド](https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&keywords=ruby+on+rails&qid=1561634313&s=gateway&sr=8-1)

写経しながら、RSpecでテストコードを書いて、いざはじめてのRSpecと思って、
ワクワクしながらコマンドを叩くと、以下のエラーが出た。

```error
Selenium::WebDriver::Error::UnknownCommandError:
       unknown command: Cannot call non W3C standard command while in W3C mode
```

Google Chromeとchromedriverのバージョンを最新の75にアップデートしたことで、W3CモードがデフォルトONになったみたい。


# 解決策

オプションに「w3c:false」を渡してやると、うまく解決が出来た。
自分の場合はオプションの設定方法が分からなくてハマったけど、何とかテストコードが動いて、
All Greenになった！

```ruby
RSpec.configure do |config|

  config.before(:each, type: :system) do
    # 修正前
    driven_by :selenium_chrome_headless

    # 修正後
    caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {"w3c" => false})
    driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400], options: { desired_capabilities: caps }
  end
```

# 参考にしたURL
* [Cannot call non W3C standard command while in W3C mode (Selenium::WebDriver::Error::UnknownCommandError) with Selenium ChromeDriver in Cucumber Ruby](https://stackoverflow.com/questions/56111529/cannot-call-non-w3c-standard-command-while-in-w3c-mode-seleniumwebdrivererr)
* [「Cannot call non W3C standard command while in W3C mode」を解決する](https://qiita.com/paranishian/items/17bd7a77dc953f8fbd63)
* [rspec-rails 3.7の新機能！System Specを使ってみた](https://qiita.com/jnchito/items/c7e6e7abf83598a6516d)
Visual Studio Code（SSH経由）でIBMi上のNode.jsファイルを編集・デバッグする

# 目的
Visual Studio Codeを使い、IBMi上のnode.jsファイルを編集・デバッグします。

# 検証環境
- ローカルPC（Windows10）
    - VSCode 1.35.1
- IBMi
    - Node.js 10.15.3
    - SSHで接続出来ている事

# ローカルPC側準備
- VSCodeからIBMiにSSH接続するための拡張機能(SSH FS)をインストールします。
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146069/028bec72-678c-f06a-e563-fe52af3d1b14.png)

- SSHの設定をします。
Ctrl+Shift+Pでコマンドパレットを開き、SSH FSと入力し候補を出します。
Create a SSH SF configurationを選択します。
Nameは適当な名前を入力し、Saveボタンを押します。
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146069/d2eb8889-8a17-c6a6-49c5-7147e72fa5ff.png)
画面が遷移しますので、SSH接続の設定をします。（私は鍵認証方式で接続しました）
設定が終わりましたら、SAVEボタンを押してください。

- SSHで接続します。
Ctrl+Shift+Pでコマンドパレットを開き、SSH FSと入力し候補を出します。
Connect as Workspace folderを選択します。
先ほど入力した設定が候補で出てきますので、クリックします。
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146069/e146d6e9-7d2e-9eab-f34d-26703a1de8bb.png)
接続が成功すると、以下のようにフォルダ／ファイルの一覧が表示されます。
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146069/85d98183-f772-fd53-68a0-1c7f875be0cf.png)
これだけでも素晴らしいですね。

# デバッグの方法
- 作業フォルダの作成
ここでの作業はVSCodeでは出来ないので、5250のQP2TERMかSSH接続したターミナルから作業を行います。（以下、ターミナル）
※検証のため、expressをインストールしました。

```Bash
mkdir debugtest
cd debugtest
npm init -y
npm install -save express
```
VSCodeに戻り、最新表示を押します。
![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146069/1061617f-7502-c4ef-1fb8-6ce86b8aff1f.png)

- デバッグ用ソースの準備を準備します。 

```server.js
const express = require("express");
const app = express();

app.get('/hello', (req, res) => {
    const message = 'Hello IBMi Node.js!!';

    res.send(message);
});

app.listen(8080);
```


- デバッグ用package.jsonの編集します。

XXX.XXX.XXX.XXXはIBMiのIPアドレスです。

```Bash
  "scripts": {
    "start": "node --inspect=xxx.xxx.xxx.xxx:9229 server.js"
  },
```

- デバッグ用の.vscode/launch.jsonの作成し、編集します。

メニューから「デバッグ」→「構成を開く」→「構成の選択」でnode.jsを選びます。
.vscode/launch.jsonファイルが作成されるので、以下のように編集します。

```Bash
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "デバッグの開始",
      "address": "XXX.XXX.XXX.XXX",
      "port": 9229
    }
  ]
}
```

- ターミナルからプログラムを起動します。

```Bash
npm start
```

Debugger listening on ws:XXX.XXX.XXX.XXX:9229・・・
とメッセージが表示されることを確認してください。


- VSCoodeからデバッグをとる。

メニューから「デバッグ」→「デバッグの開始」を選択します。

画面左下に、「読み込み済みスクリプト」が表示されますので、server.jsを選択します。

![01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146069/29ac71e2-9a57-daf3-3f86-0e8f4856333a.png)

ここから、ブレークポイントを置くとデバッグが出来るようになります。

![02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146069/c7f83439-610b-c89d-3847-82c4ccabd26a.png)

メモ：VSCode公式のRemote SSHでは繋がりませんでした・・・
docker-compose コンテナの停止、ネットワーク・名前付きボリューム・コンテナイメージ・未定義サービスコンテナを削除

コンテナの停止、ネットワーク・名前付きボリューム・コンテナイメージ・未定義サービスコンテナをまとめてスマートに削除できないかと3ヶ月くらい考えていたら良いオプションを発見しました。

## 神のコマンド

```shell
$ docker-compose down --volumes --rmi all --remove-orphans
Stopping docker-sample_web_1 ... done
Stopping docker-sample_app_1 ... done
Stopping docker-sample_db_1  ... done
Removing docker-sample_web_1 ... done
Removing docker-sample_app_1 ... done
Removing docker-sample_db_1  ... done
Removing network docker-sample_default
Removing volume docker-sample_db-store
Removing image docker-sample_app
Removing image nginx:1.17.0-alpine
Removing image mysql:8.0.16
```

`docker volume prune` や `docker volume ls` で探して `docker volume rm` で指定してがんばって削除しなくてよくなったので嬉しいです😊

## 付録

```shell
$ docker-compose down -h
Stops containers and removes containers, networks, volumes, and images
created by `up`.

By default, the only things removed are:

- Containers for services defined in the Compose file
- Networks defined in the `networks` section of the Compose file
- The default network, if one is used

Networks and volumes defined as `external` are never removed.

Usage: down [options]

Options:
    --rmi type              Remove images. Type must be one of:
                              'all': Remove all images used by any service.
                              'local': Remove only images that don't have a
                              custom tag set by the `image` field.
    -v, --volumes           Remove named volumes declared in the `volumes`
                            section of the Compose file and anonymous volumes
                            attached to containers.
    --remove-orphans        Remove containers for services not defined in the
                            Compose file
    -t, --timeout TIMEOUT   Specify a shutdown timeout in seconds.
                            (default: 10)
```
【swift】UIButtonのタイトルラベルに下線を付けた上で色を調整する方法

#実現したいこと
UIButtonのタイトルラベルに下線を付けた上で色を調整する


#経緯
下線を付ける方法を調べていたら

```let AttributedString = NSAttributedString(string: "text", attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue```
と書けば下線を弾けることが分かった。

しかし、色が青色になってしまう。

```button.setTitleColor(ColorManager().white(), for: .normal)```

と書いても色を変更できないため、ハマった。


#結論

```let AttributedString = NSAttributedString(string: "text", attributes: [.underlineStyle: NSUnderlineStyle.single.rawValue, NSAttributedString.Key.foregroundColor : UIColor.white])
        button.setAttributedTitle(AttributedString, for: .normal)```

と書けば良い。
CompletableFuture で Google Drive Rest APIを直列処理したい。

やぁ。また会ったね。
掲題の課題を解決すｒ・・・できんわハゲ！（2019/6/27時点）

結論を出すのに３日かかった。
CompletableFutureすげぇ便利なんだけど対応してねえんだよGoogleDriveRestAPI様はよ！

今日はソースコードありません。

CompletableFutureを使わずに、AsyncTaskを使います。
AsyncTaskは処理別（Download、Uploadなど）に分けてクラスを作ってください。
起動するときは、直列処理になるようにAsyncTaskに命じます。

```java:YourDriveServiceHelper.java
    public synchronized void register(Object param1,Object param2) {
        new GetFileIDTask(param1,param2).executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
    }
```
またな！

できるようになったよ！とかあったらコメントください。
僕はTask（特段の理由がない限りThreadで並列処理すること）が嫌いです。
スパゲッティかよと思う。お米食べろ！！！
ここがムズいよ並行処理

# 【概要】
この記事は [DOG](https://techplay.jp/event/735792) という初心者向けのGo言語の勉強会に用いた資料をQiita版として落とし込んだものです。
なので初心者向けの内容となっておりますので、あしからず。

またDOGの時の資料は[こちら](https://www.slideshare.net/KiyoshiSuzuki5/too-difficult-concurrent-processing)になります。

# 【ゴルーチン】

Go言語にはゴルーチンという機能があり、ゴルーチンを用いることで関数・メソッド・クロージャを並行処理として呼び出すことが可能です。ゴルーチンを使う場合は `go` キーワードを用います。

* 関数の場合

```go
go logging("Hello, %s\n", name)
```

* メソッドの場合

```go
go logger.Printf("Hello, %s\n", name)
```

* クロージャの場合

```go
go func() {
	log.Printf("Hello, %s\n", name)
}()
```

# 【並行処理の実行順番】
## - 問題
唐突ですが問題です。以下のプログラムを実行すると何が出力されるでしょうか？

```go
func main() {
	var data int
	go func() {
		data++
	}()
	if data == 0 {
		fmt.Printf("%v\n", data)
	}
}
```
選択肢）　A. 0　　B. 1　　C. 何も出力されない

答えは、「時と場合による」でした。並行処理では実行順番の保証がないためdata変数にアクセスする順番が変わることがあります。それぞれの結果の場合の実行順番は以下の通りです。

* 0と出力される場合
 1. `if data == 0`
 2. `fmt.Printf("%v\n", data)`
 3. `data++`

* 1と出力される場合
 1. `if data == 0`
 2. `data++`
 3. `fmt.Printf("%v\n", data)`

* 何も出力されない場合
 1. `data++`
 2. `if data == 0`

## - 競合
このように順番が保証されていない状態を競合状態、特に変数に対する競合をデータ競合と言います。
並行処理に慣れていないエンジニアからするとプログラムは上から順番に実行されるという先入観があるため、知らず知らずに競合が発生するプログラムを実装し、バグを生み出しかねません。

# 【並行処理における実行順番の保証】
## - スリープによる順番保証
唐突ですが再び問題です。以下のプログラムを実行すると何が出力されるでしょうか？

```go
func main() {
	var data int
	go func() {
		time.Sleep(1 * time.Second) // 1秒間スリープする
		data++
	}()
	if data == 0 {
		fmt.Printf("%v\n", data)
	}
}
```
選択肢）　A. 0　　B. 1　　C. 何も出力されない

答えは、「0が出力されやすくなった」です。`data++`の前で1秒間スリープするのだから、絶対に0が表示されるでしょ！と思えるかもしれませんが、何らかの要因により `if data == 0` の比較処理に1秒以上要してしまった場合は何も出力されません。そんなことほとんど起きませんが、確実に起きないとは言えないためスリープでは順番の保証が行えず、あくまで順番が保たれやすくなっただけです。
## - アトミック性
他のスレッドには割り込ませずに、今行なっている変更操作が確実に終わった後に実行される性質、言い換えるならばこれ以上処理を分解できない性質をアトミック性と言います。アトミック性はスレッドセーフの実現に重要な要素となります。

例えば、 `i++` はアトミックでしょうか？
答えは、「アトミックではない」です。

`i++`は参照、計算、代入の3つに分解することが可能です。
参照している途中、計算している途中、代入している途中に他のスレッドからiを参照されるといったことはありませんが、参照してから計算するまでの間に他のスレッドからiを参照されることはあり得ます。

## - sync.Mutex
`i++` はアトミックではないと説明しましたが、syncパッケージのMutexを使うことでアトミックとすることが可能です。
Mutexはロックされたら、アンロックされるまで他の処理にロックを渡さないという機能です。
以下の例をご覧ください。

```go
func main() {
	var data int
	var mu sync.Mutex
	go func() {
		mu.Lock()
		data++
		mu.Unlock()
	}()
	mu.Lock()
	if data == 0 {
		fmt.Printf("%v\n", data)
	}
	mu.Unlock()
}
```

Mutexがロックしているため、 `data++` をしている途中に `if data == 0` が行われるといったことは無くなりました。
これで順番を保証することができました。めでたしめでたし。
と言いたいのですが、まだ保証しきれていません。`data++` が先に実行されるか、 `if data == 0` が先に実行されるかは保証されていないため、出力結果は「0」と「何も出力されない」の２通りあります。

# 【考察】
```go
func main() {
	var data int
	go func() {
		data++
	}()
	if data == 0 {
		fmt.Printf("%v\n", data)
	}
}
```

今回は紹介していませんがsyncパッケージによりMutexなどの同期処理が提供されています。が、そもそもこのプログラムを並行処理させる必要はありますでしょうか？
流石に今回の例は極端ではございますが、並行処理で実行すべき箇所、そうでない箇所を見極める能力が問われてくるのではないでしょうか？

# 【ここがムズいよ並行処理】

* 副作用がある場合、順番を保証しないとバグの温床となる
* syncパッケージを活用してアトミック性を意識する必要がある
* 並行処理で実装すべきか見極める必要がある
AndroidX関連の変更によるReact Native Androidのビルドエラーを回避した

# 経緯
2019年6月17日にあるアプリをリリースしたですが、リリースビルドしたのは2019年6月14日だったと記憶しています。

こちらに記載の通り、AndroidX関連の変更があり、本日ビルドしてみたらエラーが発生してビルドできなくなってしまいました。
https://developers.google.com/android/guides/releases

> This release is a MAJOR version update and breaking change.
Migration from Android Support Libraries to Jetpack (AndroidX) Libraries. Libraries will not work unless you make the following changes in your app:


# 対応したこと
結論だけ書きます。

## jetifier
jetifierは、Supportライブラリ等々をandroidxに対応してくれるツールです。
StackOverflowで見つけました。

```
yarn add jetifier
npx jetify
```

## AndroidXを使うことを明記
android/gradle.properties

```
android.useAndroidX=true
android.enableJetifier=true
```

## splash

これだけエラーが残ったので、修正

```
- import android.support.v7.app.AppCompatActivity;
+ import androidx.appcompat.app.AppCompatActivity;
```

以上
Go言語Slackライブラリ(nlopes)のRTM.SendMessageを使ってハマった話

# はじめに
この記事はGo言語のSlackライブラリを用いてBotでメッセージを送信する方向けです。
使用ライブラリ nlopes/slack バージョン 0.5.0

## メッセージ送信に不具合が？
Botは落ちないのにメッセージが送られていないことが今までに何度かあり、気になって調べてみたところ
日本語文字数が1334以上のメッセージを送信しようとする際に何もなかったようにメッセージが送信されなくなる事が発覚。
（ちなみにアルファベットだと4000文字でもしっかり発話してくれる🤔）
実際に自分のSlackアカウントで試したところ、4000文字までは日本語でも問題なく投稿できたので、Bot側に問題がありそうです。

最終的には解消できたのですが、いくつか罠があったので似たような問題で躓かないようにメモ書きとして残しておきます。

### その１
ライブラリ側のメッセージ送信時の文字数判定が `len(string) > 4000` という条件式になっていた
つまり、文字数ではなくバイト数で判定するというアレなことになっています

よくよく最新のライブラリを見ると修正されていた！
https://github.com/nlopes/slack/commit/9e37c90c58901e134c8bf22e97accc72eeab171e#diff-bdeefded79c795ae396d7cde5c980706
→Slackライブラリを最新(0.5.0)にアップデートにすることで解消。

ここで終わらなかった…

### その２
ライブラリを最新にした後、同様にbotから日本語4000字送信させようとすると今度はログにエラーが発生
`Error: websocket: close 1006 (abnormal closure): unexpected EOF`

なんだこれ
調べてみたところ、[未解決状態のIssue](https://github.com/nlopes/slack/issues/268)に辿りつきました。

そして、Issue上で議論された解決策は
>rtmのwebsocket関連は、標準のSendMessageがサポートしていることすべてをサポートしているわけではない
>slack.RTM.SendMessageではなく標準のSendMessageであるslack.Client.PostMessageに変更してはどうか

という内容。

確かに今は `RTM.SendMessage` を使って送信している…
実際に `Client.PostMessage` に変更したところ、4000文字の日本語を送信することに成功

```go:変更前(RTM.SendMessage)
func SendMessage(rtm *slack.RTM, channel, text string) {
        msg := rtm.NewOutgoingMessage(text, channel)
        rtm.SendMessage(msg)
}
```

```go:変更後(Client.SendMessage)
func SendMessage(client *slack.Client, channel, text string) {
        params := slack.PostMessageParameters {
                Markdown:    true,
                EscapeText:  true,
                AsUser:      true,
                UnfurlMedia: true,
                UnfurlLinks: true,
        }
        opt1 := slack.MsgOptionPostMessageParameters(params)
        opt2 := slack.MsgOptionText(text, false)

        client.PostMessage(channel, opt1, opt2)
}
```

# まとめ
Go言語のライブラリを使用してSlackにメッセージを送る手段として
・`slack.Client.PostMessage`
・`slack.RTM.SendMessage`
の２通りありますが

大量の文字列送信を想定する場合は `slack.RTM.SendMessage` ではなく `slack.Client.PostMessage` を使うのが無難のようです
【Java】Collectors.collectingAndThenを使う

# Collectors.collectingAndThenとは
`Collect`後の値を処理した値を返す`Collector`です。

## 使い方
以下のような状況があったとします。

```java:リストに一時的に格納→処理を呼び出す
List<Integer> mappedList = /* Stream */
    ./* mapなど、stream処理 */
    .collect(Collectors.toList());

return hogeFunc(mappedList);
```

このような処理は、`Collectors.collectingAndThen`を使うことで以下のように書けます。

```java:Collectors.collectingAndThenを使った形
return /* Stream */
  ./* mapなど、stream処理 */
  .collect(
      Collectors.collectingAndThen(
          Collectors.toList(),
          mappedList -> hogeFunc(mappedList) // mappedListを使った処理
      )
  );
```

# 何が嬉しいのか？
## 一時変数が減る
Collect結果を一時変数に一々格納する必要が無いので、一時変数が減らせます。
一時変数を置くことは可読性やコード品質の低下に繋がるので、それが減るのは嬉しいです。

## 直渡しより可読性が上がる
一番初めに挙げたコード例は、以下のように書くこともできます。

```java:直で関数に引数を渡す形式で書いた場合
return hogeFunc(
    /* Stream */
        ./* mapなど、stream処理 */
        .collect(Collectors.toList())
);
```

しかし、これでは特に関数がネストしていく場合の可読性が低い[^hosoku]です。
また、これだとデバッガで引っ掛けて中身を読めないという欠点が有ります。

[^hosoku]: この場面に関しては、パイプライン演算子が有れば`Collectors.collectingAndThen`を使う必要も無いんですが……。

# まとめ
`Collectors.collectingAndThen`、使っていきましょう。
google search consoleで、「データを処理しています。数日後にもう一度ご確認ください」から変わらない時の対処法

###解決策
「URL検査ツール」を使うといいです。

Google Search Consoleにて、
「URL検査ツール」を選択して、検索画面に自分のページのURLを入れてください。
指示にしたがって進めると登録できます。

参考：https://support.google.com/webmasters/answer/7474347?hl=ja

#####愚痴
fetch as google が置き換えられてちょっと分かりづらくなった気がする……
[SWIFT4]お絵描きペイントペンの色変え方法

swiftの学習を始めてペイントツールを作成しているのですが、

ペンの色を変える事ができません。

    // 描画処理
    func drawLine(path:UIBezierPath){
        UIGraphicsBeginImageContext(canvas.frame.size)
        if let image = self.lastDrawImage {
            image.draw(at: CGPoint.zero)
        }
        let lineColor = UIColor.blue // blueをデフォルトに設定
        lineColor.setStroke()
        path.stroke()
        self.canvas.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    }

最初の指定はできるのですが、色変更ボタンを設置してblackやredに変更したいのです。

描画はできています。
ボタンで別Viewを表示し、そこで色を選択して前の画面に戻ると
ペンの色が選択した状態にするのが目標です。

ご教授いただけると助かります
日々の進捗ノート_言語処理100本ノック02

# 0２.「パトカー」＋「タクシー」＝「パタトクカシーー」
>「パトカー」＋「タクシー」の文字を先頭から交互に連結して文字列「パタトクカシーー」を得よ．

```gengo02.py
pat = "パトカー"
tax = "タクシー"
res = ""
for (i, j) in zip(pat, tax):
    res += i + j
print(res)
```
####結果
`パタトクカシーー`

####備忘録
・zapじゃなくてzip
著者を短く(et al.)表示してreferencesを作りたい(BibLaTeX, 物理屋さん)

#1.はじめに
この記事の多くは以下の記事から引用させて頂いております。
> BibLaTeXでAPS（American Physical Society）の論文のスタイルでBibliographyを生成する方法
> https://qiita.com/convolm/items/8a1f2a3028df5bbdea16

#2.Referencesにおける著者を(et al.)表記したい
$\LaTeX$で参考文献を出力するためのツールとして、```BibTeX```を紹介しているサイトをインターネット上で多く目にします。しかし、出力スタイルをいじる方法が自分にとって超難しくすぐキライになりました。(bstをいじるのが無理)
そんなときに上の記事を発見し、```biblatex-phys```パッケージを使えばAPS(American Physics Society)のスタイルで参考文献リストを出力できることが分かったのでやってみましたが、引用論文の著者が複数いる場合にはめちゃくちゃ長ったらしく出力されてしまいます。
```BibTeX```も```BibLaTeX```も自分で作成した文献データベース（```reference.bib```）を参照します。著者が7名いる"hogehoge"という論文があったとしたら、```reference.bib```にはこんな記述があるでしょう。

```reference.bib
@article{hogehoge}
...
author = {hoge, piyo, huga, moge, moga, gera, poge}
...
```

このままでは7人全員が出力されてしまうので、紙の枚数に制限がある場合（学会のAbstractなど）はつらいです。そこでこんなことをします。

```reference.bib
@article{hogehoge}
...
%author = {hoge, piyo, huga, moge, moga, gera, poge}
author = {hoge and others}
...
```

著者が記述されている行をコメントアウトし、```piyo```氏以下を```and others```に書き換えた```author```を新たに記述します。そうすると、

```
hoge et al., Hoge. Rev. A 12, 123456 (2019).
```
のように、第二著者以降を et al. と表記したものが自動で出力されます。
Minecraft Skript 応用編 Part.4 ゲームモード変更コマンド＆ページ作成に関して・・・

#ゲームモード変更コマンド
従来、ゲームモード`/gamemode creative @p`とすればゲームモードを変更できます。これは省略も可能で`/gamemode c`などでも変更できます。ですが、`Minecraft1.13`から省略ができなくなったことから困った人もいるのではないでしょうか？

なので、プレイヤー指定はないけど簡単にゲームモードを変更できるようにしてみましょう。

#コード
```javascript:gamemode.sk
command /gm [<text>]:
    if arg-1 is set:
        if arg-1 is "creative" or "c":
            set player's gamemode to creative
        if arg-1 is "survival" or "s":
            set player's gamemode to survival
        if arg-1 is "spectator" or "sp":
            set player's gamemode to spectator
        if arg-1 is "adventure" or "a":
            set player's gamemode to creative
    if arg-1 is not set:
        if player's gamemode is creative:
            set player's gamemode to adventure
            stop
        if player's gamemode is adventure:
            set player's gamemode to survival
            stop
        if player's gamemode is survival:
            set player's gamemode to spectator
            stop
        if player's gamemode is spectator:
            set player's gamemode to creative
            stop
```
#解説
まずコマンド生成ですね。
`/gm <text>`でコマンドを実行できます。`<text>`というargumentは`[]`で囲まれているので`/gm`か`/gm <text>`で実行可能です。そして`/gm`と`/gm <text>`では動作が違います。とはいえ、解説もなにもないので簡単に説明しますと`<text>`部分に`creative`か`c`、`adventure`か`a`、`survival`か`s`、`spectator`か`sp`で各ゲームモードに変更できます。その機構を**if文**で書いています。
もし`<text>`部分を書かなかった場合はその時のプレイヤーのゲームモード（`player's gamemode）によってゲームモードを変更します。

#最後に・・・
最近解説が雑くないか？なんて思う人いるのではないでしょうか？
ごめんなさい。なんか、いい解説が思いついたら書き直します。

#ページ作成に関して・・・
こんなもの作ってほしいなんてものがあったら言ってくれるとありがたいです。
ページ作成にあたってねたになりますので・・・

次は[コチラ](https://qiita.com/meoto2408/items/ba5ff3aa2bdb1127f37c)

前は[コチラ](https://qiita.com/meoto2408/items/09688a46aeb4cefe2985)
machineryのDelayed Taskをテストで即時実行する

## 問題
Goのジョブキューである[machinery](https://github.com/RichardKnop/machinery)を使っていて、
Delayed Taskによりタイマーで発動するような処理があるとき、テストでは即時に実行させたい。

machineryには[GetPendingTasks](https://github.com/RichardKnop/machinery#get-pending-tasks)というインターフェースがあり、これでTaskを取得することができると思ったら、以下のIssueにあるように現状でDelayed Taskは実装的にGetPendingTasksで取得できないらしい。

GetPendingTasks does not return tasks having ETA · Issue #342 · RichardKnop/machinery
https://github.com/RichardKnop/machinery/issues/342

しょうがないのでgoのテストでタイムトラベルするときと同様のパターンで、
テストのときはETAがnilになるようにする
（もっとスジの良いやり方があったら教えてください！）

## 対処

### 1. ETAをフィルターする関数を定義

```go
import (
	"time"
)

var FilterETAFunc = FilterETA

func FilterETA(eta *time.Time) *time.Time {
	return eta
}

func DisableETA() {
	FilterETAFunc = func(eta *time.Time) *time.Time {
		return nil
	}
}
```

### 2. TaskにETAを指定するときに必ずフィルタをかます

```go
import (
  "github.com/RichardKnop/machinery/v1/tasks"
)

eta := time.Now().UTC().Add(time.Second * 5)
signature := &tasks.Signature{
  Name: "add",
  Args: []tasks.Arg{
    {
      Type:  "int64",
      Value: 1,
    },
    {
      Type:  "int64",
      Value: 1,
    },
  },
  ETA: FilterETAFunc(&eta)
}

asyncResult, err := server.SendTask(signature)
```

### 3. テストからはDisableETAを呼ぶ

```go:some_test.go
func init() {
	utils.DisableETA()
}
```

### 4. Taskを実行する

GetPendingTasksしてworker.Processで実行する

```go
func ProcessJobTasks(server *machinery.Server) error {
	worker := server.NewWorker("for_test", 1)
	tasks, err := server.GetBroker().GetPendingTasks(server.GetConfig().DefaultQueue)
	if err != nil {
		return err
	}
	for _, task := range tasks {
		err := worker.Process(task)
		if err != nil {
			return err
		}
	}
	return nil
}
```
Outsystemsにて、不要なモジュールを消す時に確認すること

#はじめに

ある日、Service Studioを開いた私。
社内で開発するアプリ数も増えてきて、使ってなさそうなモジュールが増えてきたからモジュール消しちゃおってなりました。


Service Studioで依存関係も確認したし、消しちゃえ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/cf34633e-1881-54ae-8880-be8f181a633e.png)



・・・・次の日。
>他のチームメンバー

必要なはずのモジュールの依存関係でエラーがでてて、うまくデプロイできないです。

>私

そんなはずはない、Service Studioでアラートのポップアップがでなかったし！！


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/6fb37ad9-9311-dc92-9fea-849e5c6a28b1.png)



こんな状況になってしまったので、ここに記します。


#想定読者
いらないモジュールいっぱいあるなー、だけど消すの怖いなーって方

#事前準備
特になし

#確認ポイント

##■たとえばCSVUtilを削除したいケース

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/85ccb3fe-5e8d-b03b-0bc9-227ebdeccdd6.png)

Service Studio上ではアラートがでない

![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/b87bf2aa-77f7-0cf8-2381-65ed7acfd02a.jpeg)
もし依存関係があればこんな感じにエラーでます


だがしかし、
依存関係が検知されない。。。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/6631311f-a3f8-18ac-c560-22f5bd01789b.png)


##■そうならないために

###①Discoveryを使う
アプリ全体の依存関係を可視化できるようになるForgeのモジュールがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/761f0324-f570-aa97-97ed-ccb8265f9131.png)

https://www.outsystems.com/forge/component-overview/409/discovery

具体的には、DiscoveryをPublishした後にブラウザ上で表示すると、
モジュール間のConsumerとProducer関係がこんな感じで可視化できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/7d4e8a58-9ee7-d3ca-a5d2-d8b8f8554897.png)

###②Service Centerで目で確認する
CSVUtilのeSpecesタブをチェックすると、依存関係があるものが表示されます。
これを一個一個チェックしていく手法です。

![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/1b4144ee-8070-5df7-147f-f9f65325a588.jpeg)



#終わりに

皆さんもいらないモジュールを消す時は慎重に！!



そういえば昨日Outsystemsのユーザーカンファレンスに参加させていただきました。

Outsystemsの各社の事例の紹介や、実際にユーザー様と情報交換などをできて楽しかったです。
下記、Outsystems様のカステラとBluememe様のお茶をいただきました。
来年も是非参加したいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/64761d1a-4e48-9f9b-c406-b804f2514dba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/5fb17c59-ff47-6578-da64-c63b314335ec.png)
Elasticsearch aliasを用いた運用

# 背景

社内では既にElasticsearchを取り入れていましたが、運用においていくつか不便な点がありました。

## 既存index運用方法

- ある用途に特化したindexを作成
- 初期データをインポート
- 追加発生 => インポート
- 更新発生 => インポート
- 削除発生 => 削除タスクの生成と実行

### 問題点

更新する場合は問題がありませんが、インポート対象が削除されていた場合は別途削除する為に削除リクエストをElasticsearchに送信する必要があります。

そのために発生したのが下記のようなもの。

* 削除条件が増えるたびに専用の削除用rakeタスクができた。
* インポートしてから削除するといった運用手順が生まれる。
* 削除用rakeタスクのメンテ忘れによる、必要データが消えてしまう事件発生。
* 不要なデータが残り続ける。

またindexの定義を更新または刷新したい時にAPI側はindex名を直指定しているため、容易に切り替えたり更新することができません。

## 新規index運用方法

新規運用方法といっても大したものではないですが、既存の問題を解決する為に **alias** を参照する用に変更して、裏に紐づくindexを切り替えるという方法を導入しました。

これにより、データを刷新したものに切り替えができるため削除用のタスクが不要になり、indexの定義更新等も容易になります。

### 例

下記を一つのタスクとすることで、シンプルな運用とする。

1. index作成
2. データのインポート
3. alias切替
4. 旧indexの削除

※更新の場合はインポートのみを実行

[elastic/elasticsearch-ruby](https://github.com/elastic/elasticsearch-ruby)を利用してます。
※例なので、省略などを行なっておりそのまま実行はできません。

```ruby
  def create
    # indexの定義を読み込む
    json = open(file_path) { |io| JSON.load(io) }

    # suffixにタイムスタンプを設定
    timestamp = Time.now.strftime('%Y%m%d%H%M%S')
    index_name = "#{alias_name}_#{timestamp}"
    
    # indexを作成
    client.indices.create index: index_name, body: json

    # 必要なデータのインポート
    client.bulk body: data

    # alias切り替え
    switch_alias(index: index_name)
  end

  def switch_alias(index:)
    # aliasに紐づいた古いindexを取得
    old_indices = client.indices.get_alias(name: alias_name).keys

    # alias削除リクエスト作成
    for_remove = old_indices.map { |old_index| { remove: { index: old_index, alias: alias_name } } }

    # alias追加リクエストを追加
    actions = for_remove + [{ add: { index: index, alias: alias_name } }]

    # リクエスト実行
    client.indices.update_aliases body: { actions: actions }

    # aliasに紐づいた古いindexを削除
    client.indices.delete index: old_indices
  end
```
npm startしてもエラーが出る問題

#今回のエラー
React Reduxの環境構築で躓きました
全てインストール出来たと思い、意気揚々とコマンドを打つ:sunglasses:

```$ npm start```

すると、以下のエラーコードが出てきて全く動きません:thinking:

*There might be a problem with the project dependency tree.*...以下略
<img width="642" alt="スクリーンショット 2019-06-26 11.38.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447788/04a390f6-d55e-8738-e4d3-2e32ca9fd266.png">



#反省点
どの言語も共通で、エラー文をよく読むこと
画像内にあるオレンジ色の番号通りに進めて行けば無事解決しました:ok_hand:
一応下に書き記しておきます

```
  1. Delete package-lock.json (not package.json!) and/or yarn.lock in your project folder.

  2. Delete node_modules in your project folder.

  3. Remove "webpack" from dependencies and/or devDependencies in the package.json file in your project folder.

  4. Run npm install or yarn, depending on the package manager you use.

In most cases, this should be enough to fix the problem.
If this has not helped, there are a few other things you can try:

  5. If you used npm, install yarn (http://yarnpkg.com/) and repeat the above steps with it instead.
     This may help because npm has known issues with package hoisting which may get resolved in future versions.

  6. Check if /Users/home/node_modules/webpack is outside your project directory.
     For example, you might have accidentally installed something in your home folder.

  7. Try running npm ls webpack in your project folder.
     This will tell you which other package (apart from the expected react-scripts) installed webpack.
```



#参考元

[npm startで怒られたときの話](https://note.mu/harape/n/nd9e53fb6f322)
Flutter iOS実機での開発で "Lost connection to device" が出る場合の対処

Flutter でiOSの実機での開発起動（flutter run）しようとすると、アプリが起動した直後に接続が切れてしまうことがあります。以下のようなエラーが出ます。

```
An Observatory debugger and profiler on My iPhone is available at: http://127.0.0.1:1025/
For a more detailed help message, press "h". To detach, press "d"; to quit, press "q".
Service protocol connection 
Lost connection to device.
DevFS: Deleting filesystem on the device (file:///private/var/mobile/Containers/Data/Application/.../)
Sending to VM service: _deleteDevFS({fsName: myapp})
Ignored error while cleaning up DevFS: TimeoutException after 0:00:00.250000: Future not completed
```

接続が切れると、ホットリロードができなくなってしまいます。

----

これは iOS の開発に使っている libusbmuxd というツールのバグのようです。

- https://github.com/libimobiledevice/libusbmuxd/issues/71

このバグが修正されるまでは、特定のバージョンの libusbmuxd を使う必要があり、Flutterの [Issue #35102 のコメント](https://github.com/flutter/flutter/issues/35102#issuecomment-505952116) で以下のようなワークアラウンドが紹介されていました。

```
brew uninstall --ignore-dependencies usbmuxd libimobiledevice ideviceinstaller
brew tap flutter/flutter https://flutter-mirrors.googlesource.com/homebrew-flutter
brew install --HEAD usbmuxd-flutter libimobiledevice-flutter ideviceinstaller-flutter
```

上記のような感じで usbmuxd libimobiledevice ideviceinstaller の３つを入れ直すと動くようになると思います。
日々の進捗ノート_言語処理100本ノック01

# 0１.「パタトクカシーー」
>「パタトクカシーー」という文字列の1,3,5,7文字目を取り出して連結した文字列を得よ．

```gengo01.py
p = "パタトクカシーー"
print(p[0::2])
```
####結果
`パトカー`

####備忘録
・パタトクカシーーなんて言葉はない
Jestの結果がおかしくなったら--clearCacheしよう。

ある日の出来事...

.vueでレイアウトちょっと変えただけだけどいちおうテストしとこうっと。

やぁ！

```sh
yarn run test:unit
```

結果はどうかな？

<img width="480" alt="pre.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51116/bcdd66e0-2835-53ce-baf4-b1253e92f135.png">


...なんかめちゃめちゃやんけ！！

Uncovered Lineの表示もソースコードと全然合っていません。

こんな時は慌てず騒がず（騒いだけど...）キャッシュをクリアしましょう。

うりゃ〜！

```sh
yarn run test:unit --clearCache
$ vue-cli-service test:unit --clearCache
Cleared /var/folders/2l/gq85xz3j06x5y3rzsmlnq8vr00172j/T/jest_uvl
```

みたいになります。

再びテストします！やぁ！！

```sh
yarn run test:unit
```

<img width="480" alt="aft.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51116/0a50f7e9-a8fa-9551-6ef4-0d58b324d5b3.png">


ばっちりですね。
WebRTC技術検証メモ

# WebRTC技術検証メモ
ビデオチャット機能を実装する必要が生じてWebRTCについて色々と調べているのでその記録

## そもそもWebRTCとは？
ブラウザやモバイルアプリ同士でP2P通信を行うための規格。
モダンブラウザなら標準で搭載されており、javascriptでAPIを叩くことで利用できる。
(かつてはFlashやSilverLightなどのサードパーティ製ライブラリが必要だったのと対照的)

ビデオチャットに利用されることが多いが、厳密にはWebRTCはP2P通信の規格のため単なるデータ通信にも利用できる。(ビデオチャットはメディア系のAPIで取得した映像や音声をWebRTCで流している)

P2P通信であるため、原則的に通信されるデータを捌くサーバーは必要ない。(例外に関しては後述)

少し古い資料だとiOSが未対応という記述もあるようだが、現在は問題ない模様。

## WebRTCに必要なもの

### シグナリング
P2P通信のため、通信に関わるクライアント同士がお互いの情報を交換しなければならない。
この処理がシグナリング。
通常はシグナリングサーバーを用意してWebSocket接続を通して行うが、特にシグナリングの方法は決まっていないので方法は何でもいい。
実際サンプルでは最低限やり取りしなければいけない情報(SDP)を手動でコピペして動かしているものも結構ある。
一度つないでしまえば特に必要はない上、重いデータのやり取りもないので、
シグナリングサーバーにはそれほどのサーバーパワーは必要ない。

### NAT問題への対応
P2P通信を行うためにはお互いに疎通するIPアドレスとポート番号が必要である。
お互いが同じネットワーク上にいたり、グローバルIPアドレスを単独で保持していれば問題ないものの、
実際にはお互いに別ネットワーク上におり、ブラウザやクライアントプログラムが認識しているプライベートIPアドレスと(ipconfigで見えるやつ)、外から見えるIPアドレス([こういう類のサービス](https://www.cman.jp/network/support/go_access.cgi)で確認できる奴)が異なっていることは多い。
(ネットワークアドレス変換(NAT)が行われている)

ブラウザは自分から見えるIPアドレスしかわからないので何とかこの部分を解決して通信経路を確保しなければならない。

#### STUNを使う
外から自分がどのようなグローバルIPとポートで見えているのかを確認するプロトコル。
STUNサーバーに問合せを行うことで確認ができる。
処理自体は非常に軽いので、STUNサーバーもほとんど負担はなく、
[googleなどが一般に公開しているもの](https://gist.github.com/zziuni/3741933)も利用できる。


#### TURNを使う
しかし、STUNではNATで割り振られたポートを利用するため、
Firewallで利用可能なポートをしっかりと制御している場合弾かれてしまうことがある。
このような場合には外部に中継用のサーバーを建てて、そこにアクセスするという形をとるしなかなくなる。これがTURNサーバーである。

TURNを利用するとP2P通信ではなくなり、すべてのデータがTURNサーバーを通過することになる。
つまり、TURNサーバーには強力な通信能力が要求される。
IaaSに[coturn](https://github.com/coturn/coturn)などを自分で建てるにせよ、SaaSを利用するにせよ通信量に応じた従量課金になる場合が多いのでコストについては注意が必要。
なるべく他の通信手段を使い、どうしようもない場合のみTURNを使うべきである。(あるいはSTUNで済まない場合は諦める)
ただし、幸いにして、ここの制御は開発者が行わなくても後述のICEという仕組みでSTUN側を優先的に選んでくれるようになっている。

なお、TURNが必要になるのはサービスの形態と利用するネットワーク(BかCか？Cでもモバイルか家庭内ネットワーク向けか？）によって異なるが、概ね1～20％の範囲の模様。
[参考](https://webrtc.ecl.ntt.com/pricing.html#利用モデル)

#### ICE
Interactive Connectivity Establishmentの略。
P2P間での直接通信やSTUN、TURNなど複数の通信方法の中から最適なものを選ぶ仕組み。
基本的にはブラウザが勝手にやってくれるので、利用したいSTUNサーバーやTURNサーバーの情報を設定値として渡してやればよい。

## API等
以前は必要なAPIにベンダープレフィクスがついていたものが多く、[peerjs](https://peerjs.com)などが求められていたようだが、
最近は標準の新APIに置き換わっているので不要。WebRTCが盛り上がっていた2015～2016年前後の資料は旧APIで書かれているものが多いので適宜読みかえる必要アリ。


## サービス等
前述のシグナリングサーバーやSTUN,TURNサーバーなどとsdk一式を提供してくれるサービスもある。
国内だと[SkyWay](https://webrtc.ecl.ntt.com)世界的には[tokbox](https://tokbox.com/developer/)など。
高い接続成功率を維持したいものの、TURNサーバーなどのインフラ管理に割く労力に不安がある場合はこれらの有償サービスに頼るのが無難か。

## まとめ
* APIはかなり整備されているので、コーディングは楽
* NAT越え問題だけは考えておく必要アリ。(TURNはどれだけ必要か、どう用意するのか)
知識ゼロから学ぶ ソフトウェアテスト(3章 ブラックボックステスト③ ディシジョンテーブル)

知識整理のために投稿しています。
本は `知識ゼロから学ぶ ソフトウェアテスト[改訂版]`です。
テストってなかなか書けない。

## ディシジョンテーブル

- 複雑な入出力に対応する

(例) 
入力A：1~999まで入力可能
入力B：同上
入力C：A*B

|状態 |ルール1|ルール2|ルール3|ルール4|
|:--:|:--:|:--:|:--:|:--:|
|入力A=正しい | T | T | F | F |
|入力B=正しい | T | F | T | F |
|動作：計算値出力 | ✔️ |  |  |  |
|動作：入力エラー出力 |  | ✔️ | ✔️ | ✔️ |

**役立つとき**

- 項目が少なくかつ複雑な動きをするソフトウェア
- 全体のテストケースの状態を一目で確認でき、抜け漏れを発見しやすくなる

**向かないとき**

- 1000を超えるような大量の項目には使えない
- 現実的でない