OmniAICreator/Qiita-1.07M huggingface dataset:
gitlabプロジェクトの不要なプイプラインを削除する方法

# 概要
最近 gitlabはCI/CD及びパイプライン（pipeline)機能が入っている。デフォルト設定ではオンになり、既に別のCI/CD環境、もしくは、その機能を（まだ）使いたくない時、その機能を消したい時がある。`pipeline/job`が自動的に有効になり、プロジェクトの表示では、余計なパイプラインのアイコンが表示されている。

| ![gitlab_capture_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310585/f289cadf-c146-e442-7aac-ef344ac10eeb.png) |
|:-:|

そのアイコンをクリックすると、一覧のパイプラインが表示される。正しくCI/CD設定されていない場合、だいたいエラーで終了した状態である。

機能的は問題はないであるが、さっぱりきれいにしたい。但し、この時点では、webUIでその機能をサポートしていない。ここでAPIを使い、具体的に必要のないパイプラインを削除する方法を説明する。

# 環境
- gitlab CE 12.1.1
- postman 7.9.0


# 準備
まず、対象のプロジェクトのメンテナーであることは必要。他に、準備する必要なのは以下である。

  - API token 
  - プロジェクトID
  - パイプラインID

それぞれの準備について説明する。

## API tokenを取得する方法
gitlabの右上のユーザ・アイコンをクリックし、`Setting → Access Tokens` のパネルで、`api` を選択し、`Create Personal Token` をクリックすれば、個人用のtokenを発行することができる。


| <img width="1414" alt="gitlab_capture_02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310585/e91bfe2a-8616-37e2-cc7d-9d77f9995e44.png"> |
|:-:|

## プロジェクトID

プロジェクトの詳細表示で`プロジェクトID`が確認できる。

| <img width="1141" alt="gitlab_capture_04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310585/f8f51481-0013-7de0-f0c9-71f7d614fd01.png"> |
|:-:|


## パイプラインIDを確認方法
プロジェクト詳細表示のパイプライのアイクをクリックするもしくは左パネルの`CI/CD → Pipelines` から確認できる

| <img width="1489" alt="gitlab_capture_05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310585/ea13e5ba-2d5c-936f-c012-fff90cb5c872.png"> |
|:-:|


# パイプライン削除する
gitlabに対してREST APIを実施する。`curl` もしくは `api tool (postman)` 等からできる。この例では、`postman` の例を示す。

 1. `Header`に`Private-Token`のキーを作成し、準備したtokenの値を設定する
 2. メソッドは`DELETE`を選択する
 3. URLは `<gitlabのベースurl>/api/v4/projects/<取得したプロジェクトID>/pipelines/<取得したパイプラインID>`を設定する

| ![gitlab_capture_031.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310585/f900d0f4-8006-6871-0335-0e1406d2edf7.png) |
|:-:|

この状態で`Send`ボタンを押すと、該当パイプラインを削除することができる。

パイプラインIDを変更しながら、で全てのパイプライを削除し、パイプライの状態を消すことができる。

| <img width="995" alt="gitlab_capture_032.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310585/81c7118e-e720-b976-f235-157fa4786831.png"> |
|:-:|

# まとめ
postmanの例でgitlabプロジェクトに必要ないパイプライン削除することについて説明した。postmanではなく、curlなどでも同じことが実施できる。例えば、上の例のcurlは以下です。

```shell:curl
curl -X DELETE \
  http://10.128.3.50/gitlab/api/v4/projects/85/pipelines/270 \
  -H 'Private-Token: <取得したtoken>'
```
【HTML、CSS、JSの書式】これを読めばコードが読める！書ける！まとめ！

Webサイトを作ってみたいが、作り方がわからない！そんな方向けに

* HTML、CSS、JSの位置付けを理解する
* 人が書いたコードが読めるようになる
* CodePenで自分でも書いてみる

というステップでWebサイト作りができるようになる記事を書きました。下記にまとめます。

# Webの基礎知識

まず、HTML、CSS、JSの位置付けを理解する。

* HTML：文書構造
* CSS：見た目
* JS：動作、変更

