OmniAICreator/Qiita-1.07M huggingface dataset:
golangでAzureDevOps#2

[前回](https://qiita.com/8su4i/private/4d9a05791bcb1dfcb396)作ったDevOpsプロジェクトをベースに更新の導入部分についてまとめていきます。

# やり方

## DevOpsプロジェクトへ移動

[Azure Portal](https://portal.azure.com/#home)からDevOpsProjectを選択します。
![スクリーンショット 2019-12-02 16.05.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/8ff19e49-9e44-1e5e-69fb-bbf9ec679b72.png)

プロジェクトを選択します。
![スクリーンショット 2019-12-02 16.06.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/2d7ae95e-6219-7ee5-a3d4-9f13958319d7.png)

「Project homepage」というリンクがあるので選択します。
![スクリーンショット 2019-12-02 16.06.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/56a2ced0-d638-c3f6-a242-754bd071c7d7.png)

左のスライドメニューから「Repos -> Files」の順に選択します。
![スクリーンショット 2019-12-02 16.07.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/135ac110-5505-93b5-d430-f5e520100eb3.png)

git urlをコピーします。
![スクリーンショット 2019-12-02 16.07.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/6d204fe9-48df-547c-2692-d403e8f5209c.png)

コマンドを実行します。

```
git clone git@ssh.dev.azure.com:v3/sample/pod042/pod042
```

下記エラーが出た場合はssh-keyを登録します。
![スクリーンショット 2019-12-02 16.09.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/c28957eb-4959-48ac-c136-d3717ca65a68.png)

## ssh key 登録

下記コマンドでssh keyを表示&コピーします。

```
cat ~/.ssh/id_rsa.pub
```

DevOpsプロジェクトページのユーザー情報に設定します。
![スクリーンショット 2019-12-02 16.10.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/cbe04753-d5ba-3744-0dc0-ae221fc3f2da.png)

「+ New Key」からウィンドウを開いてペーストします。
名前は適当なものを入れましょう。
![スクリーンショット 2019-12-02 16.11.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/e9163369-caf9-802a-1724-48dbc8f32314.png)

再度git cloneコマンドをし、下記の様に表示されたら成功です。
![スクリーンショット 2019-12-02 16.11.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/f76d40d0-0038-c74a-848b-86670c1bff2a.png)

適当なエディタで開いて
Application/app.goの「Home」関数を適用な文言に編集してみます。
![スクリーンショット 2019-12-02 16.17.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/ad93f79a-4afb-0d3a-79e8-24902c7d380b.png)

commit -> git pushすると
DevOps側でBuilds -> Releasesとジョブが走り公開されます。
![スクリーンショット 2019-12-02 16.47.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30796/25a0ccbd-fb95-78fc-5e9d-de63d5a2956c.png)
以上
お疲れ様でした。
DjangoのテンプレートをAWS boto3を組み込んで翻訳

#各国の言語に対応したWebアプリが必要だったのでAWSのboto3を使ってタグを生成

メモとして活用します。
完成したら細かいところを記述したいと思います。
環境
djang == 2.1
boto3 == 1.0.0?
python == 3.6 ?

やりたいこと
クライアントが言語選択したらその言語で翻訳して表示

中身
boto3を組み込んだタグを作って
HTML内でタグに囲んだ部分を翻訳する。
⇓イメージ
{% translate %}ここ翻訳{% endtranslate %}
すでにDjangoには{% trans %}という翻訳用のタグがあるようだけど
自分でpoファイルやら何やらよりも
AWSの翻訳API使った方が一程度無料でクオリティ高いかな～と思ったので
まずはやってみる。

##事前準備
・AWS登録
・pip install boto3

##テンプレートタグについて
djangoはサーバサイドの言語だからHTMLを生成するような便利な機能が必要だったのでDTL(django template language)という便利機能が組み込まれました。
DTLには４つ種類があり、
１つは、変数=>{{ first_name }}
2つ目は、タグ=>{% block %}{% endblock %}
3つ目は、フィルター＝＞{{ value | filter }}
4つ目は、、、4つ目は、忘れた、とりあえず一時的メモなので後ほど

##タグの生成
タグの作り方は、djangoのドキュメントでテンプレートエンジンの仕組みのところを通読すると
その後スムーズにできます。

タグの生成下準備
①アプリは直下に templatetags ファイル生成
②templatetags 内に __init__.pyを生成　＜＝これでテンプレートエンジンが探索してくれる
③templatetags 内に translate.py 生成　＜＝ファイル名は何でもオッケー

translate.py の中身（まだ途中）

```
from django import template
import boto3

register = template.Library()

REGION = 'ap-northeast-1'
SRC_LANG = 'ja'
TRG_LANG = 'en'

@register.filter(name="translate", is_safe=True, needs_autoescape=True)
def translate(value, autoescape=True):
    translate = boto3.client(service_name='translate', region_name=REGION,use_ssl=True)
    result = translate.translate_text(Text=value,
        SourceLanguageCode=SRC_LANG,
        TargetLanguageCode=TRG_LANG)
    return result.get('TranslatedText')
```

とりあえずこれはフィルターを生成してみました
HTMLファイルで
{{ '箱' |translate }}
とすると
Box
とブラウザで表示されます。
この'箱'部分に本文をいれれば翻訳されて返ってきますが
今回は{% translate %}ここ翻訳{% endtranslate %}が理想なので
お次はこのタグをつくります。フィルターは簡単そうだったので作ってみました。
これからタグつくるのでメモはここまででまた更新します。
マークダウンエディタSimpleMDEを使ってみた！

# はじめに
最近バッグログのwiki機能を触っている際に、これ、自分でも作れるんじゃね？
と思ったので、色々調べてみると、良さげなエディタを見つけたので使ってみることにした。

# Simple MDEとは？
JavaScriptのMarkdownエディターです。
[公式ページ](https://simplemde.com/)

# 選んだ理由
1. シンプルでわかりやすいUI
2. 記載しながらリアルタイムでプレビューしてくれる書きやすさ
3. 導入のしやすさ

画像で見て取れるように、太字にしたい箇所や見出しにしたい箇所などがわかりやすく、
リアルタイムでプレビューしてくれるので、見やすいし、描きやすい。
なおかつ導入には数コードですむため、初期導入にもってこいの印象

<img width="1428" alt="スクリーンショット 2019-12-05 13.49.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124316/4d9f5e05-4e10-23f3-f23f-19b3f22aff72.png">

# 環境
Laravel Framework 5.8.35
PHP 7.1.23 (cli)

simpleMDEはcdnで読み込むことにする
基本サイトはlaravelで組んでいるのでlaravel上で動くことを確認

# コード
```php:create.blade.php
<textarea id="body" name="name" rows="8" cols="40"></textarea>

<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
<script>
var simplemde = new SimpleMDE({ element: document.getElementById("body") });
</script>
```

# 問題発生
エディタが入力できねえ・・・
<img width="709" alt="スクリーンショット 2019-12-05 14.02.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124316/46700381-84a6-f24a-1aaf-41a8a6f8f20a.png">

laravel上で読まれているjsかソースの順番からか、jsの読み込み順が前後したっぽい。
なので、domが生成されるのを待って実行することに

```php:create.blade.php
<link rel="stylesheet" href="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.css">
<script src="https://cdn.jsdelivr.net/simplemde/latest/simplemde.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script>
    $(document).ready(function(){
        var simplemde = new SimpleMDE({ element: document.getElementById("body") });
    });
</script>
```

## できたーーーー！！！
<img width="709" alt="スクリーンショット 2019-12-05 14.07.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124316/87cdf300-04de-ec40-855e-77ac2176edc2.png">

# 感想
導入はトラブルもあったがめっちゃ簡単にできた。
色々オプションもあるらしいので調べながら使ってみたい。

ちなみにPOSTデータはこんな感じ。
<img width="440" alt="スクリーンショット 2019-12-05 14.11.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124316/c4ba3edb-593e-87cd-7d2f-d7945b97bf7e.png">

まあそりゃそうだけどマークダウンのテキストそのままポストされるので、それを保存したらいいかも。

今後も色々試してみる。
Pythonで任意のディレクトリの画像をシャッフルして別のフォルダーに連番で保存する。

#Pythonで任意のディレクトリの画像をシャッフルして別のフォルダーに連番で保存する。
Jupyter-notebookでディレクトリの画像をシャッフル。

```Python:shuffleimage.ipynb
#フォルダ内の画像をシャッフルして保存するコード
import os
from random import shuffle
from glob import glob
from shutil import copy


data_dir_path = "ここに画像が入っているディレクトリの絶対パスをペースト" #シャッフルしたい画像を内包しているフォルダーパス

base_path = os.path.join(data_dir_path ,"*.png")

#シャッフルした画像の保存先ディレクトリの作成
make_dir_path = data_dir_path +"_shuffle" #保存先ディレクトリのパス
os.makedirs(make_dir_path, exist_ok=True) 

#フォルダー内の画像をシャッフルして保存先ディレクトリに保存
files = sorted(glob(base_path))
shuffle(files)
n = 1 #ファイル名開始番号

#連番で画像を作成したディレクトリに保存
for file in files:
    copy(file,'{}/{}.jpg'.format(make_dir_path,str(n).zfill(5)))
    n += 1

print("保存先ディレクトリ　%r　 を作成"%os.path.basename(make_dir_path))
print("シャッフルした画像数 : %d　　　保存完了\n"%(int(len(files))+1))
```

#引用

[Pythonでパス文字列からファイル名・フォルダ名・拡張子を取得、結合 | note.nkmk.me](https://note.nkmk.me/python-os-basename-dirname-split-splitext/)
[python 相対パス 親ディレクトリの場所を取得する方法 - 初心者入門サンプル](https://code-examples.net/ja/q/2afcf0)
[[Python] フォルダやファイルのコピー、移動、削除（shutilモジュール） | Hibiki Programming Notes](https://hibiki-press.tech/learn_prog/python/shutil_copy_move_rmtree/1305)
[【Python】カレントディレクトリのファイル数をカウントする Python](https://qrunch.net/@1ntegrale9/entries/QTasG4UxdtelIA8S)


初投稿なので書き直す予定です＾＾
LazyHighChartsにプルリクを送ってマージされた

（この記事は、[高専OBOG Advent Calendar 2019](https://adventar.org/calendars/4238)の12/5に送った記事です。）

# 要約

普段使っているgemに、Pull Requestを送って、マージされました。

[LazyHighCharts](https://github.com/michelson/lazy_high_charts)というgemの動きが気に入らなくてモンキーパッチを当てて使っていました。
自分のアプリケーション以外でも役に立つ、gem本体に取り込まれるべき修正だと考えたので、gemのリポジトリにプルリクを送ることにしました。

流れはこんな感じです。

1. 不具合を見つける
2. 手元でgemの修正を試す
3. githubのリポジトリに修正を送る
4. マージされる

# PRがマージされるまで
## 1. 不具合を見つける

LazyHighChartsは、[Highcharts JS](https://www.highcharts.com/)というチャートを描画するJavaScriptライブラリを、RailsやSinatraなどのフレームワーク内で簡単に使えるようにするgemです。
詳しい紹介は本家をご覧ください。[https://github.com/michelson/lazy_high_charts](https://github.com/michelson/lazy_high_charts)

RailsでJavaScriptの読み込みにdefer属性を付与した場合、チャートが描画されない、という不具合に遭遇しました。
viewに書き出されたjsを見てみると、どうやらLazyHighChartsがこしらえたjsに問題があるようでした。

## 2. 手元でgemの修正を試す

手元でgemの修正をためします。

問題になっている箇所を書き出しているModuleを探して、モンキーパッチを当てます。
[IntelliJ IDEA](https://www.jetbrains.com/ja-jp/idea/)だとコードジャンプで該当箇所に飛べるので、すぐにModuleやClassの名前がわかって便利ですね！
モンキーパッチを当てると、問題なくチャートが描画されました。
（しばらくこの状態で本番で使っていました）

次はgemのリポジトリをforkして、gemに修正を加えます。
Gemfileのlazy_high_chartsの取得先をこんな感じにforkしたリポジトリ＆ブランチに書き換えて、手元で修正版のgemを試します。

```
gem 'lazy_high_charts', git: 'git@github.com:kosappi/lazy_high_charts.git', branch: 'use_event_listener'
```

この修正版も、モンキーパッチのときと同じように、問題なくチャートを描画してくれました。

## 3. githubのリポジトリに修正を送る

手元で動作確認ができたので、本家にも同じ修正を送ります。
まずはREADME.mdを読んで、どのような流れで修正を提案するのか見てみます。[README.md](https://github.com/michelson/lazy_high_charts/blob/master/README.md)
Contributingを読んでみると、このように書いてあります。

> - Fork the project
- Do your changes and commit them to your repository
- Test your changes. We won't accept any untested contributions (except if they're not testable).
- Create an issue with a link to your commits.

まずは動作確認して、それからissueを作って欲しい、とのことでした。
動作確認は済んでいるので、issueを作ります。
英語は得意ではないので、すでにマージされたPRや、closeされたissueを参考にしつつ、時間をかけて書くことになりました。
[作ったissue](https://github.com/michelson/lazy_high_charts/issues/253)

１日経つと、メンテナからPRを作って欲しいという旨の返事がありました。
PRを作ります。
[作ったPR](https://github.com/michelson/lazy_high_charts/pull/254)

PRを作ってしばらくするとCIがコケて赤くなっていました。
specを少し修正するだけで解決したんですが、事前にforkしたリポジトリでもCIを回しておくと、ベターかも知れません。

あとはマージされるのを待ちます。

## 4. マージされる

PRを出してから１日後、マージされました。
やったね！

# 感想

RubyやRailsを仕事で触りだして数年になりますが、めちゃくちゃgemを使うわりには、contributeする機会はまったくありませんでした。
タダで使ってばっかりでなんかスマン、という気持ちがありました。
今回、はじめてcontributeすることができて、とてもうれしいです。
Octaveでone-hotベクトル表現を作る

何通りかの値をとる整数を「その値のインデックスのみが1になっているベクトル」で表現するエンコード方法をone-hot encodingと呼ぶそうです。機械学習などでしばしば見られる手法です。

```text
1 -> [1, 0, 0, 0]
2 -> [0, 1, 0, 0]
3 -> [0, 0, 1, 0]
4 -> [0, 0, 0, 1]
```

[GNU Octave](https://www.gnu.org/software/octave/)でこの変換をきれいに書く方法を調べていたのですが、ブロードキャストという言語の機能を使うと簡潔な記述ができることを知ったので紹介します。

## どうやるか

`X == 1:max(X)` を使うと簡単です。ここでは1から最大値までとしましたが、例えば値が1〜10だと決まっているなら `X == 1:10` とするかと思います。

```text
octave:1> X = [1; 1; 2; 3; 5]
X =

   1
   1
   2
   3
   5

octave:2> X == 1:max(X)
ans =

  1  0  0  0  0
  1  0  0  0  0
  0  1  0  0  0
  0  0  1  0  0
  0  0  0  0  1

```

ちなみに不連続でも構いません。

```text
octave:1> X = [1; 1; 2; 3; 5]
X =

   1
   1
   2
   3
   5

octave:2> X == [1, 2, 4, 6, 8]
ans =

  1  0  0  0  0
  1  0  0  0  0
  0  1  0  0  0
  0  0  0  0  0
  0  0  0  0  0

```

## なぜこれで上手くいくのか

Octave 3.6.0からブロードキャスト（broadcasting）という機能が入ったらしいです。二項演算をする際に、次元が大きい方のベクトル・行列に合わせるように要素コピーをしてくれます。このとき小さい方の次元は1である必要があるようです。

先の例でいうと、 `1:max(X)` は `[1, 2, 3, 4, 5]` となり、 `==` 演算は5×1ベクトルと1×5ベクトルに関して行われていました。
したがって、この場合はブロードキャストが発生し

```text
X  = [1, 1, 1, 1, 1;
      1, 1, 1, 1, 1;
      2, 2, 2, 2, 2;
      3, 3, 3, 3, 3;
      5, 5, 5, 5, 5]

X == [1, 2, 3, 4, 5;
      1, 2, 3, 4, 5;
      1, 2, 3, 4, 5;
      1, 2, 3, 4, 5;
      1, 2, 3, 4, 5]
```

このように評価されて一致していた箇所の値が1になったようです。簡潔でいいですね。

## 参考リンク

- <https://octave.org/doc/interpreter/Broadcasting.html>
- <https://stackoverflow.com/a/38948272/11169807>
リリースビルドで「SocketException: Failed host lookup: 'xxxxxxx' (OS Error: No address associated with hostname,)」と言われたときは。

# 要約
- デバッグモードでリクエスト飛ばせたのに、リリースビルドだと表題のエラーが出る
- ちゃんと`<uses-permission android:name="android.permission.INTERNET" />`を付与しよう！
- 公式ドキュメントを、見よう


# 事例と原因、対策
Flutterアプリで`http`など通信を行うアプリを作っている時に気を付けたい事例です。
デバッグビルドやiOSのリリースビルドでは問題なく動いたのに、リリースビルドのAndroidのみ通信部分でエラーが起きる場合があります。

エラー内容としては以下の通りです
`SocketException: Failed host lookup: 'xxxxxxx' (OS Error: No address associated with hostname,)`

原因としては、インターネットに関するパーミッションが付与されていないことでした。

Android開発を経験した人にはお分かりだと思いますが、Androidではネットワークを使用するためには
`<uses-permission android:name="android.permission.INTERNET" />`
をAndroidManifest.xmlに付与しないといけません。

しかしながらflutterのデバッグモードでは、このパーミッションを付与せずともネットワークが使用可能になっています。
https://flutter.dev/docs/deployment/android#reviewing-the-app-manifest

Flutterから入った人、Android開発経験が久しぶりな人には、ついうっかり起きてしまうのではないでしょうか。
Flutterの公式ドキュメントは内容が豊富なので（ただし英語)しっかり活用していきたいところです。
AWSでSQSをLambdaのトリガーをマネージメントコンソールで設定するときに気をつけたい運命の分かれ道

### はじめに
AWS LambdaのトリガーにSQSを設定されている方も多いと思います。
SQSのキューにメッセージが送られると、トリガーに設定されたLambdaが呼び出されます。
一度の起動で複数のメッセージを処理することも可能で、このメッセージの数は**バッチサイズ**で指定できます。最大は10です。

Lambdaの用途によっては、バッチサイズを**1**にして運用する場合もあります。
マネージメントコンソールでトリガーを設定する主な導線は、

1. SQSからLambdaを設定する
1. LambdaからSQSを設定する

の2通りがありますが、**これが運命の分かれ道**です。
実際にトリガーを設定してみるので、どのような画面遷移なのかご覧ください。

### 状況
`sqs_sample`というLambdaと`lambda_trigger`というSQSのキューがあります。
`lambda_trigger`がメッセージを受信すると`lambda_trigger`が発火するようにトリガーを設定します。

### Lambdaからトリガーを設定する場合
マネージメントコンソールからLambda > 関数 > sqs_sampleを選択します。
この画面で「トリガーを追加」をクリックします。
![スクリーンショット 2019-12-03 10.11.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/44d98da9-722f-e9c7-f270-3851b0498b4b.png)

プルダウンからSQSを選択します。
![スクリーンショット 2019-12-03 10.17.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/eb24704f-51b6-7e1b-415d-0c0fb82b9a6b.png)

![スクリーンショット 2019-12-03 10.28.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/e45b142d-bf19-db26-9be6-84a7ca0c2160.png)

プルダウンから`lambda_trigger`を選択します。
ここで注目してもらいたいのは、**バッチサイズ**が画面に表示されている点です。
これにより、トリガーのバッチサイズが10であることをユーザーは認識できます。
今回は10で設定しました。

![スクリーンショット 2019-12-03 10.31.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/789348c5-de6b-63d5-d295-9a3044648fbd.png)

トリガーが設定されるまで1分ほど待ちます。
これで設定完了です。
![スクリーンショット 2019-12-03 12.16.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/8545eca4-46df-00d5-2c22-ce9372206630.png)


### SQSからトリガーを設定する場合

マネージメントコンソールからSQSを選択します。すでにキューが存在する場合は作成済みキューの一覧が表示されます。
`lambda_trigger`を選択して「キュー操作」をクリックします。
![スクリーンショット 2019-12-03 13.36.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/3745f723-c076-0a30-a07b-6a7f5957ef40.png)

表示されたメニューから「Lambda関数のトリガーの設定」を選択します。
![スクリーンショット 2019-12-03 13.36.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/7e04133e-09db-5e34-62c1-1a4ac2307434.png)


プルダウンメニューから`sqs_sample`を選択して「保存」をクリックします。
![スクリーンショット 2019-12-03 13.44.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/48197658-ef55-efc5-1209-e80c37a49ba1.png)

これでトリガーが設定されました。:rocket:
![スクリーンショット 2019-12-03 13.51.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/334984/7c9cccd7-3770-e220-fc6c-916e1029fb81.png)

ご覧いただいたように、**SQSからトリガーを設定する場合はバッチサイズなんてワードは一切出てきません**。
ちなみに、バッチサイズは10で設定されます。

### まとめ

バッチサイズが1に設定されていることを前提としたLambdaをデプロイするときは気をつけましょう

設定済みのトリガーのバッチサイズを変更する方法はみつからなかったので、一度削除してからLambdaからトリガーを設定しましょう。

---
[ハンズラボ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/handslab) 17日目は@bakupenさんです🎉
Notionのブロックをドラッグ・アンド・ドロップで操作する

アルプ株式会社でエンジニアをしています、集約のエンティティ@pictinyです。
これは[Notion Advent Calendar 2019](https://qiita.com/advent-calendar/2019/notion) 5日目のエントリです。
4日目は[Notionのページにアイコンを設定する](https://qiita.com/pictiny/items/04a74e8a5844e4e19615)でした。

# ブロック

[**What is a "block"?**](https://www.notion.so/What-is-a-block-e88f2d5154734d00863e1f6b97f849e5)

Notionのコンテンツにはブロックという最小単位があります。
見出し、リスト、コードブロック、画像、などなど。全てがブロックです。

ブロックを意識できるようになると、範囲選択がフォーカスしている対象がテキストかブロックかわかるようになったり、ドラッグ・アンド・ドロップでブロック単位でのページ編集ができるようになります。

ドラッグ・アンド・ドロップによるブロックの操作を見てみましょう。

![blockdd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427952/a8430bfc-5a6a-7fb6-8270-94b394599cc6.gif)

# まとめ

ブロックはNotionの大きな特徴の一つです。
ブロックによって、複数行あるテキストのペーストが崩れてしまったり、Notionから複数行をコピーするときに少し不便だと感じてしまうかもしれませんが、Notionでピュアにテキストを扱いたい場合にはコードブロックを作ってしまうのがおすすめです。
Accessファイル加工に関するマクロTips

(随時追記)何回かGoogle先生に聞いた気がする関数やメソッドを追加予定

---

# はじめに

「[Excelファイル加工に関するマクロTips](https://qiita.com/iguru/items/dcce1a2994025354f190)」のAccess版記事を作りました。
説明資料を作る機会が増えてきましたので、その時にお世話になったマクロの紹介です。
そもそもパワポでマクロを使う機会がそこまでないのでExcelと比べ内容が薄くなると思いますが、備忘録がてら日々更新していけたらと思います。

# マクロ

## 最初に選択した図形基準に選択したオブジェクトを加工する

**「パワポで構成図？　いやいやExcelのほうがいい感じにできるでしょｗｗ」**とほざいていたころの自分を殴りたくなります。
下図の項目を使うと構成図とか作りやすくていいですよね、これのおかげでパワポ好きになりました。

![Accessの便利なアレ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392066/fd57761e-2155-d4cb-1c98-7909edfbca15.png)

とはいえ、こちらは複数選択したときに**どれを基準に**配置されるかがよくわからないです。
厳密にはあるのでしょうけど、シンプルに**最初に選択したオブジェクト**を基準に配置してくれるようにしたマクロです。

イメージこんな感じです。

![マクロファイルに入れてるスライド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392066/cc80dba5-ca46-e6ea-0aab-93782b8bf29a.png)

時たま使う機会があるので、マクロの入っているパワポスライドに、以下のように書いておくと親切かもしれません。


```vb
Sub a01_最初に選択した図形に高さを揃える()

  With ActiveWindow.Selection
    With .ShapeRange

      .Height = .Item(1).Height
      
    End With
  End With
End Sub

Sub a02_最初に選択した図形に幅を揃える()

  With ActiveWindow.Selection
    With .ShapeRange

      .Width = .Item(1).Width

    End With
  End With
End Sub

Sub a03_最初に選択した図形に左端を揃える()

  With ActiveWindow.Selection
    With .ShapeRange

      .Left = .Item(1).Left
      
    End With
  End With
End Sub

Sub a04_最初に選択した図形に上端を揃える()

  With ActiveWindow.Selection
    With .ShapeRange

      .Top = .Item(1).Top
      
    End With
  End With
End Sub

Sub a05_最初に選択した図形に上下中央を揃える()
  
For i = 1 To ActiveWindow.Selection.ShapeRange.Count

    With ActiveWindow.Selection.ShapeRange
        tmp = ActiveWindow.Selection.ShapeRange.Item(i).Height

        .Item(i).Top = .Item(1).Top + .Item(1).Height / 2 - .Item(i).Height / 2

    End With

Next i
            
End Sub

Sub a06_最初に選択した図形に左右中央を揃える()

For i = 1 To ActiveWindow.Selection.ShapeRange.Count

    With ActiveWindow.Selection.ShapeRange
        tmp = ActiveWindow.Selection.ShapeRange.Item(i).Width

        .Item(i).Left = .Item(1).Left + .Item(1).Width / 2 - .Item(i).Width / 2

    End With
Next i
            
End Sub

```
CSSは神なのでゲームも作れる

#はじめに
この記事は[N高等学校 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/n-highschool)の12日目の記事です。
昨日の記事は同じキャンパスの先輩であるGenbu氏の[静的な Web サイトをどうやって速くするか](https://qiita.com/Genbu/items/282642b2be3b558106bc)です。合わせて是非。
因みに明日の記事も同じキャンパスの狂人Nemesis氏の[Flutterと云ふものを触った話を語りんす](https://qiita.com/Nemesis/items/4af9c3e34d20be584d8f)です。こちらも合わせてどうぞ。

こんにちは。N高等学校1年生の[はと](https://twitter.com/himajinn_N)と申します。プログラミング歴は一年にも満たない若輩者ではありますが、ここまでの学習の成果としてアドベントカレンダーを書かせていただきます。よろしくお願いいたします。
#作ったもの
<p class="codepen" data-height="600" data-theme-id="default" data-default-tab="result" data-user="hatopoppo" data-slug-hash="GRgJjZL" data-preview="true" style="height: 629px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="GRgJjZL">
  <span>See the Pen <a href="https://codepen.io/hatopoppo/pen/GRgJjZL">
  GRgJjZL</a> by HATO (<a href="https://codepen.io/hatopoppo">@hatopoppo</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だけで実装しました。JavaScriptは使ってません。
inputの自動選択は、私が知る限りHTMLとCSSではどうにもならないので一々クリックしないといけない仕様となっております。
本来こんな事CSSでやるべきじゃないので当然の如く脳筋クソコードです。それにあいまって元々のクソコード力も重なりクソの二段構えコードとなっております。
#若干ゃ解説
このコードの鍵や、苦労した点等の解説を少しだけします。
##仕組み
まずこのタイピングゲームで鍵になるのはここ

```CSSisGOD.html
<input type="text" class="A1" pattern="java" required>
```

inputタグの中の

```CSSisGOD.html
pattern="java"
```

ここ。

このpatternという所でinputに入れられたテキストの正誤判定をしています。
本来の用途としては、

```sample.html
pattern="^[0-9A-Za-z]+$"
```

等で受け付ける文字の種類を限定するのですが[^1]、今回はここに文字列javaを入れることにより、この文字列以外は受け付けないという形に出来ました。

そして、文字列が正しいと判断されると擬似要素 :valid が、
正しくないと判断されると擬似要素 :invalid が与えられる為、CSSで

```CSSisGOD.css
.A1:valid ~
.A2:invalid ~
.A3:invalid ~
.A4:invalid ~
.A5:invalid ~
.A6:invalid ~ .Q2 {
  opacity: 1;
}
```

のように書いてやって、A1（最初の問題のinput）が正しければ次の問題を表示という形に出来ました。
因みに得点の部分もこういう感じで切り替えています。本来は別の方法を使いたかったのですが後述の理由により断念しました。
##苦労した点
今回苦労したのは、inputの切り替えと得点の兼ね合いです。
現在正解時のinputの交代は、

```CSSisGOD.css
input[pattern]:valid{
  display: none;
}
```

このように、validの時に要素を消すという処理で行なっているのですが、このような形にすると、元々得点の部分で行なっていた、要素のカウントを出来るコード


```sample.css
input[pattern]:valid{
counter-increment: count; 
```

が動かなくなり、原因と改善案の模索で半日ほど潰していました。
理由は恐らく、要素そのものを消している為、カウント対象の要素がなかった事だと思います。
実際、opacityを0にする方式にしてみるとしっかりと得点のカウントがされました。
しかし、opacityを切り替える場合では、inputが常に存在している状態になります。
その状態だと問題を解いた後も、見えないinputがまだ選択状態、即ち入力待ちの状態になってしまう為、そこから次のinputの選択をせずに入力を行うと

一問前のinputに入力
　　　　↓
patternの正誤判定が働き一問前の問題とinputがまた表示

というストレスフルの状態になった為、やむなくinputは消滅させ得点は正誤判定で切り替えるシステムとしました
#終わりに
脳筋実装ではありますが、CSSでもゲームを作る事ができました。
CSSの限界はもっと上にあると思うので、今後もCSSの限界に挑み続けようと思います。
最後に、このゲームを作っている途中にクラスメートに言われた言葉を金言として書き、終わろうと思います。
**「CSSはゲームを作るものじゃない」**
**「時間の無駄」**
**「JavaScript使え」**
**「CSS中毒」**

ご覧いただきありがとうございました。

#追記
すでにCSSで僕なんかよりも完成度高くタイピングゲームを作り、分かりやすく解説もしていらっしゃる先駆者の方がおりましたので、畏敬の念を込めてリンクを貼らせていただきます。
[codegrid](https://app.codegrid.net/entry/derive-html-css-1)
[^1]: この場合は、半角英数字のみという制限をかけている。詳しくは他記事参照。
Blender2.8からVRMを出力する

Blenderで１からVRMを出力してみます。
インストール方法は https://github.com/iCyP/VRM_IMPORTER_for_Blender2_8 から <font color="green">Clone or Download</font> からZIP Download でzipをDL、そのzipをそのままaddon installし、TESTINGタブから有効にしてください。
改変チュートリアル動画はこちら(合わせて見ると分かりやすいです、特にﾏﾃﾘｱﾙについてはこちらでは詳しく説明しません。
https://nico.ms/sm36033523

ではまず。
#1 アーマチュアを作る
VRMはボーンの階層(要はunity humanoid)・姿勢(T-pose)が決まっています。自分で作れる方は自分で作ってください。
## 自動生成
面倒だよ、という方はアドオンインストールでAdd->Armatureで追加されるVRM humanoid を追加してください。
これ↓
<img width="278" alt="a.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21368/531c5750-cb3a-3811-1862-45870f262e08.jpeg">
一発でhumanoidアーマチュア(humanoid等のVRM属性設定済み)ができます。パラメータは、身長、等身、手の大きさ、股上の高さなどです。そこからそれっぽく作成されるようになっています。
<img width="410" alt="コメント 2019-12-05 131320.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21368/61c482b5-5d0d-96c8-585f-439ab2c706b5.jpeg">

Bone tall ：ボーンの一番上の先の高さ
Head ratio : 等身
nail bone:VRMで指先の当たり判定が欲しい場合は付けた方が良いです。
などなど、雰囲気でいろいろ弄ってみてください。

##手動生成
 アーマチュアはT-poseでunity humanoid ヒエラルキーにしてください。そのへんの面倒はまだ見ることができません。（そも仕様がブラックボックスだったり個人的にpendingかなという所だったりがあるので…）
 - 制限として、１本の木のようになるような構造にしてください。親のないボーンは１本のみ(root)許されます。
 その後、アーマチュアを選択した状態で、VRM HELPER　タブから Add VRM attribute を押してください。とりあえず簡単なVRM拡張設定をアーマチュアに付与しテキストエディタに設定ファイルのひな型(揺れものなど)を書き込みます。<img width="1079" alt="コメント 2019-12-05 131931.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21368/c4858821-7638-aed8-9fe1-6d5dff9c16c6.jpeg">

その後、アーマチュアを選択したままの状態でいくと、SSの右端のVRM HELPERタブにVRM require(option) bones,という欄があります。
そこの requireの方のAdd ~~ boneをクリックします。すると、ボーンを設定できるようになるので、そこでhumanoid属性を紐づけしてください(
- 名前の属性にあたるボーンを指定してください
- 出力時にボーン名が変わっていたりするとエラーになります
- requireは抜けが許されません(0.0仕様で）　optionは抜けが許されます

#メッシュについて
- モディファイアはすべて適応しておいてください。シェイプキー持ちは拙作 https://github.com/iCyP/Add_Modifier_Applied_Object_forBlender2_8 でメッシュを選択してオブジェクトモードで右クリック->Add Modifier applied ~~ をすればバウンティングボックス横にメッシュが作られるので便利かもしれません（ｳｪｲﾄ転送がいまいちかも…
- すべて三角形に分割してください。面倒な人はctrl+Tを押せば自動で割れます。
- UV展開しておいてください。また、出力時には１つだけにしておいてください。複数ある場合すべて出力されるはずですが、VRMはTEXCOORD_0（１番目のUV）の一つしか使いません。容量の無駄遣いになります。
- ボーンウェイトは４つまでです。
- マテリアルの設定については https://nico.ms/sm36033523?from=74 を見てください。制限が厳しいです。

#ライセンス設定について：
アーマチュアのオブジェクトの方のカスタムプロパティに全部あります。書きましょう。
<img width="362" alt="コメント 2019-12-05 133752.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21368/ebdaaec0-dc5b-e24a-080b-558c073886dd.jpeg">

#firstperson, springbone などについて
テキストエディタにjson形式で書かれています。(Add VRM attributeしていれば最低限のひな型がすでにあります)頑張ってください。(uniVRMにもっていった方が楽です)
## springboneのcolliderについて
importしたことがある人はお気づきかと思いますが、ボーンの直属の子emptyがそのボーンのcolliderになっています、名前はどうでもいいです。
設定は同じことをすればよいです。（ボーンの子emptyをつくって移動させてempty_display_sizeを調節する
スケール（Sキー）で大きさを調節せず、empty_display_sizeで調節してください。後者をｺﾗｲﾀﾞｰのサイズに使います。

#出力
アーマチュアとメッシュをすべて選択してexport->vrm
Translationをonにしていて、OSのロケールが日本なら、エラーメッセージは日本語です。読んで意味がわからなければ作者(私)に言ってください。何とかなるかもしれないし何とかならないかもしれません。ﾂｲｯﾀｰが有効ですが、githubのissueが最適です（pythonのdictの説明などはご勘弁願います)

雑文ご拝読ありがとうございました。
未経験がいまさらCCENTを取ろうとしてみる！＃０

初めまして、たたまるです。
#初めに自己紹介と経緯
私は11月に建設業からIT企業に転職しました、2019年中は社内で研修の予定でしたがなぜか12月から現場に行くことになりました
入社してから社内のシステムに慣れてきたところで、本格的に業務に必要な知識を蓄えていかなければなりません
そこで何かベンダー資格を取ることになり、cisco製品を扱うことが多いいらしいのでciscoの認定試験を受けることになりました

#まずやったこと
どの資格でも共通して言えますがまずは**試験の日取り**を決めてゴールの設定をすることです
私の場合は2月23日で今の試験体制が変わってしまうので、2月23日までに資格の試験を受けなければなりません
なので私は試験の日を2月23日に設定しました
次にテキストを買いました、ネットで調べて**黒本**なるものがあるらしいのでそれを使うことにしました
あとは、社内にあるネットワーク関係の本を読んで基礎知識をしっかりと付けている段階です

#最後に
私はネットワークに関する知識はありませんがこれからしっかり知識をつけていきます
この資格取得を意味のあるものにしたいと思っています


投稿が止まったら察してください（笑）
C言語の関数,ポインタまとめ（前半）




参考にした本：粂井康孝『猫でもわかるC言語プログラミング　第３版』SB Creative

注意：全角で空白を入れるとエラーがでる。

##第6章：関数（p129）

１.プロトタイプ宣言を行う。　例：int func(int, int);

２.%dで後の変数を埋め込める。　例：printf("%d x %d = %d\n", a, b, c);

３.関数は引数int aなどで指定する。

４.return cなどで返り値を指定する。　


```C
/*かけ算して返す*/

#include <stdio.h>

/*プロトタイプ宣言*/
int func(int, int);

int main(){
    int a,b,c;

    a = 10;
    b = 20;
    c = func(a, b);
    printf("%d x %d = %d\n", a, b, c);

    return 0;
}
int func(int a, int b){
    int c;
    c = a * b;

    return c;
}
```


５.static変数：プログラムが終了するまで値を保持する。


```C
/*値を足していく*/

#include <stdio.h>

int add(int);

int main(){
    int sum;

    sum = add(10);
    printf("sum = %d\n",sum);

    sum = add(20);
    printf("sum = %d\n",sum);

    sum = add(100);
    printf("sum = %d\n",sum);
    
    return 0;
}
int add(int x){
    static int gokei = 0; //記憶クラス指定子
    gokei += x;

    return gokei;
}
```
##第7章：ポインタ（p150）
&i：変数iのアドレス表示、&を変数の前につける
→変数のアドレスを他の変数に代入出来ないかを考える！

```C

/* アドレスを求める*/

#include <stdio.h>

int main(){
    char c;
    int i;
    double d, e;

    /*%pはアドレス埋め込み用の書式指定*/
    printf("変数のcのアドレスは%pです\n", &c);
    printf("変数のiのアドレスは%pです\n", &i);
    printf("変数のdのアドレスは%pです\n", &d);
    printf("変数のeのアドレスは%pです\n", &e);    

    return 0;
}
```
bcc32cによるコンパイル、のち実行結果　↓

```
C:\kadai>bcc32c sample_04.c
Embarcadero C++ 7.20 for Win32 Copyright (c) 2012-2016 Embarcadero Technologies, Inc.
sample_04.c:
Turbo Incremental Link 6.75 Copyright (c) 1997-2016 Embarcadero Technologies, Inc.

C:\kadai>sample_04
変数のcのアドレスは0019FEF7です
変数のiのアドレスは0019FEF0です
変数のdのアドレスは0019FEE8です
変数のeのアドレスは0019FEE0です
```

後半：配列、文字列とポインタ
getElementByTagNameの使い方！divだけ取り出す方法【備忘録】



```HTML
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="UTF-8">
  <title>divだけ取り出す方法</title>
</head>

<body>
  <div>要素1(div)</div>
  <p>要素2(p)</p>
  <div>要素3(div)</div>
  <span>要素4(span)</span>
  <div>要素5(div)</div>

  <input type="button" value="取得" onclick="showElements()">

  <script>
    function showElements() {
      const elements = document.getElementsByTagName('div');
      for (let i = 0; i < elements.length; i++) {
        console.log(elements[i].innerText);
      }
    }
  </script>
</body>

</html>
```
'op_Addition' という名前のメソッドが含まれないため、メソッドの呼び出しに失敗しました。

#ググってトップに出なかったけど、わかれば何とはないエラー
Office365の設定にPowerShellいじってて基本的なところで躓いたのでメモ。

以下だと２ループ目以降「'op_Addition' という名前のメソッドが含まれないため、メソッドの呼び出しに失敗しました。」というエラーになる。

```powershell
$mbxs = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited
foreach ($mbx in $mbxs){
  $alias = ${mbx}.alias
  $item =(Get-MailboxFolderStatistics $alias | ? {$_.FolderType -eq "Calendar"})
  $output+=New-Object PSObject -Property @{name=$item.name;Identity=$item.Identity}
}
$Output|Out-GridView
```

「\$Outputは配列だよ(``` $output=@()```)」、って書いてやるだけでした。

```powershell
$mbxs = Get-Mailbox -RecipientTypeDetails UserMailbox -ResultSize Unlimited
$output=@()
foreach ($mbx in $mbxs){
  $alias = ${mbx}.alias
  $item =(Get-MailboxFolderStatistics $alias | ? {$_.FolderType -eq "Calendar"})
  $output+=New-Object PSObject -Property @{name=$item.name;Identity=$item.Identity}
}
$Output|Out-GridView
```

(参考)
[PowerShellで全ユーザーの予定表権限を変更 - 日々徒然](https://blog.o365mvp.com/2015/05/26/change_calendar_permission_of_all_users/)
boost.diのannotations `BOOST_DI_INJECT(Hoge , (named = int1) int a, double b)` みたいな文法ってどういう原理なの?

※boost.diそのものに関する話は出てきません。ご了承ください
この記事は 2019C++アドベントカレンダー (https://qiita.com/advent-calendar/2019/cpp) 5日目の記事になります

# boost.diのannotations 
[boost.di](https://boost-experimental.github.io/di/)には(今気にすべきことだけを言うと)「オブジェクトの構築を補助する機能」が含まれている
その中にはannotationsというものがあり、以下のようにコンストラクタ引数に名前を付ける機能がある

```C++
// 名前用型
auto int1 = [] {};
// 型定義
struct Hoge {
  BOOST_DI_INJECT(Hoge , (named = int1) int a, double b) // aに"int1"という名前を付ける
     : a(a), b(b) {}
  int a = 0;
  double b = 0;
};
```

```C++
auto injector = di::make_injector(
    di::bind<int>().named(int1).to(42)  //intでint1という名前のパラメタを42で初期化
    , di::bind<double>().to(3.14)  // doubleのパラメタを3.14で初期化
);
auto x = injector.create<Hoge>(); // 便利に構築。何が便利なのかはboost.diのドキュメントかDIに関する記事を読んでくれ 

// 想定通りにオブジェクトが構築された
std::cout<<x.a<<std::endl;  // 42
std::cout<<x.b<<std::endl;  // 3.14
```
https://wandbox.org/permlink/CvgqL0NBjJEcRtPr

しかし、`BOOST_DI_INJECT(Hoge , (named = int1) int a, double b)` の `(named = int1) int a`という文法はC++的に考えて奇妙だ。しかもこのannotations、付けてもつけなくてもよい
これはどういったトリックだろうか?


# 大雑把な実装原理

```C++
#define B(_) A
#define TEST(X) B X
```
上のようなマクロを書いたとき、`TEST(X)`の`X` が 

- `(hoge) 1` の場合: `B(_)`で置換されてtoken列 `A 1` になる
- `1`の場合: それ以上置換できるルールが存在しないのでtoken列 `B 1`になる

ことを利用している


# もう少し具体的な挙動

```C++
#define PP_CAT(L,R) PP_CAT2(L,R)
#define PP_CAT2(L,R) L##R
#define AA 1,
#define AB 0,
#define B(_) A
#define TEST(X) PP_CAT(A,B X)
```

- `TEST((1)1)`は
  - `TEST((1)1)` -> `PP_CAT(A,B(1)1)` -> `PP_CAT2(A,A 1)` -> `AA 1` -> `1,1` のように置換される
- `TEST(1)`は
  - `TEST(1)` -> `PP_CAT(A,B 1)` -> `PP_CAT2(A,B 1)` -> `AB 1` -> `0,1` のように置換される

このように置換すれば最終的にいい感じのtoken列に変換できるので、あとはマクロなりで好きな個所を取り出しいい感じに使える `using type = なんとか` でもなんでも生やしてほしい

https://wandbox.org/permlink/HYQfxPdQiKjErjbv

# boost.diにおける実装
https://github.com/boost-experimental/di/blob/v1.1.0/include/boost/di/aux_/preprocessor.hpp#L102
この行のあたりの挙動を追ってほしい
管理者権限でバッチファイルを実行しファイルをコピーをするとコピー後のファイルの所有者はローカルのAdministratorsグループになる

# 気づき
ファイルをコピーするバッチ処理があって、それを管理者権限で実行した後で、
コピーされたファイルを編集し保存しようとしたら、
なぜか保存できなかった（アクセス拒否）ので、アレっと思いまして…。

# 管理者権限でのファイルコピー
今、あるPCにログインしているユーザーXが、Administratorsグループには入っていないとします。
また、ファイル「コピー元.txt」があり、所有者が「ユーザーX」だったとします。

※所有者の確認方法
　ファイルのプロパティ＞セキュリティタブ＞詳細設定ボタンで開く画面上に記載があります。

このファイルを別のファイル「コピー先.txt」にコピーする単純な処理が書かれたバッチファイル「filecopy.bat」を用意します。

```
copy コピー元.txt コピー先.txt
```

* ユーザー権限で実行したときは元のファイルと所有者が変わらない
「filecopy.bat」をダブルクリックして実行すると、「コピー先.txt」が作成されます。
「コピー先.txt」の所有者を確認すると、「コピー元.txt」と一緒の「ユーザーX」になりました。

* 管理者権限で実行したときはAdministratorsグループになる
「filecopy.bat」を右クリックして「管理者権限で実行」を選択して実行すると、「コピー先.txt」が作成されます。
「コピー先.txt」の所有者を確認すると、「ユーザーX」ではなく **「PCのローカルのAdministratorsグループ」** となっていました。


つまり、「気づき」のところに書いた事象は、↑のファイルコピーの例でいうと、
「コピー先.txt」にアクセス権のない「ユーザーX」で編集し、保存しようとしたため、
保存できなかった（アクセス拒否）ようです。

# あたりまえと言えばあたりまえ
管理者権限を利用して行ったことなので、あたりまえと言えばあたりまえなのですが、気づきにくいことなので注意せねば…と自戒。
R.swiftを使っていてビルドしたらビルドエラーが発生した話

こんにちは。私です。
最近はswiftを頑張ってます。
今回はライブラリ導入頑張ったのにR.swiftでビルドエラーが発生して泣いたお話です。

## R.swiftを導入した
先輩から「コード規約に沿って綺麗にソースコードを書けるよう『swiftlint』と『R.swift』を入れておいてね。」と言い渡された私。
まずライブラリ導入が苦手な私。
ライブラリ導入手順についてはこちらのGitHubを参照してください。
[R.swift_GitHub](https://github.com/mac-cain13/R.swift)
頑張りました。

##手順通りやったのにエラーが発生した！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217071/b6624aab-bdb9-5bb9-c3bb-21a64ac1cce1.png)
エラー内容を確認すると『Run Script』に記載した内容でエラーが発生してました。
GitHubに倣ってRun Scriptに
`"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/R.generated.swift"`
を記載していたのですが、調べてみるとこちらの記法は古いようです。

##バージョンアップされていた！
バージョンアップでスクリプトの記法が変更されたようです。
[R.swift_GitHubアップグレード](https://github.com/mac-cain13/R.swift/blob/master/Documentation/Migration.md)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/217071/c964351a-7a2d-7169-40f0-b55a13306e7c.png)

要約させていただくと
！スクリプトが変更されました
→`"$PODS_ROOT/R.swift/rswift" generate "$SRCROOT/[YOUR_PATH]/R.generated.swift"`
！Input Filesに以下を入れてください！
→`$TEMP_DIR/rswift-lastrun`
！Output Filesに以下を入れてください！
→`$SRCROOT/[YOUR_PATH]/R.generated.swift`

こちらを対応させるとビルドエラーが解消されました！
アップグレードで明示的な出力ファイル指定が必要になったようです！
[YOUR_PATH]には自身のプロジェクトに合わせて変更してください！


## さいごに
調べてもなかなか事象がなく、困りましたが同じ現象が起きている方の助けになれればと思います。
では皆様、綺麗で良いswiftライフを٩( 'ω' )و
Firebaseをなるべく安い料金で頑張りたい人へ

この記事は[Firebaseアドベントカレンダー](https://qiita.com/advent-calendar/2019/firebase)の5日目の記事です。

どうも！ハムカツおじさんという名前でtwitterやってます([@hmktsu](https://twitter.com/hmktsu))🤘
自分でだったり弊社でだったりなどFirebaseを使ってサービスを作っています。

ちなみに先日Firebase Meetup #15 Cloud Functions Dayにて下記のスライドを発表させていただいたので、興味ある人はご覧になってください！
[Firebaseオンリー + React Nativeでアプリを作ると果たして簡単になるのか？](https://speakerdeck.com/watanabeyu/firebaseonri-plus-react-nativedeapuriwozuo-rutoguo-tasitejian-dan-ninarufalseka)

## はじめに
色んなツールを作るのにFirebaseを使うととても便利だなぁという感想を持っています。
料金に関しては体感としてですが常時サーバを立ち上げてるのとは違いお安くなります。
それでももっと安く済ませたいとかそういったことはあるのでしょうか。

本番環境でそれなりにお金がかかるのはしょうがないんだけども、テスト環境ではなるべくお金かけたくないしなぁ〜ということもあるのではないでしょうか。


ということでここらへんを気をつければなるべく料金を抑えれるんじゃないかなということを今回は紹介させていただきます。

## 対象とするFirebaseのサービス
* Firestore
* Functions
* Hosting

## ざっくり気をつけたポイント

### Firestore
* リージョンをどうするか
* ドキュメントの読み出し/書き込み/削除
* ページングの方法
* セキュリティールールについて

### Functions
* メモリ(CPU)の割り当て
* 料金プラン

### Hosting
* どういったファイルを置いているのか

## こういう風に工夫するとよいかも

### Firestore
* USじゃないといけない理由がないならば他のリージョンを使う
    * USはマルチリージョンなのでちょっと他よりもお高め([地域別料金](https://firebase.google.com/docs/firestore/pricing?hl=ja#pricing_by_location))
* このデータが入っているか？という確認をしたいときに、コレクションからwhereするのではなく、複数のドキュメントを配列に格納したドキュメントを用意して、その中に入ってるかどうか比較する
* 読み出しをする際にオフセットを使わないでカーソルを使う
    * オフセットを使うとそれ以前のデータも読み取り回数に入ってしまう([大きな結果セットを管理する](https://firebase.google.com/docs/firestore/pricing?hl=ja#large-result-sets))
* ルールの評価はリクエストごとに1回のみ課金されるので、複数ドキュメントを呼び出すときはえいやと思い切って呼び出してみる([Cloud Firestore セキュリティ ルール](https://firebase.google.com/docs/firestore/pricing#firestore-rules))

### Functions
* メモリ量でGB秒やCPU秒の料金が変わるので、さっと終わる処理ならばメモリを小さくする([コンピューティング時間](https://cloud.google.com/functions/pricing?hl=ja#compute_time))
* Blazeプランを使うと料金プランページに表示されているSparkプラン以上に無料で使える範囲が広くなる

### Hosting
* Storageと比べると転送量や保存量が割高なので、Storageに画像とかをちゃんとおく

## まとめ
正直なところFirebaseはAWSなどで組むのと違ってあまりお金はかかりません。
それにスケーラブルなので落ちないという利点もあります。

ただその代わり[この記事](https://gigazine.net/news/20180803-spent-much-money-in-firebase/)みたいに落ちないからこそ、使い方などを間違えてしまうと異常な料金になってしまうこともあります。
地味によくある話としてはStorageを使わずにHostingのみでWebサイトを作り、バズってしまったがために中々な請求金額がきてしまうとか。

ちなみに最終手段ですが、1日の使用料を実は制限することができます。
また1ヶ月の予算を設定して使用料に応じてアラートを出すこともできます。
[1日あたりの費用制限を設定する](https://firebase.google.com/docs/firestore/quotas?hl=ja#set_spending_limits)
[1か月の予算を設定する](https://firebase.google.com/docs/firestore/quotas?hl=ja#budget)

これらを使うこともある意味ありなんじゃないかなと思います。
IonicはナビゲーションしてもngOnDestoryが呼ばれない！

Ionic Advent Calendar 2019
5日目の記事です。

もともとAngular で開発経験のあった私が、ionicも似たようなもんやろ！と思ってろくにドキュメントも読まずに開発していてハマった、ページのスタックについて書きます。

# Ionicは一度表示したページをスタックしている

Ionic では、Angular の```<router-outlet /> ```を継承・拡張した```<ion-router-outlet />```というrouter outletが使われています。これによってAngularのナビゲーションとは異なり、ナビゲーションした後も、ナビゲーションする前のページをDOMに残すスタック方式のルーティングになっています。

以前特定のページにHostlistener でkeydown event を登録していたところ、そのページを表示して以降ずっとそのkeydown event が有効になってしまったことがありました。これはページをスタックしていたために起こっていたようです。

# スタックされると何が変わる？

この記事のタイトルにもあるように、コンポーネントが破棄されないので、Angularのライフサイクルメソッドである```ngOnInit```は最初に呼ばれたときだけ、```ngOnDestory```はスタックから破棄されるときだけ呼ばれます。

なのでAngularでよくやる、```ngOnInit```でObservableをsubscribeして```ngOnDestory```でunsubscribeするみたいなコードを書くと、一度表示されたらそれ以降スタックから破棄されるまでsubscribeし続けてしまいます。

# スタックを消したいとき

ユーザーがログアウトした後など、今までのスタックを全部消して新しく始めたい場合は、下記2つの方法で実現できます。

- template側: ```routerLink```のプロパティ```routerDirection="root"``` を併記する
- ts側: ionic-angular の```NavController.navigateRoot()``` を使う

# Hostlistener はどうすればよかったか

Hostlistenerでイベントを登録するとコンポーネントが破棄されない限り登録を解除できないので、コンポーネントに```isDisplay```みたいなプロパティを持ってIonicのライフサイクルメソッドで更新、Hostlistenerに```isDisplay```のガード節を追加すればよかったと感じています。

# まとめ: 素直にIonicのライフサイクルメソッドを使おう

色々試してみたところIonicのスタックは、IonicがよしなにPushしたりPopしたりしてくれる様でOnInitやOnDestoryがいつ呼ばれているかイマイチ分かりづらいので、OnInitやOnDestoryは使わずにIonicのライフサイクルメソッドを使った方が良さそうです。

もともとAngularを使っている人がIonicを使ったときのつまづきポイントである、ページのスタックについてでした！
KubernetesのHPAを試験する際のサンプル

超小ネタです。メモ程度。KubernetesのHPAが正しく動作しているか確認する時のyamlのメモ書き。

# 前提
- HPAの導入が済んでいる
- HPAが正しく動いているか調査する際のコマンド

# 1. hpa-test.yaml を作成する
以下のファイルを作成する

``` hpa-test.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hpa-deploy
  minReplicas: 1
  maxReplicas: 2
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 50
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: hpa-deploy
spec:
  replicas: 1
  template:
    metadata:
      name: hpa-app
      labels:
        app: hpa-app
    spec:
      containers:
      - image: frapsoft/openssl
        name: openssl
        command: ["sh", "-c", "openssl speed -multi `grep processor /proc/cpuinfo|wc -l`"]
        resources:
          limits:
            cpu: 2700m
            memory: 4000M
          requests:
            cpu: 2700m
            memory: 4000M
```

## 以下は必要に応じてパラメータは変更ください
- maxReplicas
- targetAverageUtilization
- resources.limits
- resources.requests

# 2. apply する

```
$ kubectl apply -f hpa-test.yaml
horizontalpodautoscaler.autoscaling/hpa created
deployment.extensions/hpa-deploy created
```

# 3. hpaを確認する
直後はまだ計測できない。30秒に一回計測されるので少し待つ

```
$ kubectl get hpa hpa
NAME   REFERENCE               TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
hpa    Deployment/hpa-deploy   <unknown>/50%   1         2         1          42s
```

opensslコマンドがマルチCPUをフルで稼働させてくれるので、以下の通りに96%使用し、REPLICASが2になりスケールしている。

```
$ kubectl get hpa hpa
NAME   REFERENCE               TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
hpa    Deployment/hpa-deploy   96%/50%   1         2         2          2m51s
```
getElementByIdの使い方【備忘録】



```HTML
<!DOCTYPE html>
<html lang="ja">
<head>
  <title>Document</title>
</head>
<body>
  <p id="result">pタグの文字列です。</p>
  <!--onclickはボタンが押されたときにshowを読むことができる!-->
  <input type="button" value="取得" onclick="show()">
  <script>
    //show関数を作る
    function show() {
      //変数を定義
      const result = document.getElementById('result');
      //innerTextプロパティを使うことで「pタグの文字列です。」を取得することができる
      console.log(result.innerText);
      const nowDate = new Date();
      result.innerText = nowDate.toLocaleString();
    }
  </script>
</body>
</html>
```
vue sass-loader エラー：Module build failed: TypeError: this.getResolve is not a function

##背景##

```
$ npm install sass-loader --save-dev
```
をinstallして、$npm run devを実行すると、

下記のエラーが出た。

```
Module build failed: TypeError: this.getResolve is not a function
```

##原因##

sass-loaderのバージョンは最新すぎる


##解決策##

まず、sass-loaderをuninstallする

```
$ npm uninstall sass-loader
```

後、若干古いバージョンをinstallしたら、ok

```
$ npm install sass-loader@7.3.1 --save-dev
```
Pub/Subメッセージングモデルの業務利用における難しさ

# はじめに
[フューチャーAdvent Calendar 2019](https://qiita.com/advent-calendar/2019/future) の4日目ですが、遅れて5日目に書いています。

この記事ではPub/Subを業務利用しようとして難しさを感じた点についてまとめ、どんな苦労をしたのかをちょっとだけ書きます。

背景としてはmosquittoやkafkaといったPub/SubブローカーからPubあるいはSubするアプリケーションをGoで作成してどのような形で業務利用できるかを考える機会がありました。

# Pub/Subメッセージングモデルとは

以下の３つの要素で構成されるモデルです。

- メッセージを仲介する**Broker**
メッセージをためている部分
Topicという論理的なチャンネルにメッセージを紐付けて管理する

- メッセージを発信する**Publisher**
Topicを指定してメッセージをBrokerに投げる

- メッセージを受信する（取りに行く）**Subscriber**
Topicを指定して（指定しないで取れるBrokerもある）メッセージを取りに行く

### Pub/Subメッセージングモデルの利点
一般的なPub/Subメッセージングモデルの利点は以下の2点です。

- **疎結合**
    - プロトコルとTopicのみ知っていればPublisherとSubscriberは相互に知らなくてもやりとりが可能である


- **スケールがしやすい**
    - PublisherとSubscriberはそれぞれ別々に動的にスケール可能である
    - Brokerの仕様次第ではあるが、1つのTopicを複数のパーティションに分けることによって並列にメッセージを処理できる

# Pub/Subメッセージングモデルの難しさ

- **順序制御が難しい**
    
スペックをあげるためにTopicのパーティションを分割すると、結構順番が乱れがちである。
業務利用においていえば、順序を制御しないといけないといけないケースは多々あり、FIFOのキューイングサービス使えば良いのではないかと思ってしまう。

- **スケールが可能であるとはいえスケール可能な設計が難しい**

Publisher・Subscriberともに動的に増やせるが業務では更に他のシステム・サービスと連携をすることが多く、実際のところスケール可能な点がどの程度活かせるかが設計にかかっており、その設計が非常に難しい

- **PubとSubの間はPubからSubへの経路しかないため、リトライなどがしにくい**

 Subscriber側でエラーが出てもPublisher側に通知する機能はないため、単独では一方向のコミュニケーションしか行えない。

- **多くのPub/SubデフォルトのQos1だと重複してデータがBrokerに入る可能性がある**

 Subscriber側で重複を許容できるようにする必要がある

# 業務的にPub/Subメッセージングモデルを取り入れやすいケース

とはいえ業務利用ができないかと言われれば実際上記難しさを克服できるケースであれば利用可能であるとは考えられます。

- **順序制御がいらないケース**
直前の状態に左右されない、例えば通知システムであれば利用は可能であると思われます。
0,1の状態を繰り返し直前の状態に左右されるようなシステムでは利用は難しいですが、例えばメールのPUSH通知など一つ一つのメッセージが独立して意味があるケースでは利用可能です。

- **メッセージの流量が多くないケース**
ピークがあるようなシステムだと難しいです。
ただ流量が少なくパーティションが1でも処理できるようなケースであれば順序が乱れることも少なく、安定して運用することは可能ではないかと考えられます。

# Pub/Subメッセージングモデルを外側から支える
- **Publisherの前で順番をメッセージに振り、Subscriberで受け取ったメッセージを順序通り次処理に投げれるようにになるまで滞留させる**

Sub側のシステムで待たせれば、順番通りにして次の処理に投げることも（試したことはないですが）できるとは思います。
ただ、Qos0だと無限に待つ可能性があるので、利用するBrokerのプロトコルや設定次第だと罠はありそうです。

- **Subscriber側で流量を制限する**

Subscribe側の処理が終わるまで次のメッセージを受けるのをBlockします。ただ注意が必要なのはPubの量が常にSubの量より多い場合どんどんPubしてからSub側の処理までの時間が伸びていきます。

- **Publisherの前にAPIサーバを構える**

セキュリティやバリデーションを考える場合、Brokerにユーザごとの権限の制御をもたせることはできないのもあり、またどのようなメッセージをも許容できてしまうため、外部システムとの連携ではAPIサーバを建てるということも考えられます。

- **Subscriber側で重複許容処理をいれる**

もともと重複しても問題ないような処理であれば良いですが、重複が許容されない場合はPub側でidを入れてSub側で同じidを排除するような機構をいれることが望ましいです。


# 実際にどんなところでハマったか

工場IoTで機器の故障を通知するようなシステムを作成するにあたって、私がプロジェクトに入る前に工場側でPubしてサーバ側でSubする方向になってました。
サーバ側の開発を私が受け持っていました。機能としては簡単で、機器が正常と異常の間で変化があった場合に通知をすると言ったものです。
ここで正常と異常を無限に繰り返すテストプログラムを流したところでハマりました。

サーバで受け取れるメッセージ（想定）
`正常→異常→正常→異常→正常→異常→正常→異常→正常`

出る通知（想定）
`なし→通知→通知→通知→通知→通知→通知→通知→通知`

サーバで受け取れたメッセージ（実際）
`正常→異常→正常→異常→正常→正常→異常→異常→正常`

出る通知（実際）
`なし→通知→通知→通知→通知→なし→通知→なし→通知`

ちなみに実際に想定の7割ぐらいしか通知は出ませんでした。
ただ、tpsを下げれば通知回数は想定数と一致したので、
高負荷でパーティションが詰まることがあることが大きな要因のようです。
そこでは実際想定される理論値で問題がなかったためOKが出ましたが、
負荷が大きいような状況だと厳しいことが伺われました。


# まとめ
疎結合であるという点は間違いなく魅力的なので、うまく使えるシチュエーションを見つけて利用するにはPub/Subメッセージングモデルは有用です。
ただ、流行に乗っかってわけもわからず使うというには趣味ならばともかく、業務で利用するにはしっかりとした設計が必要であると感じました。


余談ですが、別の会社で働く友人はQueueですらあまり使いたくない、なるべく同期処理でやらないと怖いとのこと。
実際私も疎結合を意識しなくて良いのであればPub/Subは考えることが多いのであまり使いたくないとハマって思いました。
順序が乱れて宇宙の法則が乱れるので、、、
VSCodeでWARNING: CocoaPods requires your terminal to be using UTF-8 encoding.が発生する


Flutterの開発でVSCodeを使用していますがなぜか
VSCodeからiOSをrunする場合、cocoapodsの以下のようなエラーが発生しました

```
WARNING: CocoaPods requires your terminal to be using UTF-8 encoding.
```

Flutterのversionは`v1.9.1+hotfix.6`です

```
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, v1.9.1+hotfix.6, on Mac OS X 10.14.6 18G95, locale ja-JP)
```


Terminalからflutter runすると問題なく起動できますが
F5での起動ができないと困るので以下の設定をVScodeのsettings.jsonに追記します

```settings.json
   "dart.env": {
        "LC_ALL": "ja_JP.UTF-8",
        "LANG": "ja_JP.UTF-8"
    }
```

master channelには修正が入ったようなのでstableに修正が落ちてきたら設定が不要になるはずです
https://github.com/Dart-Code/Dart-Code/issues/2035
マークアップする人に教えたいPhotoshopとIllustratorの小技

## 時間短縮のための2つの小技
私たちの会社は分業制でデザインをする人とマークアップする人が分かれています。
なので、デザインをする人がマークアップ言語詳しく知らない様に、マークアップする人もデザインツールに対して知らない事が多いです。
そこでマークアップする時に使えそうなPhotoshopとIllustratorの小技を紹介したいと思います。

## Photoshopの小技「コンテンツを置き換え」
デザインのOKが出てテストアップまでした段階で、使っているレンポジ画像を本番画像にして下さいとなる事があります。
デザイン側はレンポジ画像を本番画像にしてマークアップ側にデータを渡しますが、マークアップ側には新たに渡されたデータをスライスやグループ名を整えなければなりません。
そこで紹介したのはPhotoshopの「コンテンツを置き換える」機能です。
この機能を使えば簡単にレンポジ画像を本番画像に置き換える事ができます。

### Photoshopの「コンテンツを置き換え」の使い方
例えば、以下のレンポジ画像にはウォーターマークが入っておりサンプル画像なので、そのままでは世に出すことはできません。また、大きさもバラバラであり得ないほど変形した画像もあります。
これらを１つずつ大きさを整えたりして本番画像にしていくのは大変です。

<img width="1000" alt="01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168967/04f36eb9-ef74-fe08-c9b5-c2905c997d5f.png">

まず、差し替えたい画像のレイヤーを右クリックするとメニューが開かれるので「コンテンツを置き換え」を選択します。

<img width="1000" alt="02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168967/6aa52b74-6917-4811-6f25-bceaecd837d8.png">

すると、画像を選択する画面が出るので置き換えたい本番画像を選択し配置をクリックします。

<img width="1000" alt="03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168967/95087f94-9983-50b8-1e53-5508cb179c4e.png">

以上でウォーターマークの無い本番画像に置き換えれます。また、大きさもバラバラであり得ないほど変形した画像があったとしても同一の画像であれば一緒に置き換えてくれます。

<img width="1000" alt="04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168967/db8d54a6-1dd8-4227-eb92-50af78117aab.png">

この機能はとても便利で大きさが違っても比率さえ同じであれば同じ様に配置してくれます。
今回の画像も置き換え前と置き換え後ではサイズが５倍以上違いましたが比率が同じなので、サイズは勿論の事位置も1pxのズレなく配置されました。
しかし比率が違う画像を置き換えるとズレる事もありますのでご留意下さい。


## Illustratorの小技「CC ライブラリ活用術」

Illustratorのデータからマークアップする場合、アセット書き出しを使うと思います。
ただ、アセット書き出しを使う上で1つ弱点がありマスクをした状態の画像を書き出すと、画像の元のサイズ分だけ余白が出来てします。

<img width="1000" alt="05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168967/4eabe4c0-cc60-8084-e876-97633f94cf3b.png">

この余白を一々Photoshopに取り込みトリミングするのは億劫です。
そこで活躍するのがIllustratorの「CC ライブラリ」機能です。
「CC ライブラリ」に入れ、取り出す事でマスクの外にあった画像の余白を無くしてくれます。 

<img width="1000" alt="06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168967/92508543-ac02-82f6-79e6-1fcc9c3efc7b.png">


そして、取り出した画像をいつも通りアセット書き出しすると余白の無い画像の出来上がりです。

<img width="1000" alt="07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168967/9bb07ab4-d765-1aad-3cff-23db2fa2810c.png">

かなり簡単なので是非お試し下さい。
と記事を作りながら色々と調べていたらCC 2020で余白出なくなったみたいですね。
CC 2020に上げる予定の無い方は是非お試し下さい。

## まとめ
以上で小技の紹介を終わります。少しでも参考になりましたら幸いです。
AWSの避けるべき五つの間違い

開発者およびシステム設計者のMichael Wittigは、Cloudonoutブログで、AWS（Amazon Web Services）を使用する際の最も一般的な誤りに関する興味深い[記事](https://cloudonaut.io/5-aws-mistakes-you-should-avoid/)を投稿しました。 この記事の要点をご紹介します。

WittigはAWSコンサルタントとして働いており、サイズに関係なく多くのシステムを見てきたそうです。ほとんどの場合、これらは標準のウェブアプリケーションです。 彼は、避けるべき5つの最も一般的な間違いのリストを紹介しました。

#典型的なWebアプリケーション

標準のWebアプリケーションは次のものが含まれています。

- ロードバランサー
- スケーラブルなサーバーサイド（ウェブバックエンド）
- ストレージ

図では、次のようになります。

![05f1b63b8cf645a5a5b0c2c1ccd5f190.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435418/c532bc1f-e0be-6f97-f99a-1b1f1d9c165a.png)

これは一般的なパターンです。 他の方法を使用してアプリケーションを設計する正当な理由がなければなりません。

#間違い1.インフラストラクチャを手動で管理すること

コンソールを使用してAWSのリソースが作られているということは、インフラストラクチャが手動で管理されているということです。この制御オプションの主な問題は、リソースの設定は再現できず、どこにも登録されていないことです。その結果、多くのエラーが発生する可能性があります。幸いなことに、この問題を無料で解決できるAWS CloudFormationがあります。

リソース（EC2インスタンス、セキュリティグループ、サブネット）を手動で作成する代わりに、テンプレートでリソースを記述したり、独自に作成したり、既製のものを使用したりできます。 CloudFormationは、それらを現在のスタックに統合する方法を処理します。図の通り、このサービスが正しい順番にリソースを作成してくれます。

![d8b6068c0608412cbe155d2d21b8409a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435418/17700918-d057-79cf-f021-7365d61dac59.png)

#間違い2. Auto Scalingグループを使用しないこと

一部の人は、特別な機能に頼らずに自分でリソースを拡張できると信じています。もちろん、それは大間違いです。各EC2インスタンスはAuto Scaling Groupで実行される必要があります。独自のインスタンスであっても。 Auto Scaling Groupは、必要な数のインスタンスの起動を制御します。実際、仮想マシンの論理グループのように動作します。この機能は無料で使用できます。

標準のWebアプリケーションでは、サーバーはAuto Scaling Group内の仮想マシンの中に起動されます。負荷に基づいてコンピューティングリソースの量を増加または減少させることができます。アドミニストレーターは、自動スケーリングを開始する条件を指定できます。これは例えば、論理グループのCPUパフォーマンスのしきい値または負荷分散のためのリクエストの数です。

#間違い3. Amazon Cloud Watchの分析を怠ること

AWSサービスに関する必然的なデータは、Cloud Watchから取得できます。 仮想マシンは、プロセッサの負荷、ネットワーク、ディスク操作について通知します。 ストレージは、メモリ使用量とI/O操作の数に関する情報を提供します。 これらの統計を正しく使用するのはあなたです。 一日のCPU使用率のメトリックスを見てみましょう。

![537fbd289f854db798acd9ad70904871.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435418/c5905c26-720c-8ed8-310c-32d8bc33c888.png)

ピークをご覧ください。Wittigは、この飛躍が毎日同じ時間に発生していると確信していました。

>タスクスケジューラが悪さしているように見えます。 やっぱりそうですね。 このマシンからWebサーバーが起動されたということはスケジューラにより毎日待機時間が増加していたということです。 別の仮想マシンでスケジューラを起動すると、問題は解決するはずです。情報はすべてCloudWatchにありますが、あなたはそれを見る必要があります！

メトリックを分析した後のステップは、メトリックのアラームを定義することです。 その逆ではダメです！

#間違い4.Trusted Advisorを無視すること

Trusted Advisorツールは、AWS環境がサービスを操作するベストプラクティスに準拠しているかどうかを確認します。 チェックされるのは：

- コストの最適化
- パフォーマンス
- 安全性
- 耐障害性。


Trusted Advisor管理コンソールが次のようになっている場合：
![c6eb9ac910fa4a66b4db171497b0ad20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435418/68fab6f1-76bc-a04f-610a-92958f9ebe39.png)
Wittig氏によると、環境内のプロセスの最適化を開始すべきです。

>まず、セキュリティに十分注意をした方がいいです。 毎週のフィードバック機能を使うと、Trusted Advisorは現在および解決済みのすべての問題について報告してくれます。 無料版と有料版があります。 有料版により検証の機能がさらに広がります。

#間違い5.仮想マシンの効率を管理しないこと

EC2インスタンスが十分に活用していないことに気付いた場合、インスタンスのサイズ（マシンの数またはc3.xlargeからc3.largeへ）を縮小しないようにする理由はありません。手動で管理されているインフラストラクチャなら話は別ですが。
十分に活用していないというのをどうすればわかると？ CloudWatchのメトリックスを確認してください！ とても簡単です。
Auto Scalingグループを使用している場合は、スケーリングする前にオートスケーリングルールとCloudWatchメトリックスを確認した方が良いです。

#おまけ

今度インフラストラクチャを確認するのはあなたの番です。
TikTokAdsAPIの取得に踊らされた件

# Developerアカウントの取得に至るまで
こんにちは、最近は各種広告媒体のAPIを叩いてばっかりのkumanomiです。
tiktokやbuzzvideoの広告宣伝費などをAPI経由で取得したくなりました。
特にどこかに関連記事があるわけでもなく、APIを叩くまでに無駄に時間がかかったのでメモしておきます。

## まずドキュメントをもらった
そしてドキュメント内にDeveloper登録にはここのアドレスにメールを送ってくださいみたいなことが書いてあり、そちらにメールを送りました。
しかしながら返信がありません。ドキュメントを送付してくださった方に再度問い合わせをすることになります。

## ドキュメントのお問い合わせのメアドが違う
申請時のメアドが更新されており、実際はこちらに送ってくださいとの連絡がきました

## 新しいメアドにメールを送ってみても返事がない
数日間返事がありません。追撃のメールもダメです。

# 正解はこちら
https://ads.tiktok.com/marketing_api/docs?id=6
広告のIDでログインしたのちに上のリンクへ行き`Register as a Developer`を押すだけ！
<img width="1147" alt="スクリーンショット 2019-12-04 14.50.46２.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170870/1f297c9a-c89c-bd16-8f0a-1a276d668499.png">

取得めちゃ簡単。

## 審査はあるけど・・・
APIを使うためには、アプリの申請が必要になります。
各種APIがあり、例えば広告投稿だったり広告宣伝費取得用だったり・・・。
APIごとにパーミッションがあり、どれを使うかの申請になります。

19時すぎに申請していたのですが、翌日の10時には通っていました。

![スクリーンショット 2019-12-04 18.28.18のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170870/c74cd936-a08b-9db3-70f0-03a99bd81082.png)
![スクリーンショット 2019-12-05 12.24.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170870/f2dde0bf-fbb3-c619-ea04-795794d99e48.png)

# まとめ
公式ドキュメントと渡されたものを信じてはいけない。
Webを信じろ。