OmniAICreator/Qiita-1.07M huggingface dataset:
【試験合格記】AWS 認定 ビッグデータ – 専門知識(BDS-C00)

お疲れさまです。
表題の試験に合格したため記録として残したいと思います。

# 注意点
本試験は2020年4月12日に「ビッグデータ」から「データ分析」へ生まれ変わります。
そのため、当該日を過ぎてからこの記事や他の方の過去記事を参考にされると出題範囲が大きく異なる可能性があります。

# 結果
合格(※スコアレポートが戻り次第追記予定)

|分野|名称|割合|
|:-----------------|:-------------------|:-------------------|
|1|収集|17%|
|2|格納|17%|
|3|処理|17%|
|4|分析|17%|
|5|可視化|12%|
|6|データセキュリティ|20%|

# 所有資格

| 資格名       |取得年月日 |
|:-----------------|:-------------------|
|AWS Certified Solutions Architect - Associate (SAA)|2018-06-14|
|AWS Certified SysOps Administrator - Associate (SOA)|2018-06-22|
|AWS Certified Developer - Associate (DVA)|2018-06-25|
|AWS Certified Solutions Architect - Professional (SAP)|2018-07-19|
|AWS Certified DevOps Engineer - Professional (DOP)| 2020-02-19| 
|AWS Certified Big Data - Speciality (BDS)| 2020-03-23| 

# 事前知識
過去にGCPのデータエンジニア試験を受験していたこともあり、覚えのある内容がいくつかあったこともアドバンテージになりました。

# 所感
基本的にはHadoopエコシステムの特徴とビッグデータに分類されるサイズ感に対応したAWSリソース、機械学習の基礎知識があれば合格ラインが見えると思います。

# 受験者に向けたアドバイス
- HDFS, HBase, MapReduceなどの特徴を理解する
- Presto, Spark, Pig, Sqoop, Phoenix, Hiveなどの特徴を理解する
- Kinesisの種類とそれらがどんな要件に適していてどのリソースと親和性が高いのか理解する
- DynamoDBとRedshift、RDSの明確な違いを理解する
- ストリーミングからの分析や可視化のアプローチに対して、状況ごとにどう組み合わせるか理解する
- 機械学習モデルとしての回帰、カテゴリ、バイナリなどの傾向を把握する

# まとめ
実質一週間で準備した割にはある程度時間を余らせて合格できました。
ビッグデータに全く触れたことがない方は、まず関連書籍を一冊読んでから
上記のワードが何を意味してどこまで対応できるのかを比較できるよう、情報整理を始めることが理解を早める方法になるかもしれません。

次はセキュリティか機械学習あたりを4月中に取れるよう頑張っていこうと思います。
batファイル内からPowerShellスクリプトを実行するサンプル

batファイル内からPowerShellスクリプトを実行するサンプル。
ちょっとしたツール用に。1行目はおまじない。。

```powershell
@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof

# -----------------------------------------------------------------------------
# batファイルからPowerShellスクリプトを実行します。
# -----------------------------------------------------------------------------
# クイックアクセスにピンを追加する
function Pin2QuickAccess($Path){
    if(Test-Path $Path){
        $Shell = New-Object -com "Shell.Application"
        $Namespace = $Shell.Namespace($Path)
        $Target = $Namespace.Self
        $Verb = $Target.Verbs() | ? {($_.Name -match "^クイック アクセスに.+ピン留め") -or ($_.Name -match "Pin to Quick access")}
        if($Verb -ne $null){
            $Verb.DoIt()
        }
    }
}

Pin2QuickAccess("C:\hoge")
```
超雑な IndexedDB のメモ

## 雑な理解メモ

```plantuml
@startsalt
{{T
+ IndexedDB
++ DB_NAME
+++ OBJECT_STORE
++++ RECORDS
+++++ ROW
}}
@endsalt
```

## 普通の RDB に置き換えるなら

* DB_NAME → DB
* OBJECT_STORE → Table
* RECORDS → Rowset
* ROW → Row
話題のanalyzeコマンドを実装してみた

今、イケてるエンジニア界隈で話題沸騰中の`analyze`コマンドをご存知でしょうか。

こういうやつですね。


<img width="552" alt="スクリーンショット 2020-03-26 9.41.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150934/1cdfa0b9-7a6b-8421-57b5-1657a707904d.png">

# Yet another `analyze` command

コレCLIっぽい見た目をしていますが、実はWebブラウザ上[^sobaya007]でしか動作しません。不便ですね。
[^sobaya007]: https://qiita.com/sobaya007

Shellでも使いたい！という声にお答えして、実装してみました！！