※参考：[【Webの基礎知識】書ける前に読む！HTML、CSS、JSの書式-1](https://www.i-ryo.com/entry/2017/10/25062057)

# HTMLの基本

タグと閉じタグで囲う「要素」の解説。

```html
<!--DOM要素-->
<タグ名 属性="値">テキスト</タグ名>
```

※参考：[【HTMLの基本】書ける前に読む！HTML、CSS、JSの書式-2](https://www.i-ryo.com/entry/2017/10/25/062221)

# CSSの基本

「セレクタ」「プロパティ」「値」などの解説。

```css
/*セレクタ*/
セレクタ {
    プロパティ: 値;
}
```

※参考：[【CSSの基本】書ける前に読む！HTML、CSS、JSの書式-3](https://www.i-ryo.com/entry/2017/10/25/062256)

# JSの基本-前編（オブジェクト、関数、変数）

オブジェクト指向「オブジェクト（何が）」「プロパティ（どうなる）」「メソッド（どうする）」や「DOM」「変数」「関数」などを解説。

```javascript
//プロパティ
オブジェクト.プロパティ = 値;

//メソッド
オブジェクト.メソッド(引数);

//変数
var 変数名 = 値;

//関数
function 関数名(引数){
//処理
}
```

※参考：[【JSの基本-前編】書ける前に読む！HTML、CSS、JSの書式-4](https://www.i-ryo.com/entry/2017/10/25/062333)

# JSの基本-後編（イベント、制御構造）

イベントと制御構造の解説。イベントは「いつ」にあたる部分。制御構造は「分岐」と「反復」。

```javascript
//イベントリスナ
オブジェクト.addEventListener("イベント名", 
//処理
, false);

//if文（分岐）
if (条件式) {
//処理
}

//for文（反復）
for (初期化式; 条件式; 増減式) {
//処理
}
```

※参考：[【JSの基本-後編】書ける前に読む！HTML、CSS、JSの書式-5](https://www.i-ryo.com/entry/2017/10/25/062403)

# ソースコード

GitHubにソースコードを追加（**2020/07/24追加**）

※参考：[ソースコード](https://github.com/ryo-i/HTML_CSS_JS_formats)

※参考：[プレビュー](http://ryo-i.github.io/HTML_CSS_JS_formats/)

# HTML、CSS、JSの基本（動画版）

上記の内容を抜粋した動画版。CodePen使ってYoutube上でライブコーディングしてみた。

※参考：[CodePenでHTML、CSS、JSを体験しよう【クモコツ一人もくもく会-1】](https://www.i-ryo.com/entry/2019/10/09/070250)

YoutubeのURLはこちら！

※参考：[CodePenでHTML、CSS、JSを体験しよう【クモコツ一人もくもく会-1】](https://www.youtube.com/watch?v=d9gznxnnXSs)
PowerShellにて配列から別コマンドの処理にマッチしたもののみを抽出

環境変数Pathから特定のフォルダを探すときなど、配列の項目にフィルタをかける(Pythonでいう`Filter()`)機会はたまにあると思います。

そのようなときには`Where-Object`コマンドを使うと便利です

```powershell
$Env:Path -split ";" | ? { Test-Path "$($_)\Lib\distutils" } #←C:\Python38\ などと出力される
```

?は`Where-Object`の短縮表記です。

上記の場合ですと、「環境変数Pathにあるパスの中で、`\Lib\distutils`というサブフォルダがあるパス(Pythonのディレクトリ)」を抽出します

一行で書ききれないような長い内容でフィルタしたいときは、その名もズバリ`filter`という構文でフィルタ関数を自作することも可能です(参考記事の＠ITの記事参照)

# 参考記事

* [PowerShellでのMap、Filter、Reduce \- or1ko's diary](http://or1ko.hatenablog.com/entry/20100125/1264425759)
* [PowerShellでよく使うパイプライン経由の処理をフィルタとして定義する － ＠IT](https://www.atmarkit.co.jp/)
LaravelでリダイレクトテストするとルートURLが返ってきてしまう


Laravel で、`->assertredirect()` を使ってPOST後に指定したページにリダイレクトできているかテストしようとした。
画面上では問題なく動作するのに、テストでは想定外のURLにリダイレクトしてしまう現象が起こり、少しハマった。


## 環境
Laravel 6.2.0

## うまくいかなかったテスト

記事を投稿をするテスト

```php

public function testCreatePost()
    {
        $response = $this
            ->post('post/create', [
                'title' => 'sample title'
                'text' => 'sample text'
            ])
            
        $response->assertRedirect('posts');
    }

```

テスト結果


```
There was 1 failure:

1) Tests\Feature\PostTest::testCreatePost
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'https://localhost/posts'
+'https://localhost'
```

画面上の動作でははちゃんと `/posts` にリダイレクトされてるのに、なぜルートURLに飛ばされることになってる？？

## 原因

リダイレクトテストをしたとき、`back()` で前の画面に戻されるが、テストの仕様上、前の画面は保存されていない。
よって、ルートURLの `https://localhost` が返されてしまう。



## 対策

`->from()` で前の画面を指定（リファラーを定義）する必要があった。

```php
public function testCreatePost()
    {
        $response = $this
            ->from('posts') //追加
            ->post('post/create', [
                'title' => 'sample title'
                'text' => 'sample text'
            ])
            
        $response->assertRedirect('posts');
    }

```

これでうまくテストが通った！
【画像あり】CentOS 8インストール後に再起動しても初期画面に戻る問題

※ ご質問頂いたので追記

画面が押せない状態になっている場合は、実行中のCentOSを「電源オフ」にすれば選択可能状態になるかと思われます。

　　

（戒めも兼ねて）備忘録目的です。

# 背景＆問題
MacでLinuxを触れてみようとVirtualBox → CentOS8をインストールしようとしたところ、何度インストールしても何事も無かったかのように初期画面に戻る問題が発生。
「公開されたばかりのCatalinaの互換性？それともセキュリティソフトの設定？あるいはダウンロード中に何かしらファイル破損、もしくは...」と1日半ほど勝手に迷走しておりました。

# 環境
・ VirtualBox： 6.0.14 r133895
・ ホストOS： MacOS Catalina 10.15
・ ゲストOS： CentOS 8.0.1905

# 原因＆解決
起動時のブートメディアのHDD優先順位が光学より下だったことが原因でした（※画像は修正したもの）。
ブートローダがインストールしたCentOSを再起動で選ぶのにHDDが後だと初期の画面（でもインストールで容量は埋まってる）になっていた模様。
<img width="783" alt="スクリーンショット 2019-10-20 18.10.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434223/017b409f-8797-9753-90dc-218b9242605d.png">

# その他
非エンジニアで学習のため、表現ミス等あればどうぞご指摘ください🙇‍♂️

# 参考にさせて頂いたURL
https://teratail.com/questions/217845
http://park12.wakwak.com/~eslab/pcmemo/boot/boot3.html
https://wa3.i-3-i.info/word15558.html
【swifter】Twitter連携アプリを作るためのswifterの主な関数の使い方の記録[2021/5/22追記]

## Swifterとは
swiftで書かれたTwitter Framework.
ソースコードも公開されているため、使いやすい.
TWitterKitがサポート終了したし、こっち使えばいいんじゃね。

ソースコード ： [github : Swifter](https://github.com/mattdonnelly/Swifter)

## Swifterに用意された主な関数の使い方
### 連携する

```swift

    //login処理
    // swifter構造体の宣言
    let swifter = Swifter(consumerKey: <twitter consumer key>, consumerSecret: <twitter consumer secret>)
    // のちに使う変数
    var twitterTokenKey:String!
    var twitterTokenSecret:String!

    swifter.authorize(
            withCallback: URL(string: "swifter-<twitter consumer key>://")!,
            presentingFrom: self,
            success: { accessToken, response in
                print(response)
                guard let accessToken = accessToken else { return }
                twitterTokenKey = accessToken.key
                twitterTokenSecret = accessToken.secret
            }, failure: { error in
                print(error)
            }
        )
```

### tweetする
返り値はjsonデータ形式

```swift:
    // さっきゲットしたtwitterTokenKeyとtwitterTokenSecretを使ってswifterを宣言し直す
    swifter = Swifter(consumerKey: <twitter consumer key>, consumerSecret: <twitter consumer secret>, oauthToken: twitterTokenKey, oauthTokenSecret: twitterTokenSecret)
    
    swifter.postTweet(status: "Tweetの内容", success: { json in
            // 成功時の処理
            print(json)
        }, failure: { error in
            // 失敗時の処理
            print(error)
        })
```

### timelineを取得する
返り値はjsonデータ形式

```swift:
        // こっちは、連携中のユーザーのフォローしてるユーザーのツイートを時系列順に。
        swifter.getHomeTimeline(count: 50,success: { json in
            // 成功時の処理
            print(json)
        }, failure: { error in
            // 失敗時の処理
            print(error)
        })

        // こっちは、@~~~で指定したユーザーのツイートを時系列順に取得。        
        swifter.getTimeline(for: .screenName("<twitterの@~~~のuser名の~~~の部分>"),success: { json in
            // 成功時の処理
            print(json)
            
        }, failure: { error in
            // 失敗時の処理
            print(error)
        })
```

### ユーザーを検索する（2021/5/20追記
返り値はjsonデータ形式
twitterの検索結果一覧画面っぽいのを作るために、jsonデータの中からtwitterの名前とicon画像のurlとscreenNameを取得する。
他にもいろいろあるから、使いたい時にまた見てみる。

```swift:
        let searchString: String = "test" //検索ワード
        let pageNum: Int = 1 // 検索結果の何ページ目を返すか
        let requestNum: Int = 10 // 1ページあたり何件の結果を返すか
        swifter.searchUsers(using: searchString,
            page: pageNum,
            count: requestNum,
            includeEntities: false,
            success: { response in
                for i in 0..<self.requestNum {
                    print(response[i]["name"])
                    print(response[i]["screen_name"])
                    print(response[i]["profile_image_url_https"])
                }

            },
            failure: { error in
                print(error)
                print("failure")
            }
        )
```

## まとめ
他にも、twitter上での操作はコードを通して全部できるようになってるっぽかったから、ソースコード見て必要な機能があったら実装していこう。
Carthageのライブラリをユニットテストで使う方法

# 最初に
Carthageのライブラリを含めた上でXCTestによるテストを行うための手順を備忘録として残します。
なお、この記事はXCode11の使用を前提としています。

# テスト時に発生するエラー

`Alamofire` のようなライブラリをCarthageで取り込み、そのライブラリを含むテストの実行を試みた際、以下のようなエラーが表示されました。

> Undefined symbol: protocol witness table for Foundation.URLRequest : Alamofire.URLRequestConvertible in Alamofire

これはユニットテストのターゲットにライブラリ(この場合はAlamofire)をリンクしていないことによって起こる問題です。
このエラーを解消するには、以下の手順でライブラリをリンクする必要があります。

# リンクの設定
テストのターゲットを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/dff5fe17-9662-1282-0f7d-fc6c07402e6a.png)

`Build Phases` のタブを選択し、 `Link Binary With Libraries` セクションの `+` をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/63030fc7-1b01-8ba2-aaba-4f5ec1027296.png)

必要なライブラリを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/bb16f01d-40e9-586a-c541-eee9b91dea9c.png)

これで、テストターゲットとライブラリの間にリンクが設定され、テストが可能になります。


# 参考
[Adding frameworks to unit tests or a framework](https://github.com/Carthage/Carthage#adding-frameworks-to-unit-tests-or-a-framework)
STS(Spring Tool Suite)でEclipseのバージョンを確認する方法

EclipseにSTSを入れる形ではなく以下のSTSのサイトから直接いれたのでこのSTSのEclipseのバージョンが分からなかった。
<img width="1440" alt="スクリーンショット 2019-10-20 18.51.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514060/22c76f4e-2820-eef0-9eb3-9ba561ae8742.png">

この場合のSTSのバージョンは以下のようにSpring Tool Suiteについてから確認できる。
<img width="971" alt="スクリーンショット 2019-10-20 18.54.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514060/53bba5d0-1b19-2d5a-b74a-46426dbb5039.png">

このSTSのEclipseのバージョンを確認したい場合、ここからさらに、ポップアップウインドウのEclipseのマーク(?の真上のアイコン）をタップすると開く画面のEclipse PlatEclipse PlatformがそれEclipseの本体なのでこれのバージョンを確認すればOK。
<img width="1440" alt="スクリーンショット 2019-10-20 19.03.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514060/f8293b1f-97c3-5ef9-6972-52baf01bf734.png">
今回はこれがEclipceのバージョンとなる。
「Version: 4.13.0.v20190916-1323」
CodeBuild の buildspec.yml で `YAML_FILE_ERROR Message: did not find expected comment or line break` が発生

# 現象

buildspec.yml で CodeBuild を動かすと、以下エラーが発生してビルドがストップする。

```
[Container] 2019/10/16 11:28:42 Phase complete: DOWNLOAD_SOURCE State: FAILED 
[Container] 2019/10/16 11:28:42 Phase context status code: YAML_FILE_ERROR Message: did not find expected comment or line break at line 20
```

# 環境

- buildspec.yml の version: 0.2

# 原因

エラーが示した line 20 は以下の `$DRYRUN` ... の行。

```yaml
  build:
    commands:
      - [[ $DRYRUN != 1 ]] || bash -c "./deploy.sh -e ${BUILD_STAGE} ${MODE}"
```

当該行は、そもそも YAML の構文に従っていなかった。具体的には論理和 `||` の部分。
`|` が複数行を記述するための予約文字になっているため、文字列として認識されない。

同様に `&&` も `&` がアンカーの予約文字になっている。

# 対応

ダブルクオートでくくることで構文エラーを回避できる。

```yaml
      - "[[ $DRYRUN != 1 ]] || bash -c \"./deploy.sh -e ${BUILD_STAGE} ${MODE}\""
```

# 参考

- http://www.yamllint.com/
mypy-0.740 から object.__exit__() の返り値の判定が変化した話

つい先日(10/17)、[mypy](https://pypi.org/project/mypy/) 0.740 がリリースされました。そこでハマった話を共有します。

## mypy-0.740 が新たなエラーを出すようになった

新バージョンが出たことにより、mypy が以下のエラーを出すようになりました。

```
sphinx/util/docutils.py:186:5: error: "bool" is invalid as return type for "__exit__" that always returns False
sphinx/util/docutils.py:186:5: note: Use "typing_extensions.Literal[False]" as the return type or change it to "None"
sphinx/util/docutils.py:186:5: note: If return type of "__exit__" implies that it may return True, the context manager may swallow exceptions
```

0.740 から常に False を返す `__exit__()` は返り値の型に bool を使うべきではない、というエラーが出るようになりました。そして、ヒントとして `Literal[False]` を指定するか、None を返すようにコードを書き換えるべきだという Note が出ています。


しかし、 [Python のドキュメント](https://docs.python.org/ja/3/reference/datamodel.html#object.__exit__) では `object.__exit__()` の返り値は以下のように説明されており、False を返してもよいように見えます。

>もし、例外が送出され、かつメソッドが例外を抑制したい場合（すなわち、例外が伝播されるのを防ぎたい場合）、このメソッドは True を返す必要があります。そうでなければ、このメソッドの終了後、例外は通常通り伝播することになります。

これは一体どういうことでしょう。

## 変更を追いかけてみる

ということで、mypy と typeshed の変更点を拾い読みしてみたところ、[こんなイシュー (mypy#7214)](https://github.com/python/mypy/issues/7214)と[こんなコミット](https://github.com/python/typeshed/commit/b2947821832bb4d098985383c75c2d712b12f133)を見つけました。
細かいやり取りは読んでもらうとして、どうやらこのイシューがきっかけで mypy に新しい(暗黙的な)ルールを追加されたようです。

新ルールでは `__exit__()` メソッドの返り値によって、その振る舞いを次のように推測します。

* 返り値の型が bool の場合は例外を抑制する(可能性がある)
* 返り値の型が None の場合は例外を伝播する

このルールに則って mypy は「常に False を返す (= 例外を伝搬する)」 `__exit__()` メソッドの返り値に bool を指定すべきではない、と判定するようになったようです。

## どう対処するとよいか

エラーに従って

* 返り値の型を `Literal[False]` にする
* コードを書き換えて返り値を None にする (型も None にする)

と書き換えるか、伝家の宝刀 `# type: ignore` しかなさそうです。
ちなみに、手元では返り値を None に変更しました。

正確な返り値の型チェックのためには context manager の振る舞いを知る必要があるので致し方ないのですが、mypy 独自の(しかも暗黙の)ルールが登場するのはちょっと厳しいですね。


## 謝辞

@atsuoishimoto とのやりとりがきっかけでこの記事を書きました。いつもありがとうございます。
CloudFormation で `Security group *** did not stabilize` が出て UPDATE できない

# 現象

CloudFormation でセキュリティグループを更新しようとすると、15 分ほど進捗がストップした後 `did not stabilize` エラーが出て更新に失敗する。具体的なエラーメッセージは以下の通り。

```
2019-10-16 18:10:36 UTC+0900	***	UPDATE_FAILED	Security group SG1 did not stabilize
```

なお、エラーの前にはセキュリティグループが `creating one` されようとしている。

```
2019-10-16 17:55:11 UTC+0900	***	UPDATE_IN_PROGRESS
Requested update requires the creation of a new physical resource; hence creating one.
```

# 前提

- セキュリティグループ名を変更しようとしている
  - ここでは例として sg1 から SG1 に変更

# 原因

CloudFormation のエラーメッセージは不親切なことが多いので、実際にマネジメントコンソール上で手を動かしてエラーを再現させる。
`creating one` だったので、画面上から新規でセキュリティグループを作成したときに発生したエラーメッセージが以下。

> セキュリティグループの作成中にエラーが発生しました。
> The security group 'SG1' already exists for VPC 'vpc-xxxxx'

今回行おうとしている更新はセキュリティグループ名の大文字小文字の変更だが、どうやら AWS 上ではグループ名の大文字小文字は区別されないらしい。それによって `already exists` が生じていた模様。

# 対応

CloudFormation で、大文字小文字の以外の変更 (`sg1` → `SG1temp` など) をすると更新が成功する。
その後、本来変更したかったグループ名 (`SG1`) に再度変更することで、期待通りの更新ができる。
【OCI】DockerでOCI-CLIを実行する。

# はじめに

OCIを操作するOracle Cloud Command Line Interface（OCI CLI）の実行環境を用意する。
なるべく環境を汚したくない＆バージョンアップ楽にしたいタイプなのでDockerで用意します。

今回作成したDocker環境はGit hubで公開しています。
[manaki-naoe/docker-oci-cli
](https://github.com/manaki-naoe/docker-oci-cli)

## 準備

### Dockerfileの作成

```dockerfile:Dockerfile
FROM python:3.8.0-alpine3.10
LABEL maintainer "Manaki <manakinaoe@gmail.com>"

RUN set -xe && \
    apk add --no-cache --update \
        alpine-sdk \
        libffi \
        libffi-dev \
        openssl \
        openssl-dev && \
    pip install --upgrade pip && \
    pip install --no-cache-dir \
        oci \
        oci-cli

ENTRYPOINT ["/usr/local/bin/oci"]
```

### ConfigファイルとAPI Keyの設置ディレクトリを作成

```bash
$ mkdir .oci
```

### 構造

```bash
.
├── .oci
└── Dockerfile
```

### イメージの作成

```bash
$ docker build -t oci-cli .
```

## OCI CLIの実行

### 実行方法

> **※.ociがあるディレクトリで実行します**
> 
> ```bash
> $ docker run --rm -v ${PWD}/.oci:/root/.oci -it oci-cli:latest 《OCI CLI Command》
>```
> [OCI CLI Command Reference](https://docs.cloud.oracle.com/iaas/tools/oci-cli/latest/oci_cli_docs/)
>

---

### 実行例

> **ConfigファイルとAPI Keyの作成**
> 
> ```bash
> $ docker run --rm -v ${PWD}/.oci:/root/.oci -it oci-cli:latest setup config
> ```
>

---

## その他

> ### aliasでコマンドを楽にする
>
> 以下を~/.bashrcに追記します。
> 《Repository path》をご自身の環境に合わせて.ociがあるディレクトリに置き換えてください。
>
> ```bash:~/.bashrc
> alias oci-cli='docker run --rm -v《Repository path》/.oci:/root/.oci -it oci-cli:latest "$@"'
> ```
>
> 反映させる
>
> ```bash
> $ source ~/.bashrc
> ```
>
> 実行
>
> ```bash
> $ oci-cli --version
> 2.6.9
> ```
2019/8 AWS SysOpsアドミニストレータ（SOA) 合格した時にやったことまとめ

<img width="200" alt="20180612125850.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145192/637086db-7bd9-fa1a-75ef-7378f22b1c2b.png">

#はじめに
2019年8月にAWS SysOpsアドミニストレータ（以下SOA）に合格しました。
**SAAに合格してこれからSOA受験を検討している方向け**に情報を共有したいと思います。

私は7月下旬に1回受けて落ちてしまいましたが、8月11日に再受験して合格しました。

**結論から言うと試験範囲と勉強の対象となるサービスに目星をつけてWhizlabsのPractice Tests2019を2周以上してください**

AWS support
AWS shield
config
cloudformation
cloudtrail
cloudwatch
IAM
Organizations
WAF
…とか。

不合格になったのは私の準備不足です。
ちゃんとドキュメントを確認しながら勉強することで不合格から2週間後に合格することができました。

目次
・スケジュール
・教材とツール
・やり方
・余談  ーAWS資格本を安く購入する方法ー

#スケジュール
7/15〜16 AWS SOAについて情報収集
7/17〜27 WEB問題集・BlackBeltで学習
7/28 AWS SOA受験 不合格
7/29〜8/10 WhizlabsのAWS SOAを購入。Practice Tests2019を2周半、AWSのドキュメント
8/11 AWS SOA受験 合格

#教材とツール
**Whizlabs・Blackbelt・AWSの各種サービスのドキュメントがおすすめ**

[Whizlabs](https://www.whizlabs.com/aws-sysops-administrator-associate/)
<img width="1257" alt="スクリーンショット 2019-10-20 18.15.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145192/79f03ff5-902f-2b96-2978-3013aece7b9e.png">

ここは英語のサイトですが問題が充実していてかつリーズナブルな価格で大変助かりました。読めなければChromeの翻訳を使えば問題なく学習を進めることができます。
Practice Tests2019をとにかくやりましょう。
あとLabsというAWSのチュートリアルもついてくるのでオススメです。
SAPやDEVの教材もあるので頼もしい。
**700問とAWSのチュートリアルが使えて$19.95**です。

[AWS サービス別資料 BlackBeltセミナー](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)
<img width="1257" alt="スクリーンショット 2019-10-20 18.19.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145192/e56495f9-2d6f-9f21-89e8-8b4a1f55e6f2.png">

ログ周りについてめちゃくちゃ問われるので、そのあたりのサービスは全部見ておきましょう。

[AWS 各種サービスのドキュメント](https://docs.aws.amazon.com/ja_jp/)
<img width="1253" alt="スクリーンショット 2019-10-20 18.21.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145192/dd07ee20-7ef7-a5a0-e5a2-bda4c379b541.png">

BlackBeltでは取り上げられない細かい話はやっぱりドキュメントを見るに限ります。
問題を一通りやった後に答え合わせの時などに見ると理解が深まります。

[WEB問題集で学習しよう](https://aws.koiwaclub.com)
SOAの問題集もありますが、ちょっと問題がそれほど多くありません。
SAAの勉強時にSOAまで学習できるプランで登録していたら。

[Scrapbox](https://scrapbox.io)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145192/7fa89142-ab1d-1965-b248-a9dc78f05ed6.png)

私はメモを全部これで取りました。画像の貼り付けやメモがすごく楽。
昨年までは手書きでやっていたのですが、どうしても書くことそれ事態にとても時間がかかってしまうのと、PCとノートをそれぞれ見ながらやるのに疲れてしまったので、現在はこれだけ使っています。

#やり方（最初からこうしておけよかった…）
**WhizlabsとAWSドキュメント、BlackBeltをぐるぐるしてください**

1〜2日目 SOAについて情報収集と受験予約
書籍やWEBで情報収集します。試験範囲や合格記・不合格記などから情報を集めて、どのくらいで合格できそうか目星をつけてスケジュールに落とします。

3日目〜試験日 Whizlabs・BlackBelt・AWSドキュメント
個人的に問題集はWhizlabsのみでいいような気がしています。英語ではありますが問題が充実していてかつ解説もあり、なにより**安価**です。
Whizlabsをやりながら、分からないところはドキュメントを見ながらやりましょう。


#余談  ーAWS資格本を安く購入する方法ー
流れ
**フリマで定価より安いAWS資格本購入 → AWS資格合格 → AWS資格本を購入した価格でフリマに出品**

資格本の購入は、面倒でなければフリマアプリを推奨します。
なぜなら定価の7~8割程度の価格で売ることができるからです。

またAWS資格本は厚みもそれほど無いので、クッション付きの封筒でも問題なく梱包することができます。

フリマで買ってフリマで売却することで費用を最小限に抑えることができます。なぜならフリマで購入した時についてきた梱包材をそのまま出品する際に流用することができるからです。（もちろん物によりますが）
yarn install 時に Incorrect integrity when fetching from the cache とエラーが発生した時の対処法

## 問題

`yarn install` 時に以下のエラーが発生した。

```
error Incorrect integrity when fetching from the cache
```

## 解決策

```
yarn cache clean
```

上記のコマンドによりグローバルキャッシュが消去される。

## 参考文献
[yarn cacheに関して]
https://yarnpkg.com/lang/ja/docs/cli/cache/
PythonからRustに乗り換えたときに使える小技メモ

# 動機
`C/C++`から出発して主に`Python`を使う筆者．現在は，速度と安全性を求めて`Rust`を学習している．
そこで，本稿では`Python`の構文に対応する`Rust`の構文をまとめておく．
また，新たに知り得た段階で随時更新していくこととする．

# 実行環境

```
Python = 3.7.4
rustc = 1.38.0
```

# 本題
厳密に「1対1対応」なのかは考慮しないものとする．

## キャスト
個人的によく使うもの．

```python
a = int('1') # str -> int
b = str(1)   # int -> str
```

```rust
fn main(){
  let num: i32 = "1".parse().unwrap(); // str -> int
  let s: String = num.to_string();     // int -> str
}
```
## `enumerate()`

```python:enumerate.py
lst = [1, 2, 3, 4]
for idx, v in lst.enumerate():
  print(idx, v)

# OUTPUT:
# 0 1
# 1 2
# 2 3
# 3 4
```

```rust:main.rs
fn main(){
  let vec = vec![1,2,3,4];
  for (idx, v) in vec.iter().enumerate(){
    println!("{} {}", idx, v);
  }
}
```

## `zip()`

```python:zip.py
vec = [1,2,3,4]
tor = [5,6,7,8]
for v, t in zip(vec, tor):
  print(v, t)

# OUTPUT:
# 1 5
# 2 6
# 3 7
# 4 8
```

```rust
fn main(){
  let vec = vec![1,2,3,4];
  let tor = vec![5,6,7,8];
  for (v, t) in vec.iter().zip(tor.iter()) {
    println!("{} {}", v, t);
  }
}
```

## `exit()`
```python
import sys

sys.exit(0)
```
```rust
std::process;

fn main() {
  process::exit(0);
}
```
あくまで安全にプログラムを終了させるだけなら`return;`で良いらしい．

```rust
fn main() {
  //...(some codes)...
  return;
  //...(some codes)...
}
```

## `subprocess`

`subprocess`という[crate](https://crates.io/crates/subprocess)もある．

```python
import subprocess as sp

sp.call("ls -al", shell=True)
```

```rust
use std::process::Command;

fn main() {
  let mut child = Command::new("sh").arg("-c")
      .arg("ls -al").spawn().expect("failed to execute process");
  let ecode = child.wait().expect("failed to wait on child")
  assert!(ecode.success());
}
```
[参考](https://doc.rust-lang.org/std/process/struct.Child.html)

## `dict`
Pythonでいうところの辞書型`dict`はRustでは`HashMap`となる．

```python
d = {'a':[1,2,3], 'b':[4,5,6]}
```

```rust
use std::collections::HashMap;

fn main(){
  // d = {'a':[1,2,3], 'b':[4,5,6]}
  let mut map: HashMap<char, Vec<usize>> = HashMap::new();
  map.insert('a', vec![1,2,3]);
  map.insert('b', vec![4,5,6]);
}
```

### Keyがあるかどうかの確認

```python
print('a' in d) # -> True
```

```rust
println!("{:?}", map.contains_key(&'a')); // -> true
```


## `dict`の中身の`list`の要素を削除 
詳しくは[別の記事](https://qiita.com/Scstechr/items/4601687c8ff617c49c8e)を参照

```python
# まずはIndexを取得する
index = d['a'].index(1)
# 要素の削除
del d['a'][index]
```

```rust
// まずはIndexを取得する
let index = map[&'a'].iter().position(|x| *x == 1).unwrap();
// HashMapの要素に対するIndexMutは無くなってしまったので代わりにget_mut()を使う
map.get_mut(&'a').unwrap().remove(index);
```

## `sum`

```python
lst = [1, 2, 3, 4]
print(lst.sum()) #=> 10
```

```rust
let lst = vec![1,2,3,4];
let lst_sum: u64 = lst.iter().sum();
println!("{}", lst_sum); #=> 10
```
PythonでPDFからテキスト抽出

#はじめに
全文検索などで、PDFのデータをテキストとして抽出したい場合があります。
PyPDF2というライブラリはいけそうですが、日本語がある場合は
pdfminer.six、Apache Tikaのいずれかを使って日本語を抽出することは可能です。

抽出する関連ライブラリをメモします。

#Tikaで抽出するサンプル
##Tikaインストール
`pip install tika`

##サンプル
```pdf.py
from tika import parser

pdf = parser.from_file("C:/var/k_ryouyouhi_shinseisho.pdf")

print(pdf["content"])
```

実行すると、JARファイルをダウンロードされますね。テキストも正しく抽出されました。

```
python .\pdf.py
2019-10-20 18:08:52,392 [MainThread  ] [INFO ]  Retrieving http://search.maven.org/remotecontent?filepath=org/apache/tika/tika-server/1.19/tika-server-1.19.jar to C:\Users\username\AppData\Local\Temp\tika-server.jar.
```

#pytesseract
pytesseract: https://pypi.org/project/pytesseract/

>Python-tesseract is an optical character recognition (OCR) tool for python. That is, it will recognize and “read” the text embedded in images.

画像、チャートがある場合、画像、チャートに入っている文字の抽出も可能のようです。

#camelot

camelot: https://camelot-py.readthedocs.io/en/master/

camelotはPDFからテーブルのデータフレームを取得できるようですが、
ローカルでGhostScriptエラーがあって、３２，６４ビットを両方インストールすると、インストールしていないエラーが解消されましたが、
下記のエラーがあって一旦動作確認はやめました。

```
File "C:\Python37\lib\site-packages\camelot\ext\ghostscript\_gsprint.py", line 169, in init_with_args 
    rc = libgs.gsapi_init_with_args(instance, len(argv), c_argv)
OSError: exception: access violation writing 0x00000080
```

`pip install camelot-py[cv]`を実行すると、関連するパッケージはclick, jdcal, et-xmlfile, openpyxl, PyPDF2, sortedcontainers, pdfminer.six, opencv-python, camelot-pyも一緒にインストールされます。

あとはghostscriptをダウンロードしてインストールできます。（Windowsの場合は32ビットが必要みたいです）
ghostscript: https://www.ghostscript.com/download/gsdnld.html


以上
React + Next.jsで画像をimportする

# 困ったこと
Reactで画像のパスが読み込めない

```typescript:logo.tsx
const logo = require('../../assets/images/logo.png')
// =>
// [ error ] ./src/assets/images/logo.png 1:0
// Module parse failed: Unexpected character '�' (1:0)
// You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See 
// https://webpack.js.org/concepts#loaders
// (Source code omitted for this binary file)

```

# 原因
画像ファイルのパスをパースできない

# 解決
1. url-loaderを追加する
2. next.config.js にその設定を追加する

```bash
yarn add url-loader
```

```typescript:next.config.json
module.exports = withSass(withTypescript({
    [...]
    // ここから
    config.module.rules.push({
      test: /\.(png|jpg|gif|svg)$/,
      use: {
        loader: 'url-loader',
        options: {
          limit: 100000
        }
      }
    })
    // ここまで

    return config;
  }
}));
```

# 画像の読み込み方について
importよりrequire使った方がよさそう。

```typescript:logo.tsx
const logo = require('../../assets/images/logo.png')
```

# 参考ページ
https://whoisryosuke.com/blog/2018/nextjs-tip-using-media-in-css/
【SpringBoot】警告「javax.annotation.meta.Whenのクラス・ファイルが見つかりません」への対処

# 問題
既存の`SpringBoot`プロジェクトで、ビルドすると「*Warning:java: 不明な列挙型定数ですjavax.annotation.meta.When.MAYBE 理由: javax.annotation.meta.Whenのクラス・ファイルが見つかりません*」という警告が出る状況でした。

これは以前から出ている警告であり、最小構成で何とか再現できないものかと試しましたが再現できませんでした。
よって、何の依存によってこの警告が出ているのかは確認していません。

# 原因
`mvn dependency:tree`して調べたところ、`javax.annotation`パッケージは`spring-boot-starter-tomcat`によって追加されていましたが、その中には`meta`パッケージが含まれておらず、当然`javax.annotation.meta.When`も定義されていませんでした。

# 対処法
要するに`javax.annotation.meta.When`が定義されていれば良いので、それを含む依存を持ってくれば解決します。

調べた限り一番手軽な方法は、以下リポジトリより`FindBugs JSR305`を持ってくる事でした。

- [Maven Repository: com\.google\.code\.findbugs » jsr305 » 3\.0\.2](https://mvnrepository.com/artifact/com.google.code.findbugs/jsr305/3.0.2)

## 補足
[`javax.annotation`リポジトリ](https://mvnrepository.com/artifact/javax.annotation)には`jsr305`という名前のライブラリが存在します（記事執筆時点ではバージョン0.1と1.0が存在）。

- [Maven Repository: javax\.annotation » jsr305](https://mvnrepository.com/artifact/javax.annotation/jsr305)

ただ、こちらのリポジトリは、バージョン0.1の方は依存へ正常に追加する方法が分からず、1.0の方は以下のリポジトリを追加しなければ動かないという状況でした。
1.0の方で警告が消えるのは確認しましたが、リポジトリを追加する必要があったり、1.0の最終更新は2014年だったりとちょっと怖い状況だったので、`FindBugs JSR305`を持ってくるのが無難だと思います。

```xml:pom.xml
<repositories>
    <repository>
        <id>hippo</id>
        <name>Hippo Maven 2</name>
        <url>https://maven.onehippo.com/maven2/</url>
    </repository>
</repositories>
```

# 雑感
ここまで書いておいてなんですが、関係なさそうな物を追加しなければ動かなかったり、`FindBugs`は2017年で開発終了していたりと、対処法の方もちょっと不安がある状況なので、実害が無ければこの警告は放置する方が無難という気がします。

# 参考にさせていただいた記事
- [java compilation error using findbugs\. com\.sun\.tools\.javac\.code\.Symbol$CompletionFailure: class file for javax\.annotation\.meta\.When not found \- Stack Overflow](https://stackoverflow.com/questions/11104667/java-compilation-error-using-findbugs-com-sun-tools-javac-code-symbolcompletio)
- [essentials\-intellij\-plugin/essentials\_pom\.xml\.ft at 10e9969c4bd1299630e9f29ce21962d1fd0ce284 · machak/essentials\-intellij\-plugin](https://github.com/machak/essentials-intellij-plugin/blob/10e9969c4bd1299630e9f29ce21962d1fd0ce284/src/main/resources/fileTemplates/internal/essentials_pom.xml.ft)
周期関数の周期を知りたかったので、がんばった。～pythonを使って～

# 周期的に変化する関数の周期を知りたい
　計算の結果が周期関数的なふるまいをすることがあり、その周期の具体的な値を求めたいことがあります。そのため、任意の計算結果から周期を求めるアルゴリズムを自作してみました。適切なデータ間隔であれば良い精度で正しい値を求められそうです。

# 周期を求めるためのアイデアの説明
　周期関数$y = f(x)$が閾値$y = h$の上下で振動しているとします。基本的には、$h$を下から上、または、上から下に横切る時から$h = f(x_h)$となる$x_h$を3つ以上記録し、それらから周期を求めることがゴールです。しかし、不連続なデータの集まりである計算結果から正確な$x_h$をどのように求めたらよいでしょうか。ここで$h 
 \simeq f(x)$の$f(x)$が直線的なふるまいとなると仮定して、三角形の相似を用いることとしました。(下図)

![period.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481391/ae5df5df-c405-e285-f6aa-2bcc4f03e0af.png)

このように考えれば、$x_h$はデータ点$(x_i,y_i), (x_{i+1},y_{i+1})$から、

```math

x_h = x_i + (x_{i+1}-x_i) \times \frac{|y_i - h|}{|y_i - h|+|y_{i+1}-h|}

```
と求めることができるでしょう。

# プログラムの作製
　プログラムは以下のようになりました。$x_h$が3つ未満であればエラー文を返すのと、それ以上であれば各点から周期を計算して平均化し返すようにしました。使用したパッケージはnumpyだけです。

```python:
'''
周期的なふるまいの計算結果list_xとlist_yと
閾値thresholdを与えることで周期を返す関数
'''
import numpy as np

def period_checker(list_x,list_y,threshold):
    #xhを格納するためのリスト
    list_x_zero = np.array([])

    #xhを計算するためのデータ点を選別。thresholdから±0.5のyの値のみ。
    list_y_check = list_y[abs(list_y - threshold) < 0.5]-threshold
    list_x_check = list_x[abs(list_y - threshold) < 0.5]

    #選別したデータから、thresholdを横切る時タイミングを確認しxhを計算・記録。
    for i in range(list_y_check.shape[0]-1):
        if list_y_check[i]*list_y_check[i+1]<0:
            ratio = abs(list_y_check[i])/(abs(list_y_check[i])+abs(list_y_check[i+1]))
            list_x_zero = np.append(list_x_zero, list_x_check[i]+ratio*(list_x_check[i+1]-list_x_check[i]))

    #記録されたxhが3未満であればエラー文を返す。
    if list_x_zero.shape[0] < 3:
        return print('please input valid interval \n')
    #xhが3以上であれば、それらより周期を求め平均化したのち、求めたxhと周期を表示
    else:
        periodT = 0
        Num_of_period = 0
        for j in range(list_x_zero.shape[0]-2):
            periodT += list_x_zero[j+2] - list_x_zero[j]
            Num_of_period += 1
        periodT = periodT/Num_of_period
        return print('x(y = {:.4f}) \n'.format(threhold),list_x_zero,'\n period : {:.18f} \n'.format(periodT))
 
```

# プログラムのテスト
　周期関数の代表であるsin関数とcos関数でプログラムをテストしてみました。これらの周期の厳密解は$2 \pi$なので比較することでプログラムの正確性が測れるでしょう。
　例えば、$x$の範囲を$0$~$17$とし、その間を$5000$分割した時のsin関数とcos関数の周期を以下のように計算してみました。ついでにnumpyの組み込み関数を用いて$2 \pi$の値も表示しました。

```python:
In:
h = 0
list_angle = np.linspace(0,17,5000)
list_sin = np.sin(list_angle)+h
list_cos = np.cos(list_angle)+h

period_checker(list_angle,list_sin,h)
period_checker(list_angle,list_cos,h)

print(2*np.pi)
```

```python:
out:
x(y = 0.0000) 
 [ 3.14159265  6.28318531  9.42477796 12.56637061 15.70796327] 
 period : 6.283185307836515854 

x(y = 0.0000) 
 [ 1.57079633  4.71238898  7.85398163 10.99557429 14.13716694] 
 period : 6.283185307875393200 

6.283185307179586

```

　$x_h$がそれぞれ5つずつ記録されており、計算された周期が出力されました。また、組み込み関数の値と周期の値を比べると、それぞれの計算結果は$10^{-9}$の桁数まで一致していることが分かります。より分割数を増やすことでより高い精度の答えを求めることもできます。正確な結果を求めるには$h 
 \simeq f(x)$付近での十分なデータ数が必要なようです。

#まとめ

　周期関数の周期を求めるプログラムを作製してみました。十分なデータ点があればよい精度が求められそうです。よい補間法と組み合わせることで少ないデータ点から周期を求めることもできるかもしれませんね。それは、また思いついたときに……。
【Ionic】AdMob FreeのインストールとアプリIDの設定方法(Android/iosそれぞれ)

#初めに
どうもZizの田中です。今回はAdMob FreeのインストールとアプリIDの設定方法をAndroidとiosに分けてそれぞれ簡単に解説します。
バナー/インタースティシャル広告の具体的な実装が見たい方や動画で見たい方は[Zizのブログ](https://ziz-engineer.com/【ionic】admob-freeのインストールと具体的な実装方法/)で解説しているのでぜひ！

#前提
AdMobアカウント作成済みであること
Ionicプロジェクト作成済みであること

#まずはcordova-pluginをプロジェクトに追加
```Bash:
ionic cordova plugin add cordova-plugin-admob-free --save --variable ADMOB_APP_ID="【Android用のアプリID】"
```

※昔はconfig.xmlに書いていたようだが2019年10月時点では__Androidについては__cordova-pluginの追加時にアプリIDを追加するらしい

アプリIDはGoogle AdMobから該当アプリの広告を開いて『アプリの設定』をクリックすると確認できる

こんな感じ
![アプリID.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390321/89de31ac-452b-fdcf-41fb-4aa938f7dbfe.png)

#@ionic-native/admob-freeをインストール
```Bash:
npm install @ionic-native/admob-free 
```
#iosのアプリIDをconfig.xmlで設定
config.xmlにedit-configを2つ追加

```html:
<edit-config file="*-Info.plist" mode="merge" target="GADApplicationIdentifier">          
 <string>ios用のアプリID</string>
</edit-config>
```


```html:
<edit-config file="*-Info.plist" mode="merge" target="GADIsAdManagerApp">
 <true />
</edit-config>
```
※ios用のアプリIDには『アプリの設定』から確認した__ios用のアプリID__を入力する
※ios用の広告とAndroid用の広告はそれぞれ別に作る必要がある
CSSアニメーションで揺らぐ円を描いてみる

# CSSアニメーションで揺らぐ円を描いてみる

円の外側がゆらゆらしている円を描いてみます。

## 想定

理想形(結果)はこれです。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="yamaok" data-slug-hash="MWWbQZZ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="ShakingBall">
  <span>See the Pen <a href="https://codepen.io/yamaok/pen/MWWbQZZ">
  ShakingBall</a> by YamaOK (<a href="https://codepen.io/yamaok">@yamaok</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
## 素材
- html
- css
    - css-animation
- Vue

## 仮説
ゆらゆらしている円を描くにはどうしたらいいのか？を考えてみます。

1. 外側がそれっぽく波を打っていればいい?
2. 波を打つ = 凸凹を表現してあげればよい?
3. 角の丸み(border-radius)が異なるdivを適当な数、重ねて配置して回転すればよい？
4. 重ねたときに水っぽく見えるように色の透過度を調整してあげる必要がありそう

## 実践

### 円を重ねる

複数のdivを作成し、重ねます。
0. サイズの指定は適当に・・・揺らぎの幅を少なくしたい=正方形/大きくしたい=長方形
1. 表示位置を絶対指定にすることで重なるよう調整します。
2. 真ん中寄せにして必ず画面中央にします。
3. 色の透過度を指定する

```css
.ball{
    // 0.
    width:30em;
    height:30em;
    // 1.
    position:absolute;
    // 2.
    left:0px;
    top:0px;
    margin:0auto;
    // 3.
    background-color:rgba()
}
```

### 異なる角度の丸みを設定する

ここでVueを使います。
すべてhtmlで描くこともできますが、後々の設定変更に柔軟に対応できそうなのでVue側で制御してしまいます。

1. 描画する円の数は、Vueで指定します(後々、どれくらいの円を描けばちょうどよいか調整するため)
2. 描画する際の角の丸みについては、あまり角張るといけないのでこちらでいくつか定義します
3. 回転のスピードにも __ばらつきをもたせる__ ことで揺らぎをそれっぽくさせてみます

```html
<html>
<body>
    <div id="content">
        <div id="animationBlock">
            <div id="contentName"><span>Hello World</span></div>
            <!--1. これで、ballCount(int)の数分だけdivを描画できます-->
            <template v-for="count of ballCount">
            <!--2. 可変にしたいスタイルの定義はVueで定義したメソッドで出力します-->
                <div class="ball" :style="getCss(count)"></div>
            </template>
        </div>
</body>
</html>
```

```js
    const balls = new Vue({
        el:'#animationBlock',
        data:{
            //1. とりあえず10個あればいいと思いましたが、各自でちょうど良い数を定義してください
            ballCount:10,
            //2. 丸み付けのパターンをいくつか定義します
            // 丸みは正方形の場合、一辺の半分で円になってしまいます
            // したがって、半分未満の長さを指定します
            features:[
                {radius:13},
                {radius:13.5},
                {radius:14}
            ],
        },
        methods: {
            getCss:function(wave){
                //2.
                let feature = this.features[wave % this.features.length]
                //3.
                let duration = Math.floor(Math.random() * 10 % 5 + 2)
                return `border-radius:${feature.radius}em;animation-duration:${duration}s`
            }
        },
    })
```

### まとめ

応用させれば似たような揺らぎをもたせることはできそうだなあと思います。
今回は定義しませんでしたが、アニメーションの開始をずらす Or 開始位置をずらすなどしても面白いかもしれません。

できるかぎり可変にはしたつもりなので、皆さんの美的センスに合わせて改良してください。
例に描いたものはすべて自分のセンスですので・・・笑

皆さんのお役に立てれば幸いです。
【完全保存版】よく使うgitコマンド集【初心者・初級】

よく使うgitコマンドを共有します。無意識のうちにできれば、あなたはgit中級者以上です！

では、共有します。

## ①サーバーから最新版を取得
git fetch
git pull

## ②ローカルの差分確認
git status

## ③ローカルのファイルをコミット対象に追加
git add .

## ④ローカルでコミット
git commit

## ⑤サーバーへプッシュ
git push -u origin master

※Masterブランチに直接Pushするいうのは、複数人で作業する時は、基本ないと思うので、その場合は、devブランチ等へpushします
全ての開発者に知って欲しい5つの業務効率化ツール

>こちらの記事は、[Indrek Lasn](https://medium.com/@indreklasn) 氏により2019年 6月に公開された『 [Here Are 5 Productivity Tools Every Developer Should Know](https://medium.com/swlh/here-are-5-productivity-tools-every-developer-should-know-4a3f70783835) 』の和訳です。
本記事は原著者から許可を得た上で記事を公開しています。

私がプログラミングに関して学んだ最も重要なスキルは、おそらく適切な仕事に適切なツールを選ぶことでしょう。ハンマーしか持っていないと、すべてが釘のように見えてしまいます。そのため、開発者の生産性と満足度を向上させる新しいツールを常に探すことが重要なのです。

注意:私はここで紹介する会社やツールとは一切関係がありません。私がそれらを選んだのは、それらが単純とても便利だと感じたからです。

# [Insomnia](https://insomnia.rest/)

![](https://miro.medium.com/max/1542/1*XlQ7prVGHOqGdATPetKajw.png)

バックエンド、フロントエンド、フルスタックのいずれの開発者でも、APIを使った作業をする時があります。ほとんどのモダンアプリケーションのフロントエンドは、APIを介してバックエンドからデータを要求するような形式になっています。Insomniaはそういったクエリやリクエストをテストできる優れたツールです。

![](https://miro.medium.com/max/2208/1*cDa1nNziDVZgfWDevC87sQ.png)

P.S; Insomniaは無料で、GraphQLもすぐに使用できます。

# [Zoom](http://zoom.us)

![](https://miro.medium.com/max/1900/1*DIwmCY23ORFeztJ0zbjIww.png)

私は普段クライアントと通話することが多く、信頼性の高いビデオ会議ツールがあるに越したことはありません。たくさんのリアルタイムコミュニケーションを取るのに、Zoomは最適なツールだと思いました。

Zoomと[Muzzle](https://muzzleapp.com/)の組み合わせがオススメです。Muzzleはスクリーン共有中の恥ずかしいデスクトップ通知を無効化するシンプルなMacアプリです。ビデオ会議やライブコードラウンドを録画するときに特に便利です。

![](https://miro.medium.com/max/880/1*JXRKPGR4_7up2jN1KYqItg.gif)

# [Notion](https://www.notion.so/)

![](https://miro.medium.com/max/2844/1*Wh3McEkf81GeNtg1tUsOaQ.png)

Notionは私がこれまで使ってきた中でも最高のノート作成アプリケーションです。Notionはテーブル、トピック、分野ごとに様々なテンプレートを提供しており、ブラウザ拡張機能やモバイルアプリからも利用可能で、複数のアカウント間で同期することもできます。

ウェブ上で何か参考になりそうなものを見つけても、今すぐ読む時間がない場合、私はいつもNotionのブラウザの[拡張機能](https://chrome.google.com/webstore/detail/notion-web-clipper/knheggckgoiihginacbkhaalnibhilkk?hl=en)を使い資料として保存しています。

![](https://miro.medium.com/max/664/1*BeFnmM0cygrfsfggjg999g.gif)

# [Trello](https://trello.com/en)

![](https://miro.medium.com/max/2330/1*x7zFUAbMUFF8wbKQXb_4GQ.png)

Trelloはアジャイルチームのための軽量なカンバンボードサービスです。私は自分の仕事を整理するのが好きで、Trelloのおかげで簡単にそれができるようになりました。Trelloは、動きの速い小規模チームに最適です。

例えば、engineeringというボードを作成し、「To Do」、「進行中」、「完了済み」など各ステータスの列を作成します。このアプローチではチームの一人一人が何をすべきか、何をしているかなどの情報と同期、そして調整することができます。

# [Figma](https://www.figma.com/)

![](https://miro.medium.com/max/2260/1*Sn2Bt7muPVG6NpDK-wzL_Q.png)

Figmaはデザイナー、開発者、製品担当者向けの設計ツールです。Figmaはブラウザ上で動作するので、専用のアプリをダウンロードする必要はありません。デザイナーがFigmaを使ってくれると、それだけでチームがすべてのデザインアセット、色、幅、高さなどの情報にリンク一つで簡単にアクセスできるようになるので、とても助かります。

![](https://miro.medium.com/max/2558/1*BoTomHkaQkak7A2sUlTpDQ.png)

# 原著者からのメッセージ
読んでくれてありがとう、もしあなたのお気に入りのツールがある場合は、是非コメントでお知らせください。

# 翻訳協力　
Original Author:  **[Indrek Lasn](https://medium.com/@indreklasn)** 
Thank you for letting us share your knowledge! 

この記事は以下の方々のご協力により公開する事が出来ました。
改めて感謝致します。
選定担当: yumika tomita
翻訳担当: siho1
監査担当:  @nyorochan
公開担当: @aoharu
azure-cli の Docker イメージでタグを指定する

Azure CLI のDockerイメージがMicrosoftから提供されている。
https://docs.microsoft.com/ja-jp/cli/azure/run-azure-cli-docker?view=azure-cli-latest

ドキュメントではタグが指定されていないので分かりにくいが、ちゃんとバージョン毎のタグが設定されている。


```bash
> docker pull mcr.microsoft.com/azure-cli:2.0.75
2.0.75: Pulling from azure-cli
ff3a5c916c92: Already exists
471170bb1257: Already exists
d487cc70216e: Already exists
9358b3ca3321: Already exists
d4d73eb5841d: Already exists
060e2e842cfa: Pulling fs layer
f280a6b0a467: Pulling fs layer
a42502e42802: Pulling fs layer
141674a00574: Waiting
4ec0494b07aa: Waiting
601890f935e5: Waiting
```

うれしい。
カジュアル面接の行き方

## 〜宣伝〜

:::note info
個人開発でエンジニア専門マッチングサービスを開発しましたので、是非未経験からエンジニア目指している人！現役エンジニアで教えたい人！使ってみてください！

β版リリース記念キャンペーン中です！

10名様限定、抽選でお好きな技術本1冊プレゼント！
🎉当選者にはメッセージ差し上げます(送付の際に住所はお聞きしません)
詳しくはこちらから↓

https://x.com/dokupro01/status/1796837336145436846
:::
https://dokupro.dev/

# 目的

- 初めてカジュアル面談に行く方のハードルを下げる。

# この記事のターゲット

- カジュアル面談に行ってみたいけど方法がわからない方
- カジュアル面談をWantedlyで申し込んだが企業側からの反応が良くない方

# カジュアル面接までの概要(筆者の場合)

1. Wantedlyに登録する。
1. 気になる企業にカジュアル面談を申し込む。
1. 前日までに準備をする。
1. カジュアル面談に行く。

# カジュアル面談までの詳細(筆者の場合)

1. Wantedlyに登録する。
  1. 下記リンク先にアクセスする。  
  [https://www.wantedly.com/projects](https://www.wantedly.com/projects)
  1. 新規登録を行う。
  1. プロフィールを充実させる。
    1. 各種記入項目はなるべく埋めるようにする。
    1. 少し抵抗があるかと思うが現職の企業名や電話番号、学歴、職歴など深掘りして書くとなお良い。
    1. 技術系ツイッターアカウント、Githubアカウントと連携をさせる。
    1. Qiitaなどの外部リンクもプロフィールに貼る。
    1. トップ画像、カバー写真はかならず設定する。(トップ画像はなるべく本人が写っていた方が良い) 
1. 気になる企業にカジュアル面談を申し込む。
    1. 「話を聞きに行きたい」のボタンを押すことでカジュアル面談を申し込んだことになる。
    1. 企業側からカジュアル面談が承諾されると自分あてにWantedly内でメッセージが届く。
    1. カジュアル面接の日程を企業側と調整する。(オンラインのビデオチャットで実施してくれる企業も多数あるので、都合が合わなかった場合お願いすることもあり)
1. 前日までに準備をする。
    1. カジュアル面接をしてもらう企業に対する質問などをあらかじめ用意しておくとよい。
    1. Web上にある情報くらいは最低限調べておく。
    1. 実際に直接話さないと聞けないような質問を用意する。
1. カジュアル面談に行く。
    1. ドタキャンなどは極力避けよう。
    1. どうしても行けない予定ができてしまったら早めに連絡しよう。
    1. 最初は緊張すると思うが、素直にそのことを伝えよう。 

# まとめ

- Wantedlyのプロフィールは詳しく書こう。
- Webで調べられるようなことは質問しないようにしよう。
- 予定が合わないときはオンラインミーティングを行ってくれる企業さんもある。
- 普段聞けないようなちょっと突っ込んだ内容を質問してみよう。
UE4のポストプロセスでリライト

去年、UE4歴3か月くらいしかない時にポストの学習がてらやった事を書きます。

# リライトとは？
ポスト上で自前でディファードレンダリングするような物で、予めレンダリングされた法線やワールド位置情報をもとに、ポストプロセス上でライティングを行います。
UE4に存在しないライティングモデルの適用や、デフォルトのライトチャンネルやマスクでは難しい表現ができます。
完全に置き換える時もありますし、既存のライティング結果にライトを足す事もできます。


# 実装
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">去年練習がてらやったUE4でのリライト、左UE4標準、右、ポストでリライト <a href="https://t.co/ZFw6zL0lbl">pic.twitter.com/ZFw6zL0lbl</a></p>&mdash; おく/奥川 剛 (@t_oku) <a href="https://twitter.com/t_oku/status/1185827064424718336?ref_src=twsrc%5Etfw">October 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">もう一個 <a href="https://t.co/NqYgBZfWN8">pic.twitter.com/NqYgBZfWN8</a></p>&mdash; おく/奥川 剛 (@t_oku) <a href="https://twitter.com/t_oku/status/1185827359485644801?ref_src=twsrc%5Etfw">October 20, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
今回は既存の結果に上乗せではなく、置き換える実装をしています。わかりやすく画面の半分より左がUE4の標準の出力、右側がGバッファはじめ、ポストプロセスで取得できる情報をもとにライティングしたものです。

## 準備
ポストマテリアルを一個用意するだけです。
ライティングをするので、トーンマップ適用前のパスに設定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/8559a1b9-9fe3-a26c-b55d-b9d6c04a3b3f.png)

## ポスト上でリライトのために取得できる情報
カメラ位置、ワールド座標は専用のノードから取得できます。
以下はSceneTextureノードから取得することが可能です。
-マテリアルAO、AO、ワールド法線、メタリック、ラフネス、ベースカラー
### 取得、実装が難しい事
#### 影
シャドウマップが生成できないのが難点です。もし、どうしても影が欲しい場合は、レイマーチ女る実装をするか、同じ位置、向きのライトがシーン上にあるのであればデライトして使う事ができます。
#### エミッシブ
ポストマテリアル上ではエミッシブをとる事が出来ません。
欲しい場合はあらかじめ別のRTにレンダリングしておくなどの対応をする必要があります。
## ライティング
### 直接光
今回は平行光のみGGXでカスタムノードを実装しました。
viewDirにはワールド座標からカメラ位置を引いた物を、lightDirにはベクターパラメータとして外にだしているものを渡し、同じくベクターパラメータのlightColorにはα成分にインテンシティーをパックして入れています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/eacee01e-73b5-0a92-cefc-ab9fb554c5d2.png)

### 環境光
環境光周りで用意したのはフレネル関数とキューブマップ2つです。
radianceキューブはラフネスに応じて参照するMipレベルを変えます。この素材は事前にcmftやIBLBakerなどのツールでフィルター処理して作成しておきます。
irradianceキューブについてはテクスチャではなく、SHの係数であることが多いですが、今回は手を抜いてテクスチャをそのまま参照しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/fc1a0009-bbfc-b492-cddc-a510c2e27c76.png)

これらにAO、マテリアルAOの影響を適用し、さらに直接光の結果と合成すれば完成です
# まとめ
どうしても標準のライティングだけでは表現が難しかったり遠回りになってしまう時があります。そんな時、痒い所に手が届くことが多いのでリライト用の関数など整備しておくといいかもしれません。
ただし、前途した通り、影やエミッシブの問題はあるので、その辺り留意した上で使っていくのがいいでしょう。
面接で聞かれた技術問題

未経験で転職活動中に聞かれた技術質問を復習も兼ねてまとめておきます。
何か不備やこうした方がいいなど、ご指摘いただければ幸いです。

#アルゴリズム
###フィボナッチ数列
（1, 1, 2, 3, 5, 8, 13, 21 ,,,のように第n+2項が、第n+1項と、第n項の和になるよう数列）

何番目の数字を求めるかを、コンソールに入力し、その番号の数字を返すプログラムを考える。

``` fib.rb
def fib(n)
  if n == 0 || n == 1
    return 1
  end
  fib(n - 2) + fib(n - 1)
end


puts "何番目の数字を求めますか？"
input = gets.chomp.to_i
puts fib(input)
```

こんな感じ。
一応動くけど、30番目くらいからめちゃくちゃ遅くなる。

###原因
例えばn=5を求めようとすると、

```fib.rb
fib(5) = fib(3) + fib(4) #fib(3)とfib(4)が定義されていないので再計算
 fib(3) = fib(1) + fib(2)
  fib(2) = fib(0) + fib(1) = 2
 fib(4) = fib(2) + fib(3)
  fib(3) = fib(1) + fib(2)
   fib(2) = fib(0) + fib(1) = 2
```
n=5とかだとなんとかなるけど、数字が大きくなるにつれて時間がかかる。

###解決策
配列に保存してしまう

```fib.rb
def fib(n)
  f = []
  f[0] = f[1] = 1
  if n >= 2
    (2..n).each do |i| #2〜nまでeachで回す
      f[i] = f[i-1] + f[i-2]  #2〜nのfib[i]を保存
    end
  end
  f[n]
end

puts "入力してください"
input = gets.chomp.to_i
puts fib(input)
```

これが直感的でわかりやすいように思う。

#SQL

以下のようなテーブルがあったとする。

生徒テーブル

| id | 名前 |
|----|-----|
| 1  |田中|
| 2  |山田|
| 3  |中田|
教科テーブル

| id | 教科 |
|----|-----|
| 1  |数学|
| 2  |国語|
| 3  |英語|
テストテーブル

| id |生徒ID|教科ID|点数|
|:----:|:-----:|:------:|:----:|
| 1  |1    |1     |40
| 2  |1    |2     |50
| 3  |1    |3     |70
| 4  |2    |1     |60
| 5  |2    |2     |50
| 6  |2    |3     |80
| 7  |3    |1     |80
| 8  |3    |2     |70
| 9  |3    |3     |50


問１
各生徒の名前と平均点を求めよ
（例　田中：◯点）

```SQL
SELECT b.名前, AVG(点数)  --生徒の名前と平均点を表示
FROM テスト a                  --テストテーブルを「a」と名前をつける（任意）
INNER JOIN 生徒 b
ON a.生徒ID = b.id        --生徒テーブルのidとテストテーブルの生徒IDをくっつける
GROUP BY 生徒ID           --student_idでグループ化
```

問２
６０点未満の生徒と教科を表示

```SQL
select b.名前, c.教科, a.点数
from テスト a 
inner join 生徒 b 
on a.生徒ID = b.id 
inner join 教科 c
on c.id = a.教科ID
where 点数 > 60
```

inner join で結合した後のテーブルのイメージはこんな感じ

| id |生徒ID|教科ID|点数|id|名前|id|教科|
|:----:|:-----:|:------:|:----:|:--:|:--:|:--:|:--:|
| 1  |1    |1     |40|1|田中|1|数学|
| 2  |1    |2     |50|1|田中|2|国語|
| 3  |1    |3     |70|1|田中|3|英語|
| 4  |2    |1     |60|2|山田|1|数学|
| 5  |2    |2     |50|2|山田|2|国語|
| 6  |2    |3     |80|2|山田|3|英語|
| 7  |3    |1     |80|3|中田|1|数学|
| 8  |3    |2     |70|3|中田|2|国語|
| 9  |3    |3     |50|3|中田|3|英語|

外部キーなどを扱う時は便利


#まとめ
両方とも基本的な問題だが、結構あやふやにしているところもあり、
100%答えることができなかった・・・

webスクール等で簡単なwebアプリケーションなら作れるようにはなったが、
上記のようなアルゴリズムやSQLはフレームワークがうまくやってくれたりするので、理解していなくても作れてしまうのが現状です。

こういった言語に依らない基礎をもう一度やり直す必要があると思いました。

##因みに
フィボナッチ数列の問題は小学6年生で取り上げるレベルだそうです。
ぼやぼやしていたらあっという間に置いていかれるという危機感・・・
プログレスバーを実装してみた

久しぶりの投稿です。

今回はプログレスバーを実装してみました。

#ソース

では、いつもどおりソースを載せておきますね。

```progress_practice.html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>プログレスバー　練習</title>
    <script src="./js/progressbar.js"></script>
</head>

<body>
    <div>
        <!-- 進捗(%)を表示 -->
        <input type="text" id="bar" value="0%" style="border-style: none" disabled="true">
        <br>
        <!-- プログレスバー -->
        <progress id="myProgress" value="0" max="100" width="200px">0%</progress>
    </div>
    <!-- ボタンを押すと、プログレスバーが実行される -->
    <input type="button" id="myButton" onclick="updateProgress()" value="start">
</body>

</html>

```

```progress.js
var interval;
var val;

function updateProgress() {
    val = 0;
    document.getElementById("myButton").disabled = true;
    // 50ミリ秒ごとに更新
    interval = setInterval("updateVal()", 50);
}

function updateVal() {
    // 進捗(%)を表示する
    var bar = document.getElementById("bar");
    bar.value = val + "%";
    
    // 100%になるまで、バーを更新
    if (val < 100) {
        val += 1;
        document.getElementById("myProgress").value = val;
        document.getElementById("myProgress").innerText = val + "%";
    // 100%になったら、バーが止まる
    } else if (val == 100) {
        clearInterval(interval);
        document.getElementById("myButton").disabled = false;
    }
}
```

#解説
まず、htmlからですね。
プログレスバーのタグは`progress`要素となります。

次に、jsですね。
ポイントは2つです。
1つ目が、`setInterval`関数です。
この関数は一定間隔で、処理を実行します。
第一引数に、関数を入れます。
この関数に、処理を実装すれば、いいわけです。
第二引数には、時間を入れます。
指定した時間が経過すると、もう一度第一引数で指定した関数が実行されます。

2つ目に、`clearInterval`関数です
`setInterval`を止めたいときに使うものです。

#参考
[【JavaScript入門】setIntervalの使い方まとめ](https://www.tagindex.com/html5/form/progress.html)
[＜progress要素＞ - タスクの進捗度 | HTMLのタグリファレンス](https://syncer.jp/Web/HTML/Reference/Element/progress/)
CircleCIでbundler2のインストール時に実行ファイルの削除でYnの入力を求められるやつの対策

CircleCIでbundler2系を使いたいので以下のコマンドを実行するようにしていたが

```yml
     - run:
          name: setup bundler 2
          command: | 
              sudo gem uninstall bundler
              sudo rm /usr/local/bin/bundle
              sudo rm /usr/local/bin/bundler
              sudo gem update --system
              sudo gem install bundler
```
以下のログを出してタイムアウトすることがあった

```sh
Remove executables:
	bundler

in addition to the gem? [Yn]  Remove executables:
	bundler

in addition to the gem? [Yn]  Remove executables:
	bundler

in addition to the gem? [Yn]  context canceled
```
要はユーザーからの入力を待ってタイムアウトしている。

## 対策
こうすればよかった

```yaml
      - run:
          name: setup bundler 2
          command: |
              sudo gem update --system
              sudo gem uninstall -ax bundler
              sudo gem install bundle
```
`gem uninstall`はaオプション（バージョン問わず該当するものを全て削除）とxオプション（インタラクティブに実行形式ファイルの削除を問わずアンインストールを続行する）を取れるので、それを指定すればよかった。rmコマンドとかいらない。

yesコマンドを使ってもいいのでは？と思ったがなんか動かなかった。理由は調べてないのでわからん。
Raspberry Pi の起動メディアを作成する (Raspbian のイメージを microSD に書き込む)

# Raspberry Pi の起動メディアを作成する
## 一言で言うと
ただのメモ

## 環境
Linux か macOS (macOSでのコマンドを貼っているので、Linuxの場合は適宜読み替える必要あり)

## 作業内容
### Raspbianのイメージをダウンロードする
https://www.raspberrypi.org/downloads/raspbian/

### ハッシュの確認と解凍
この記事を書いた時には SHA-256 だったので、以下のコマンドで同一の結果になるか確認しておく
問題なければ解凍

```shell
$ shasum -a 256 [ファイル名(zip)]
$ unzip [ファイル名(zip)]
```
### 書き込みなど

```shell
// ディスク名を探す (Raspbianを書き込むmicroSDを探す)
$ diskutil list

// アンマウント
$ diskutil unmountDisk /dev/disk3

// フォーマット
$ diskutil erasedisk FAT32 BOOT /dev/disk3

// フォーマットが終わると自動でマウントされたので、再度アンマウント
$ diskutil list
$ diskutil unmountDisk /dev/disk3

// 書き込み
// macOSでddしてるので、rdiskを使用している
sudo dd bs=1m if=[Raspbianのイメージ (img) へのPATH] of=/dev/rdisk3
```