OmniAICreator/Qiita-1.07M huggingface dataset:
alpakka-kafkaのTipsメモ

alpakka-kafkaを使った際のメモ書き、得られた知見を貯めとく場所

## DrainingControlの設定あれこれ

こっそり[ドキュメントにノートされてる](https://doc.akka.io/docs/alpakka-kafka/current/consumer.html#draining-control)けど、DrainingControlを用いることでシャットダウン時のDelayの設定は不要になる。なのできっちり設定しておいた方が幸せ。

```scala
val drainingControl =
  Consumer
    .committableSource(consumerSettings.withStopTimeout(Duration.Zero), Subscriptions.topics(topic))
```

## DrainingControlとRestartSourceの組み合わせについて

[公式の例](https://doc.akka.io/docs/alpakka-kafka/current/consumer.html#draining-control)はCommittableSourceでのサンプルが記述してあるんですが、RestartSourcemについての言及はありません
テストコードを覗くと下記のようなコードが見つかります

Refs: https://github.com/akka/alpakka-kafka/blob/ed97467ab1be70db10584ae57f35811429f7f76a/tests/src/test/scala/docs/scaladsl/ConsumerExample.scala#L509-L534


```scala
  it should "work with committable source" in assertAllStagesStopped {
    val consumerSettings = consumerDefaults.withGroupId(createGroupId())
    val committerSettings = committerDefaults
    val topic = createTopic()
    val partitionNumber = 0
    val control = new AtomicReference[Consumer.Control](Consumer.NoopControl)

    val result = RestartSource
      .onFailuresWithBackoff(
        minBackoff = 3.seconds,
        maxBackoff = 30.seconds,
        randomFactor = 0.2
      ) { () =>
        val subscription = Subscriptions.assignment(new TopicPartition(topic, partitionNumber))
        Consumer
          .committableSource(consumerSettings, subscription)
          .mapMaterializedValue(c => control.set(c))
          .via(businessFlow)
          .map(_.committableOffset)
          .via(Committer.flow(committerSettings))
      }
      .runWith(Sink.ignore)
    awaitProduce(produce(topic, 1 to 10))
    // when shut down is desired
    val drainingControl = DrainingControl(Tuple2(control.get(), result))
    drainingControl.drainAndShutdown().futureValue shouldBe Done
  }
```

ここでは `RestartSource.onFailuresWithBackoff` を使っていますが、実は `RestartSource.withBackoff` を使うと `drainAndShutdown` をコールしてもいつまでもConsumeが止まらない状態になってしまいます。(2019/12/08現在)
そのため、サンプルに合わせて `RestartSource.onFailuresWithBackoff` を用いる必要があります。元々、`RestartSource.withBackoff`を使っていた人向けの対策は分からず…
Lightning Web Components Playground を試してみよう

今年もアドベントカレンダーの季節がやってきました。

というわけで、~~ネタ切れしてたので~~個人的にちょっと試したものを載せたいと思います。

## Lightning Web Components Playground って？
Salesforce.com 社が用意している、Web 上で lwc を試せる環境です。

Web 上でコードを編集したものを実行できるものとして、次のようなものがあるかと思います。

- Codepen.io
- jsfiddle
- StackBlitz (Angular)
- CodeSandbox
- Glitch

サイトへ次の URL で行くことができます。
https://developer.salesforce.com/docs/component-library/tools/playground

## どんな感じなのか
画面は次の画像のような感じです。(2019/12/08 時点)
![Lightning_Web_Component_Playground.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34297/707cd076-5430-c1d7-78ca-4bd806a65659.png)

ざっくり
- ファイル構成
- エディター
- 表示画面

という構成になっています。

## 試す

### 自動コンパイル
試しに `app.html` のファイルの中を編集すると、変更があるたびに自動でコンパイルが走り、レンダリングされます。
この設定は `Live Compilation` のチェックがデフォルトで入っているため、自動で変更が反映されます。
![Live_compilation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34297/524128dc-b8c3-096f-0dce-5312555d2ff8.png)
`Live Compilation` のチェックを外すと、ファイルを変更しても自動での反映は行われず、`Run` ボタンを押すことで反映されます。

### コード補完
文字を入力すると、サジェスチョンがいくつか出てきます。
<img width="465" alt="suggestion.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34297/ac3761af-cb77-70fc-481e-2604dd2ef26a.png">

入力した感じだと、標準のHTMLタグは出てくるようなのですが、lwcのサジェスチョンは出ない感じでした。
これから変わっていくのかもしれません。

## どのように使っていくか
あくまで Playground なので、当然のことながら本格的な開発を想定して作られたmのではありません。
個人的な感覚ではあるのですが、要件定義の段階で試しに見せたり、あるいは PoC で何かを簡単に作るときなんかには試せるのかもしれません。

## 合わせて参照
試す前に、こういったものを見て感覚を掴んでからもいいかも
[Sample Gallery](https://trailhead.salesforce.com/sample-gallery)
Github Packages に gradle shadow pluginを使って maven-publish する

# はじめに
この記事は [Github Packages](https://github.com/features/packages) に [gradle shadow plugin](https://github.com/johnrengelman/shadow) を使って [maven-publish](https://docs.gradle.org/current/userguide/publishing_maven.html) する方法を備忘録として残しています。

# おことわり

この記事は既に [Gradle](https://gradle.org/)、[gradle shadow plugin](https://github.com/johnrengelman/shadow)、[maven-publish](https://docs.gradle.org/current/userguide/publishing_maven.html)を使っている人を対象にしています。また [Github Packages](https://github.com/features/packages) の説明もしません。あと、Gradle 難しくて全然理解できてないので他にいい方法あれば教えて下さい🙏

# 解決したい課題
* [Jitpack](https://jitpack.io/) を利用していたが安定性に難があるので他の Package Repository にも Publish しておいて [Jitpack](https://jitpack.io/) が利用できなくても他の Repository から依存 Package のインストールをできるようにしておきたい。
* CI も [Github Actions](https://github.com/features/actions) で行っているため [Github Packages](https://github.com/features/packages) に置けると全部 Github で解決する💪
    * (少し無理やりな理由ですが要は使ってみたかったってことです)
* [gradle shadow plugin](https://github.com/johnrengelman/shadow) を使ってるので[Github Packages の公式ドキュメントに載っている方法](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages) をカスタマイズしないと使えない。
* [gradle shadow plugin の公式ドキュメント](https://imperceptiblethoughts.com/shadow/publishing/) にも特に [Github Packages](https://github.com/features/packages) に publish する方法は載ってない。

# どう解決したか

```groovy
publishing {
    publications {
        shadow(MavenPublication) { publication ->
            project.shadow.component(publication)
        }
    }
    repositories {
        maven {
            if (System.getenv("GITHUB_TOKEN")) {
                name = "GitHubPackages"
                url = uri("https://maven.pkg.github.com/civitaspo/publish-sample")
                credentials {
                    username = "civitaspo"
                    password = System.getenv("GITHUB_TOKEN")
                }
            }
            else {
                url "$buildDir/repo"
            }
        }
    }
}
```

* `publishing.publications` 下は [gradle shadow plugin の公式ドキュメント](https://imperceptiblethoughts.com/shadow/publishing/) に載っている設定を追加します。
* `publishing.repositories` 下は [Github Packages の公式ドキュメント](https://help.github.com/en/github/managing-packages-with-github-packages/configuring-gradle-for-use-with-github-packages) に載っている設定を追加します。
    * `GITHUB_TOKEN` が設定されている場合のみ maven.pkg.github.com に publish する設定を書いています。
    * `password` と書いてますが `GITHUB_TOKEN` を入れるようです。
        * `GITHUB_TOKEN` は https://github.com/settings/tokens から発行できます。
        * `read:packages`, `repo`, `write:packages` の権限を与えておく必要があります。

# おわりに
解決する方法は「そうだね」というかんじですが、 Gradle は Plugin も影響範囲がよく分からずソースコード読めばすぐ分かる感じじゃないので難しいですね。
GCEインスタンス内からProjectIDなどを取得する

## 概要
GAEでは環境変数としてProjectIDがとってこれるけど、
GCEインスタンス内でProjectIDなどを取得するにはどうすればいいか。
やり方は簡単。GCEのメタデータサーバからcurlとかでリクエストなげてとってくる。


## GCEのメタデータサーバとは
プロジェクト内のGCEのインスタンスすべてのメタデータを格納しているサーバで、GCEインスタンス内や ComputeEngineAPIから問い合わせることができます。
インスタンス内から問い合わせる場合は認証は必要なく、**curlなどを使用してAPIを叩いて特定の情報を取得することができます。**

## メタデータサーバからProjectIDを取得するには
ヘッダに `Metadata-Flavor: Google` を入れて取得用のエンドポイントを叩きます。

```
$ curl "http://metadata.google.internal/computeMetadata/v1/project/project-id" -H "Metadata-Flavor: Google"
```

## 参考
project-id以外も取得できます。以下を参考にしてください。

https://cloud.google.com/compute/docs/storing-retrieving-metadata?hl=ja#querying
[swift5]iOSアプリで地図機能を実装

緯度・経度、縮尺を設定した地図を実装する方法を紹介します！
![map_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547575/74ac974e-f3e6-6a3c-307b-15b4e35f6364.jpeg)

## 動作環境

| 対象 | バージョン |
|---|---|
| iOS | 13.3 |
| macOS | Catalina 10.15.2 |
| Xcode | 11.3.1 |
| Swift | 5.1.3 |

## 地図を表示

まずは、画面上に地図を表示します。
ここが完了すると、緯度・経度や縮尺を設定しないため、日本地図がすっぽりはまったような地図が表示されます。

![map2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547575/f633d8b4-2117-a508-0824-5a8fce8ac8a2.jpeg)

### ファイル作成

- Storyboard
    - ここでは、"Map.storyboard" とします
- ViewController.swift
    - ここでは、"MapViewController.swift" とします

### 画面を作成

Storyboard に、地図を表示するための MapKit を載っけます。

### 画面とソースの紐付け

MapKit をソースコード上に紐付けします。

```swift
/// 地図を表示するマップビュー
@IBOutlet weak var mapView: MKMapView!
```

## 緯度・経度を設定

次に、表示する地図の中心地を設定します。
今回は東京駅を中心とした地図を実装します。

![map3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547575/a5d816d9-a299-f87d-ef80-ed95bf4de0f7.jpeg)

はじめに、MapKit をインポートします。

```swift
import MapKit
```

そしてvi ewDidLoad メソッド内に、緯度・経度を設定する処理を実装します。

- CLLocationCoordinate2DMake メソッドは、緯度・経度を設定するメソッドです。
    - 詳細は、[CLLocationCoordinate2DMake（公式）](https://developer.apple.com/documentation/corelocation/1423838-cllocationcoordinate2dmake?language=objc) を参照してください。

```swift
// 東京駅の位置情報を設定（緯度: 35.681236 経度: 139.767125）
let latitude = 35.681236
let longitude = 139.767125
// 緯度・軽度を設定
let location = CLLocationCoordinate2DMake(latitude, longitude)
// マップビューに緯度・軽度を設定
mapView.setCenter(location, animated:true)
```

## 縮尺を設定

最後に、縮尺を設定する処理を実装します。
![map_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547575/b4ffacd0-bf5e-3e48-74e1-be300b6338b0.jpeg)

viewDidLoad メソッド内に、以下の処理を実装します。

- MKCoordinateRegion は、緯度と経度を中心とした長方形の地理的領域です。
    - 詳細は、[MKCoordinateRegion（公式）](https://developer.apple.com/documentation/mapkit/mkcoordinateregion) を参照してください。

```swift
// 縮尺を設定
var region = mapView.region
region.center = location
region.span.latitudeDelta = 0.02
region.span.longitudeDelta = 0.02
// マップビューに縮尺を設定
mapView.setRegion(region, animated:true)
```

## ソースコード

```swift
import UIKit
import MapKit

/// Map の View
class MapViewController: UIViewController {

    /// 地図を表示するマップビュー
    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 東京駅の位置情報を設定（緯度: 35.681236 経度: 139.767125）
        let latitude = 35.681236
        let longitude = 139.767125
        // 緯度・軽度を設定
        let location = CLLocationCoordinate2DMake(latitude, longitude)
        // マップビューに緯度・軽度を設定
        mapView.setCenter(location, animated:true)

        // 縮尺を設定
        var region = mapView.region
        region.center = location
        region.span.latitudeDelta = 0.02
        region.span.longitudeDelta = 0.02
        // マップビューに縮尺を設定
        mapView.setRegion(region, animated:true)
    }
}
```
bashでファイル名にサフィックス（連番）を付加する

##要件

* 特定のファイルにサフィックスを付加したい
* サフィックスは`_`＋`2桁の自然数`（つまり`_01`～`_99`）とする
* サフィックスは既存のファイルの中で最大のサフィックスより`1`だけ大きい値とする
* 既存のファイルがない場合、サフィックスは`_01`とする
* `_99`が存在するケースは考慮しなくてよい
* 関係のないファイルは無視する

##具体例
#### 例１
`/home/micky/work`というディレクトリに以下のファイルが存在する場合

* `AAA.dat`（サフィックスを付加するファイル）
* `AAA_01.dat`

この場合、`AAA.dat`の変更後のファイル名は`AAA_02.dat`になる

#### 例２
`/home/micky/work`というディレクトリに以下のファイルが存在する場合

* `AAA.dat`（サフィックスを付加するファイル）
* `AAA_01.dat`
* `AAA_98.dat`

この場合、`AAA.dat`の変更後のファイル名は`AAA_99.dat`になる

#### 例３
`/home/micky/work`というディレクトリに以下のファイルが存在する場合

* `AAA.dat`（サフィックスを付加するファイル__だけ__）

この場合、`AAA.dat`の変更後のファイル名は`AAA_01.dat`になる

#### 例４
`/home/micky/work`というディレクトリに以下のファイルが存在する場合

* `AAA.dat`（サフィックスを付加するファイル）
* `AAA_001.dat`（関係ないファイル）

この場合、`AAA.dat`の変更後のファイル名は`AAA_01.dat`になる

## bash で実装
#### 環境

* VirtualBox 6.0
* OS : Cent OS release 7.2.1511
* bash : 4.2.46

```bash
#!/bin/bash
work=/home/micky/work/
suf=(`ls "${work}" |
    awk 'match($0, /^AAA_([[:digit:]]{2})\.dat$/, a) { printf "%02d\n", ( a[1] + 1 ) }' |
    sort -n |
    tail -1`)
mv "${work}"AAA.dat "${work}"AAA_"${suf:-01}".dat
```
#### 補足
* `awk`で正規表現によるパターンマッチ、部分文字列の取得、カウントアップを行なう
* `sort`で昇順に並び替える
* `tail -1`で最後の値（最大値）を取得する
* __`AAA_xx.dat`が無い場合の考慮：__`${suf:-01}`で`$suf`が空のとき`01`を設定する
* 参考：[awkの正規表現でグループ化とキャプチャ、後方参照を行う](https://www.greptips.com/posts/1256/)

## ついでに PowerShell でも実装
#### 環境

* OS : Windows 10 Pro 1903
* PowerShell : 5.1

```powershell
$work='c:\work'
Rename-Item ( Join-Path $work 'AAA.dat' ) -NewName (
    'AAA_{0:00}.dat' -f ( 
        ( @( dir $work | 
                ?{ $_.Name -match '^AAA_(\d{2})\.dat$' } | 
                %{ $Matches[1] }
            ) + '0' | 
            Measure-Object -Maximum
        ).Maximum + 1 
    ) 
)
```
#### 補足
* `-match`で正規表現によるパターンマッチを行う
* `$Matches`で部分文字列の取得
* __`AAA_xx.dat`が無い場合の考慮：__`+ '0'`で、あらかじめ要素`'0'`を用意しておく
* `Measure-Object -Maximum`で最大値を取得する
テスト駆動飲み会はモブプロイベントではない！飲み会だ！

##この投稿は
[モブプログラミングAdventCalendar2019](https://qiita.com/advent-calendar/2019/mobprogramming) 12/8分の投稿です。

私の所属する[会社](https://www.val.co.jp/)では「[テスト駆動飲み会](https://tddrinking.connpass.com/)」というイベントの会場を毎回提供しています。
内容や開催のきっかけは[昨年のモブプログラミングアドベントカレンダー](http://takigawa401.hatenablog.com/entry/2018/12/07/000000)で[@takigawa401](https://twitter.com/takigawa401)さんが書かれているので、今年はイベント運営や会場提供をしている立場から、この”場”について感じていることについて書いてみようと思います。

##テスト駆動飲み会とは
テスト駆動開発(Test-Driven Development:TDD)をお酒を飲みながら体験しようというイベントで、 イベント名をTest-Driven Drinking＝TDDとかけています。
第1回を2018年の8月に開催して、過去に8回開催しました。

各回の参加者の3分の1から半分はリピーターなので、最近の傾向としてはマンネリ対策と兼ねて開催時期にちなんだネタを運営側で用意しています(運営側が遊びたいだけという説もｗ

2/5はバレンタイン前なのでチョコレートリキュールを用意したり。
4/1はエイプリルフールスペシャルとして、エイプリルフール→嘘をつく→相手を騙す駆け引きのあるポーカーのプログラムをテーマにしたり。
10/31のハロウィン回では、ドライバー交代ごとにサイコロの目でTrick or Treatを抽選して、Trickが出たら制限がかかるという趣向を用意しました。
![DSC_3761.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152460/362bc5a4-d0f0-1ce7-134e-bcc43208f2ee.jpeg)![DSC_3764.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152460/d6f1d8e8-60a6-72fd-d1c8-f48d5e8689e2.jpeg)
![DSC_3766.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152460/e60402ad-248d-925c-7425-34b8d13f0771.jpeg)

##テスト駆動飲み会はモブプロイベントではない？
イベント参加申し込み時によくある問合わせとして、「PCは個人のものを持参したほうが良いでしょうか？」「言語は〇〇しかわかりませんが大丈夫でしょうか？」などが多いのですが、事前準備はほとんど要らないですし、使用する言語がわからなくてもナビゲーターがサポートしてくれます(モブプログラミングとはそういうものだと思うし)。

あと、少しお酒が入っていることで、「こんなナビゲートで大丈夫？間違ってない？」みたいな不安や見栄のブレーキが外れて、モブのガヤ…じゃなかったナビゲートが活発になっているのも良いところだと思います。
「雰囲気はゆるいが、サポートはしっかり」で、上手くバランスが取れているので、モブプログラミングとはどんなものかをまずは体験してみたい方に向いているイベントです。

##まとめ
テスト駆動飲み会はあくまで「モブプロを肴にお酒を飲む”飲み会”」です。
興味を持った方は、[次回開催は12/26を予定](https://tddrinking.connpass.com/event/155627/)しているので参加してみてはいかがでしょうか。年末なのでまたそれらしい趣向を用意しなくては…どうしようかな…
Arrayの分割2種

# chunk

Lodashとかであるやつです。
第1引数の配列を第2引数の数の要素数の配列に分割します。

```javascript

const chunk = (array, n) =>
  array.reduce(
    (a, c, i) =>
      i % n == 0 ? [...a, [c]] : [...a.slice(0, -1), [...a[a.length - 1], c]],
    []
  );
```

実行結果はこんな感じ

```javascript
const array = Array.from({ length: 7 }, (v, k) => k);
chunk(array, 2);
// [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ], [ 6 ] ]
```

---

# divide

自分が欲しかったやつはこれでした。
第1引数の配列を第2引数の数の配列に分割します。

```javascript
const divide = (array, n) => {
  const tbl = new Array(n);
  for (let y = 0; y < n; y++) {
    tbl[y] = new Array();
  }
  array.forEach((a, i) => {
    tbl[(i + 1) % n].push(a);
  });
  return tbl;
};
```

決められたスレッドを利用して並列化したかったのでこんなのが必要になりました。
実行結果はこんな感じ

```javascript
const array = Array.from({ length: 7 }, (v, k) => k);
divide(array, 2);
// [ [ 1, 3, 5 ], [ 0, 2, 4, 6 ] ]
```

---

ぐぐっても`chunk`みたいな処理しかでてこなかった。もっといい書き方ありそう。

---

追記

コメントにて @ttatsf さんからイカしたコードをいただきました！かっこいい...!

```javascript
const chunk = n => xs =>
  xs.reduce(
    (acc, _, i) => 
      i % n === 0 ? [ ...acc, xs.slice( i, i + n ) ]
      : [...acc]
    , []
  )

const divide = n => xs => 
  zipLongest( chunk( n )( xs ) )
const zipLongest = xs =>
  xs.reduce( zipLonger, [])
const zipLonger = (xs, ys) =>
  xs.length >= ys.length ? xs.map( 
    (e, i) => i >= ys.length ? [e].flat() : [ e, ys[i] ].flat()
  )
  : ys.map(
    (e, i) => i >= xs.length ? [e].flat() : [ xs[i], e ].flat()
  )

//使用例：
const n = 2
const xs = [ 0, 1, 2, 3, 4, 5, 6 ]
chunk( n )( xs )  // [ [ 0, 1 ], [ 2, 3 ], [ 4, 5 ], [ 6 ] ]
divide( n )( xs ) // [ [ 0, 2, 4, 6 ], [ 1, 3, 5 ] ]
```
学生にプログラミングを教えるときのカンニングシート（Gitコマンド編）

# 対象
- 普段は使わないけど、たまたまCloud9を使うことになった人（←自分）
- (GUI以外で)gitを使うことになった人（←学生さんとか新人さんとか）

# 目的
学生にプログラミングを教えることがあるけど、そういうときにいちいちローカル（学生のPC）に環境を作ってられないので、AWS Cloud9を利用する。
ただ、普段、ディターはRubyMine（もしくはVScode）、GitはSourcetreeを使っているから、Cloud9で作業するときに、
「コマンド忘れたー」「あー、あの機能はこのショートカットキーじゃないのー？」
ってなってる人を救いたい。（←自分）


# Git編
## 前提
- チーム開発風でやっている
- Cloud9にすでにプロジェクトをクローンしている

**普段開発しているときと同じような流れにすることが大切**
Souceteeでやっていることをイメージする。

## フェッチする  
誰かが作業を進めているかもしれないから。

```
$ git fetch
```

## ブランチを確認  
自分がいる場所を確認

```
$ git branch
```  

リモートのやつも確認したかったら

```
$ git branch -a
```

## 作業するブランチにチェックアウト  
ローカルにあるブランチだったら

```
$ git checkout [branch名] 
```
ローカルにないブランチだったら

```
$ git checkout -b [branch名] origin/[リモートブランチ名]
```

## プルしておく

```
$ git pull
```

## ローカルの変更されているファイルを確認（ステージも確認）

```
$ git status
```

## 変更されているファイルの詳細を確認
```
$ git diff
```
ファイルを指定したいなら

```
$ git diff [調べたい/ファイル]
```

## ローカルの変更を全て破棄する
ブランチ切り替えるときとか、そういうことしたときあるよね。

```
$ git checkout .
```
新規追加したファイルはなくならないので、そういうときは別途↓。

```
$ git clean -df .
```

## 変更をステージに上げる
一回で全部ステージに上げる

```
$ git add --all
```

ファイルを指定する

```
$ git add [addしたい/ファイル]
```

## ステージに上げたファイルをステージから下ろす

```
$ git reset HEAD .
```
ファイル名を指定したいとき

```
$ git reset HEAD [ファイル名]
```

## 作業したらコミット

```
$ git commit -m 'コミットメッセージ'
```

## プッシュする

```
$ git push origin [ブランチ名]
```

## マージとかログとかは。。。
無理せずにクラウドサービス上でやるとか、Soucetreeだけローカルに入れてもらうとかのほうが間違いが少ないかも。
クラウドでプルリク作ってもらうとかの方がわかりやすい。

# おわり
gitコマンドの記事はたくさんあるから今更コマンドの記事とか投稿しても。。。て思ったけど、作業の流れで追えるコマンド集がほしいと思ってたから、まぁいいか。

長くなったから、Cloud9編（主にショートカットキーとか）は[また次回](https://qiita.com/yamatokun9/items/df5baf81938eb02d9676)
[VSCode] サイドバーを非表示にするショートカット設定

# 参考

[こちが参考になります！](https://amzn.to/2Ban2Aq)


# 方法

Keyboard Shourtcuts(ショートカット設定)にて`View: Toggle Side Bar Visibility`にバインドしてください。
私は`Ctrl+l`としています。
正規表現 メモ

# 前書き

正規表現を使用する場面はよくあります。
一部の正規表現はよく使うため覚えていますが、覚えていない正規表現も多く、都度調べることになっています。
そこで、正規表現の全体像をまとめてみました。


# 正規表現

### 1. 基本的な正規表現

|記号|意味|正規表現の例|マッチする例|
|----|----|------------|------------|
|`.`|任意の1文字|ab.d|abcd<br/>abed|
|`+`|直前の文字の1回以上の繰り返し<br/>最長一致（条件に合う一番長い部分に一致する）|abc+d|abcd<br/>abccd|
|`*`|直前の文字の0回以上の繰り返し<br/>最長一致（条件に合う一番長い部分に一致する）|abc*d|abd<br/>abcd<br/>abccd|
|`?`|直前の文字が0個～1個の繰り返し<br/>最長一致（条件に合う一番長い部分に一致する）|abc?d|abd<br/>abcd|
|`+?`|直前の文字の1回以上の繰り返し<br/>最短一致（条件に合う一番短い部分に一致する）|abc+?d|abcd<br/>abccd|
|`*?`|直前の文字の0回以上の繰り返し<br/>最短一致（条件に合う一番短い部分に一致する）|abc*?d|abd<br/>abcd<br/>abccd|
|`??`|直前の文字が0個～1個の繰り返し<br/>最短一致（条件に合う一番短い部分に一致する）|abc??d|abd<br/>abcd|
|`～`&#124;`～`|&#124;の左右の文字列のいずれか（～または～）|abcd(ef&#124;gf)|abcdef<br/>abcdgf|
|`\`|直後の正規表現記号をエスケープする|`ab\+d`|ab+d|
|`[ ～ ]`|[ ]の中のどれか1文字|[abc]<br/>[a-c]|a, b, c|
|`[^ ～ ]`|[ ]の中に無い1文字|[^abc]<br/>[^a-c]|a, b, c以外の文字|
|`( ～ )`|( )内を1文字扱い（１つのグループにまとめる）|abcd(ef&#124;gf)|abcdef<br/>abcdgf|
|`{n}`|直前の文字のn回の繰り返し|a{3}|aaa|
|`{n,}`|直前の文字のn回以上の繰り返し|a{3,}|aaa<br/>aaaa...|
|`{min,max}`|直前の文字のmin以上max以下の繰り返し（min、maxは省略可能）<br/>最長一致（条件に合う一番長い部分に一致する）|a{3,4}|aaa<br/>aaaa|
|`{min,max}?`|直前の文字のmin以上max以下の繰り返し（min、maxは省略可能）<br/>最短一致（条件に合う一番短い部分に一致する）|a{3,4}|aaa<br/>aaaa|

### 2. 定義済みの正規表現

|記号|意味|対応する表現|
|----|----|------------|
|`\t`|タブ|(なし)|
|`\r`|改行。CR(Carriage Return：0x0D)|(なし)|
|`\n`|改行。LF(Line Feed：0x0A)|(なし)|
|`\d`|数字1文字|[0-9]|
|`\D`|数字以外の1文字|[^0-9]|
|`\s`|半角スペース、タブ、改行のどれか1文字|[ \t\f\r\n]|
|`\S`|半角スペース、タブ、改行以外の1文字|[^ \t\f\r\n]|
|`\w`|アルファベット、数字、アンダスコア（ _ ）のどれかの1文字|[a-zA-Z_0-9]|
|`\W`|アルファベット、数字、アンダスコア以外の1文字|[^a-zA-Z_0-9]|

### 3. 特定の位置関係の正規表現

|記号|意味|
|----|----|
|`^`|行の先頭|
|`$`|行の末尾|
|`\<`|単語の先頭|
|`\>`|単語の末尾|
|`\b`|単語の先頭か末尾
|`\B`|単語の先頭、末尾以外|
|`\A`|ファイルの先頭|
|`\z`|ファイルの末尾|
|`\G`|直前の一致文字列の末尾|

### 4. 置換文字列で使える正規表現
|記号|意味|
|----|----|
|`\0`|一致した文字列全体|
|`\1 \2 … \9`|それぞれ検索文字列の1～9番目の ( ) に一致した文字列
|`\l`|次の1文字を小文字にする
|`\L...\E`|挟まれた文字列を小文字にする
|`\u`|次の1文字を大文字にする
|`\U...\E`|挟まれた文字列を大文字にする


### 5. よく使う正規表現式

|名称|正規表現|
|----|--------|
|Email アドレス<br/>(RFC準拠ではない)|`^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$`|
|URL|`^https?://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$`|
|ドメイン名|`^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z-]{2,}$`|
|日付 (YYYY-MM-DD形式)|`^\d{4}-\d\d-\d\d$`|
|桁区切りカンマ付数字|`\b\d{1,3}(,\d{3})*\b`|
|固定電話番号|`^0\d(-\d{4}`&#124;`\d-\d{3}`&#124;`\d\d-\d\d`&#124;`\d{3}-\d)-\d{4}$`|
|携帯電話番号|`^0[789]0-\d{4}-\d{4}$`|
|IP 電話番号|`^050-\d{4}-\d{4}$`|
|フリーダイヤル|`^(0120`&#124;`0800)-\d{3}-\d{3}$`|
|郵便番号|`^\d{3}-\d{4}$`|


以上
Nuxt + TypeScriptでvuex-module-decoratorsでESLintがエラーを吐くとき

# 対象
Nuxt + TypeScriptで、クラス構文の使えるVuexモジュール、vuex-module-decoratorsを使いたいと思っているヒトで、Linterがエラーを起こしている人

# エラー内容
```
Exporting mutable 'let' binding, use 'const' instead.
```

内容からして
eslint(import/no-mutable-exports)　
ミュータブルな変数、つまるところletで定義された変数をエクスポートしちゃダメ、という話ですね。

# 解決方法
やや場当たり的な解決法で申し訳ないですが、特定行のみLinterのルールを停止させましょう。
このとき`// eslint-disable-next-line`を問題の行の上に指定して、問題のルールをdisableにします。


vuex-module-decorators公式の例文の場合は、以下のようにします。

```typescript
import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import example from '~/store/example'

// eslint-disable-next-line import/no-mutable-exports
let exampleStore: example

function initialiseStores(store: Store<any>): void {
  exampleStore = getModule(example, store)
}

export { initialiseStores, exampleStore }
```


## 今後似たようなエラーが出た場合
もしも「Linterによるエラー」と分かっており、なんか細かい仕様も分からないのでその行だけLintを取り消したいなら、VScodeの場合赤いラインが出ている行で` Ctrl + . `を押して解決法を探してください。
解決法の中に問題のLinterエラーを解除する方法が(おそらく)あります。

# 終わりに
vuex-module-decoratorsは素晴らしいモジュールなので、ぜひ取り入れてください！
API開発が捗るツールたち（設計書編）

# 背景
APIを開発するとき、色々なツールがありどれを使えばいいのか、  
それぞれどのような特徴があるのかよくわからず迷いました。

いくつか実際に使ってみた感想をまとめました。  

## 設計書編

### Swagger 
有名なオープンソースフレームワーク。Web APIを開発する人は結構知っている人も多いかと思います。
Swaggerにはいくつか種類があります。

* [Swagger Editor](https://editor.swagger.io/)：Web上でプレビューをみながら修正することができる。
- [Swagger UI](https://petstore.swagger.io/?_ga=2.150673526.1399526733.1569256460-460980884.1569256460#/pet/addPet)：指定のyaml, jsonファイルを元にAPIリファレンスをWeb上に表示することが可能。叩いてみたいAPIを選択し、Web上から実行することもできる。

お手軽にWebから利用することもできますが、Dockerイメージが転がっているのでローカルにSwaggerコンテナを[Docker Hub（Swagger）](https://hub.docker.com/search?q=swagger&type=image)立てて利用することもできます。使ってみたいけどセキュリティ的にWebから使うって抵抗あるな...という方や、チームで共有するときにSwaggerサーバを1台立てておくと非常に便利で良いと思います。

また、VsCodeをお使いの方は専用のプラグインがあります。   
編集するだけであればプラグインで十分かと思います。
<img width="886" alt="18ef3b63bd4c84a30f70697cc0f6db4b.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260598/8132df60-d3ea-f0ca-749e-f9b3120faf08.png">


Swagger UIでAPIリファレンスを眺めていると、「これそのまんまAPI定義書にしちゃいたいわ」なんて欲が出てきます。そんなときは[ReDoc](https://github.com/Redocly/redoc)がおすすめです。

Swaggerで書いたAPI定義ファイルを良さげなhtmlファイルに変換してくれます。[例](https://redocly.github.io/redoc/)

そのほかにもSwaggerからドキュメントを生成するツールがいくつかあるようです。
[こちら](https://qiita.com/buzztaiki/items/6b04d735f28e00b8b574) の記事にわかりやすくまとめてくれています。

### Re:VIEW
こちらはAPIの設計書と直接的な関係はありませんが、設計書を書くことにおいて非常に便利なツールですので合わせてご紹介します。
API定義を内部で利用するだけであればReDocのようなツールから生成したHTMLファイルだけで良いですが、お客様によってはかっちりとしたAPI設計書の提出を求められる場合があります。  

私の職場では設計書はwordで書き上げるのが一般的でしたが、面倒に感じることが多々あります...  
そんなときにおすすめなのがRe:VIEWです。

Re:VIEW用のMarkDown形式で書いた文書を良さげにPDFやHTMLにして出力してくれます。  

linterなどを利用することにより文書校正も可能です。  
専用のDockerファイルもありますので、面倒な環境構築もすることなく利用が可能です。
([Re:VIEW for Docker](https://hub.docker.com/r/vvakame/review))

### Plant UML
こちらもAPIの設計書と直接的な関係はありません。  
これを知ってるかどうかで設計書修正のコストをだいぶ下げることができる（かもしれない）と思います([plantUML公式](http://plantuml.com/ja/sequence-diagram))。

シーケンス図やクラス図をコードベースで書くことができます。  
設計内容をコード化することでGitでの管理が可能となるのが大きな利点だと思います。

手書き風とか色を変えたりとか、見た目も少しいじることができます。
似たようなものに[mermaid.js](https://github.com/knsv/mermaid)というものがあります。

この辺は好みかと思います。

## まとめ
* API全体の構成やユースケースの設計：PlantUML, mermaid js
* APIリファレンスやモックの作成：Swagger, (必要に応じて)ReDoc
* お客様へ別途資料の提出が必要な場合：Re:VIEW

というような使い分けが良いかと思います。

次はクライアントツールやアプリについてまとめたいなぁと思います。
Bitriseでjqをインストールする

## 目的
BitriseでGitHubやAppCenterなど、別サービスに連携するためにAPIを叩くケースがよくある。
もちろんJsonで結果が返却されるので、jqで処理したい！
BitriseのAndroid/iOSで対応できるようにインストールしよう！

## やり方
手元のmacだけならば、「Homebrewで終わりやん！」ってなるんですが、Bitriseでビルドするとそんな簡単に話は終わらない。

BitriseはAndroidとiOSのビルド環境が用意されている。(Xamarinとかももちろん用意されている。)
どちらもMacが環境として選択されていれば問題ないが、弊社の場合はそれぞれUbuntuとMacが設定されているのでそれぞれに対応する必要がある。

### Mac
MacはHomebrewでインストールする。

```
if hash jq 2>/dev/null; then
  echo "jq already installed."
else
  echo "jq is not installed. Installing..."
  /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  brew install jq
fi
```

### Ubuntu
Ubuntuはaptでデフォルトで入っているのでそのままインストールできる。
念の為updateはしておいたほうが良い。

```
if hash jq 2>/dev/null; then
  echo "jq already installed."
else
  echo "jq is not installed. Installing..."
  apt -y update
  apt -y install jq
fi
```

## まとめ
まぁ、可能であればマシンはXCodeにしておくのがベターですかね！
google画像からすぐにスクレイピング！

#はじめに
画像検索からいちいち保存やらなんやらの画像収集がめんどくさいので、探してみたらいいドライバがあったので自己満でまとめてみる。

#準備
__google_images_dwonload__をインストール
ページ⇒

```common_lisp
$pip install google_images_download
$pip install os
$pip install glob
$pip install chromedriver
```
が必要となるのでインストールしておく。
chromedriverのなかに、アプリケーションの"chromedriver"がなければ、
https://chromedriver.chromium.org/downloads
よりダウンロードして、chromedriverのファイルの中に保管。

以上で、大体の準備完了

#環境
・pycharm
・python 3.7.4
・windows10

#ソースコード
import文

```python
from google_images_download import google_images_download
import glob
import os
```
中身
今回は、検索ワードを"ONE OK ROCK"とする。
limit = 100　とし、画像の枚数を100枚とする。

```python
config = {
    "Records": [
        {
            "keywords": "ONE OK ROCK LIVE",
            "no_numbering": True,
            "limit": 100,
            "output_directory": "images",
            "image_directory": "ONE OK ROCK",
            "chromedriver": "C\\[path to chromedirver]\chromedriver\chromedriver.exe",

        }
    ]
}
```
chromedriverまでのpathをしっかりと書くこと。


```python
response = google_images_download.googleimagesdownload()
for rc in config["Records"]:
    response.download(rc)
```

一応、gif画像は抜けにする。（めんどくさいので）

```python
gifImgs = glob.glob("images" + os.sep + "*" + os.sep + "*.gif")
print(f"removing gif files: {len(gifImgs)} files")
_ = [os.remove(f) for f in gifImgs]
```

上記のものを順におこなうと、取得できる。
#結果

![スクリーンショット (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533115/e01d851b-d314-dabd-8b08-9f729634e2a3.png)


#さいごに
このスクレイピングは情報収集にはいいものとなっていて、非常に便利である。
ページからの画像取得とはだいぶ異なるのでそれについては別記事で書こうと思う。
簡単にしか書いてないので、くわしいことは調べてください。
Route 53と従来のDNSサービスとの違い

#Route53によるDNSの進化
![dns.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/31f5ae49-e5d5-97cc-8e65-8a9202a448a2.png)


こんにちは．
鬼滅の刃の映画が待ち遠しい茂木です．

さて，GMOは息していますかね．
大手クラウドベンダーの技術力に圧倒されてます．

一度はサービスをローンチさせた人なら分かる
DNSについてです．

ドメインネームサービスです．
ドメインをIPアドレスに変換をしてくれる技術です．

オンプレなんかはDNS設定をしてやっとネット上で購入したドメインからサービスを見ることが出来ます．

AWSではこれを**Route53**というサービスで担っています．

これを知っていないとawsでの構築は出来ないので，
やり方と従来との違いを説明して行きます！

##Route 53のお仕事
ドメイン内のDNSリソースレコードを*ホストゾーンを作成して登録出来ます．
簡単に言うと，可用性の高いドメイン->IP変換システムでしょう．

用語
「*ホストゾーン... レコードのコンテナ．
特定のドメインのトラフィックを
どのようにルーティングするかに関する情報を保持します.
.com/.co.uk/.org/.netの4つのトップレベルDNSサーバーで管理されている」

ホストゾーンには，
**パブリックホストゾーン**と**プライベートホストゾーン**があります
インターネット上に公開するか否かの設定です．
![スクリーンショット 2019-12-08 15.05.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/7265e0d5-cf02-31c6-acda-b9ae5510e20a.png)

##Route 53の特徴
###エイリアスレコード
Route 53固有の仮想リソースレコード．
こちらを利用するシナリオは，

**AWSサービスのエンドポイントをDNSに登録する**時です
AWSのIPは動的に変化します．
言い換えると，Aレコードの設定を行うことが出来ないんですね．
その為，エイリアスレコードが必要になってきます．

この辺は中身も知っておいた方がいいでしょう．
CNAMEと比較して説明します．

CNAMEは読み替え機能です．
motemote.com | CNAME | elb1.~~~.com
とやると読み換えてくれます

![スクリーンショット 2019-12-08 15.24.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/9136e264-7611-8e6c-df5e-44c8af6ae22d.png)

Aレコードの登録が出来ない場合，CNAMEで上の図のように別名で登録をしますが，
エイリアスレコードは更に進化した方法で登録できます．

従来よりもレスポンスが高速で，S3やCloudFrontへのクエリが無料になる利点もあります．

###Zone Apex
DNSドメインの頂点となるノードの事．
パッとしない方の為に例を用意．
例としては，www.motemote.comの「motemote.com」の部分

DNSの性質上，すでにNSレコードとしてZone Apexが登録されていると
CNAMEレコードでは登録出来ないんですね．
エイリアスレコードならこれが解決します．

ムームードメイン+ herokuとかで構築した人ならわかると思いますが，
この辺知っていないと，サブドメインでしかCNAME登録出来ません．

きちんとエイリアスレコードでエンドポイントを指定しましょう!


##Route 53の特徴その2
従来と比較するとルーティングから別物です．
従来のDNSサービスの様に事前に定義されている静的リソースレコードに基づいて応答するだけでは無いんです．

ポリシーで定義されたルールに基づいて動的に転送先を変更する，
**ポリシーベースのルーティング**となっています．

![スクリーンショット 2019-12-08 15.54.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/405dc2c8-d629-2461-ac05-d5d7cb1bfa56.png)

加重ルール...複数のエンドポイントに対して重みを付ける．重みの高いものが優先される

フェイスオーバールール...ヘルスチェックの結果に基づく

位置情報ルール...クライアントの位置に基づく

レイテンシールール...リージョン間の遅延が少ないほうのリソースにルーティングされる

複数値解答のルール...複数のリソースに DNS レスポンスを分散する場合に使用

地理的近接性ルール...リソースの場所に基づいてトラフィックをルーティングし、必要に応じてトラフィックをある場所のリソースから別の場所のリソースに移動する場合に使用


要件に合わせて選んで使い分けましょう．
用途に合わせて使い分けることが出来れば，トラフィックを分散させられたり，
ドメインのダウンタイム軽減が可能になりますよ！！
Bitriseでこれだけは覚えておけって環境変数7選！！

## この記事は...？
みなさん！Bitrise使ってますか！？
僕はお仕事で毎日使っていて、1日あたり20ビルド、1回のビルドの平均時間が25分のそこそこのヘビーユーザです！

Bitriseの環境変数は[公式ページ](https://devcenter.bitrise.io/jp/builds/available-environment-variables/)でまとめられているものの、使い道とかよくわからんって人も多いと思います。

ここでは僕目線でこれだけは使うから覚えておけって変数をまとめてみたいと思います！
参考になったなら幸いです！

## 一覧
### CI
■ 説明(公式から引用)
CLIがCI（Continuous Integration）モードで実行されているかどうかを示します。値は"true"または"false"です。

■ 使い道
CIの時に動作させたくないステップの制御に使用します。
具体的な例でいうと、SwiftLintのRunScriptに組み込みます。

```
if [ -z ${CI+x} ];then
  # ここでSwiftLintの処理設定
fi;
```

---
### PR
■ 説明(公式から引用)
bitriseCLIがPR（プル要求）モードで実行されているかどうかを示します。値は"true"または"false"です。

■ 使い道
こちらも`CI`と似たような感じでプルリク起動時のみに実施したい処理がある時に分岐で使用します。
後述する`BITRISE_PULL_REQUEST`で判断でもいいのですが、分岐なのでできればtrue/falseがいいですよねって事でこちらを使います。

プルリクをトリガーにしてビルドをし始めると、プルリクにコメントを入れたりレビュワーを登録したくなると思いますので、その時によく使用します。

---
### GIT_REPOSITORY_URL
■ 説明(公式から引用)
gitリポジトリURL

■ 使い道
言わずもがなですが、GitリポジトリのURLが設定されます。(git://hogehoge形式)
GitHub APIを使用する時に、このGitリポジトリURLからエンドポイントを生成し直したりします。
GitHub Enterprizeを使用しているパターンだとよく使用します。

こんな感じ

```
readonly GITHUB_API_BASE_URL=$(echo $GIT_REPOSITORY_URL | sed -e "s/git@/https:\/\//g" -e "s/:${BITRISEIO_GIT_REPOSITORY_OWNER}\/${BITRISEIO_GIT_REPOSITORY_SLUG}\.git/\/api\/v3/g")
```


---
### BITRISE_GIT_MESSAGE
■ 説明(公式から引用)
コミットメッセージ、プルリクエストタイトル、または手動でビルドを起動した場合は指定したメッセージ。この環境変数は、APIの[commit message]([https://devcenter.bitrise.io/api/build-trigger/#git-related](https://devcenter.bitrise.io/api/build-trigger/#git-related "https://devcenter.bitrise.io/api/build-trigger/#git-related"))にマッピングされています。

■ 使い道
説明が長ったらしいですが、設定される内容は以下の2通りです。
1. プルリク起動の時・・・プルリクのタイトル + プルリクの説明
2. 手動起動の時・・・起動時に設定したMESSAGE

<img width="601" alt="スクリーンショット 2019-12-08 15.59.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144029/32cb7e34-900c-8ae3-1e89-3a2f625d154b.png">

Slackのメッセージやリリースノートに使用するといいですね！
AppCenterなどサービスによっては改行コードのエスケープが必要なので気をつけましょう！

---
### BITRISEIO_GIT_REPOSITORY_OWNER
■ 説明(公式から引用)
プロジェクトのGitリポジトリのオーナー（例、bitrise-team）

■ 使い道
GitHub API叩く時に使用します。
それ以外は特に使用する機会はないですが、そもそもGitHub API叩くケースはそこそこあるので、覚えておくと楽です。

---
### BITRISEIO_GIT_REPOSITORY_SLUG
■ 説明(公式から引用)
プロジェクトのGitリポジトリのスラッグ（例、bitrise-blog）

■ 使い道
前述の`BITRISEIO_GIT_REPOSITORY_OWNER`と同じです。

---
### BITRISE_PULL_REQUEST
■ 説明(公式から引用)
ビルドをトリガーしたプルリクエストID（あれば）

■ 使い道
プルリクをトリガーにビルドする時にプルリクエストIDが設定されます。
`PR`の欄でも記述しましたが、プルリク起動にするとやりたいことが結構出てくるのでよく使います。
僕はレビュワーのアサインとか、Slackに投稿するメッセージに埋め込んでいます。
Qiitaでクソ記事を探す方法


Qiitaのすべての記事一覧ページ

https://qiita.com/items

から頑張って探す。


ちなみに、JSONで取得する場合は、

https://qiita.com/api/v2/items

です。
次のベージは、

https://qiita.com/api/v2/items?page=2

です。
【文系新卒が】基本情報技術者試験に立ち向かった話

# 事の始まり

～某会社の部内会議にて～
先輩：「私たちの事業部では年内に**全員の資格取得**を目標にしています」
僕：先輩たちは業務もあって、資格も取るなんて大変だなぁ・・(他人事)
先輩：「もちろん『**新卒の皆さん**』も対象です」
僕：「ファ!?!?」

茶番はさておき、弊事業部では1年目の新卒も資格取得を目標で掲げています。
1年目の新卒は**基本情報技術者試験**を取ろう！！みたいな風潮ありますよね!???
そういうIT系会社って多いんじゃないかなと思い、
基本情報技術者試験を受験する方向けの記事を投稿させていただきました。

## やったこと
私が基本情報試験に行った勉強は以下の通りです。

- 午前問題
    - 6月初旬～8月初旬：テキストを読む(1ヵ月1周で合計2周しました)
        - 平日の通勤時間の20～30分/1日読みました。
    - 8月初旬～10月初旬：過去問をひたすらやる(約1000問位)
     - 平日の通勤時間で30問/1日を繰り返し。(約20～25分位かかりました)
- 午後問題
    - 9月中旬～試験日：過去問をやる(3年分)
        - これは土日のどちらかで、1年分/1日をやりました。

### 午前問題

#### テキストを読む(6月初旬～8月初旬)

試験内容も分からないし、ITの知識もゼロ・・・
とりあえず図の多いテキスト買わなきゃ・・・

**参考書**
[キタミ式イラストIT塾 基本情報技術者 令和02年キタミ式イラストIT塾 基本情報技術者 令和02年](https://www.amazon.co.jp/%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88IT%E5%A1%BE-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E4%BB%A4%E5%92%8C02%E5%B9%B4-%E3%81%8D%E3%81%9F%E3%81%BF%E3%82%8A%E3%82%85%E3%81%86%E3%81%98/dp/4297110210?ref_=Oct_BSellerC_502776_0&pf_rd_p=194ad9ce-5304-5088-9ff2-08924029768e&pf_rd_s=merchandised-search-10&pf_rd_t=101&pf_rd_i=502776&pf_rd_m=AN1VRQENFRJN5&pf_rd_r=XYXBDKDM9NGZK66EGCNH&pf_rd_r=XYXBDKDM9NGZK66EGCNH&pf_rd_p=194ad9ce-5304-5088-9ff2-08924029768e)

これすごいわかりやすいと思います！！(ステマではない)
出る内容も抑えてあるし、図が豊富で分かりやすい！
通勤時間に読んでも苦にならない内容でした。
IT初心者は文字だけ書いてあっても理解できないものなんです・・

#### 過去問をひたすらやる(8月初旬～10月初旬)
無料アプリを使いました！
[020年春版 基本情報技術者試験問題集(無料全問解説付)](https://play.google.com/store/apps/details?id=com.startthailand.fe_lite)

無料でできるし、間違えた問題とかのフィルターがついているので繰り返しやるにはおすすめです！
あとスマホだと満員電車でもやれるからいいよね！

### 午後問題

#### 過去問をやる(9月中旬～試験日)

一番最後にプログラムの問題が出ますが、新卒の方は『**表計算**』をお勧めします！
Excel触ったことある人なら大丈夫です。難しいことは聞かれません（笑）
公式のHPに無料で問題が置いてあるので、そこからダウンロードしちゃいましょう！
お金に余裕がある人は、問題集を買ったほうが理解しやすいと思います。
(公式は回答しか載っていません)
[IPIA 独立行政法人 情報処理推進機構：過去問題](https://www.jitec.ipa.go.jp/1_04hanni_sukiru/_index_mondai.html)

### 合計勉強時間
合計：約30時間でした！

- 勉強時間内訳
    - 午前問題
        - テキスト読み：25分×30日(平日の通勤)=12時間30分
        - 過去問題：25分×30日(通勤)=12時間30分
    - 午後問題
        - 過去問題：90分×3年分=4時間30分

##  結果
やったぁ！やりました！
『**合格**』です！！！！
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469819/355b61dd-c797-733a-d157-a4cbeb55f129.png)


あまり誇れる点数ではないですが、受かればみんな同じです！（笑）

というわけで、最後まで見てくれてありがとうございました。
これから基本情報を受ける方たちへ少しでも参考になれば幸いです。



文系新卒エンジニアの挑戦は続く・・・
仕様変更対応から学ぶ恋愛術

# はじめに
もうすぐクリスマスです。
皆さんは一緒に過ごす大切な人いらっしゃいますか？＾＾

今回は自分が作っているシステムの仕様変更対応を極めることで、対女性対応も上手にできてしまう話をします。(当記事は実業務とは一切関係ありません)

# 前提
ここで言う仕様変更対応とは

* 事前に仕様変更の告知がくる
* 急に仕様変更の告知がくる
* 言ってたことと違う仕様変更が施される時もある
* 何も言わずに仕様変更される

ということにして、対女性対応に繋がる話をします。

# 事前に仕様変更の告知がくる
【システム目線】
これは一番いいパターンです。
そんなに近くない日に「ここがこう変わるよ」って教えてくれたら、それに合わせて対応できます。
それに、突貫工事で作るのではなく、これを機にリファクタとか、時間が許せば色々できることもあります。
【彼女目線】
「この日に遊ぼうよ」と事前に言われるようなものです。
相手に合わせて遊んであげましょう。
きっと喜んでくれます。
事前に分かっているなら、サプライズを仕込むとか、より彼女が喜べるよう考えてあげましょう。
時間が長ければ長いほど丁寧な対応ができます。
彼女には見えない時間かもしれませんが、結果はちゃんと実ります。

# 急に仕様変更の告知がくる
【システム目線】
恐らく先方の方で何か事情はあったのでしょう。
先方の連携ミスとか、急なバグとか。
まぁあまり探っても仕方がないので、できる最善手で手早く対応します。
【彼女目線】
「今から会える！？時間調整して！」と言われるようなものです。
彼女にも彼女の都合があります。
あまり理由を聞いても、いい結果にはならないので、大人しく合わせてあげましょう。
こっちが冷たい態度を取ってはいけません。
他の予定があったとしても、それを表に出してはいけません。
そんなことよりも、彼女が一番大事なので。

むしろ「連絡くれてありがとうね！」みたいに何か一言言ってあげましょう。
相手との関係を崩さないことが大切です。

# 言ってたことと違う仕様変更が施される時もある
【システム目線】
仕様変更の連絡をしてから、先方の方で対応内容が少し変わることもあるでしょう。
そのフォローが間に合わない時もありますよきっと。
自分が開発しているものを、ちゃんと文字に起こして伝えることはできますか？

【彼女目線】
彼女が「あれやりたい！」と言って、こっちが合わせたにも関わらず
「やっぱり違う！」と言われることがあります。
しかし、それに腹を立てても仕方がありません。
大人しく彼女が満足するまで、彼女に合わせて動いてあげます。
全ては彼女が喜ぶためです。
「言ってたことと違うじゃないですか！」と言っても、喧嘩になるだけです。

# まとめ
結局仕様変更対応を柔軟にできると、それと同じ要領で彼女対応もできるはずです。
波風立てず、大人しく迅速に。
対応することが目的なので、それ以上のいらぬことは言いません。

# 最後に
仕様変更対応を対女性と話すときに少しでも心がけたら、恋愛も上手く行くかもしれません。
今回の記事は少しふざけてしまいお目汚ししてしまったかもしれませんが、
仕様変更も彼女対応も、とにかく相手に合わせて最速で最善手で動くことに変わりはありません。
温泉に入ってて、フッと気づきいつか書こうと思っていたのでこのタイミングで書きました。
それでは皆さん、よいクリスマスをお過ごしください！
配列を一定の要素数で分ける処理 Ruby編

```ruby:file.rb
#今回説明に使う配列
#要素数51
array = [
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
  10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
  20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
]

#新しい配列を格納するのに使う配列
new_array = Array.new

#古い配列を分割するサイズ
num = 10

while array.size() != 0 do
  new_array << array.shift(num)
end

print new_array
```

while文で行なっている処理
1. ローカル変数arrayの要素数が１つ以上あるかを判断。1つ以上あればwhile文のブロックを実行
2. arrayの先頭から10要素分を取り出し、新しい配列に追加

最後に新しい配列を出力


実行結果

```ruby
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34, 35, 36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47, 48, 49], [50]]
```
Three.jsを用いてBlenderデータ(.obj,.mtl)をHTMLに組み込んで表示する方法がわからない

Blenderで作ったデータを
Three.jsを用いて表示されたい

参考ページURL
https://reffect.co.jp/html/3d-model-mouse-operate#Example

コードが本文に入れれないんでURLで見てください

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Load a 3D model</title>
    <style>
        body { margin: 0; }
    </style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/loaders/OBJLoader.js"></script>
<script src="js/loaders/MTLLoader.js"></script>
<script>
    /* scene(シーン)の作成 */
    var scene = new THREE.Scene();

    /* camera(カメラ)の作成 */
    var camera = new THREE.PerspectiveCamera(50, window.innerWidth/window.innerHeight, 1, 1000 );
     
    /* renderer(レンダラー)の作成　*/
    var renderer = new THREE.WebGLRenderer({antialias: true});
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize( window.innerWidth, window.innerHeight );
    document.body.appendChild( renderer.domElement );
     
    /* Light(ライト)の設定 */
    var ambientLight = new THREE.AmbientLight( 0xcccccc, 2 );
    scene.add( ambientLight );
     
    /* camera(カメラ)の位置設定　*/
    camera.position.z = 250;
     
    /* camera(カメラ)をマウス操作する設定　*/   
    var controls = new THREE.OrbitControls(camera);
     
    /* MTLファイルとObjファイルの読み込み */           
    new THREE.MTLLoader().setPath('three/')
                         .load('try.mtl',function(materials){
        
        materials.preload();
        
        new THREE.OBJLoader().setPath('three/')
                             .setMaterials(materials)
                             .load('try.obj',function (object){
            
            object.position.y = - 95;
            scene.add(object);
            
        }); 
    });
     
    /* 繰り返しの処理　*/
            
    var animate = function () {
        
        requestAnimationFrame( animate );

        renderer.render( scene, camera );
        
    };

    animate();
                        
</script>  
</body>
</html>
```

-->
-----
変更した部分

```js
    /* MTLファイルとObjファイルの読み込み */           
    new THREE.MTLLoader().setPath('models/male02/')
                         .load('male02.mtl',function(materials){
        
        materials.preload();
        
        new THREE.OBJLoader().setPath('models/male02/')
                             .setMaterials(materials)
                             .load('male02.obj',function (object){
```


以上、コードを理解していない部分も多々ありますが
setPathの部分とloadの部分を変更して、
jsのデータもフォルダ内に格納しているんで
これをすれば何かは出力されるはずだが
なにもされないです。

原因を教えてください
vagrant upしてもdestroyしても立ち上がらない

LaravelのHomesteadを作って作業していたが、うっかりVirtualBoxから仮想マシンを消してしまった。
いろいろ復元しようとしたが上手くいかなかったので、諦めていちから再構築しようとしたら、同じ名前で作り直したHomesteadが立ち上がらない。

```
A VirtualBox machine with the name 'homestead' already exists.
Please use another name or delete the machine with the existing
name, and try again.
```

Homesteadのフォルダはいったん削除して、新たにgit cloneしなおして作成したし。
Laravelのプロジェクトも新たに作成したし。
「vagrant global-status」で変に残ってたvagrantもdestroyしたし。
なのに動かない。

#原因
VM VirtualBox Mangerを立ち上げてみたところ、同じ名前の仮想マシンがあった。
これを除去してからvagrant upを実行したら、立ち上がりましたよ。

あのエラーメッセージって、VirtualBoxに同じ名前があるってことだったのね。
って、そう書いてあるやんか！

大変失礼いたしました。
自分への戒めとして投稿しておきます。
テキストの暗号化について(AES暗号化)

初投稿です！

Pythonを勉強している中で、パスワードの暗号化をやりたい！と思い調べてみました。
暗号化のパッケージとしてはpycryptoが有名のようで、Anacondaでもインストール可能だったため、今回はpycryptoを使って、文字列のAES暗号化についてまとめてみます。

# 参考文献
AES暗号化を学ぶ上で参考にしたリンクは以下の通りです。
[https://blanktar.jp/blog/2013/04/python-crypto-aes.html](https://blanktar.jp/blog/2013/04/python-crypto-aes.html)
[https://ujise.com/2019/08/23/post-1869/](https://ujise.com/2019/08/23/post-1869/)
[https://ja.wikipedia.org/wiki/Advanced_Encryption_Standard](https://ja.wikipedia.org/wiki/Advanced_Encryption_Standard)

# 実装
では、実際のコードです。下記のコードはパスワードのテキスト文を渡し、暗号化&複合化するものです。暗号化データはpassword_data_fileとして保存されます。

```python:pycrypto.py
from Crypto.Cipher import AES

# キー設定関数
def create_key(KeyWord):
    key_size = 32
    KeySizeFill = KeyWord.zfill(key_size)
    Key = KeySizeFill[:key_size].encode('utf-8')
    
    return Key

# パスワードの暗号化関数
def encryptOn(PassWord, KeyWord):
    iv = "1234567890123456"   # 初期化ベクトル設定
    Key = create_key(KeyWord) # キー設定

    obj = AES.new(Key, AES.MODE_CFB, iv)
    ret_bytes = obj.encrypt(IPassWord)　#パスワードの暗号化
    
    # 暗号化ファイルの出力    
    OFileName = "password_data_file"
    with open(OFileName, mode='wb') as f:
        f.write(ret_bytes)

# パスワードの複合化関数
def encryptOff(KeyWord):
    # パスワードファイルの読み取り
    PassFile = "password_data_file"  
    with open(PassFile, 'rb') as f:
        EnPass = f.read() # 暗号化されたパスワード 

    iv = "1234567890123456"   # 初期化ベクトル設定
    key = create_key(KeyWord) # キー設定

    obj = AES.new(key, AES.MODE_CFB, iv)
    OPassword = obj.decrypt(Pass).decode('utf-8') #パスワードの複合化

    return OPassword

if __name__ == '__main__':
    IPassWord = "modelPass"
    KeyWord = "login_file"
    
    # 暗号化関数呼び出し
    encryptOn(IPassWord, KeyWord)
    # 複合化関数呼び出し
    OPassWord = encryptOff(KeyWord)

    print(OPassWord)
```

# 最後に
最初に参考のコードを見たときは、複雑だな〜分かるかな？と思ったけど、案外単純なロジックです。キーとベクトルが単純に直書きしてるだけなので、この二つを暗号化ごとに変えないと見破られちゃな。
Three.jsでプリセットのマテリアルに独自の処理を追記する。

ShaderMaterialではなくその他プリセットのマテリアルを使って追記したいときは、onBeforeCompileを使う。

```javascript
mesh.material.onBeforeCompile = function (shader){
    shader.fragmentShader = shader.fragmentShader.replace('gl_FragColor = vec4( outgoingLight, diffuseColor.a );','gl_FragColor = vec4( 0.5,0.5,0.5, diffuseColor.a );');
};
```

shader.fragmentShader/shader.vertexShaderが文字列なので、テキストの文字列を好きなように書き換えればOK。


CSSのtransitionをひとつ付けようがイチからWebGLでやろうが単価は変わらないのがこの世の真実なので、時短に勤しんで、さっさと仕事を片付けましょう😉

uniformも追加可能。mrdoobの解説。
https://github.com/mrdoob/three.js/issues/11475
Javascript + sinon スタブの実践的利用

# tl;dr
完成した関数をテストしたいが、未完成の関数をコールしているのでunit testができない。
その場合の対処です。

# 確認環境
- node: v10.17.0
- npm: 6.11.3

# プロジェクトの準備

### 以下のコマンドを実行します。
```
mkdir play_utest
cd play_utest
npm init
npm i --save-dev chai mocha sinon
touch index.js index.spec.js
```
### `package.json`を変更します。

```Diff
{
  "name": "play_utest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
-   "test": "echo \"Error: no test specified\" && exit 1"
+   "test": "mocha *.spec.js"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "chai": "^4.2.0",
    "mocha": "^6.2.2",
    "sinon": "^7.5.0"
  }
}
```

# テスト対象のコード
index.jsを編集します。
main()関数が単体テストの対象(SUT)です。
doubleNumber()をコールしていますが、この関数はまだ中身を作っていません。

```Javascript:index.js
const doubleNumber = (x) => {
  // ここに、xを2倍にして返すロジックを書く予定 
  return 0; // 暫定
}

const main = (x) => {
  const answer = doubleNumber(x);
  return answer + 1;
}
module.exports.main = main
```
# テストコード
index.spec.jsを編集します。

```Javascript:index.js
const sinon = require("sinon");
const expect = require("chai").expect;
const index = require('./index.js');

describe('index.js', () => {
  it('main(n)のテスト: n = {0, 5, -1}', () => {
    expect(index.main(0)).equal(1)
    expect(index.main(5)).equal(11) 
    expect(index.main(-1)).equal(-1)
  })
})

```
main()関数の引数に、{0, 5, -1}を渡したケースで単体テストを行いたいと考えています。
doubleNumber()関数は、暫定的に0を返すようにしているため、引数0のケースだけテストが成功しそうですが、それ以外のケースだと想定する結果になりません。

# テスト対象コードを、テスト向けにリファクタ
doubleNumberをテストスタブに置き換えるため、クラスでラップします。このクラスもmodule.exportsを使って外部公開します。

```Diff:index.js
const doubleNumber = (x) => {
  // ここに、xを2倍にして返すロジックを書く予定 
  return 0; // 暫定
}

const main = (x) => {
-  const answer = doubleNumber(x);
+  const answer = helpers.doubleNumber(x);
  return answer + 1;
}
module.exports.main = main

+ class Helpers{
+   doubleNumber(x) { return doubleNumber(x) }; 
+ }
+ const helpers = new Helpers();
+ module.exports.helpers = helpers;

```


# テストコードを変更
doubleNumber()のスタブを作成します。

```Diff:index.spec.js
const sinon = require("sinon");
const expect = require("chai").expect;
const index = require('./index.js');

describe('index.js', () => {
  it('main(n)のテスト: n = {0, 5, -1}', () => {
+   const stub = sinon.stub(index.helpers, 'doubleNumber');
+   stub.withArgs(0).returns(0);  // 引数が0の時、0を返す
+   stub.withArgs(5).returns(10);  // 引数が5の時、10を返す
+   stub.withArgs(-1).returns(-2);  // 引数が-1の時、-2を返す

    expect(index.main(0)).equal(1)
    expect(index.main(5)).equal(11)
    expect(index.main(-1)).equal(-1)
  })
})
```

# テストの実行
以下のコマンドでテストを実行します。

```
npm test
```

結果：

```
> mocha *.spec.js

  index.js
    ✓ main(n)のテスト: n = {0, 5, -1}

  1 passing (11ms)
```
SlackからMattermostに移行して1週間たったので感想を書いてみる

私の勤務先でSlackからMattermostに移行しました．
本格的に使用して1週間経過しての感想です．
Mattermostのバージョンは5.16.3です．

# 機能に大きな違いはない

移行前にテストしつつ確認したので特に大きなトラブルはありません．
細かな違いはあるものの，大きな違いはないと思います．

# 絵文字リアクションが一覧できない

Slackから移行した結果，個人的にはいまのところこれが大きくUXを低下させている印象です．

Slackでは画面右上の`@`ボタンを押すとメンションに加え，絵文字リアクションの一覧が表示されました．
自分のポストに対する「オッケーです」「了解です」「Good Job」のようなリアクションが一覧できるため，絵文字リアクションと`@`ボタンでコミュニケーションが成立していた面が大きいです．

Mattermostでは同様に`@`ボタンがありますが，メンション一覧のみの表示です．
この場合，相手のリアクションは自分がポストしたチャネルを次に表示したタイミングでないとわからないわけで，Slackと同様のコミュニケーションが成立しません．
すでに自分のポストが流れていてそもそもリアクションに気づかない，ということも起こります．

Mattermostでは絵文字リアクションではなく，ポストで直接リアクションしないと円滑なコミュニケーションが成立しないのかなー，という印象です．

# その他

Slackと比較してアプリ連携が貧弱というレビューをよく見ます．
これについてはSlack利用時もあまり活用できていなかったので，いまのところ大きな影響はない印象です．
社内で使っているGitbucketやJenkins等との連携はSlackと同様できています．

細かいところではいろいろ違いはありますが，そのうち実装されるだろうなーという気がします．

絵文字リアクションについてはどうなんでしょうね．絵文字リアクションでコミュニケーションするのってあまり一般的な文化じゃないのかな．
Ansible で Mackerel を操作するプラグインを作りました！

（この記事は [地平線に行く](https://yujisoftware.hatenablog.com/entry/ansible-mackerel-module) とのマルチポストです）

Ansible で Mackerel の設定を取得したり変更したりできたらなーと思う時があります。
例えば…

* アラートが鳴ってしまうのを防ぐために、Ansible 実行中はホストのステータスを standby にしたい
* 特定のロールが設定されているホストの場合だけ、ファイルをコピーしたい

でも、Ansible の command モジュールで mackerel-agent を実行してこのような処理をさせるのは手間がかかります。
そこで、 **Ansible の設計にのっとった形で簡単に Mackerel を操作できるように、プラグインを作ってみました！** [^official]

[^official]: すでに [mackerelio/ansible-mackerel-agent](https://github.com/mackerelio/ansible-mackerel-agent) というのがあるのですが、これは mackerel-agent をインストールするための Ansible テンプレートです。一方で、今回作ったプラグインは Mackerel API のラッパーです。

https://github.com/YujiSoftware/ansible-mackerel-module

# どういう風に使えるの？

例えば、**Ansible 実行中はホストのステータスを standby にしたいとき。**

```yaml
- name: Set Mackerel Host Status
  mackerel_host:
    status: standby

# ～ホストの更新処理～

- name: Set Mackerel Host Status
  mackerel_host:
    status: working
```

**ホストのロールを設定したいとき。**

```yaml
- name: Set Mackerel Host Role Fullnames
  mackerel_host:
    role_fullnames:
      - test_project:web
```

**ロールによって動作を変えたいとき。**

```yaml
- name: Get Mackerel host configuration
  mackerel_host:
  register: mackerel

- name: Copy file if roles has "test_project"
  copy:
    src: ../files/example.conf
    dest: /etc/httpd/conf.d/
  when: mackerel['host']['roles']['test_project'] is defined
```


こんな感じに使えます！
（ちなみに、API Key や Host ID はサーバ内にある mackerel-agent の設定ファイルをデフォルトで読み取るので、記述は不要です）


詳しい使い方は、[GitHub の README をご覧ください！](https://github.com/YujiSoftware/ansible-mackerel-module)

# まとめ

まだ **ホストの情報取得/ステータス設定/ロール設定** しか対応していません。[^1]
今後、JOJOに対応する操作を増やしていく予定です。

[^1]: Mackerel Advent Calendar が空いてる！チャンスだ！と思って急いで作りました。

もし、こういうことができるようにしたい！という要望がありましたら、GitHub の Issues へ書き込んでいただければと思います。もしくは Up vote :thumbsup: をお願いします。
https://github.com/YujiSoftware/ansible-mackerel-module/issues

ぜひご利用ください！

---

次の Mackerel Advent Calendar 2019 は @kazeburo さんです！
[mackerel-plugin-pinging について - Hateburo: kazeburo hatenablog](https://kazeburo.hatenablog.com/entry/2019/12/09/102338)
#Stripe #API How to specify expandable fields ( example with Ruby  )

# e.g Retrieve Customer invoice setting default payment method with Ruby ( why null returns? )

# not expandable

```
customer = Stripe::Customer.retrieve('cus_xxxxxxxxxx')
```

# expandable

```
customer = Stripe::Customer.retrieve({ id: 'cus_xxxxxxxxxx', expand:  ['invoice_settings.default_payment_method'] })
```

# Expandable Document

![image](https://user-images.githubusercontent.com/13635059/70369421-6b585e00-18fc-11ea-9226-b19ebeeb0862.png)

https://stripe.com/docs/api/expanding_objects?lang=ruby

# How to find expandable specification

search API docs and 
![image](https://user-images.githubusercontent.com/13635059/70369433-9b076600-18fc-11ea-939f-5fe70c98fcc8.png)

invoice_settings.default_payment_method


# Japanese 

Stripe API で顧客のデフォルトの支払い方法が得られない、nullになるので拡張指定をする例

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2822








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->