コチラです。
[![NPM](https://nodei.co/npm/qiita-analyze.png)](https://nodei.co/npm/qiita-analyze/)

Source code: https://github.com/kaz/qiita-analyze

# 使い方

インストールは以下のコマンドを実行するだけです。nodejs/npmは別途インストールしてください。

```
$ npm i -g qiita-analyze
```

そしたらこうやって実行

```
$ analyze @sobaya007
```

すごい！！！！　（実際は色もついてるよ）

```
$ analyze @sobaya007
 投稿した記事           読んだ記事            LGTMした記事
   D言語: 20%　　　　　　　Docker: 7%          dlang: 19%
   D言語くん: 20%　　　　　Python: 5%          D言語: 7%
   プログラミング: 10%　　 JavaScript: 3%      Vim: 4%
   GPGPU: 10%　　　　　　 docker-compose: 3%  C: 4%
   dlang: 10%　　　　　　 Node.js: 2%         C++: 4%
```

# 解説

NodeJSでのWebスクレイピングには[cheerio](https://github.com/cheeriojs/cheerio)が便利です。（申し訳程度の技術要素）
Qiitaユーザページリニューアルで無くなった機能とその代替手段

2020年3月25日、[ユーザーページをリニューアルしました - Qiita Blog](https://blog.qiita.com/user-page-renewal/)という告知とともに、ユーザページがリニューアルされました。

そのアップデートで、もともとユーザページにあった機能のうちいくつかが無くなってたり、使いにくくなったり、わかりにくくなったりしているかと思います。

この投稿では、ユーザサイドでできる対応を紹介したいと思います。

## 自分の投稿一覧

アップデート前は自分の投稿一覧が1ページあたりもっとたくさん表示されていたと思いますが、アップデート後は1ページあたり5投稿の表示と少なくなっています。過去の自分の投稿をたどるためにはたくさんクリックしないといけなくなりました。

現状ユーザができる代替手段は、検索を使うことです。検索で「user:自分のアカウント名」で検索し、並び順を「新着順」にすると、自分の投稿の一覧が表示されます。

例: 僕の投稿一覧: [「user:suin」の検索結果 - Qiita](https://qiita.com/search?q=user%3Asuin&sort=created)

## 限定投稿の一覧

アップデートにより、限定投稿の一覧への導線がなくなりました。

自分の限定投稿一覧を見るには、自分のユーザーページを開き、URLに`/private`をつけると見ることができます。

例: `https://qiita.com/自分のユーザ名/private`

ちなみにこの問題についてはQiita開発陣は認識しているようなので、そのうち対応されると思います。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ご不便をおかけし申しわけございません。<br>今対応中ですので、もう少々お待ちいただければ見えるようになります。<br><br>また、現在もURLのitemsの箇所をprivateに書き換えていただければ閲覧可能です。</p>&mdash; Qiita (キータ) 公式 (@Qiita) <a href="https://twitter.com/Qiita/status/1242802125433782273?ref_src=twsrc%5Etfw">March 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 自分がLGTMした投稿一覧

アップデート前は、自分がLGTMした投稿一覧のタブがあったと記憶しています。アップデート後はそのタブがなくなりました。

行き方が分かりにくいかも知れませんが、アップデート後もそのページはあり、自分のプロフィールの右上の「・・・」をクリックすると、「LGTMした記事」というメニューがあり、そこから行くことができます。

<img width="1144" alt="suin_-_Qiita.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/7b2abb75-b94f-a5bc-19fb-a693e415c216.png">

## 人気の投稿

アップデート前は、自分の投稿のうち、LGTM数が多い投稿トップ5？がプロフィールに表示されていたと思いますが、それがアップデートでなくなりました。

その代わりに？、「ピックアップ記事」という機能が追加され、PRしたい記事をユーザが選べるようになりました。

残念ながら、自動的に投稿ランキングをプロフィールに出すことはもうできませんが、一旦は「ピックアップ記事」を使うことで、投稿ランキングっぽいものは作れるかもしれません。

ちなみに、自分のLGTM数順投稿ランキングを調べるには検索を使うとできます。「user:自分のアカウント名」で検索し、並び順を「LGTM数順」にします。

例: 僕のLGTM数順投稿一覧: [「user:suin」の検索結果 - Qiita](https://qiita.com/search?q=user%3Asuin&sort=like)

## ストックした投稿

アップデート前は自分がストックした投稿が、ユーザページのタブにありましたが、アップデートにより無くなりました。

新UIでは、ストックした投稿の一覧は、メニューバーの「ストック一覧」を開くと行けます。

<img width="1316" alt="ストック一覧_-_Qiita.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/ab7ca650-ff2c-b8bf-1fc3-1285991f7f9e.png">

## 自分のコメント

自分が投稿したコメント一覧を表示するタブがアップデート前にはありましたが、これも無くなりました。

アップデート後は、自分のプロフィール右上の「・・・」をクリックし、「コメント履歴」を開くと、自分のコメント投稿を一覧することができます。

<img width="1134" alt="suin_-_Qiita.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/9ea2a50e-5037-dacf-6107-1f6c35219dfb.png">

## その他

* Contribution数の折れ線グラフや、投稿タグの円グラフは完全に無くなってしまいました。これに対応する方法は分かりません。
Virtualboxのインストール


ローカルPCに仮想環境としてCentOSをセットアップするために仮想化ソフトウェアであるVirtualboxのインストールを行います。
インストールはGUIのインストーラーでも行えますが、ここではHomebrewを利用してみたいと思います。

Homebrewのインストールが完了していない方は[こちら](https://qiita.com/zaburo/private/29fe23c1ceb6056109fd)を参考にインストールしてください。

## Homebrewによるvirtualboxのインストール

ターミナルを起動し、

```bash
 brew cask install virtualbox
```

を実行。

>caskとはbrewを利用してGUIアプリケーションをインストールする方法（オプション）です。

![スクリーンショット 2020-03-26 8.44.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/f599b93c-6403-5caa-a435-31cdcd54a874.png "スクリーンショット 2020-03-26 8.44.57.png")


インストールが開始され、パスワードを聞かれますのでログイン時のパスワードを入力していください。

![スクリーンショット 2020-03-26 8.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/5a4e311f-d984-80ab-9673-6753af0dc73b.png "スクリーンショット 2020-03-26 8.46.43.png")

MacではmacOS 10.13以降、サードパーティ製のアプリインストールチェックが強化され、アプリ毎に明示的に許可を行う必要があります。
["セキュリティー"環境設定を開く]をクリックし、セキュリティーとプライバシー環境設定画面を開きます。

![スクリーンショット 2020-03-26 8.47.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/9eba7acd-dcae-7dd8-6d1e-752e5582c8c9.png "スクリーンショット 2020-03-26 8.47.04.png")

標準ではロック状態で編集不可になっているので、左下の鍵マークをクリックし、ユーザ名、パスワードを入力してロックを解除します。

![スクリーンショット 2020-03-26 8.47.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/c783ff55-9941-2f93-daa3-6058f7bd13e6.png "スクリーンショット 2020-03-26 8.47.20.png")

開発元"Oracle America, Inc."のシステムウエアの読み込みがブロックされました。とある右側の[許可]ボタンをクリックします。
これでVirtualboxのインストールが許可されました。

![スクリーンショット 2020-03-26 8.47.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/f8aaa291-f6c2-db15-927e-c728854dd8d4.png "スクリーンショット 2020-03-26 8.47.32.png")

もう一度ターミナルにてbrew cask install virtualboxを実行します。

![スクリーンショット 2020-03-26 8.47.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/ce40a660-99f2-15aa-d3a7-24d0035b6902.png "スクリーンショット 2020-03-26 8.47.43.png")

今度は問題なくインストールされ、virtualbox was successfully installed!と表示されるはずです。

![スクリーンショット 2020-03-26 8.48.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/93be4164-4210-4126-1155-8a5136e7115e.png "スクリーンショット 2020-03-26 8.48.18.png")


## Virtualboxの起動

インストールが完了したのでVirtualboxを起動させてみます。
いくつかの起動方法がありますが、Launchpadからアイコンをクリックして起動してみます。Launchpadは画面下のDocのロケット風アイコンをクリックすることで起動します。

![スクリーンショット 2020-03-26 8.49.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/00e4a570-197f-8c8a-ea8a-fa83f10bfd93.png "スクリーンショット 2020-03-26 8.49.43.png")

Virtualboxのアイコンを見つけてクリックして起動させます（ページが複数ある場合があります）。

![スクリーンショット 2020-03-26 8.50.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/6429378d-33bc-cab2-cdd1-e4785c066645.png "スクリーンショット 2020-03-26 8.50.18.png")


Virtualboxが起動しました。

![スクリーンショット 2020-03-26 8.52.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/7d63f9de-6bd5-94aa-fa2f-021c4aeacd32.png "スクリーンショット 2020-03-26 8.52.56.png")

必要であればアイコンをDockにドラッグ＆ドロップすることでショートカットを登録できます。

## 考えよう

* なぜHomebrewでVirtualboxをインストールしたのか？
* Virtualboxとは何か？（どういうソフトか）
* Virtualbox以外の選択肢は何か？（なぜVirtualboxを選択したか）
topic、projectID、サービスアカウントキーなどをexportせずに、GCP Pub/Subのtopicにメッセージをpublishする(python3)


env.pyで環境変数など設定すれば、コマンドでのexportを実施せずに済みますので、楽です！

ポイント：

＊サービスアカウントキーファイル(jsonファイル)はenv.py、publish.pyと同じディレクトリに置いておくと、便利です！

＊リクエストを Pub/Sub サーバーに送信する際に、
```publisher = pubsub_v1.PublisherClient() 
```
を使わず、

```publisher = pubsub_v1.publisher.Client.from_service_account_file(JSON_KEY)
```
に変更すればokです！



```env.py
# GCPサービスのプロジェクトID                     
GOOGLE_CLOUD_PROJECT = '[PROJECT_ID]'
# Cloud Pub/Subのトピック名
TOPIC = '[TOPIC_NAME]'
# サービスアカウントキーファイル(jsonファイル)の保存パース  
JSON_KEY = '[PATH_TO_JSON_KEY]'
```


```publish.py
from env import *
from google.cloud import pubsub_v1


# # # メッセージのパブリッシュ

# # リクエストを Pub/Sub サーバーに送信する
publisher = pubsub_v1.publisher.Client.from_service_account_file(JSON_KEY)
# # The `topic_path` method creates a fully qualified identifier
# # in the form `projects/{project_id}/topics/{topic_name}`
topic_path = publisher.topic_path(GOOGLE_CLOUD_PROJECT, TOPIC)

# # エラーハンドラー
futures = dict()

def get_callback(f, data):
    def callback(f):
        try:
            print(f.result())
            futures.pop(data)
        except:  # noqa
            print("Please handle {} for {}.".format(f.exception(), data))

    return callback


# # トピック(topic_name)にメッセージをパブリッシュする
for i in range(10):
    data = str(i)
    futures.update({data: None})
    # When you publish a message, the client returns a future.
    future = publisher.publish(
        topic_path, data=data.encode("utf-8")  # data must be a bytestring.
    )
    futures[data] = future
    # Publish failures shall be handled in the callback function.
    future.add_done_callback(get_callback(future, data))

# Wait for all the publish futures to resolve before exiting.
while futures:
    time.sleep(5)

print("Published messages.")

```

参考リンク：
1、https://cloud.google.com/pubsub/docs/publisher?hl=ja
2、https://googleapis.dev/python/pubsub/latest/publisher/api/client.html
3、https://qiita.com/xtkd/items/61e16fd980e5ea87519b
4、https://qiita.com/shibacow/items/cb3b011b41bcc47f5e4c
ReactでHTTPボディを送る方法

## やりたいこと

reactから `req.body.id` をnodeへ送って、nodeで、 `req.body.id` を受け取りたかった。その後、 `req.body.id` の値を使ってmongoから値を取得する流れ

## react

```js
    const fetchData = async () => {
      var params = new URLSearchParams()
      params.append('id', pass)
      const result = await axios.post('http://localhost:3000/signin', params);
```

## node

```js
  app.post('/signin', function(req, res) {
    User.findOne({_id: req.body.id}, function(err,obj) { 
        console.log(obj);
```

## 参考

[axiosの使い方まとめ (GET/POST/例外処理)](https://www.sukerou.com/2019/05/axios.html)
[[Web] HTTPリクエストの中身を学んでみた。GETやPOSTの違いなど](https://www.yoheim.net/blog.php?q=20120611)
Qiitaに投稿した記事のバックアップを取得する (C#)

雑いけど。

https://qiita.com/settings/applications で取得したアクセストークンを pat 変数に設定し実行すると、指定したフォルダにitems.jsonと画像がダウンロードされる。記事本文の Markdown は items.json に含まれる。

投稿した記事が多い場合は↓のURLと保存するファイル名を変えればよさげ。
https://qiita.com/api/v2/authenticated_user/items?page=1&per_page=100

```csharp
// NuGet で Newtonsoft.Json を要インストール

public class Qiita
{
    // generate personal access token
    // https://qiita.com/settings/applications
    static string pat = Util.GetPassword("qiita");
    
    // set output directory
    static string outdir = @"C:\qiita";

    static HttpClient httpClient = new HttpClient();
    
    static async Task Main()
    {
        string itemsjson;
        var itemsjsonfile = Path.Combine(outdir, "items.json");
        if (File.Exists(itemsjsonfile))
        {
            itemsjson = File.ReadAllText(itemsjsonfile);
        }
        else
        {
            httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", pat);
            itemsjson = await httpClient.GetStringAsync("https://qiita.com/api/v2/authenticated_user/items?page=1&per_page=100");
            httpClient.DefaultRequestHeaders.Authorization = null;
            File.WriteAllText(itemsjsonfile, itemsjson);
        }

        var jobject = JArray.Parse(itemsjson);
        foreach (var item in jobject)
        {
            var title = (string)item["title"];
            var url = (string)item["url"];
            var markdown = (string)item["body"];

            Regex re = new Regex(@"https://qiita-image-store.s3.amazonaws.com/.*\.png");
            var imgurls = re.Matches(markdown);

            foreach (Match imgurlm in imgurls)
            {
                var imgurl = imgurlm.Value;
                string fname = Path.Combine(outdir, imgurl.Split('/').Last());
                if (!File.Exists(fname))
                {
                    var data = await httpClient.GetByteArrayAsync(imgurl);
                    File.WriteAllBytes(fname, data);
                }
            }
        }
    }
}
```
catapult-server@v0.9.3.1で公開鍵の導出方法が変わった

# はじめに

catapult-serverのv0.9.3.1から、公開鍵の導出方法が変わりました。

https://github.com/nemtech/catapult-server/releases/tag/v0.9.3.1

これまでは、Ed25519のハッシュ関数をKeccak256やSHA3にして使っていました。

これが、リファレンス（[http://ed25519.cr.yp.to/](http://ed25519.cr.yp.to/)）（読んでないけど）に沿って、SHA256を使うように変更されました。

従って、同じ秘密鍵であっても、導出される公開鍵が変わることとなり、公開鍵から導出されるアドレスも変わることとなります。

# 特殊なライブラリが必要ない

NIP10にも書いてあったと思いますが、Ed25519+Keccakは特殊な使い方なので、例えばopensslとか対応していません。

これが標準のEd25519に沿うようになったので、symbol-sdkがまだないような言語でも、秘密鍵から公開鍵の導出や、署名と検証くらいは簡単にできるようになります。

# 以前のものと比較してみる

[NIP10](https://github.com/nemtech/NIP/blob/eef91708a05fc6ce24a903d742ff46682008a8b7/NIPs/nip-0010.md)にあるやつ（v0.9.3.1 RC5）

```yaml
private: 575dbb3062267eff57c970a336ebbc8fbcfe12c5bd3ed7bc11eb0481d7704ced
public:  2e834140fd66cf87b254a693a2c7862c819217b676d3943267156625e816ec6f
address: TATNE7Q5BITMUTRRN6IB4I7FLSDRDWZA37JGO5UW
```

それ以前のバージョン（v0.9.2.1 Fushicho4）

```yaml
private: 575dbb3062267eff57c970a336ebbc8fbcfe12c5bd3ed7bc11eb0481d7704ced
public:  D6C3845431236C5A5A907A9E45BD60DA0E12EFD350B970E7F58E3499E2E7A2F0
address: TCFGSLITSWMRROU2GO7FPMIUUDELUPSZUNUEZF33
```

同じ秘密鍵を使っていますが、公開鍵とアドレスが変わっています。

# リンク

[Goでやってみる](https://qiita.com/planethouki/items/a4c4ca65189f66ded65e)
Wildfly profileの変更が反映されてないときは

## A.リロードしましょう
profileはサーバー起動中でも多くが即時反映されますが、
async-handlerなど項目によっては、リロードが必要です。
jboss-cliで以下を叩きましょう。

```
# domainモードで、host名がmasterの場合
/host=master:reload(restart-servers=true)
```

## おまけ
Wildflyでわからないことがあるときは、[公式docs](https://docs.wildfly.org)の他に、[JBossのdocs](https://access.redhat.com/documentation/ja-jp/red_hat_jboss_enterprise_application_platform/)も参考になります。
定在波による超音波浮揚の実験

# 概要
[_Make:Magazine_ のサイトに紹介されている記事](https://makezine.com/projects/micro-ultrasonic-levitator/)を再現してみる。周波数の同じ2つの超音波を干渉させ、生じた定在波の節に何かを浮かせる。

# 紙片を超音波浮揚させている様子
<iframe width="560" height="315" src="https://www.youtube.com/embed/FQgtksNoemo" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 手順
1. とにかく何らかの方法で周波数40 kHz、デューティ50%の相補パルスを生成し、その相補パルスで2つの超音波スピーカーを駆動する。
2. 超音波スピーカー同士を対面させて定在波を立てる。
2. 生じた定在波の節に何かを浮かせる。節は半波長(約4 mm)おきに生じる。超音波スピーカー同士の距離は1波長の整数倍にした。

# 相補パルスを生成して超音波スピーカーを駆動する方法
マイコンとモータードライバーとを使ったが方法は何でもよい。反射板を利用して定在波を立てるのであれば超音波スピーカーは片側だけでよい。市販の「[超指向性 超音波スピーカーキット](https://www.switch-science.com/catalog/1842/)」「[パラメトリック・スピーカー実験キット](https://akizukidenshi.com/catalog/g/gK-02617/)」などを使えばもっと安定した強い定在波が容易に立てられる。     
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193936/983dee89-5f12-b4b0-35d0-0cf83f3303e8.png)       
下のコードは参考記事\(Arduino Nanoを使用\)のコードを真似たものである。Atmel Studio 7でビルドした。          

```for_ATtiny13A.c
// ヒューズのCKDIV8ビットは解除しておく。
// クロックは内蔵9.6 MHzを使う。
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIM0_COMPA_vect){
	PORTB ^= 0b11; // コンペアマッチするたびにPB1:0の出力をトグルする。
}

int main(){
	DDRB  = 0b11; // PB1:0からパルスを出力することにする。
	PORTB = 0b01; // 最初にPB1とPB0とのロジックを相補関係にしておく(だから0b10でもよい)。

	TCCR0A = 1 << WGM01;  // CTCモード
	TCCR0B = 1 << CS00;   // クロックを分周せずにカウント
	OCR0A  = 114;         // コンペア値(この値を調整して周波数を40 kHzにする)。計算上は(9.6MHz/80kHz)-1 = 119。
	TIMSK0 = 1 << OCIE0A; // コンペアマッチ割り込みを有効化
	sei();

	while(1);
	return 0;
}
```

このコードを実行すると、マイコンから下のような相補パルスが出る。Hブリッジを動かすわけではないのでデッドタイムについては気にしなくてよい。     
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193936/fc75d05d-5a24-7d18-6d6a-b35290bdd1f4.png)

# 使った超音波スピーカー
型番UT1007-Z325R (秋月で売っている)
Treasure DataにQiitaの情報公開停止を依頼してみた。

以下の記事にはTreasure Dataに依頼しろって書いてあったので。

https://blog.qiita.com/user-page-renewal/

(リンク先)
https://www.treasuredata.co.jp/privacy/

リンク先はTreasure Dataのプライバシーポリシーのページになっており、~~よく読みたくなかったので~~ privacy@treasuredata.com にメールを送信すればオプトアウトできるよって書いてあったので最低限の情報だけ書いて送ってみました。

![ET_YS4FUcAAoYdi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47658/bd5f7c06-48db-ab38-64fd-27d523a76b9e.jpeg)

どういう返事が来るのかね。


# 追記

もう誰も興味ないと思うけど、普通に間違いなのでこちらでは対応できないよって返事でした。
ユーザーページにLGTMトップの記事を表示するユーザースクリプト

![Screen Shot 2020-03-26 at 08.32.09-fullpage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/02801e48-4135-1218-2b2c-16ec53349d82.png)

```js
// ==UserScript==
// @name         Qiita top items
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  なんか名前が変わったやつをたくさんあつめたのを表示する
// @author       khsk
// @match        https://qiita.com/*
// @exclude      https://qiita.com/
// @exclude      https://qiita.com/timeline*
// @exclude      https://qiita.com/tag-feed*
// @exclude      https://qiita.com/notifications*
// @grant        none
// ==/UserScript==

(async function() {
  'use strict';
  // APIで取得しようと思ったけどソートしないといけないし100投稿ごとにタイムラグが大きくなるのでもう検索結果を雑に流し込むことにした

  //ユーザーページ判定とid取得を雑に新ページ対応
  const userMain = document.querySelector('[class^="UserMain"]')
  if (!userMain) {
    return
  }

  // ページが変わったからまたID取得が怪しいかも @削除
  const id = document.querySelector('[class^="AccountBaseInfo__UrlName"]').textContent.substr(1)

  const response = await fetch('https://qiita.com/search?&sort=like&q=user%3A' + id)
  if (response.ok == false || response.status != 200) {
    console.error('fetch error', id , response)
    return
  }

  const dummyDOM = document.createElement('div')
  dummyDOM.innerHTML = await response.text()
  // ちょっとnth-of-typeの挙動を意図通りにできない。クラスでなくtag名(div)にかかるのでresult以外のdivひとつ分増やしている
  const topItems = dummyDOM.querySelectorAll('.searchResultContainer_main > div.searchResult:nth-of-type(-n+6)')
  const sideBar = document.querySelector('[class^="UserSidebar"]')

  topItems.forEach ((topItem)=> {
    // アイコン画像がでっかく表示されちゃうから雑に消す
    let tmp = topItem.querySelector('.searchResult_left')
    tmp.parentElement.removeChild(tmp)
    // 概要も不要
    tmp = topItem.querySelector('.searchResult_snippet')
    tmp.parentElement.removeChild(tmp)
    sideBar.innerHTML += topItem.outerHTML
    // TODO(しない)整形もっとがんばる
  })
})();
```

デザイン思い出せない
Homebrewのインストール


## Homebrewとは？

最近ではOSや言語毎にパケージマネージャとよばれるツールが提供され、ソフトウエアや拡張機能のインストールはパッケージマネージャを利用して行うことが一般的になってきています。HomebrewはMacOS環境におけるいわゆるデファクトスタンダードなパッケージマネージャです。

>HomebrewはAppleから提供されているものではありません。またWindowsでも動作します。


## 余談：各OS/言語におけるパッケージマネージャ

### OS

* Windows:Chocolatey
* MacOS: Homebrew(brew)
* Linux(RH系): yum, dnf
* Linux(Ubuntu): apt


### 言語

* PHP: composer
* JavaScript(node): npm
* Ruby: gem
* Python: pip
* C#: NuGet


## Homebrewのインストール

[Homebrew](https://brew.sh/index_ja)ページに移動し、記載されているインストールコマンド（シェルスクリプト）をターミナル画面にペーストし実行（Enter）します。

![スクリーンショット 2020-03-26 8.04.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/84f92f4f-c5eb-42cd-3620-e48379a211ce.png "スクリーンショット 2020-03-26 8.04.26.png")

下記スクリプトをターミナルで実行します。

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```


### ターミナルの開き方

Macのターミナルは、Application -> ユーティリティー -> ターミナルに存在します。
また、command + space を押し、Spotlight検索を起動し、terminal.appと入力することでも起動します。

>Termnalはよく使うのでDockにショートカットを登録しておくといいでしょう。

### インストール

ターミナルを開きスクリプトをペーストし、Enter。


![スクリーンショット 2020-03-26 8.08.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/67d3d7bc-0576-797c-a8ca-08f0600092bb.png "スクリーンショット 2020-03-26 8.08.39.png")


続けるにはEnterを押す。パスワードを聞いてくるのでログイン時のパスワードを入力


![スクリーンショット 2020-03-26 8.09.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/6fcf6455-412c-8636-9357-98bb6de89c16.png "スクリーンショット 2020-03-26 8.09.42.png")

Xcodeのcommand linet toolが必要になるが、自動インストールされる。

![スクリーンショット 2020-03-26 8.10.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/b85a9739-01b3-692c-391d-8968d7dbb627.png "スクリーンショット 2020-03-26 8.10.03.png")

インストールが進み、[Installation Success]と表示されたらインストール完了。

![スクリーンショット 2020-03-26 8.16.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/7a716c62-6a35-466e-32a7-06b48778936b.png "スクリーンショット 2020-03-26 8.16.54.png")

### 動作確認

ひとまずバージョン確認してみます。

```bash
brew -v
Homebrew 2.2.11
Homebrew/homebrew-core (git revision 23625a; last commit 2020-03-25)
```

インストールは以上です。


## よく使うコマンド

* brew update: 更新
* brew upgrade: 更新を実行
* brew list: インストール済みのformulaを見る
* brew install: formulaをインストール
* brew uninstall [formula name]: アンインストール
* brew info [formula name]: 情報を見る

## 考えよう

* なぜバッケージマネージャが利用されるようになったのか
Laravel7＋Reactの環境を構築する 

Laravel7 で React を利用した開発を可能にする手順をご紹介いたします。
ここでは Laravel と React はインストール済みとして進めていきます。

# 開発環境
- Laravel 7.2.1
- React 16.13.1
- PHP 7.4.3

# Laravel で React を利用できるようにする

React を利用する Laravel のプロジェクトを作成し、
作成されたプロジェクトフォルダに遷移します。

```
composer create-project laravel/laravel hoge-project
cd hoge-project
```

次に Laravel が React を利用するように設定を変更します。
ui artisan コマンドを使用するので、laravel/ui パッケージを先にインストールしています。

```
composer require laravel/ui
php artisan ui react
```

最後に下記コマンドを実行すると、Laravel で React を使えるようになります。

```
npm install && npm run dev
```

# Laravel の動作確認をする
Laravel が正常に動作するか確認します。

```
php artisan serve
```

http://127.0.0.1:8000 にアクセスして、Laravel のページが表示されたら正常に動作しています。

<img width="879" alt="スクリーンショット 2020-03-26 7.27.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608050/b932df2c-f658-ab9e-8736-915cb97d5304.png">

# js ファイルの変更を常時反映させるようにしておく

現状のままだと js ファイルの変更が検知されないので、常時変更を検知してくれるように設定します。
**別のターミナルを起動し**、Laravel のプロジェクトフォルダ内で `npm run watch` を実行します。

```
cd hoge-project
npm run watch
```

# React のサンプルファイルで文字列を表示する

React を利用して画面上に文字列を表示できるよう、既存ファイルを変更していきます。
まずは React を使用しているサンプルファイル（resources\js\components\Example.js）を見てみましょう。

```resources\js\components\Example.js
import React from 'react';
import ReactDOM from 'react-dom';

function Example() {
    return (
        // 省略
    );
}

export default Example;

if (document.getElementById('example')) {
    ReactDOM.render(<Example />, document.getElementById('example'));
}
```

id が "example" の HTML タグに文字列を表示する処理だとわかります。

それでは Example.js が出力する内容を表示する HTML タグを記述しましょう。
http://127.0.0.1:8000 にアクセスすると表示される内容は welcome.blade.php（resources\views\welcome.blade.php）に記述されているので、
下記のように編集します。

```resouces/views/welcome.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel</title>
    </head>
    <body>
        <div id="example"></div>
        <script src="{{ mix('js/app.js') }}"></script>
    </body>
</html>
```

body タグ内に、React 出力データの挿入場所である `<div id="example"></div>` と、
Example.js を処理するファイル `app.js` の読み込みを記述します。

http://127.0.0.1:8000 にアクセスし、下記の通りに表示されていれば成功です。

<img width="285" alt="スクリーンショット 2020-03-26 8.02.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608050/867a53c3-6b5e-251a-2ea3-747b8694e12b.png">

もし Example.js 以外のファイル、例えば Hoge.js を読みこませたい場合は、
app.js（resources\js\app.js）を下記のように編集すると良いでしょう。

```\resources\js\app.js
require('./bootstrap');
require('./components/Example');

// 下記を追記
require('./components/Hoge');
```

以上です。
対戦オセロwebapi その6

#概要

対戦オセロwebapiを作ってみる。
オセロaiをtestする。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/dcff5211-ccae-a2f2-1535-ad62b9744e9e.png)


#成果物

https://embed.plnkr.co/plunk/WMHJHOPLAPUTnGyz

以上。
【Day36】積み上げ日記

##予定
■ポートフォリオの作成
ーテンプレ選定
ーオリジナルで構図作成
ー箱作る
ークラス名命名

■案件獲得方法学習

##完了
■ポートフォリオの作成
ーテンプレ選定
ーオリジナルで構図作成
ー箱作る
ークラス名命名

■案件獲得方法学習

##学習時間
1h

##学習ポイント
■案件の獲得方法
−プロフィール充実度80%以上
−プロフィール画像設定
−本人確認書類の書類の提出
−できるだけ多くのスキルを書く（同じスキルでも複数書く）
−経験年数はビビらずに大きく書く
−初心者だとばれないようにする
−常に対応可能にする
−稼働時間は41時間以上に設定
−時間単価は1000円～2000円

##計画通り進んだか？
進んだ。ポートフォリオ作成時に自然と構図作り、箱作りから入れたのは、全体像を把握してから取り組むという順序を頭でわかっていたので、自分を褒めたい。ただ、既にあるリソースを使うか否か迷っている。
AtCoder 生活　6日目

[前回]
(https://qiita.com/flandrescarlet237/items/07e4292b09991cd1be67)

#6日目
今回も前回と同じように@drkenさんのAtCoder に登録したら次にやること [～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/drken/items/fd4e5e3630d0f5859067)の第8問から第10問まで解きました。


##第8問　ABC085_C
[Otoshidama]
(https://atcoder.jp/contests/abc085/tasks/abc085_c)


```c++

#include <bits/stdc++.h>
using namespace std;
int main(){
	int N,Y;
  	cin >> N >> Y;
	int residue = 0;
  	int res10000 = -1,res5000 = -1,res1000 = -1  ;
  	for(int x = 0;x <= N;x++){
    	for(int y = 0;y <= N-x;y++){
          	int z = N-x-y;
          	int total = 10000*x +5000*y +1000*z;
            if(total == Y){
            res10000 = x;
            res5000 = y;
            res1000 = z;
            }
        }	
    }
  	cout << res10000 << " " << res5000 <<  " " << res1000 << endl;    
}

```


解けなかったが、理解はしやすかった。

##第9問　ABC049_C
[白昼夢]
(https://atcoder.jp/contests/abc049/tasks/arc065_a)

```c++

#include <bits/stdc++.h>
using namespace std;

string divide[4] = {"dream", "dreamer", "erase", "eraser"};

int main() {
    string S;
    cin >> S;

    reverse(S.begin(), S.end());
    for (int i = 0; i < 4; ++i) reverse(divide[i].begin(), divide[i].end());

    bool can = true;
    for (int i = 0; i < S.size();) {
        bool can2 = false; 
        for (int j = 0; j < 4; ++j) {
            string d = divide[j];
            if (S.substr(i, d.size()) == d) {
                can2 = true;
                i += d.size();
            }
        }
        if (!can2) {
            can = false;
            break;
        }
    }

    if (can) cout << "YES" << endl;
    else cout << "NO" << endl;
}

```


substr関数の使い方とbool型をよく知れました。

##第10問　ABC086_C
[Traveling]
(https://atcoder.jp/contests/abc086/tasks/arc089_a)

```c++

#include<bits/stdc++.h>
using namespace std;
int main() {
    int N;
    int t[110000], x[110000], y[110000];
    cin >> N;
    t[0] = x[0] = y[0] = 0;
    for (int i = 0; i < N; ++i) cin >> t[i+1] >> x[i+1] >> y[i+1];

    bool can = true;
    for (int i = 0; i < N; ++i) {
        int dt = t[i+1] - t[i];
        int dist = abs(x[i+1] - x[i]) + abs(y[i+1] - y[i]);
        if (dt < dist) can = false;
        if (dist % 2 != dt % 2) can = false;
    }

    if (can) cout << "Yes" << endl;
    else cout << "No" << endl;
}

```





解説を見ればなんとかなるけど、C問題となるとまず最初に何をらればいいかすらわからなくなりました。



とりあえず10問とき終わったので、次からはほかのB問題を解いていこうと思います。
Gatsby.jsのsourceNodesライフサイクルでresourceを参照する方法

Gatsby.jsでノードを作るライフサイクルの`sourceNodes`でresourceのデータを参照したい時に詰まったのでメモ。

# 経緯
あるresourceのデータに外部画像のURLがあり、それを gatsby-image で使うために、gatsby-source-filesystem の createRemoteFileNode で外部画像用のNodeを生やす必要がありました。

新たにNodeを生やすのでsourceNodesのライフサイクルで

1. 内部のスキーマに対してGraphQLで対象のURLを取得
2. そのURLに対してcreateRemoteFileNodeでノードを作成する

で良いのかなと思ったのですが、sourceNodesではまだschemaがないのでGraphQLのAPIを呼べませんでした。

ということで、sourceNodesライフサイクルでresourceを参照する方法です。

# 方法

**[getNode API](https://www.gatsbyjs.org/docs/node-api-helpers/#getNode)** で直接resouceのノードの情報を参照する。以上です。 schemaはないのですが、ノードはあるのでアクセスできるのですね。

```js
const node = getNode("参照したいノードのID")
```


実際のコードはこちらです。
sourceNodesでfacebookのfeedのresourceから画像情報を取得してcreateRemoteFileNodeから外部画像用のノードを作成する例です

```js:gatsby-node.js
"use strict";
const { createRemoteFileNode } = require(`gatsby-source-filesystem`);

exports.sourceNodes = async ({
  actions: { createNode, createNodeField },
  createNodeId,
  cache,
  store,
  getNode
}) => {
  // クエリは投げられないでNodeから直接取得。
  // 画像がないfeedもあるのでfilterで除外
  const feedData = getNode("ノードID").feed.data.filter(
    u => u.full_picture != null
  );

  await Promise.all(
    feedData.map(async data => {
      // 外部画像のダウンロードとノードの構築
      const fileNode = await createRemoteFileNode({
        url: data.full_picture,
        cache,
        store,
        createNode,
        createNodeId
      });

      await createNodeField({
        node: fileNode,
        name: "feedImage",
        value: "true"
      });

      await createNodeField({
        node: fileNode,
        name: "feedId",
        value: data.id
      });

      return fileNode;
    })
  );
};
```

# 参考
以下参考にさせて頂きました。良記事ありがとうございます。

* https://takumon.com/gatsby-image-of-remote-in-building-by-using-create-remote-file-node

* https://github.com/gatsbyjs/gatsby/issues/11760
初心者によるプログラミング学習ログ 273日目

#100日チャレンジの273日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
273日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>273日目 1.0h<br>・XDデザインカンプからのwebサイト模写<br>・git,sass,flou<br>・ヘッダー、nav部分作成<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1242906046374371328?ref_src=twsrc%5Etfw">March 25, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
やらかしGitデプロイ

##やらかし
デプロイを任されたが、マージされていないことに気づかずオフィス待機状態になった話

## 経歴
SESのSIer。
GitBashはほぼ触ったことがなく（今日までEclipse上でpushしていた）、
一年前まではVisualStudioのTFSを使っていた。

## 詳細
開発ブランチの総合テスト環境へのデプロイ依頼。ユーザも使っているらしい。



まず、クローンしていない場合はクローンを行う。

```git:
git clone -b kaihatu/sogo-branch http:000/workspace.git
```

開発、総合テスト環境をプルして最新状態にする

```git:
git pull
```

ブランチの切り替えは下記の通り
例）開発用ブランチ（kaihatu_branch）をチェックアウト

```git:
git checkout kaihatu_branch
```

総合テスト用のブランチにマージするため、
再度、総合テスト用のチェックアウトしておく

すぐにコミットは行わず、まずマージを行う。
※このコマンドが失敗の原因

```git:
git marge --no-commit origin kaihatu_branch
```

競合がないことを確認出来たら、プッシュする

```
git push
```

すると以下のようなメッセージが出た

```
Already upto date. (すでに最新です.)
```

アップデート（更新）したってことね、理解した（理解してない）。
ビルドなど、デプロイ作業を行う。

### しばらく後

僕「おや、リーダーにメールがたくさん届いている。リーダーは大変だなぁ」
とか思っていたら、リーダが駆けつけてきて
リーダー「お前、デプロイできてないぞ」
僕「」

## 原因
コミットができてなかった。

## 反省
まず、マージしたら差分のあることを確認する

```
git log -m -1 --name-status
```

`-m`はログ上でマージを普通のコミットのように扱う
`-1`はひとつ前のコミット分だけ表示
`--name-status`は変更したファイルを表示する

**ログにマージされたファイルがあることを確認したら**
**コミット**

```
git commit
```

## 思ったこと
TFSに比べてGitの操作って複雑だなと。チェックイン、チェックアウトですべて事足りた時代が懐かしい。
やらかしおじさんと化して暇になったので、DockerとJavascriptの勉強を始めた。
負荷テストツール vegeta で multipart/form-data で画像を送る

## 想定読者
- **画像を送りつける負荷テストをしたい人**
- [vegeta](https://github.com/tsenart/vegeta) でもっと遊びたい人
- `multipart/form-data` についてちょっと復習したい人

## 一言でいうと

1. 下のような `targets.txt`, `body.txt` を準備
    - `{その他必要なリクエストヘッダ}` や `{画像のバイナリ}` は適宜いれてください
2. 以下のコマンドを打つ！

```
// 3分間、1秒間に2リクエストの頻度でattack!する場合の例
vegeta attack -rate 2 -duration 3m -targets targets.txt |tee result
```

```targets.txt
POST http://sample.example.com/images
{その他必要なリクエストヘッダ}
Content-Type: multipart/form-data; boundary=----BoundaryPKp7MX1veAsGyi0A
@body.txt

```

```body.txt
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="attachment"; filename="dummy"
Content-Type: image/jpeg

{画像のバイナリ}
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="other-key1"

other-value1
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="ohter-key2"

other-value2
------BoundaryPKp7MX1veAsGyi0A--
```

### もう一言
- `body.txt` 内の `name=` に続く部分(`attachment`など)も適宜変えてください
- 画像だけなら `body.txt` の最初のブロックだけで良いです

## まずは curl でやってみる
ググれば結構情報が多いです。以下のような感じでOKです。
`{path/to/img.jpg}` は画像へのパスです。簡単！

```
curl -X POST http://sample.example.com/images \
  -F other-key1=other-value1 \
  -F other-key2=other-value2 \
  -F "file=@{path/to/img.jpg};type=image/jpg"
```

## vegeta ではこうする

上の `curl` のサンプルを見るとこんな感じで良いかなと思ってしまいますが、全然ダメでした:innocent:

```wrong_targets.txt(雰囲気だけ書いたダメな例)
POST http://sample.example.com/images
{その他必要なリクエストヘッダ}
Content-Type: multipart/form-data
Content-Disposition: form-data; name="attachment"; filename="path/to/img.jpg"

other-key1=other-value1
other-key2=other-value2
```

正しくは以下のように `boundary` を使って書く必要があります。ファイルの分割は必須ではありませんが、そうした方がわかりやすいかと思います。
画像でない他の `multipart/form-data` と同じような感じになりますが、画像の場合はボディに **画像のバイナリ** を直接入れる必要があるのが特徴です。

```targets.txt
POST http://sample.example.com/images
{その他必要なリクエストヘッダ}
Content-Type: multipart/form-data; boundary=----BoundaryPKp7MX1veAsGyi0A
@body.txt

```

```body.txt
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="attachment"; filename="dummy"
Content-Type: image/jpeg

{画像のバイナリ}
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="other-key1"

other-value1
------BoundaryPKp7MX1veAsGyi0A
Content-Disposition: form-data; name="ohter-key2"

other-value2
------BoundaryPKp7MX1veAsGyi0A--
```


## 注意点
- HTTP のリクエストでは **改行などが比較的細かく仕様で決まっている** のでご注意ください
- **画像のバイナリ** を **直接** 入れ込む必要があります
    - ファイル指定はできません(やり方わかりません)でした
    - `cat body_before.txt img.jpg body_after.txt > body.txt` のようにしてバイナリを入れるとうまく行きました。
- 最後の `--` 忘れずに

## あとがき
`vegeta` で `multipart/form-data` に関する記事はちらほらありましたが、画像に特化して丁寧に書いたものがなかったので書いてみました。

## 参考文献
以下の記事など参考にして試行錯誤しました。

- HTTPリクエストの仕様
    - ヘッダについてなど
        - https://developer.mozilla.org/ja/docs/Web/HTTP/Messages
    - `multipart/form-data` について
        - https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/MIME_types#multipartform-data
- `vegeta` で `multipart/form-data`
    - https://blog.tkuchiki.net/vegeta-multipart-formdata
IQ2でもLINQを理解できるように咀嚼してみた


##LINQの用途

目的としては C#でコレクション, データベース, XML等の異なったデータ形式を共通の方法(LINQ)で操作するため。

LINQはC# 3.0で追加された。
## LINQ操作手順（概要）
LINQクエリ（データへの問い合わせ）を使った操作の手順はすべて、次の３つの手順で構成されます。
1.データ ソースを取得します。
2.クエリ[^1]を作成します。
[^1]: クエリとは、指定したデータ ソース (単一または複数) からどのようなデータを取得し、それらのデータをどのような形式と編成で返すかを説明した、命令のセット
3.クエリ結果を操作。

##LINQ操作手順（詳細）
1. 操作対象となる配列(0~6の連番)を宣言
2. 配列に対してどのようなデータ（偶数データ）を取得し、それらのデータをどのような形式と編成で返すかを記述
3. クエリ結果を操作（コンソール画面に出力）

```C#:LINQ操作手順
class IntroToLINQ
{        
    static void Main()
    {
        // The Three Parts of a LINQ Query:
        // 1. Data source.
        int[] numbers = new int[7] { 0, 1, 2, 3, 4, 5, 6 };

        // 2. Query creation.
        // (クエリ式)
        var numQuery =
            from num in numbers
            where (num % 2) == 0
            select num;
         //(メソッド式)
         //var numQuery = numbers.where(num => num % 2 == 0);

        // 3. Query execution.
        foreach (int num in numQuery)
        {
            Console.Write("{0,1} ", num);
        }
    }
}
```


##IQ2の人はここで帰ってくれ
![ダウンロード (1).jfif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467405/680affea-a4cf-e062-aefb-e36614c678ed.jpeg)

やる気があったら次の記事で解説します
Django とは。。。

Pythonの学習を始めた人の多くが耳にするであろう。Djangoについて。。。

自分用であり、誰かの学習に役立てれば嬉しいです。

Djangoを利用して作られたWEBアプリケーションで有名なのが、みんな大好き（私はやっていない）インスタです。あとCMで耳にする「日経電子のバーン」でお馴染みの日経電子版です。（私は毎月無料枠分のみ利用してます。）

Pythonを学習したいと考える人の多くは機械学習やAIに興味があるのではないのでしょうか？
Pythonはデータ分析や機械学習に優れたライブライが充実しているために、近年人気があります。

PythonのフレームワークであるDjangoの人気は今後も上がり続けると考えられます。

それではDjangoとは。。。。

DjangoはpythonでWEBアプリケーションを作成するためのフレームワークである。
DjangoにはWEBアプリケーションに必要な機能が多く用意されているので、開発のハードルが下がる。
　例）　Djangoにはユーザー周りの認証機能が標準で搭載されているので、近年のアプリケーションでは必ずと言えるほど用意されているユーザー登録などの機能を簡単に開発できる。

Djangoの特徴は『フルスタック』であると言える。
各OSのキー配列変更方法まとめ

## はじめに
キーボード配列をいじりたくなること、あると思います。
OSごとに設定方法をまとめました。

## Mac
[Karabiner-Elements](https://karabiner-elements.pqrs.org)を使用します。
設定方法は、[Karabiner-Elementsの設定項目をまとめました](https://qiita.com/s-show/items/a1fd228b04801477729c)を参考に。
1キーずつ割り当てもできるし、jsonで一括割当も可能。
またキー配列の変更だけでなく、マクロっぽい設定も可能。
ユーザーが多く、需要がある設定ならだいたいあります。
キー配列をいじるなら、Macが一番楽です。

## Linux
Linuxのキー配列管理をしてる[xkb](https://www.x.org/wiki/XKB/)の設定をいじります。
設定方法は、[XKBの設定ファイルを直接編集してキーボードレイアウトをカスタマイズする](https://wiki.archlinux.jp/index.php/X_KeyBoard_extension)がわかりやすいです。
上の記事読んで心が折れたなら、今使ってる設定ファイルを書き換えるだけでも変更できることを追記しておきます。
例えばCapsLockを変更するなら、以下ファイルです。

```
sudo vim /usr/share/X11/xkb/symbols/pc
```
Enterキーの割当を忘れると、クリーンインストールからやり直しなので気をつけてください。


## Windows
[KeySwap](https://www.vector.co.jp/soft/winnt/util/se228667.html)を使用します。
設定方法は、本体のexeを起動すればなんとなくでわかります。
1キーずつ割り当てでき、設定ファイルとして保存するタイプです。
Windows10にも対応していますが、実行にはAdministrator権限が必要です。

KeySwapの他にも、KeyTweak, SharpKeys, Microsoft Keyboard Layout Creatorなどいろんなソフトがあるみたいです。

## 終わりに
OS間で気軽にキー配列を共有したい。。。
AWSのECRに置いたコンテナイメージをお引越ししてみた

　AWSのECRに置いてあるコンテナイメージをテスト環境から本番環境に移転させるという業務があり、ザッと調べてもパッとは出てこなかったので、やり方を残しておこうと思います。
　本来、コンテナはdockerfileを書いてそれを管理した方が良いのですが、そんなものは残ってなかったし、ぺーぺーの自分はそんなことすら知らなかった。
#ECR上のコンテナイメージを移転する
　今回は2パターンのやり方を紹介します。
１：コンテナイメージをtarファイル化し、ローカルを経由してお引越し
２：コンテナイメージを直接pullして、そのままpushしてお引越し

　本記事では、お引越し先のAWS環境を移転先、お引越し元のAWSアカウントを移転元と表記します。
※スクショないです、追加できたらやります。

#環境
ローカルOS：windows10
ターミナルソフト：Rlogin
EC2のインスタンスタイプ：t3.medium


#１：コンテナイメージをtarファイル化し、ローカルを経由してお引越し
　実際の業務ではこちらを採用しました。2つ目の方が早くて簡単ですが、無作法なので却下されました。
　大まかな流れとしては、こんな感じになります。

①Rloginで移転元のEC2インスタンスにログインする
②EC2インスタンスからAWSコマンドで移転元のECRにログインして、任意のコンテナイメージをpullする
③pullしてきたコンテナイメージをtarファイル化して、ローカルにダウンロードする
④移転元のEC2インスタンスから切断し、Rloginで移転先のEC2インスタンスにログインする
⑤tarファイル化したコンテナイメージをEC2インスタンスにアップロードして展開する
⑥展開して出来たコンテナイメージにtagをつけて、移転先のECRにpushする

　実践したわけじゃないけれど、多分ローカルにDocker Desktopをインストールして、AWSコマンドを叩けるようにしておけば、(クレデンシャル情報が載ってるconfigureファイルがローカルにガッツリ残ることはさておき)わざわざRlogin使ったりtarファイル化したりしなくても良いかもしれない。

###①Rloginで移転元のEC2インスタンスにログインする
　ぶっちゃけEC2インスタンスに接続できればなんでも良いので省略

###②EC2インスタンスからAWSコマンドで移転元のECRにログインして、任意のコンテナイメージをpullする
　EC2インスタンスに接続したら、次のawsコマンドでECRへ接続するためのトークンを発行します。
`aws ecr get-login --no-include-email`
　このコマンドの戻り値を余すことなくcopy&paste&EnterすることでECRをいじることができるようになります。

###③pullしてきたコンテナイメージをtarファイル化して、ローカルにダウンロードする
　一旦、AWSのコンソールでECRのリポジトリを見に行きます。そこでお引越し対象のコンテナイメージのURLを確認しておきます。
　EC2インスタンスで、次のAWSコマンドでECRからお引越し対象のコンテナイメージをpullしてきます。
`docker pull (コンテナイメージのURL)`
　pullできたら次のコマンドでtarファイル化します。
`docker save -o (任意のファイル名).tar (コンテナイメージ名)`
　終わったら、ローカルの任意の場所にダウンロードしておきます。

###④移転元のEC2インスタンスから切断し、Rloginで移転先のEC2インスタンスにログインする
　移転元での作業を終わりなので切断します。ここからは移転先での作業なので、移転先EC2インスタンスに接続します。

###⑤tarファイル化したコンテナイメージをEC2インスタンスにアップロードして展開する
　移転先のEC2インスタンスに接続できたら、さっきのコンテナイメージのtarファイルをアップロード、次のコマンドで展開します。
`docker load -i (ファイル名).tar`

###⑥展開して出来たコンテナイメージにtagをつけて、移転先のECRにpushする
　展開したコンテナイメージのコンテナイメージIDを"docker images"コマンドで確認したら、次のコマンドでタグ付けします。
`docker tag (コンテナイメージ名) (push先リポジトリのURL)`
　最後に次のコマンドでコンテナイメージをpushします。(手順②のECRへの接続を忘れずに)
`docker push (push先リポジトリのURL)`

　AWSのコンソールでECRのリポジトリを見に行き、コンテナイメージが確認出来たらお引越し成功です。


#２：コンテナイメージを直接pullして、そのままpushしてお引越し
　移転元のECRから移転先のEC2に直接コンテナイメージをpull、そのまま移転先のECRにpushする方法です。上の方で無作法と言われた理由としては、移転先EC2インスタンスで移転元のクレデンシャルを使って移転元のECRを直接触るからです。
　大まかな流れとしては、こんな感じになります。

①Rloginで移転先のEC2インスタンスにログインする
②EC2インスタンスからAWSコマンドで移転元のECRにログインして、任意のコンテナイメージをpullする
③EC2インスタンスからAWSコマンドで移転先のECRにログインして、任意のコンテナイメージをpushする

お手軽、簡単、でも無作法
pullしてきたコンテナイメージに、tag付けだけすればpushできます。

#まとめ
　今回は、AWSのECRに置いてあるコンテナイメージを別のAWS環境に移転させる方法についてまとめてみました。クレデンシャルの管理とかを徹底するなら、手間はかかりますが方法１で作業するのが良いかと思います。そこまで気にしない、作業した後にちゃんとクレデンシャルを削除します、というなら方法２もアリといえばアリかもしれないです。方法２の場合、ローカル環境にDocker DesktopとAWSCliをインストールしておけば、コマンドプロンプトでこと足りる気もしてます。
　コンテナの管理としては、dockerfileで書いて残しておくことで共有しやすくなる、というか本来のお作法だと思いますので、自分がゼロからコンテナを作る場合は、ちゃんとdockerfile残しておきたいと思いました。(ただ、コンテナをbiuldする際にインストールするものが多かったりする場合は、tarファイルでやり取りした方が若干早かったりします。)
　それでは。
Qiita記事のエクスポート

# 経緯

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">Qiita、ユーザーが読んだ記事の傾向を勝手に晒してくるんだ。ふーーーーん。 <a href="https://t.co/I3TL1HdbIX">https://t.co/I3TL1HdbIX</a> <a href="https://t.co/xpUJgazdAp">pic.twitter.com/xpUJgazdAp</a></p>&mdash; tadsan (@tadsan) <a href="https://twitter.com/tadsan/status/1242806005055934470?ref_src=twsrc%5Etfw">March 25, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-partner="tweetdeck"><p lang="ja" dir="ltr">Qiita、ユーザーが読んだ記事を解析して結果を合意もとらずに公開する時点で相当アレだと思うけど、「公開したくなければオプトアウト」と提示してるリンクが別会社のサイトで、そこを見てもオプトアウトの方法が皆目分からないのはもうサービスとして使ってはいけない領域になったと思う。 <a href="https://t.co/jhq5aF2OiY">pic.twitter.com/jhq5aF2OiY</a></p>&mdash; Keiji ARIYAMA (@keiji_ariyama) <a href="https://twitter.com/keiji_ariyama/status/1242822015767085057?ref_src=twsrc%5Etfw">March 25, 2020</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# ぼく

前々からQiitaあんまり好きじゃなかったんで全く使ってなかったんですがマジでキツいのでエクスポートします.

[jq](https://stedolan.github.io/jq/)と[httpie](https://httpie.org/)を使ってるのでMac使いの人は次のコマンドでよしなにしてください

それ以外のユーザは知りません

## Install Dependencies

```bash
$ brew install jq httpie
```

## Export Posts

```bash
$ http --follow 'qiita.com/api/v2/users/ユーザID/items' | jq '.[] | .url' | xargs -I{} echo {} | sed 's/$/\.md/g' | xargs wget
```

ユーザ認証のないAPIなので公開してる記事しか取れません

### 2020.09.14追記

@eggplants 様よりコメントいただきました, こっちのがパイプが少なくてスマートです

```bash
$ wget $(curl -s 'https://qiita.com/api/v2/users/ユーザID/items' | jq -r '[.[].url+".md"]|join(" ")')
```

# お わ り

Qiitaみんなやめようねという話ではないけど少なくとも僕はやめます

# 追記

あまりに腹が立つのでそれっぽいサイトを作ってみました

[goodbye-qiita.netlify.com](http://goodbye-qiita.netlify.com)

![Screen Shot 2020-03-26 at 4.05.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139165/008b868b-37ba-e861-602d-dd50582f9209.png)
VPC Lambda から AWS API を使う

VPC に置いた Lambda Function から AWS API を使おうとしたらタイムアウトしてしまって困った。

[公式ドキュメント](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc.html) を読むと、

> Connect your function to private subnets to access private resources. If your function needs internet access, use NAT. Connecting a function to a public subnet does not give it internet access or a public IP address.
> 
> Several services offer VPC endpoints. You can use VPC endpoints to connect to AWS services from within a VPC without internet access.

- Public Subnet に置いてもランタイムのインスタンスに Public IPv4 アドレスは割り当てられない
- インターネットへのアクセスが必要な場合は Private Subnet に置いて NAT しろ
- いくつかの AWS Service は VPC エンドポイントでアクセスできるので、それらを使うだけならインターネットアクセスは必要ない

とのこと。

つまり VPC Lambda から AWS API を使いたければ「NAT する」か「VPC エンドポイントを使う」の2択になる。

いずれの場合も Lambda Function は Private Subnet に配置する必要がある。

## VPC エンドポイント
使いたい AWS API が VPC エンドポイントに対応しているならこっちの方が簡単と思われる。

ただし今回触っていたのが趣味 AWS 環境であり、VPC エンドポイント1つに約$10/月かかってしまうのがちょっと厳しいのでやめた。

## NAT
お金がある人は NAT Gateway を使うと一瞬でできて便利。(約$45/月)

今回はお金がないので NAT インスタンスを自分で立てた。

参考： [Ubuntu の ufw で NAT サーバを作る - Qiita](https://qiita.com/hoto17296/items/3aa5863ba9ef13400283)

## 所感
Lambda で Serverless したかったのに何故ワイは NAT インスタンスを構築しているんや・・・？
【Unity(C#)】MaterialPropertyBlock使って一つのマテリアルを使いまわす

##MaterialPropertyBlock

下記記事で作成していたVRお絵描きアプリに
色の変更機能を設けようとした際に`MaterialPropertyBlock`を活用しました。

【参考リンク】：[【Unity(C#)】ハンドトラッキングで簡易版VRお絵かきアプリ](https://qiita.com/OKsaiyowa/items/b5045fc240d1d9a57880)

描いた線ごとに色を変更したかったのですが、
描く予定の線の分だけマテリアルを用意するのは
あまりにも手間ですし、その都度Instantiateするのも
負荷的にどうなの？と感じたので
`MaterialPropertyBlock`の使い方を学ぶことにしました。

##デモ

リアルタイムに色違いのキューブがランダムに生成されるデモです。

![MaterialPropertyBlock.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/029e361f-986f-be6b-11bf-ea809dd8f34e.gif)


マテリアルは１つしか使っていません。

##コード

```C#
using System.Collections;
using UnityEngine;

/// <summary>
/// 色違い場所違いキューブ自動生成プログラム
/// </summary>
public class CubeCreate : MonoBehaviour
{
    [SerializeField] private GameObject _cube;

    private MaterialPropertyBlock _materialPropertyBlock;

    private int propertyID;

    private void Start()
    {
        _materialPropertyBlock = new MaterialPropertyBlock();

        //プロパティーのIDを取得しておく　SetColorをstringで指定しても結局intに変換してるらしく、無駄らしい
        propertyID = Shader.PropertyToID("_Color");

        StartCoroutine(InstantiateColorCube());
    }

    /// <summary>
    /// ランダムな位置にランダムな色のキューブを生成 
    /// </summary>
    private IEnumerator InstantiateColorCube()
    {
        while (true)
        {
            //ランダムな値
            float randomValueA = Random.Range(-1.0f, 1.0f);
            float randomValueB = Random.Range(-1.0f, 1.0f);
            float randomValueC = Random.Range(-1.0f, 1.0f);
        
            //ランダムな値
            float randomMagnification = Random.Range(0.0f, 5.0f);

            //ランダムな位置にキューブ生成
            Vector3 randomPos = new Vector3(randomValueA, randomValueB, randomValueC);
            GameObject tmp = Instantiate(_cube, randomPos*randomMagnification, Quaternion.identity);

            //MaterialPropertyBlockで色を変更　元のマテリアルの色はそのまま
            MeshRenderer mr = tmp.GetComponent<MeshRenderer>();
            Color randomColor = new Color(randomValueA, randomValueB, randomValueC);
            _materialPropertyBlock.SetColor(propertyID, randomColor*randomMagnification);
            mr.SetPropertyBlock(_materialPropertyBlock);
        
            yield return null;
        }
    }
}
```

##SetColor , SetPropertyBlock

色をセットするために`SetColor` を使います。
第一引数にShaderで定義されている`色のProperty名`を指定します。
(今回はIDで指定しています)

その後、Rendererに反映させるために`SetPropertyBlock`を呼び出します。

##Shader.PropertyToID
`Shader.PropertyToID`を使うことで
Shader内で定義されている特定のプロパティ名を
ID(int型)に変換することができます。

先ほどの`SetColor`の第一引数に渡すことができます。

メリットしてはStart関数内でIDを取得しているので
何度も`指定したShader内プロパティの文字列`→`ID(int型)`
という処理を行わずに済み、負荷が軽くなります。


##参考リンク
[【Unity】【シェーダ】MaterialPropertyBlockの使い方](https://light11.hatenadiary.com/entry/2019/04/01/233503)

[【Unity】MaterialのPropertyIDについて]
(http://haraken.hatenablog.com/entry/2018/07/06/%E3%80%90Unity%E3%80%91Material%E3%81%AEPropertyID%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
【Laravel】テストのsetUp()でエラー「Declaration of…must be compatible with...」

###状況

```php:UserTest.php
class UserTest extends TestCase
{
    public function setUp()
    {
       //略
    }
}
```
laravelのphpunitのsetUp()メソッドを上記のように書き、テストを行ったところ
次のようなエラーが出ました。

```
PHP Fatal error:  Declaration of Tests\Feature\UserTest::setUp() must be compatible with Illuminate\Foundation\Testing\TestCase::setUp(): void in /var/www/tests/Feature/Usertest.php on line 13
```
###エラー内容とその対処
要はテストのsetUp()とIlluminate\Foundation\Testing\TestCase
のsetUp()の返り値が違うということを言われているわけです。

そこでIlluminate\Foundation\Testing\TestCaseクラスを見てみます。

```php:TestCase.php
    protected function setUp(): void
    {
        //略
    }
```
Illuminate\Foundation\Testing\TestCaseクラスではsetUp()に`void`が返り値として宣言されています。

したがってテストのほうにも`void`のタイプヒンディングをしましょう。

```php:UserTest.php
class UserTest extends TestCase
{
    public function setUp() :void
    {
       //略
    }
}
```
これで完了。
setUp()が使えるようになると思います。